diff options
author | ChulSeung Kim <charles0.kim@samsung.com> | 2017-06-21 09:50:28 +0900 |
---|---|---|
committer | ChulSeung Kim <charles0.kim@samsung.com> | 2017-07-03 10:55:31 +0900 |
commit | cdef57cbf5f07aaebfb18d6b772375b4a465e5b4 (patch) | |
tree | f914e7fd1de295e7962993a4acdccb673104083b /TVHome | |
parent | e87523555c57ae3b7c8730cd6d4905ad3887ca33 (diff) | |
download | home-cdef57cbf5f07aaebfb18d6b772375b4a465e5b4.tar.gz home-cdef57cbf5f07aaebfb18d6b772375b4a465e5b4.tar.bz2 home-cdef57cbf5f07aaebfb18d6b772375b4a465e5b4.zip |
TVHome Refactoring
- Seperate MainPageViewModel to severals
- Make a connection based on status(AppState, PanelState, PanelButtonState)
- Make it use event notification to change GUI
Change-Id: I7ccd85d15cc56410d9d64720cde1d25325abaf4e
Diffstat (limited to 'TVHome')
22 files changed, 2006 insertions, 1249 deletions
diff --git a/TVHome/TVHome.TizenTV/TVHome.TizenTV.cs b/TVHome/TVHome.TizenTV/TVHome.TizenTV.cs index c83c2c7..78845d8 100755 --- a/TVHome/TVHome.TizenTV/TVHome.TizenTV.cs +++ b/TVHome/TVHome.TizenTV/TVHome.TizenTV.cs @@ -120,25 +120,16 @@ namespace TVHome.TizenTV DbgPort.D("Key Pressed :" + e.KeyName); if (e.KeyName.CompareTo(ElmSharp.EvasKeyEventArgs.PlatformHomeButtonName) == 0) { - if (notification != null) - { - notification.OnHomeKeyPressed(); - } + notification?.OnHomeKeyPressed(); } else if (e.KeyName.CompareTo(ElmSharp.EvasKeyEventArgs.PlatformMenuButtonName) == 0 || e.KeyName.CompareTo("XF86Info") == 0) { - if (notification != null) - { - notification.OnMenuKeyPressed(); - } + notification?.OnMenuKeyPressed(); } else if (e.KeyName.Equals("Up") || e.KeyName.Equals("Down") || e.KeyName.Equals("Left") || e.KeyName.Equals("Right")) { - if (notification != null) - { - notification.OnNavigationKeyPressed(e.KeyName); - } + notification?.OnNavigationKeyPressed(e.KeyName); } } @@ -172,11 +163,11 @@ namespace TVHome.TizenTV string pinnedApp; if (e.ReceivedAppControl.ExtraData.TryGet(AppControlPort.KeyAddedAppID, out pinnedApp)) { - notification.OnAppPinnedNotificationReceived(pinnedApp); + notification?.OnAppPinnedNotificationReceived(pinnedApp); } else { - notification.OnAppPinnedNotificationReceived(""); + notification?.OnAppPinnedNotificationReceived(""); } } } diff --git a/TVHome/TVHome/Controls/MainPanelButton.xaml.cs b/TVHome/TVHome/Controls/MainPanelButton.xaml.cs index e7418e0..0d731aa 100755 --- a/TVHome/TVHome/Controls/MainPanelButton.xaml.cs +++ b/TVHome/TVHome/Controls/MainPanelButton.xaml.cs @@ -107,10 +107,7 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is focused</param> public override void OnFocused(object sender, FocusEventArgs e) { - if (OnFocusedCommand != null) - { - OnFocusedCommand.Execute(""); - } + OnFocusedCommand?.Execute(""); } /// <summary> @@ -129,18 +126,18 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is clicked</param> public override void OnClicked(object sender, EventArgs e) { - if (OnClickedCommand != null) - { - OnClickedCommand.Execute(""); - } + OnClickedCommand?.Execute(""); + } + + public override void OnMoveStarting() + { } /// <summary> /// A method for handling the button when button is changed to move mode /// </summary> - /// <param name="isMoveMode">A flag indicates whether the button is move mode or not</param> - /// <param name="isDefault">A flag indicates whether this method is called by ChangeToDefaultMode method</param> - public override void ChangeMoveMode(bool isMoveMode, bool isDefault) + /// <param name="isMoveCanceled">A flag indicates whether moving is canceled or not</param> + public override void OnMoveFinishing(bool isMoveCanceled) { } diff --git a/TVHome/TVHome/Controls/PanelButton.cs b/TVHome/TVHome/Controls/PanelButton.cs index efc0162..35e735d 100755 --- a/TVHome/TVHome/Controls/PanelButton.cs +++ b/TVHome/TVHome/Controls/PanelButton.cs @@ -14,23 +14,98 @@ * limitations under the License. */ +using LibTVRefCommonPortable.Utils; using System; +using System.ComponentModel; using System.Windows.Input; +using Tizen.Xamarin.Forms.Extension; using Xamarin.Forms; namespace TVHome.Controls { /// <summary> + /// Definition of enumerations which to use for recognizing a state of the PanelButton. + /// </summary> + public enum PanelButtonState + { + /// <summary> + /// Panel button is showing. But not focused. + /// </summary> + Show, + /// <summary> + /// Panel button is focusing. + /// </summary> + Focused, + /// <summary> + /// Panel button is now showing. + /// </summary> + Hide, + /// <summary> + /// Panel button is ready to move. + /// </summary> + Move, + /// <summary> + /// Panel button is moving with a animation. + /// </summary> + Moving, + /// <summary> + /// Panel button moving is canceled. + /// </summary> + MoveCanceled, + /// <summary> + /// Panel button is showing a option menu. + /// </summary> + ShowingOption, + } + + + /// <summary> /// TVHome has two panels, MainPanel and SubPanel. The panels have several panel buttons. /// The class for handling panel button's events /// </summary> public abstract class PanelButton : RelativeLayout { - public bool isMoveMode; - public bool isFocused; - public bool isShowOptions; - public bool rightMoving; - public bool leftMoving; + protected ContextPopup popup; + + private PanelButtonState previousPanelState = PanelButtonState.Hide; + + public static readonly BindableProperty PanelButtonStateProperty = BindableProperty.Create("PanelButtonState", + typeof(PanelButtonState), typeof(PanelButton), PanelButtonState.Hide, BindingMode.TwoWay); + + public PanelButtonState PanelButtonState + { + get { return (PanelButtonState)GetValue(PanelButtonStateProperty); } + set { SetValue(PanelButtonStateProperty, value); } + } + + + public bool IsButtonFocused + { + get + { + return PanelButtonState == PanelButtonState.Focused; + } + } + + public bool IsButtonMoving + { + get + { + return (PanelButtonState == PanelButtonState.Move || + PanelButtonState == PanelButtonState.Moving); + } + } + + public bool IsOptionsShowing + { + get + { + return PanelButtonState == PanelButtonState.ShowingOption; + } + } + + public EventHandler<PanelButtonState> OnPanelButtonStateChanged; + /// <summary> /// A Command will be executed the button is focused. /// </summary> @@ -49,7 +124,7 @@ namespace TVHome.Controls /// <summary> /// A Command will be executed when the button moving is finished /// </summary> - public ICommand OnMoveFinishedCommand { get; set; } + public ICommand OnMoveToggleCommand { get; set; } /// <summary> /// A Command will be executed the button is unpinned. @@ -71,10 +146,6 @@ namespace TVHome.Controls /// </summary> public ICommand OnDefaultModeCommand { get; set; } - /// <summary> - /// A Command will be executed the option menus are showed. - /// </summary> - public ICommand OnShowOptionsCommand { get; set; } /// <summary> /// Handles Button Focused event @@ -97,22 +168,87 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is clicked</param> public abstract void OnClicked(object sender, EventArgs e); + public abstract void OnMoveStarting(); + /// <summary> /// A method for handling the button when button is changed to move mode /// </summary> - /// <param name="isMoveMode">A flag indicates whether the button is move mode or not</param> - /// <param name="isDefault">A flag indicates whether this method is called by ChangeToDefaultMode method</param> - public abstract void ChangeMoveMode(bool isMoveMode, bool isDefault); + /// <param name="isMoveCanceled">A flag indicates whether moving is canceled or not</param> + public abstract void OnMoveFinishing(bool isMoveCanceled = false); /// <summary> - /// A method for showing context popup + /// A method for showing context pop-up /// </summary> public abstract void ShowContextPopup(); /// <summary> - /// A method for changing context popup mode + /// A method for changing context pop-up mode /// </summary> - /// <param name="showOptions">Options for change context popup mode</param> + /// <param name="showOptions">Options for change context pop-up mode</param> public abstract void ChangeShowOptionsMode(bool showOptions); + + + public PanelButton() + { + PropertyChanged += OnPropertyChanged; + } + + /// <summary> + /// An event handler for handling property changed event + /// </summary> + /// <param name="sender">A source of event</param> + /// <param name="e">The event that is occurred when property is changed</param> + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "PanelButtonState") + { + if (PanelButtonState == previousPanelState) + { + DebuggingUtils.Dbg("[PanelButtonState] " + previousPanelState + " => " + PanelButtonState); + return; + } + + DebuggingUtils.Dbg("[PanelButtonState] " + previousPanelState + " => " + PanelButtonState); + switch (PanelButtonState) + { + case PanelButtonState.Move: + if (previousPanelState != PanelButtonState.Moving) + { + OnMoveStarting(); + } + + break; + + case PanelButtonState.ShowingOption: + ShowContextPopup(); + ChangeShowOptionsMode(true); + break; + } + + OnPanelButtonStateChanged?.Invoke(this, PanelButtonState); + + + switch (previousPanelState) + { + case PanelButtonState.ShowingOption: + popup?.Dismiss(); + break; + + case PanelButtonState.Move: + if (PanelButtonState != PanelButtonState.Moving) + { + OnMoveFinishing(); + } + + break; + + case PanelButtonState.MoveCanceled: + OnMoveFinishing(true); + break; + } + + previousPanelState = PanelButtonState; + } + } } } diff --git a/TVHome/TVHome/Controls/SubPanelAllAppsButton.xaml.cs b/TVHome/TVHome/Controls/SubPanelAllAppsButton.xaml.cs index 17004d1..f7c0804 100755 --- a/TVHome/TVHome/Controls/SubPanelAllAppsButton.xaml.cs +++ b/TVHome/TVHome/Controls/SubPanelAllAppsButton.xaml.cs @@ -51,10 +51,7 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is clicked</param> public override async void OnClicked(object sender, EventArgs e) { - if (OnClickedCommand != null) - { - OnClickedCommand.Execute(""); - } + OnClickedCommand?.Execute(""); await this.FadeTo(0.99, 300); } @@ -66,10 +63,7 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is focused</param> public override async void OnFocused(object sender, FocusEventArgs e) { - if (OnFocusedCommand != null) - { - OnFocusedCommand.Execute(""); - } + OnFocusedCommand?.Execute(""); #pragma warning disable CS4014 ButtonTitle.On<Xamarin.Forms.PlatformConfiguration.Tizen>().SetFontWeight(FontWeight.Medium); @@ -96,12 +90,15 @@ namespace TVHome.Controls ButtonDimmedImage.Scale = 1.0; } + public override void OnMoveStarting() + { + + } /// <summary> /// A method for handling the button when button is changed to move mode /// </summary> - /// <param name="isMoveMode">A flag indicates whether the button is move mode or not</param> - /// <param name="isDefault">A flag indicates whether this method is called by ChangeToDefaultMode method</param> - public override void ChangeMoveMode(bool isMoveMode, bool isDefault) + /// <param name="isMoveCanceled">A flag indicates whether moving is canceled or not</param> + public override void OnMoveFinishing(bool isMoveCanceled = false) { } diff --git a/TVHome/TVHome/Controls/SubPanelButton.xaml.cs b/TVHome/TVHome/Controls/SubPanelButton.xaml.cs index ce84884..a94d57f 100755 --- a/TVHome/TVHome/Controls/SubPanelButton.xaml.cs +++ b/TVHome/TVHome/Controls/SubPanelButton.xaml.cs @@ -49,88 +49,77 @@ namespace TVHome.Controls ButtonTitle.FontSize = SizeUtils.GetFontSize(26); ButtonTitle.On<Xamarin.Forms.PlatformConfiguration.Tizen>().SetFontWeight(FontWeight.Normal); + // TODO : make this subscribe when it is in the move mode. MessagingCenter.Subscribe<App, string>(this, "NavigationKeyPressed", (sender, e) => { - if (isMoveMode && IsEnabled) + if (IsButtonMoving) { OnMoveCommand?.Execute(e); } }); - //InitializeLongTapGesture(); } - /* - private void InitializeLongTapGesture() - { - var longTapGesture = new LongTapGestureRecognizer - { - Timeout = 0.5 - }; - longTapGesture.TapCompleted += (sender, args) => - { - ShowContextPopup(); - }; - - View.GestureRecognizers.Add(longTapGesture); - } - */ /// <summary> /// A method for showing Context popup /// </summary> public override void ShowContextPopup() { - if (isShowOptions) + if (popup != null) { return; } - ContextPopup popup = new ContextPopup + popup = new ContextPopup { IsAutoHidingEnabled = true, Orientation = ContextPopupOrientation.Vertical, DirectionPriorities = new ContextPopupDirectionPriorities(ContextPopupDirection.Down, ContextPopupDirection.Up, ContextPopupDirection.Right, ContextPopupDirection.Left) }; + PanelButtonState = PanelButtonState.ShowingOption; + popup.Items.Add(new ContextPopupItem("MOVE")); popup.Items.Add(new ContextPopupItem("UNPIN")); popup.SelectedIndexChanged += (sender, args) => { var ctxPopup = sender as ContextPopup; - if (ctxPopup.SelectedIndex == 0) - { - OnMoveFinishedCommand.Execute(""); - } - else if (ctxPopup.SelectedIndex == 1) + DebuggingUtils.Dbg("popup SelectedIndexChanged = " + ctxPopup.SelectedIndex); + switch (ctxPopup.SelectedIndex) { - OnUnpinCommand.Execute(""); - } + case 0: + OnMoveToggleCommand.Execute(""); + ctxPopup.Dismiss(); + break; - popup.Dismiss(); + case 1: + OnUnpinCommand.Execute(""); + ctxPopup.Dismiss(); + break; + } }; popup.Dismissed += (sender, args) => { + DebuggingUtils.Dbg("popup dismissed, " + PanelButtonState); var ctxPopup = sender as ContextPopup; - isShowOptions = false; - if (ctxPopup.SelectedIndex == -1) { - OnDefaultModeCommand.Execute(""); + OnDefaultModeCommand.Execute(string.Empty); } - else if (ctxPopup.SelectedIndex == 1) + + popup = null; + if (!IsButtonMoving) { - OnShowOptionsCommand?.Execute(isShowOptions); + PanelButtonState = PanelButtonState.Focused; } }; popup.Show(this, Width / 2, Height - (moveTransitionHeight + selectTransitionHeight)); ButtonTitle.FadeTo(0, 300); - isShowOptions = true; } - /// <summary> /// Handles Button Clicked event /// </summary> @@ -138,59 +127,56 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is clicked</param> public override async void OnClicked(object sender, EventArgs e) { - if (!isMoveMode) + DebuggingUtils.Dbg("OnClicked, moving = " + IsButtonMoving); + if (!IsButtonMoving) { - if (OnClickedCommand != null) - { - OnClickedCommand.Execute(""); - } + OnClickedCommand?.Execute(""); await this.FadeTo(0.99, 300); } else { - OnMoveFinishedCommand.Execute(""); + OnMoveToggleCommand.Execute(""); } } + public override async void OnMoveStarting() + { + DebuggingUtils.Dbg("OnMoveStarting"); + +#pragma warning disable CS4014 + ButtonTitle.FadeTo(0, 300); + + for (int i = 0; i < 2; i++) + { + LeftBtnImg.FadeTo(1, 300); + await RightBtnImg.FadeTo(1, 300); + LeftBtnImg.FadeTo(0, 300); + await RightBtnImg.FadeTo(0, 300); + } +#pragma warning restore CS4014 + } + /// <summary> /// A method for handling the button when button is changed to move mode /// </summary> - /// <param name="moveMode">A flag indicates whether the button is move mode or not</param> - /// <param name="isDefault">A flag indicates whether this method is called by ChangeToDefaultMode method</param> - public override async void ChangeMoveMode(bool moveMode, bool isDefault) + /// <param name="isMoveCanceled">A flag indicates whether moving is canceled or not</param> + public override async void OnMoveFinishing(bool isMoveCanceled = false) { - isMoveMode = moveMode; + DebuggingUtils.Dbg($"OnMoveFinishing, isMoveCanceled = {isMoveCanceled}"); #pragma warning disable CS4014 - if (moveMode) + if (!isMoveCanceled) { - ButtonTitle.FadeTo(0, 300); - - for (int i = 0; i < 2; i++) - { - LeftBtnImg.FadeTo(1, 300); - await RightBtnImg.FadeTo(1, 300); - LeftBtnImg.FadeTo(0, 300); - await RightBtnImg.FadeTo(0, 300); - } + await this.TranslateTo(SizeUtils.GetWidthSize((int)TranslationX), 0, 300); } else { - if (!isDefault) - { - await this.TranslateTo(SizeUtils.GetWidthSize((int)TranslationX), 0, 300); - } - else - { - await this.TranslateTo(0, SizeUtils.GetHeightSize((int)TranslationY), 0); - await this.TranslateTo(0, 0, 300); - } - - OnFocused(null, null); + await this.TranslateTo(0, SizeUtils.GetHeightSize((int)TranslationY), 0); + await this.TranslateTo(0, 0, 300); } - OnShowOptionsCommand?.Execute(moveMode); + OnFocused(null, null); #pragma warning restore CS4014 } @@ -200,6 +186,8 @@ namespace TVHome.Controls /// <param name="showOptions">Options for change context popup mode</param> public override async void ChangeShowOptionsMode(bool showOptions) { + DebuggingUtils.Dbg("ChangeShowOptionsMode, showOptions = " + showOptions); + if (showOptions) { #pragma warning disable CS4014 @@ -212,8 +200,6 @@ namespace TVHome.Controls await this.TranslateTo(0, 0, 300); OnFocused(null, null); } - - OnShowOptionsCommand?.Execute(showOptions); } /// <summary> @@ -223,16 +209,17 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is focused</param> public override async void OnFocused(object sender, FocusEventArgs e) { - isFocused = true; - if (isMoveMode || isShowOptions) + DebuggingUtils.Dbg("SubPanelButton " + ButtonTitle.Text + " - OnFocused"); + + if (IsOptionsShowing || IsButtonMoving) { + DebuggingUtils.Dbg("SubPanelButton " + ButtonTitle.Text + " - OnFocused - IGNORE"); return; } - if (OnFocusedCommand != null) - { - OnFocusedCommand.Execute(""); - } + PanelButtonState = PanelButtonState.Focused; + + OnFocusedCommand?.Execute(""); #pragma warning disable CS4014 ButtonTitle.On<Xamarin.Forms.PlatformConfiguration.Tizen>().SetFontWeight(FontWeight.Medium); @@ -250,18 +237,23 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is unfocused</param> public override async void OnUnfocused(object sender, FocusEventArgs e) { - isFocused = false; + DebuggingUtils.Dbg("SubPanelButton " + ButtonTitle.Text + " - OnUnfocused"); - if (!isMoveMode && !isShowOptions) + if (IsOptionsShowing || IsButtonMoving) { + DebuggingUtils.Dbg("SubPanelButton " + ButtonTitle.Text + " - OnUnfocused - IGNORE"); + return; + } + + PanelButtonState = PanelButtonState.Show; + #pragma warning disable CS4014 - ButtonTitle.On<Xamarin.Forms.PlatformConfiguration.Tizen>().SetFontWeight(FontWeight.Normal); - ButtonTitle.FadeTo(0.6, 300); - ButtonTitle.TranslateTo(0, 0, 300); + ButtonTitle.On<Xamarin.Forms.PlatformConfiguration.Tizen>().SetFontWeight(FontWeight.Normal); + ButtonTitle.FadeTo(0.6, 300); + ButtonTitle.TranslateTo(0, 0, 300); #pragma warning restore CS4014 - await ButtonImage.ScaleTo(1, 300); - ButtonDimmedImage.Scale = 1.0; - } + await ButtonImage.ScaleTo(1, 300); + ButtonDimmedImage.Scale = 1.0; } } }
\ No newline at end of file diff --git a/TVHome/TVHome/Controls/SubPanelSettingButton.xaml.cs b/TVHome/TVHome/Controls/SubPanelSettingButton.xaml.cs index 5d63ae3..f5c6eff 100755 --- a/TVHome/TVHome/Controls/SubPanelSettingButton.xaml.cs +++ b/TVHome/TVHome/Controls/SubPanelSettingButton.xaml.cs @@ -51,10 +51,7 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is clicked</param> public override async void OnClicked(object sender, EventArgs e) { - if (OnClickedCommand != null) - { - OnClickedCommand.Execute(""); - } + OnClickedCommand?.Execute(""); await this.FadeTo(0.99, 300); } @@ -66,10 +63,7 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is focused</param> public override async void OnFocused(object sender, FocusEventArgs e) { - if (OnFocusedCommand != null) - { - OnFocusedCommand.Execute(""); - } + OnFocusedCommand?.Execute(""); #pragma warning disable CS4014 ButtonTitle.On<Xamarin.Forms.PlatformConfiguration.Tizen>().SetFontWeight(FontWeight.Medium); @@ -96,14 +90,16 @@ namespace TVHome.Controls ButtonDimmedImage.Scale = 1; } + public override void OnMoveStarting() + { + } + /// <summary> /// A method for handling the button when button is changed to move mode /// </summary> - /// <param name="isMoveMode">A flag indicates whether the button is move mode or not</param> - /// <param name="isDefault">A flag indicates whether this method is called by ChangeToDefaultMode method</param> - public override void ChangeMoveMode(bool isMoveMode, bool isDefault) + /// <param name="isMoveCanceled">A flag indicates whether moving is canceled or not</param> + public override void OnMoveFinishing(bool isMoveCanceled) { - } /// <summary> diff --git a/TVHome/TVHome/Controls/SubPanelThumbnailButton.xaml.cs b/TVHome/TVHome/Controls/SubPanelThumbnailButton.xaml.cs index 9e4aeb6..e3c76e1 100755 --- a/TVHome/TVHome/Controls/SubPanelThumbnailButton.xaml.cs +++ b/TVHome/TVHome/Controls/SubPanelThumbnailButton.xaml.cs @@ -27,11 +27,6 @@ namespace TVHome.Controls public partial class SubPanelThumbnailButton : PanelButton { /// <summary> - /// A flag which will enable showing a popup. - /// </summary> - private bool isPopupShowing = false; - - /// <summary> /// Constructor /// </summary> public SubPanelThumbnailButton() @@ -43,49 +38,7 @@ namespace TVHome.Controls ThumbnailTitle.FontSize = SizeUtils.GetFontSize(26); ThumbnailTitle.On<Xamarin.Forms.PlatformConfiguration.Tizen>().SetFontWeight(FontWeight.Normal); - //InitializeLongTapGesture(); - } - - /* - private void InitializeLongTapGesture() - { - var longTapGesture = new LongTapGestureRecognizer - { - Timeout = 0.5 - }; - - var tapGesture = new TapGestureRecognizer - { - NumberOfTapsRequired = 1 - }; - - tapGesture.Tapped += (sender, args) => - { - if (!isMoveMode) - { - if (OnClickedCommand != null) - { - OnClickedCommand.Execute(""); - } - - View.FadeTo(0.99, 300); - } - else - { - OnMoveFinishedCommand.Execute(""); - } - }; - - longTapGesture.TapCompleted += (sender, args) => - { - ShowContextPopup(); - //OnMoveFinishedCommand.Execute(""); - }; - - View.GestureRecognizers.Add(longTapGesture); - //View.GestureRecognizers.Add(tapGesture); } - */ /// <summary> /// Handles Button Clicked event @@ -94,10 +47,7 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is clicked</param> public override async void OnClicked(object sender, EventArgs e) { - if (OnClickedCommand != null) - { - OnClickedCommand.Execute(""); - } + OnClickedCommand?.Execute(""); await this.FadeTo(0.9, 300); } @@ -109,12 +59,11 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is focused</param> public override async void OnFocused(object sender, FocusEventArgs e) { - isFocused = true; + DebuggingUtils.Dbg("SubPanelThumbnailButton " + ThumbnailTitle.Text + " - OnFocused"); - if (OnFocusedCommand != null) - { - OnFocusedCommand.Execute(""); - } + PanelButtonState = PanelButtonState.Focused; + + OnFocusedCommand?.Execute(""); #pragma warning disable CS4014 ThumbnailGradient.Source = "ic_list_thumbnail_gradient_focused.9.png"; @@ -131,7 +80,13 @@ namespace TVHome.Controls /// <param name="e">The event that is occurred when button is unfocused</param> public override async void OnUnfocused(object sender, FocusEventArgs e) { - isFocused = false; + DebuggingUtils.Dbg("SubPanelThumbnailButton " + ThumbnailTitle.Text + " - OnUnfocused"); + + if (!IsOptionsShowing) + { + PanelButtonState = PanelButtonState.Show; + } + #pragma warning disable CS4014 //ThumbnailTitle.FadeTo(0.3, 300); ThumbnailGradient.Source = "ic_list_thumbnail_gradient_normal.9.png"; @@ -140,12 +95,16 @@ namespace TVHome.Controls await this.ScaleTo(1.0, 300); } + public override void OnMoveStarting() + { + + } + /// <summary> /// A method for handling the button when button is changed to move mode /// </summary> - /// <param name="isMoveMode">A flag indicates whether the button is move mode or not</param> - /// <param name="isDefault">A flag indicates whether this method is called by ChangeToDefaultMode method</param> - public override void ChangeMoveMode(bool isMoveMode, bool isDefault) + /// <param name="isMoveCanceled">A flag indicates whether moving is canceled or not</param> + public override void OnMoveFinishing(bool isMoveCanceled) { } @@ -155,43 +114,48 @@ namespace TVHome.Controls /// </summary> public override void ShowContextPopup() { - if (isPopupShowing) + if (popup != null) { return; } - ContextPopup popup = new ContextPopup + popup = new ContextPopup { IsAutoHidingEnabled = true, Orientation = ContextPopupOrientation.Vertical, DirectionPriorities = new ContextPopupDirectionPriorities(ContextPopupDirection.Down, ContextPopupDirection.Up, ContextPopupDirection.Right, ContextPopupDirection.Left) }; + PanelButtonState = PanelButtonState.ShowingOption; + popup.Items.Add(new ContextPopupItem("REMOVE")); popup.Items.Add(new ContextPopupItem("CLEAR ALL")); popup.SelectedIndexChanged += (sender, args) => { var ctxPopup = sender as ContextPopup; - if (ctxPopup.SelectedIndex == 0) + switch (ctxPopup.SelectedIndex) { - OnClearCommand.Execute(""); - ctxPopup.Dismiss(); - } - else if (ctxPopup.SelectedIndex == 1) - { - OnClearAllCommand.Execute(""); - ctxPopup.Dismiss(); + case 0: + OnClearCommand.Execute(""); + ctxPopup.Dismiss(); + break; + + case 1: + OnClearAllCommand.Execute(""); + ctxPopup.Dismiss(); + break; } }; popup.Dismissed += (sender, args) => { - isPopupShowing = false; + popup = null; }; + DebuggingUtils.Dbg("auto hiding = " + popup.IsAutoHidingEnabled); + popup.Show(this); - isPopupShowing = true; } /// <summary> diff --git a/TVHome/TVHome/TVHome.cs b/TVHome/TVHome/TVHome.cs index 717e365..642d83e 100755 --- a/TVHome/TVHome/TVHome.cs +++ b/TVHome/TVHome/TVHome.cs @@ -200,6 +200,7 @@ namespace TVHome public void OnNavigationKeyPressed(string keyName) { + DebuggingUtils.Dbg("OnNavigationKeyPressed, " + keyName); MessagingCenter.Send<App, string>(this, "NavigationKeyPressed", keyName); } @@ -244,7 +245,7 @@ namespace TVHome public void OnAppPinnedNotificationReceived(String appID) { DebuggingUtils.Dbg("[[[ App Pinned ]]] " + appID); - AppPinnedNotificationListener.Invoke(this, new TVHomeEventArgs() + AppPinnedNotificationListener?.Invoke(this, new TVHomeEventArgs() { arg = appID, }); diff --git a/TVHome/TVHome/TVHome.csproj b/TVHome/TVHome/TVHome.csproj index 60b177e..23f1885 100755 --- a/TVHome/TVHome/TVHome.csproj +++ b/TVHome/TVHome/TVHome.csproj @@ -55,7 +55,10 @@ </Compile> <Compile Include="TVHome.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="ViewModels\IHomeViewModel.cs" /> + <Compile Include="ViewModels\MainPanelViewModel.cs" /> + <Compile Include="ViewModels\SettingsViewModel.cs" /> + <Compile Include="ViewModels\AppListViewModel.cs" /> + <Compile Include="ViewModels\RecentListViewModel.cs" /> <Compile Include="ViewModels\MainPageViewModel.cs" /> <Compile Include="Views\MainPage.xaml.cs"> <DependentUpon>MainPage.xaml</DependentUpon> diff --git a/TVHome/TVHome/ViewModels/AppListViewModel.cs b/TVHome/TVHome/ViewModels/AppListViewModel.cs new file mode 100644 index 0000000..509c659 --- /dev/null +++ b/TVHome/TVHome/ViewModels/AppListViewModel.cs @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using LibTVRefCommonPortable.DataModels; +using LibTVRefCommonPortable.Utils; +using Xamarin.Forms; +using LibTVRefCommonPortable.Models; +using TVHome.Views; + +namespace TVHome.ViewModels +{ + + /// <summary> + /// A class for ViewModel of TV Home Recent Menu List + /// </summary> + public class AppListViewModel : INotifyPropertyChanged, IStateSubscriber + { + private static readonly Lazy<AppListViewModel> instance = new Lazy<AppListViewModel>(() => new AppListViewModel()); + + public static AppListViewModel Instance + { + get + { + return instance.Value; + } + } + + private PanelState appsSubPanelState; + public PanelState AppsSubPanelState + { + set + { + if (appsSubPanelState == value) + { + return; + } + + DebuggingUtils.Dbg("AppsSubPanelState, set - " + value); + + switch (value) + { + case PanelState.Focused: + MainPageViewModel.Publisher.CurrentState = AppState.HomeSubPanelAppsFocused; + break; + + case PanelState.ShowingOption: + MainPageViewModel.Publisher.CurrentState = AppState.HomeShowOptions; + break; + + case PanelState.Moving: + MainPageViewModel.Publisher.CurrentState = AppState.HomeMove; + break; + + case PanelState.Iconified: + MainPageViewModel.Publisher.CurrentState = AppState.HomeIconified; + break; + } + + + + appsSubPanelState = value; + OnPropertyChanged("AppsSubPanelState"); + } + + get + { + return appsSubPanelState; + } + } + + /// <summary> + /// Gets or set AppList for Apps SubPanel + /// </summary> + public IEnumerable<ShortcutInfo> AppList { get; set; } + + /// <summary> + /// A command for moving item in sub panel + /// </summary> + public Command OnMoveCommand { get; set; } + + /// <summary> + /// A command for unpin item in sub panel + /// </summary> + public Command OnUnpinCommand { get; set; } + + private AppListViewModel() + { + DebuggingUtils.Dbg("AppListViewModel"); + + MainPageViewModel.Instance.RegisterStateSubscriber(this); + + UpdateAppList(null, null); + TVHomeImpl.GetInstance.AppShortcutControllerInstance.AddFileSystemChangedListener(UpdateAppList); + + OnMoveCommand = new Command<List<View>>((moveList) => + { + DebuggingUtils.Dbg("OnMoveCommand"); + MoveAppShortcutInfo(moveList); + }); + + OnUnpinCommand = new Command<string>((appId) => + { + DebuggingUtils.Dbg("OnUnpinCommand "); + UnpinAppShortcutInfo(appId); + }); + + + } + + /// <summary> + /// Gets the AppList for displaying items and updates the list to Apps SubPanel + /// </summary> + /// <param name="sender">The source of event</param> + /// <param name="e">The event that is occurred pinned app file is changed</param> + private async void UpdateAppList(object sender, EventArgs e) + { + DebuggingUtils.Dbg("UpdateAppList"); + AppList = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsWithDefaultShortcuts(); + OnPropertyChanged("AppList"); + } + + /// <summary> + /// A method for updating reordered list + /// </summary> + /// <param name="moveList">A list of reordered views</param> + private void MoveAppShortcutInfo(List<View> moveList) + { + DebuggingUtils.Dbg("MoveAppShortcutInfo"); + List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>(); + AppShortcutInfo appShortcut; + + foreach (var item in moveList) + { + appShortcut = (AppShortcutInfo)item.BindingContext; + if (!string.IsNullOrEmpty(appShortcut.AppID)) + { + pinnedAppList.Add(new AppShortcutInfo() + { + AppID = appShortcut.AppID, + }); + } + } + + TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList); + } + + + /// <summary> + /// A method for unpin application + /// </summary> + /// <param name="appId">An application ID for unpin</param> + private void UnpinAppShortcutInfo(string appId) + { + RemovePinnedApp(appId); + } + + + + /// <summary> + /// A method for updating pinned applications + /// </summary> + /// <param name="pinnedApps">A list of pinned application</param> + private void UpdatePinnedApps(Dictionary<string, string> pinnedApps) + { + List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>(); + foreach (var item in pinnedApps) + { + pinnedAppList.Add(new AppShortcutInfo() + { + AppID = item.Key, + }); + } + + TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList); + } + + + /// <summary> + /// A method for remove pinned application + /// </summary> + /// <param name="appID">An ID of application for removing from pinned application list</param> + private async void RemovePinnedApp(string appID) + { + Dictionary<string, string> PinnedApps = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs(); + if (PinnedApps.ContainsKey(appID)) + { + PinnedApps.Remove(appID); + UpdatePinnedApps(PinnedApps); + return; + } + } + + /// <summary> + /// An event that is occurred when property of MainPageViewModel is changed + /// </summary> + public event PropertyChangedEventHandler PropertyChanged; + + /// <summary> + /// A method for invoking PropertyChanged event + /// </summary> + /// <param name="name">The name of property</param> + public void OnPropertyChanged(string name) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(name)); + } + } + + public void OnStateChanged(AppState state) + { + //DebuggingUtils.Dbg("AppPanel OnStateChanged " + state); + + switch (state) + { + case AppState.HomeMainPanelAppsFocused: + AppsSubPanelState = PanelState.Show; + break; + + case AppState.HomeSubPanelAppsFocused: + AppsSubPanelState = PanelState.Focused; + break; + + case AppState.HomeShowOptions: + case AppState.HomeMove: + break; + + case AppState.HomeIconified: + AppsSubPanelState = PanelState.Iconified; + break; + + default: + AppsSubPanelState = PanelState.Hide; + break; + + } + } + + + } +} diff --git a/TVHome/TVHome/ViewModels/IHomeViewModel.cs b/TVHome/TVHome/ViewModels/IHomeViewModel.cs deleted file mode 100755 index d6d374f..0000000 --- a/TVHome/TVHome/ViewModels/IHomeViewModel.cs +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd - * - * Licensed under the Flora License, Version 1.1 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace TVHome.ViewModels -{ - /// <summary> - /// An interface for TV Home MainPageViewModel - /// </summary> - interface IHomeViewModel - { - /// <summary> - /// A method for invoking PropertyChanged event - /// </summary> - /// <param name="name">The name of property</param> - void OnPropertyChanged(string name); - - /// <summary> - /// A method changes CurrentStatus according to parameter - /// </summary> - /// <param name="newStatus">The next status name</param> - /// <param name="isForceUpdate">A flag indicates whether CurrentStatus to be changed or not</param> - void ChangeCurrentStatus(HomeStatus newStatus, bool isForceUpdate); - } -} diff --git a/TVHome/TVHome/ViewModels/MainPageViewModel.cs b/TVHome/TVHome/ViewModels/MainPageViewModel.cs index 31be243..11452ee 100755 --- a/TVHome/TVHome/ViewModels/MainPageViewModel.cs +++ b/TVHome/TVHome/ViewModels/MainPageViewModel.cs @@ -26,18 +26,6 @@ using LibTVRefCommonPortable.Models; namespace TVHome.ViewModels { /// <summary> - /// A HomeStatus type enumeration - /// </summary> - public enum HomeStatus - { - MainPanelFocused = 0, - SubPanelFocused, - ShowOptions, - Move, - Iconified - }; - - /// <summary> /// A HomeMenuItem type enumeration /// </summary> public enum HomeMenuItem @@ -51,399 +39,85 @@ namespace TVHome.ViewModels /// <summary> /// A class for ViewModel of TV Home /// </summary> - public class MainPageViewModel : INotifyPropertyChanged, IHomeViewModel + public class MainPageViewModel : INotifyPropertyChanged, IStatePublisher { - /// <summary> - /// Gets or set CurrentStatus of HomeStatus - /// </summary> - public HomeStatus CurrentStatus { get; private set; } + private static readonly Lazy<MainPageViewModel> instance = new Lazy<MainPageViewModel>(); - private HomeMenuItem selectedMenuName = HomeMenuItem.Apps; - /// <summary> - /// Gets or set SelectedMenuName of HomeMenuItem - /// </summary> - public HomeMenuItem SelectedMenuName + public static MainPageViewModel Instance { get { - return selectedMenuName; + return instance.Value; } + } - set + public static IStatePublisher Publisher + { + get { - if (selectedMenuName != value) - { - selectedMenuName = value; - ChangeSelectedPanelName(value, true); - } + return instance.Value; } } - /// <summary> - /// Gets or set MainList for MainPanel - /// </summary> - public IEnumerable<ShortcutInfo> MainList { get; set; } - /// <summary> - /// Gets or set RecentList for Recent SubPanel - /// </summary> - public IEnumerable<ShortcutInfo> RecentList { get; set; } + private AppState currentState; - /// <summary> - /// Gets or set AppList for Apps SubPanel - /// </summary> - public IEnumerable<ShortcutInfo> AppList { get; set; } - - /// <summary> - /// Gets or set SettingsList for Settings SubPanel - /// </summary> - public IEnumerable<ShortcutInfo> SettingsList { get; set; } - - /// <summary> - /// A command for executing when MainPanel is focused. - /// </summary> - public Command ChangeStatusCommand { get; set; } - - /// <summary> - /// A command for executing when SubPanel is focused. - /// </summary> - public Command SubPanelFocusedCommand { get; set; } - - /// <summary> - /// A command for changing the status to Move status - /// </summary> - public Command SetMoveStatusCommand { get; set; } - - /// <summary> - /// A command for changing the status to Unpin status - /// </summary> - public Command SetUnpinStatusCommand { get; set; } - - /// <summary> - /// A command for moving item in sub panel - /// </summary> - public Command OnMoveCommand { get; set; } - - /// <summary> - /// A command for unpin item in sub panel - /// </summary> - public Command OnUnpinCommand { get; set; } - - /// <summary> - /// A command for delete a recent item - /// </summary> - public Command OnClearCommand { get; set; } - - /// <summary> - /// A command for delete all recent items - /// </summary> - public Command OnClearAllCommand { get; set; } - - /// <summary> - /// A flag indicates whether "No recent info" in Recent SubPanel to be displayed or not - /// </summary> - public bool IsShowNoRecentContents { get; set; } - - /// <summary> - /// An event that is occurred when property of MainPageViewModel is changed - /// </summary> - public event PropertyChangedEventHandler PropertyChanged; - - - /// <summary> - /// Constructor - /// Initialize MainPanel, SubPanel, Command and EventListeners - /// </summary> - public MainPageViewModel() + public AppState CurrentState { - // Init sequence - // MainPage ( MainPageViewModel -> MainPanel -> SubPanel ) - MakeMainMenuItems(); - InitStatus(); - InitCommands(); - MakeSettingsButtons(); - - UpdateAppList(null, null); - - TVHomeImpl.GetInstance.AppShortcutControllerInstance.AddFileSystemChangedListener(UpdateAppList); - - App.SetAppPinnedNotificationListener((s, e) => + get { - // TODO : Make this for Move a pinned app/Show pinned apps(scroll to last) - ChangeSelectedPanelName(HomeMenuItem.Apps); - if (e.arg.Length > 0) - { - DebuggingUtils.Dbg("Move, AppID : " + e.arg); - } - else - { - DebuggingUtils.Dbg("Show, Pinned Apps"); - } - }); + return currentState; + } - MessagingCenter.Subscribe<App, TVHomeStatus>(this, App.AppStatus, (sender, arg) => + set { - switch (arg) + if (value == currentState) { - case TVHomeStatus.OnResume: - MakeRecentButtons(); - break; - case TVHomeStatus.OnSleep: - ChangeCurrentStatus(HomeStatus.MainPanelFocused, true); - break; + return; } - }); - PropertyChanged += MainPageViewModelPropertyChanged; - } - private void MainPageViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) - { - DebuggingUtils.Dbg(e.PropertyName); - } - - /// <summary> - /// A method for initializing HomeStatus to Default - /// </summary> - private void InitStatus() - { - ChangeSelectedPanelName(HomeMenuItem.Apps, true); - ChangeCurrentStatus(HomeStatus.MainPanelFocused, true); - } - - /// <summary> - /// A method for initializing commands - /// </summary> - private void InitCommands() - { - ChangeStatusCommand = new Command<HomeStatus>((status) => - { - ChangeCurrentStatus(status); - }); + DebuggingUtils.Dbg("----------------------------------"); + DebuggingUtils.Dbg("MPVM state = " + currentState + " ==> " + value); + DebuggingUtils.Dbg("----------------------------------"); - OnMoveCommand = new Command<List<View>>((moveList) => - { - MoveAppShortcutInfo(moveList); - }); + currentState = value; - OnUnpinCommand = new Command<string>((appId) => - { - UnpinAppShortcutInfo(appId); - }); - - OnClearCommand = new Command<string>((appId) => - { - RemoveRecentApplication(appId); - }); - - OnClearAllCommand = new Command(() => - { - ClearAllRecentApplications(); - }); - } - - /// <summary> - /// A method for making MainMenu items and display in MainPanel - /// </summary> - private void MakeMainMenuItems() - { - string[] AppName = { "Recent", "Apps", "Settings" }; - string[] AppControlID = { ManagedApps.TVAppsAppID, ManagedApps.TVAppsAppID, ManagedApps.SettingsAppID }; - string[] AppIconPath = + // TODO : asynchronously + foreach (var sub in stateSubscriber) { - "ic_home_menu_{0}_normal.png", - "ic_home_menu_{0}_focused.png", - "ic_home_menu_{0}_selected.png", - "ic_home_menu_{0}_unselected.png" - }; - - List<ShortcutInfo> TempList = new List<ShortcutInfo>(); - for (int i = 0; i < AppName.Length; i++) - { - AppControlAction appControlAction = new AppControlAction() - { - AppID = AppControlID[i] - }; + sub.OnStateChanged(currentState); + } - ShortcutInfo shortcutInfo = new HomeMenuAppShortcutInfo() - { - StateDescriptions = - { - { - "default", - new StateDescription - { - Label = AppName[i], - IconPath = String.Format(AppIconPath[0], AppName[i].ToLower()), - Action = appControlAction, - } - }, - { - "focused", - new StateDescription - { - Label = AppName[i], - IconPath = String.Format(AppIconPath[1], AppName[i].ToLower()), - Action = appControlAction, - } - }, - { - "selected", - new StateDescription - { - Label = AppName[i], - IconPath = String.Format(AppIconPath[2], AppName[i].ToLower()), - Action = appControlAction, - } - }, - { - "unselect", - new StateDescription - { - Label = AppName[i], - IconPath = String.Format(AppIconPath[3], AppName[i].ToLower()), - Action = appControlAction, - } - }, - }, - }; - shortcutInfo.UpdateState(); - TempList.Add(shortcutInfo); } - - MainList = TempList; - OnPropertyChanged("MainList"); } - /// <summary> - /// Gets the AppList for displaying items and updates the list to Apps SubPanel - /// </summary> - /// <param name="sender">The source of event</param> - /// <param name="e">The event that is occurred pinned app file is changed</param> - private async void UpdateAppList(object sender, EventArgs e) - { - AppList = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsWithDefaultShortcuts(); - OnPropertyChanged("AppList"); - } + private List<IStateSubscriber> stateSubscriber = new List<IStateSubscriber>(); - /// <summary> - /// Gets the SettingsList for displaying items and updates the list to Settings SubPanel - /// </summary> - private void MakeSettingsButtons() + public void RegisterStateSubscriber(IStateSubscriber subscriber) { - string[] ShortCutLabel = { "Brightness", "Contrast", "Color", "Tint" }; - - List<ShortcutInfo> TempList = new List<ShortcutInfo>(); - - ShortcutInfo Settings = new SettingShortcutInfo() - { - StateDescriptions = - { - { - "default", - new StateDescription - { - Label = "All Settings", - IconPath = "ic_home_settings_all_138.png", - Action = new AppControlAction() - { - AppID = "org.tizen.settings" - } - } - }, - { - "focused", - new StateDescription - { - Label = "All Settings", - IconPath = "ic_home_settings_all_182.png", - Action = new AppControlAction() - { - AppID = "org.tizen.settings" - } - } - }, - } - }; - Settings.UpdateState(); - TempList.Add(Settings); - - for (int i = 0; i < ShortCutLabel.Length; i++) - { - AppControlAction appControlAction = new AppControlAction() - { - AppID = "org.tizen.settings", - }; - appControlAction.ExtraData.Add("subview", ShortCutLabel[i].ToLower()); - - ShortcutInfo shortcutInfo = new SettingShortcutInfo() - { - StateDescriptions = - { - { - "default", - new StateDescription - { - Label = ShortCutLabel[i], - IconPath = "ic_home_settings_" + ShortCutLabel[i].ToLower() + "_138.png", - Action = appControlAction, - } - }, - { - "focused", - new StateDescription - { - Label = ShortCutLabel[i], - IconPath = "ic_home_settings_" + ShortCutLabel[i].ToLower() + "_182.png", - Action = appControlAction, - } - }, - }, - }; - shortcutInfo.UpdateState(); - TempList.Add(shortcutInfo); - } - - SettingsList = TempList; - OnPropertyChanged("SettingsList"); + stateSubscriber.Add(subscriber); } - /// <summary> - /// Gets the RecentList for displaying items and updates the list to Recent SubPanel - /// </summary> - private void MakeRecentButtons() - { - RecentList = TVHomeImpl.GetInstance.RecentShortcutControllerInstance.GetList(); - if (RecentList.Count<ShortcutInfo>() > 0) - { - IsShowNoRecentContents = false; - OnPropertyChanged("RecentList"); - } - else - { - IsShowNoRecentContents = true; - } - - OnPropertyChanged("IsShowNoRecentContents"); - } /// <summary> - /// Clears all recent applications and updates the list to Recent SubPanel + /// Constructor + /// Initialize MainPanel, SubPanel, Command and EventListeners /// </summary> - private void ClearAllRecentApplications() + public MainPageViewModel() { - TVHomeImpl.GetInstance.RecentShortcutControllerInstance.RemoveAll(); - MakeRecentButtons(); + // Init sequence + // MainPage ( MainPageViewModel -> MainPanel -> SubPanel ) + + App.SetAppPinnedNotificationListener((s, e) => + { + DebuggingUtils.Dbg("Show, Pinned Apps"); + }); } /// <summary> - /// Removes specified recent application and updates the list to Recent SubPanel + /// An event that is occurred when property of MainPageViewModel is changed /// </summary> - /// <param name="appId">An application ID</param> - private void RemoveRecentApplication(string appId) - { - TVHomeImpl.GetInstance.RecentShortcutControllerInstance.Remove(appId); - MakeRecentButtons(); - } + public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// A method for invoking PropertyChanged event @@ -458,156 +132,5 @@ namespace TVHome.ViewModels } } - /// <summary> - /// A method for changing CurrentStatus according to parameter - /// </summary> - /// <param name="newStatus">The next status name</param> - /// <param name="isForceUpdate">A flag indicates whether CurrentStatus to be changed or not</param> - public void ChangeCurrentStatus(HomeStatus newStatus, bool isForceUpdate = false) - { - if (isForceUpdate || - CurrentStatus.CompareTo(newStatus) != 0) - { - CurrentStatus = newStatus; - if (CurrentStatus.CompareTo(HomeStatus.MainPanelFocused) == 0) - { - HomeMenuItem index = HomeMenuItem.Recent; - foreach (HomeMenuAppShortcutInfo item in MainList) - { - if (index == SelectedMenuName) - { - DebuggingUtils.Dbg(index.ToString() + " To Focused"); - item.ChangeStatus("focused"); - } - else - { - DebuggingUtils.Dbg(index.ToString() + " To Default"); - item.ChangeStatus("default"); - } - - index++; - } - } - else if (CurrentStatus.CompareTo(HomeStatus.SubPanelFocused) == 0) - { - HomeMenuItem index = HomeMenuItem.Recent; - foreach (HomeMenuAppShortcutInfo item in MainList) - { - if (index == SelectedMenuName) - { - DebuggingUtils.Dbg(index.ToString() + " To be selected"); - item.ChangeStatus("selected"); - } - else - { - DebuggingUtils.Dbg(index.ToString() + " To be unselect"); - item.ChangeStatus("unselect"); - } - - index++; - } - } - - OnPropertyChanged("CurrentStatus"); - } - } - - /// <summary> - /// A method for changing selected HomeMenuItem according to parameter - /// </summary> - /// <param name="panelName">Selected menu name in MainPanel</param> - /// <param name="isForceUpdate">A flag indicates whether selected menu name to be changed or not</param> - public void ChangeSelectedPanelName(HomeMenuItem panelName, bool isForceUpdate = false) - { - if (isForceUpdate || - SelectedMenuName.CompareTo(panelName) != 0) - { - SelectedMenuName = panelName; - HomeMenuItem index = HomeMenuItem.Recent; - foreach (HomeMenuAppShortcutInfo item in MainList) - { - if (index == panelName) - { - //DebuggingUtils.Dbg(index.ToString() + " To Focused"); - item.ChangeStatus("focused"); - } - else - { - //DebuggingUtils.Dbg(index.ToString() + " To Default"); - item.ChangeStatus("default"); - } - - index++; - } - - OnPropertyChanged("SelectedMenuName"); - } - } - - /// <summary> - /// A method for unpin application - /// </summary> - /// <param name="appId">An application ID for unpin</param> - private void UnpinAppShortcutInfo(string appId) - { - RemovePinnedApp(appId); - } - - /// <summary> - /// A method for updating pinned applications - /// </summary> - /// <param name="pinnedApps">A list of pinned application</param> - private void UpdatePinnedApps(Dictionary<string, string> pinnedApps) - { - List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>(); - foreach (var item in pinnedApps) - { - pinnedAppList.Add(new AppShortcutInfo() - { - AppID = item.Key, - }); - } - - TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList); - } - - /// <summary> - /// A method for remove pinned application - /// </summary> - /// <param name="appID">An ID of application for removing from pinned application list</param> - private async void RemovePinnedApp(string appID) - { - Dictionary<string, string> PinnedApps = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs(); - if (PinnedApps.ContainsKey(appID)) - { - PinnedApps.Remove(appID); - UpdatePinnedApps(PinnedApps); - return; - } - } - - /// <summary> - /// A method for updating reordered list - /// </summary> - /// <param name="moveList">A list of reordered views</param> - private void MoveAppShortcutInfo(List<View> moveList) - { - List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>(); - AppShortcutInfo appShortcut; - - foreach (var item in moveList) - { - appShortcut = (AppShortcutInfo)item.BindingContext; - if (appShortcut.AppID != null && appShortcut.AppID.Length > 0) - { - pinnedAppList.Add(new AppShortcutInfo() - { - AppID = appShortcut.AppID, - }); - } - } - - TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList); - } } } diff --git a/TVHome/TVHome/ViewModels/MainPanelViewModel.cs b/TVHome/TVHome/ViewModels/MainPanelViewModel.cs new file mode 100644 index 0000000..43bd322 --- /dev/null +++ b/TVHome/TVHome/ViewModels/MainPanelViewModel.cs @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using LibTVRefCommonPortable.DataModels; +using LibTVRefCommonPortable.Utils; +using Xamarin.Forms; +using LibTVRefCommonPortable.Models; +using TVHome.Views; + +namespace TVHome.ViewModels +{ + + /// <summary> + /// A class for ViewModel of TV Home Recent Menu List + /// </summary> + public class MainPanelViewModel : INotifyPropertyChanged, IStateSubscriber + { + private static readonly Lazy<MainPanelViewModel> instance = new Lazy<MainPanelViewModel>(() => new MainPanelViewModel()); + + public static MainPanelViewModel Instance + { + get + { + return instance.Value; + } + } + + private PanelState mainPanelState; + public PanelState MainPanelState + { + get + { + return mainPanelState; + } + + set + { + if (mainPanelState == value) + { + return; + } + + DebuggingUtils.Dbg("MainPanelState, set - " + value); + mainPanelState = value; + + OnPropertyChanged("MainPanelState"); + } + } + + private int focusedItemIndex; + public int FocusedItemIndex + { + get + { + return focusedItemIndex; + } + + set + { + /* + if (focusedItemIndex == value) + { + return; + } + */ + focusedItemIndex = value; + DebuggingUtils.Dbg("FocusedItemIndex => " + value); + + switch (focusedItemIndex) + { + case 0: + MainPageViewModel.Publisher.CurrentState = AppState.HomeMainPanelRecentFocused; + return; + case 1: + MainPageViewModel.Publisher.CurrentState = AppState.HomeMainPanelAppsFocused; + return; + case 2: + MainPageViewModel.Publisher.CurrentState = AppState.HomeMainPanelSettingsFocused; + return; + } + + OnPropertyChanged("FocusedItemIndex"); + } + } + + + /// <summary> + /// Gets or set MainList for MainPanel + /// </summary> + public IEnumerable<ShortcutInfo> MainList { get; set; } + + + + private MainPanelViewModel() + { + DebuggingUtils.Dbg("MainPanelViewModel"); + + MakeMainMenuItems(); + + //FocusedItemIndex = 1; + + MainPageViewModel.Instance.RegisterStateSubscriber(this); + } + + + /// <summary> + /// A method for making MainMenu items and display in MainPanel + /// </summary> + private void MakeMainMenuItems() + { + string[] AppName = { "Recent", "Apps", "Settings" }; + string[] AppControlID = { ManagedApps.TVAppsAppID, ManagedApps.TVAppsAppID, ManagedApps.SettingsAppID }; + string[] AppIconPath = + { + "ic_home_menu_{0}_normal.png", + "ic_home_menu_{0}_focused.png", + "ic_home_menu_{0}_selected.png", + "ic_home_menu_{0}_unselected.png" + }; + + List<ShortcutInfo> TempList = new List<ShortcutInfo>(); + for (int i = 0; i < AppName.Length; i++) + { + AppControlAction appControlAction = new AppControlAction() + { + AppID = AppControlID[i] + }; + + ShortcutInfo shortcutInfo = new HomeMenuAppShortcutInfo() + { + StateDescriptions = + { + { + "default", + new StateDescription + { + Label = AppName[i], + IconPath = String.Format(AppIconPath[0], AppName[i].ToLower()), + Action = appControlAction, + } + }, + { + "focused", + new StateDescription + { + Label = AppName[i], + IconPath = String.Format(AppIconPath[1], AppName[i].ToLower()), + Action = appControlAction, + } + }, + { + "selected", + new StateDescription + { + Label = AppName[i], + IconPath = String.Format(AppIconPath[2], AppName[i].ToLower()), + Action = appControlAction, + } + }, + { + "unselect", + new StateDescription + { + Label = AppName[i], + IconPath = String.Format(AppIconPath[3], AppName[i].ToLower()), + Action = appControlAction, + } + }, + }, + }; + shortcutInfo.UpdateState(); + TempList.Add(shortcutInfo); + } + + MainList = TempList; + OnPropertyChanged("MainList"); + } + + + /// <summary> + /// An event that is occurred when property of MainPageViewModel is changed + /// </summary> + public event PropertyChangedEventHandler PropertyChanged; + + /// <summary> + /// A method for invoking PropertyChanged event + /// </summary> + /// <param name="name">The name of property</param> + public void OnPropertyChanged(string name) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(name)); + } + } + + public void OnStateChanged(AppState state) + { + //DebuggingUtils.Dbg("MainPanel OnStateChanged " + state); + + switch (state) + { + case AppState.HomeMainPanelAppsFocused: + case AppState.HomeMainPanelRecentFocused: + case AppState.HomeMainPanelSettingsFocused: + MainPanelState = PanelState.Focused; + + foreach (var menuItem in MainList) + { + HomeMenuAppShortcutInfo homeMenuItem = menuItem as HomeMenuAppShortcutInfo; + homeMenuItem.ChangeStatus("default"); + } + + (MainList.ElementAt(FocusedItemIndex) as HomeMenuAppShortcutInfo)?.ChangeStatus("focused"); + OnPropertyChanged("MainList"); + break; + + case AppState.HomeSubPanelRecentFocused: + case AppState.HomeSubPanelAppsFocused: + case AppState.HomeSubPanelSettingsFocused: + foreach (var menuItem in MainList) + { + HomeMenuAppShortcutInfo homeMenuItem = menuItem as HomeMenuAppShortcutInfo; + homeMenuItem.ChangeStatus("unselect"); + } + + (MainList.ElementAt(FocusedItemIndex) as HomeMenuAppShortcutInfo)?.ChangeStatus("selected"); + OnPropertyChanged("MainList"); + MainPanelState = PanelState.Show; + + + break; + + case AppState.HomeShowOptions: + MainPanelState = PanelState.ShowingOption; + break; + + case AppState.HomeMove: + MainPanelState = PanelState.Moving; + break; + + case AppState.HomeIconified: + MainPanelState = PanelState.Iconified; + break; + + default: + MainPanelState = PanelState.Hide; + break; + } + } + } +} diff --git a/TVHome/TVHome/ViewModels/RecentListViewModel.cs b/TVHome/TVHome/ViewModels/RecentListViewModel.cs new file mode 100644 index 0000000..c9150ad --- /dev/null +++ b/TVHome/TVHome/ViewModels/RecentListViewModel.cs @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using LibTVRefCommonPortable.DataModels; +using LibTVRefCommonPortable.Utils; +using Xamarin.Forms; +using LibTVRefCommonPortable.Models; +using TVHome.Views; + +namespace TVHome.ViewModels +{ + + /// <summary> + /// A class for ViewModel of TV Home Recent Menu List + /// </summary> + public class RecentListViewModel : INotifyPropertyChanged, IStateSubscriber + { + private static readonly Lazy<RecentListViewModel> instance = new Lazy<RecentListViewModel>(() => new RecentListViewModel()); + + public static RecentListViewModel Instance + { + get + { + return instance.Value; + } + } + + private PanelState recentSubPanelState; + public PanelState RecentSubPanelState + { + set + { + if (recentSubPanelState == value) + { + return; + } + + DebuggingUtils.Dbg("RecentSubPanelState, set - " + value); + + switch (value) + { + case PanelState.Focused: + if (MainPageViewModel.Publisher.CurrentState == AppState.HomeMainPanelRecentFocused) + { + MainPageViewModel.Publisher.CurrentState = AppState.HomeSubPanelRecentFocused; + } + + break; + + case PanelState.Iconified: + MainPageViewModel.Publisher.CurrentState = AppState.HomeIconified; + break; + } + + recentSubPanelState = value; + OnPropertyChanged("RecentSubPanelState"); + } + + get + { + return recentSubPanelState; + } + } + + + + /// <summary> + /// Gets or set RecentList for Recent SubPanel + /// </summary> + public IEnumerable<ShortcutInfo> RecentList { get; set; } + + + /// <summary> + /// A command for delete a recent item + /// </summary> + public Command OnClearCommand { get; set; } + + /// <summary> + /// A command for delete all recent items + /// </summary> + public Command OnClearAllCommand { get; set; } + + private RecentListViewModel() + { + DebuggingUtils.Dbg("RecentListViewModel"); + + MakeRecentButtons(); + + MainPageViewModel.Instance.RegisterStateSubscriber(this); + + OnClearCommand = new Command<string>((appId) => + { + RemoveRecentApplication(appId); + }); + + OnClearAllCommand = new Command(() => + { + ClearAllRecentApplications(); + }); + + MessagingCenter.Subscribe<App, TVHomeStatus>(this, App.AppStatus, (sender, arg) => + { + switch (arg) + { + case TVHomeStatus.OnResume: + MakeRecentButtons(); + break; + } + }); + } + + /// <summary> + /// Gets the RecentList for displaying items and updates the list to Recent SubPanel + /// </summary> + private void MakeRecentButtons() + { + RecentList = TVHomeImpl.GetInstance.RecentShortcutControllerInstance.GetList(); + OnPropertyChanged("RecentList"); + } + + /// <summary> + /// Clears all recent applications and updates the list to Recent SubPanel + /// </summary> + private void ClearAllRecentApplications() + { + TVHomeImpl.GetInstance.RecentShortcutControllerInstance.RemoveAll(); + MakeRecentButtons(); + } + + /// <summary> + /// Removes specified recent application and updates the list to Recent SubPanel + /// </summary> + /// <param name="appId">An application ID</param> + private void RemoveRecentApplication(string appId) + { + TVHomeImpl.GetInstance.RecentShortcutControllerInstance.Remove(appId); + MakeRecentButtons(); + } + + /// <summary> + /// An event that is occurred when property of MainPageViewModel is changed + /// </summary> + public event PropertyChangedEventHandler PropertyChanged; + + /// <summary> + /// A method for invoking PropertyChanged event + /// </summary> + /// <param name="name">The name of property</param> + public void OnPropertyChanged(string name) + { + DebuggingUtils.Dbg("RecentListViewModel OnPropertyChanged " + name); + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(name)); + } + } + + public void OnStateChanged(AppState state) + { + DebuggingUtils.Dbg("RecentListViewModel OnStateChanged " + state); + + switch (state) + { + case AppState.HomeMainPanelRecentFocused: + RecentSubPanelState = PanelState.Show; + break; + + case AppState.HomeSubPanelRecentFocused: + RecentSubPanelState = PanelState.Focused; + break; + + case AppState.HomeShowOptions: + case AppState.HomeMove: + break; + + case AppState.HomeIconified: + RecentSubPanelState = PanelState.Iconified; + break; + + default: + RecentSubPanelState = PanelState.Hide; + break; + + } + } + } +} diff --git a/TVHome/TVHome/ViewModels/SettingsViewModel.cs b/TVHome/TVHome/ViewModels/SettingsViewModel.cs new file mode 100644 index 0000000..fd30bbd --- /dev/null +++ b/TVHome/TVHome/ViewModels/SettingsViewModel.cs @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using LibTVRefCommonPortable.DataModels; +using LibTVRefCommonPortable.Utils; +using Xamarin.Forms; +using LibTVRefCommonPortable.Models; +using TVHome.Views; + +namespace TVHome.ViewModels +{ + + /// <summary> + /// A class for ViewModel of TV Home Recent Menu List + /// </summary> + public class SettingsViewModel : INotifyPropertyChanged, IStateSubscriber + { + private static readonly Lazy<SettingsViewModel> instance = new Lazy<SettingsViewModel>(() => new SettingsViewModel()); + + public static SettingsViewModel Instance + { + get + { + return instance.Value; + } + } + + + private PanelState settingsSubPanelState; + public PanelState SettingsSubPanelState + { + set + { + if (settingsSubPanelState == value) + { + return; + } + + DebuggingUtils.Dbg("SettingsSubPanelState, set - " + value); + + switch (value) + { + case PanelState.Focused: + if (settingsSubPanelState != PanelState.Focused) + { + MainPageViewModel.Publisher.CurrentState = AppState.HomeSubPanelSettingsFocused; + } + + break; + + case PanelState.Iconified: + MainPageViewModel.Publisher.CurrentState = AppState.HomeIconified; + break; + } + + settingsSubPanelState = value; + OnPropertyChanged("SettingsSubPanelState"); + } + + get + { + return settingsSubPanelState; + } + } + + + /// <summary> + /// Gets or set SettingsList for Settings SubPanel + /// </summary> + public IEnumerable<ShortcutInfo> SettingsList { get; set; } + + + private SettingsViewModel() + { + DebuggingUtils.Dbg("SettingsViewModel"); + + MakeSettingsButtons(); + + MainPageViewModel.Instance.RegisterStateSubscriber(this); + + } + + + + /// <summary> + /// Gets the SettingsList for displaying items and updates the list to Settings SubPanel + /// </summary> + private void MakeSettingsButtons() + { + string[] ShortCutLabel = { "Brightness", "Contrast", "Color", "Tint" }; + + List<ShortcutInfo> TempList = new List<ShortcutInfo>(); + + ShortcutInfo Settings = new SettingShortcutInfo() + { + StateDescriptions = + { + { + "default", + new StateDescription + { + Label = "All Settings", + IconPath = "ic_home_settings_all_138.png", + Action = new AppControlAction() + { + AppID = "org.tizen.settings" + } + } + }, + { + "focused", + new StateDescription + { + Label = "All Settings", + IconPath = "ic_home_settings_all_182.png", + Action = new AppControlAction() + { + AppID = "org.tizen.settings" + } + } + }, + } + }; + Settings.UpdateState(); + TempList.Add(Settings); + + for (int i = 0; i < ShortCutLabel.Length; i++) + { + AppControlAction appControlAction = new AppControlAction() + { + AppID = "org.tizen.settings", + }; + appControlAction.ExtraData.Add("subview", ShortCutLabel[i].ToLower()); + + ShortcutInfo shortcutInfo = new SettingShortcutInfo() + { + StateDescriptions = + { + { + "default", + new StateDescription + { + Label = ShortCutLabel[i], + IconPath = "ic_home_settings_" + ShortCutLabel[i].ToLower() + "_138.png", + Action = appControlAction, + } + }, + { + "focused", + new StateDescription + { + Label = ShortCutLabel[i], + IconPath = "ic_home_settings_" + ShortCutLabel[i].ToLower() + "_182.png", + Action = appControlAction, + } + }, + }, + }; + shortcutInfo.UpdateState(); + TempList.Add(shortcutInfo); + } + + SettingsList = TempList; + OnPropertyChanged("SettingsList"); + } + + + + + /// <summary> + /// An event that is occurred when property of MainPageViewModel is changed + /// </summary> + public event PropertyChangedEventHandler PropertyChanged; + + /// <summary> + /// A method for invoking PropertyChanged event + /// </summary> + /// <param name="name">The name of property</param> + public void OnPropertyChanged(string name) + { + DebuggingUtils.Dbg("OnPropertyChanged - " + name); + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(name)); + } + } + + public void OnStateChanged(AppState state) + { + //DebuggingUtils.Dbg("SettingsSubPanel OnStateChanged " + state); + + switch (state) + { + case AppState.HomeMainPanelSettingsFocused: + SettingsSubPanelState = PanelState.Show; + break; + + case AppState.HomeSubPanelSettingsFocused: + SettingsSubPanelState = PanelState.Focused; + break; + + case AppState.HomeShowOptions: + case AppState.HomeMove: + break; + + case AppState.HomeIconified: + SettingsSubPanelState = PanelState.Iconified; + break; + + default: + SettingsSubPanelState = PanelState.Hide; + break; + } + } + } +} diff --git a/TVHome/TVHome/Views/MainPage.xaml b/TVHome/TVHome/Views/MainPage.xaml index dd41bbe..cd3d409 100755 --- a/TVHome/TVHome/Views/MainPage.xaml +++ b/TVHome/TVHome/Views/MainPage.xaml @@ -5,11 +5,8 @@ xmlns:Views="clr-namespace:TVHome.Views" xmlns:ViewModels="clr-namespace:TVHome.ViewModels" xmlns:Controls="clr-namespace:TVHome.Controls" - CurrentStatus="{Binding CurrentStatus}" + CurrentState="{Binding CurrentState}" SelectedMenuName="{Binding SelectedMenuName}"> - <ContentPage.BindingContext> - <ViewModels:MainPageViewModel /> - </ContentPage.BindingContext> <ContentPage.Content> <RelativeLayout> <Controls:NinePatchImage x:Name="DimmedBgImage" @@ -27,24 +24,24 @@ RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.22}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}" RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.6537}" - ChangeStatusCommand="{Binding ChangeStatusCommand}" + PanelState="{Binding MainPanelState}" + FocusedItemIndex="{Binding FocusedItemIndex}" ItemsSource="{Binding MainList}"/> <Views:SubThumbnailPanel x:Name="RecentSubPanel" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.224}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}" RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.89}" - ChangeStatusCommand="{Binding ChangeStatusCommand}" + PanelState="{Binding RecentSubPanelState}" OnClearVMCommand="{Binding OnClearCommand}" OnClearAllVMCommand="{Binding OnClearAllCommand}" - ItemsSource="{Binding RecentList}" - ShowNoContentsInfo="{Binding IsShowNoRecentContents}" /> + ItemsSource="{Binding RecentList}" /> <Views:SubPanel x:Name="AppsSubPanel" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.2370}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}" RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.8833}" - ChangeStatusCommand="{Binding ChangeStatusCommand}" + PanelState="{Binding AppsSubPanelState}" OnMoveVMCommand="{Binding OnMoveCommand}" OnUnpinVMCommand="{Binding OnUnpinCommand}" ItemsSource="{Binding AppList}" /> @@ -53,7 +50,7 @@ RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.2370}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}" RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.8833}" - ChangeStatusCommand="{Binding ChangeStatusCommand}" + PanelState="{Binding SettingsSubPanelState}" ItemsSource="{Binding SettingsList}" /> </RelativeLayout> </ContentPage.Content> diff --git a/TVHome/TVHome/Views/MainPage.xaml.cs b/TVHome/TVHome/Views/MainPage.xaml.cs index 9daf994..c67c9b6 100755 --- a/TVHome/TVHome/Views/MainPage.xaml.cs +++ b/TVHome/TVHome/Views/MainPage.xaml.cs @@ -29,17 +29,18 @@ namespace TVHome.Views public partial class MainPage : ContentPage { /// <summary> - /// Identifies the CurrentStatus bindable property + /// Identifies the CurrentState bindable property /// </summary> - public static readonly BindableProperty CurrentStatusProperty = BindableProperty.Create("CurrentStatus", typeof(HomeStatus), typeof(MainPage), default(HomeStatus)); + public static readonly BindableProperty CurrentStateProperty = BindableProperty.Create("CurrentState", typeof(AppState), typeof(MainPage), default(AppState), BindingMode.TwoWay); /// <summary> /// Gets or sets current status of MainPage /// </summary> - public HomeStatus CurrentStatus + // TODO : modify name to CurrentState + public AppState CurrentState { - get { return (HomeStatus)GetValue(CurrentStatusProperty); } - set { SetValue(CurrentStatusProperty, value); } + get { return (AppState)GetValue(CurrentStateProperty); } + set { SetValue(CurrentStateProperty, value); } } /// <summary> @@ -66,7 +67,7 @@ namespace TVHome.Views /// </summary> private async void Iconified() { - SubPanelDictionary[SelectedMenuName]?.ForceHidePanel(); + //SubPanelDictionary[SelectedMenuName]?.ForceHidePanel(); #pragma warning disable CS4014 SubPanelDictionary[SelectedMenuName]?.TranslateTo(0.0, SizeUtils.GetHeightSize(100), 150); SubPanelDictionary[SelectedMenuName]?.FadeTo(0, 150); @@ -101,10 +102,13 @@ namespace TVHome.Views { PageMainPanel.InitialFocusing(); Uniconified(); + PageMainPanel.InitialFocusing(); } else { + CurrentState = AppState.HomeIconified; Iconified(); + //CurrentState = AppState.HomeMainPanelAppsFocused; } } @@ -117,20 +121,28 @@ namespace TVHome.Views public MainPage() { InitializeComponent(); + + BindingContext = MainPageViewModel.Instance; + SubPanelDictionary = new Dictionary<HomeMenuItem, Panel>(); SubPanelDictionary.Add(HomeMenuItem.Recent, RecentSubPanel); SubPanelDictionary.Add(HomeMenuItem.Apps, AppsSubPanel); SubPanelDictionary.Add(HomeMenuItem.Settings, SettingsSubPanel); - RecentSubPanel.HidePanel(); - AppsSubPanel.ShowPanel(); - SettingsSubPanel.HidePanel(); + RecentSubPanel.OnPanelHiding(); + RecentSubPanel.BindingContext = RecentListViewModel.Instance; + + AppsSubPanel.OnPanelShowing(); + AppsSubPanel.BindingContext = AppListViewModel.Instance; + + SettingsSubPanel.OnPanelHiding(); + SettingsSubPanel.BindingContext = SettingsViewModel.Instance; PropertyChanged += MainPage_PropertyChanged; App.SetHomeKeyListener((e, arg) => { - if (AppsSubPanel.isMoveMode) + if (AppsSubPanel.PanelState == PanelState.Moving) { AppsSubPanel.ChangeToDefaultMode(); } @@ -140,36 +152,16 @@ namespace TVHome.Views App.SetMenuKeyListener((e, arg) => { - if (AppsSubPanel.isFocused) + foreach (var subPanel in SubPanelDictionary.Values) { - AppsSubPanel.MenuKeyPressed(); - } - else if (RecentSubPanel.isFocused) - { - RecentSubPanel.MenuKeyPressed(); + if (subPanel.PanelState == PanelState.Focused) + { + subPanel.MenuKeyPressed(); + break; + } } }); - AppsSubPanel.OnShowOptionsCommand = new Command<bool>((isShowOptions) => - { - var bounds = AppsSubPanel.Bounds; - if (isShowOptions) - { - PageMainPanel.FadeTo(0, 300); - PageMainPanel.IsVisible = false; - bounds.Height += 300; - bounds.Y -= 300; - } - else - { - PageMainPanel.FadeTo(1, 300); - bounds.Height -= 300; - bounds.Y += 300; - PageMainPanel.IsVisible = true; - } - - AppsSubPanel.LayoutTo(bounds, 0); - }); MessagingCenter.Subscribe<App, TVHomeStatus>(this, App.AppStatus, (sender, arg) => { @@ -183,45 +175,6 @@ namespace TVHome.Views break; } }); - PageMainPanel.OnItemFocusedHandler += (selectedItem) => - { - SelectedMenuName = selectedItem; - DebuggingUtils.Dbg("test" + SelectedMenuName); - }; - - PageMainPanel.OnItemSelectedHandler += (selectedItem) => - { - switch (selectedItem) - { - case HomeMenuItem.Recent: - RecentSubPanel.FocusPanel(); - AppsSubPanel.HidePanel(); - SettingsSubPanel.HidePanel(); - break; - case HomeMenuItem.Apps: - RecentSubPanel.HidePanel(); - AppsSubPanel.FocusPanel(); - SettingsSubPanel.HidePanel(); - break; - case HomeMenuItem.Settings: - RecentSubPanel.HidePanel(); - AppsSubPanel.HidePanel(); - SettingsSubPanel.FocusPanel(); - break; - } - }; - AppsSubPanel.OnItemClickEventHandler += () => - { - ToggleIconified(); - }; - RecentSubPanel.OnItemClickEventHandler += () => - { - ToggleIconified(); - }; - SettingsSubPanel.OnItemClickEventHandler += () => - { - ToggleIconified(); - }; } /// <summary> @@ -234,7 +187,10 @@ namespace TVHome.Views AppsSubPanel.ItemSourceChanged += (s, e) => { - InitializeAppsSubPanelButtonFocusChain(); + if (CurrentState != AppState.HomeMove) + { + InitializeAppsSubPanelButtonFocusChain(); + } }; InitializeMainPanelButtonFocusChain(); @@ -265,7 +221,7 @@ namespace TVHome.Views /// </summary> private void InitializeRecentSubPanelButtonFocusChain() { - List<View> recentSubPanelButtons = new List<View>(RecentSubPanel.GetSubPanelButtons()); + List<View> recentSubPanelButtons = new List<View>(RecentSubPanel.GetSubPanelButtons); Button recentMainPanelButton = PageMainPanel.GetButtonToFocusing(0); if (recentSubPanelButtons.Count > 1) @@ -297,8 +253,8 @@ namespace TVHome.Views /// </summary> private void InitializeAppsSubPanelButtonFocusChain() { - List<View> appsSubPanelButtons = new List<View>(AppsSubPanel.GetSubPanelButtons()); - DebuggingUtils.Dbg("test" + appsSubPanelButtons.Count); + List<View> appsSubPanelButtons = new List<View>(AppsSubPanel.SubPanelButtons); + DebuggingUtils.Dbg("InitializeAppsSubPanelButtonFocusChain, buttons = " + appsSubPanelButtons.Count); Button appsMainPanelButton = PageMainPanel.GetButtonToFocusing(1); if (appsSubPanelButtons.Count > 2) @@ -330,7 +286,7 @@ namespace TVHome.Views /// </summary> private void InitializeSettingsSubPanelButtonFocusChain() { - List<View> settingSubPanelButtons = new List<View>(SettingsSubPanel.GetSubPanelButtons()); + List<View> settingSubPanelButtons = new List<View>(SettingsSubPanel.SubPanelButtons); Button settingMainPanelButton = PageMainPanel.GetButtonToFocusing(2); if (settingSubPanelButtons.Count > 2) @@ -351,77 +307,52 @@ namespace TVHome.Views /// <param name="e">The event that is occurred when property is changed</param> private void MainPage_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { - if (e.PropertyName.CompareTo("CurrentStatus") == 0) - { - SetCurrentStatus(CurrentStatus); - } - else if (e.PropertyName.CompareTo("SelectedMenuName") == 0) + DebuggingUtils.Dbg("MainPage_PropertyChanged, status = " + CurrentState + ", - " + e.PropertyName); + if (e.PropertyName.CompareTo("CurrentState") == 0) { - SelectMenu(SelectedMenuName); + switch (CurrentState) + { + case AppState.HomeIconified: + ToggleIconified(); + break; + } } } /// <summary> - /// A method sets current status according to parameter + /// A task for handling BackKey event /// </summary> - /// <param name="status">The next status name</param> - private void SetCurrentStatus(HomeStatus status) + /// <returns>Always returns true</returns> + protected override bool OnBackButtonPressed() { - switch (status) + DebuggingUtils.Dbg("OnBackButtonPressed"); + + switch (CurrentState) { - case HomeStatus.MainPanelFocused: - PageMainPanel.FocusPanel(); - SelectMenu(SelectedMenuName); + case AppState.HomeMove: + case AppState.HomeShowOptions: + AppsSubPanel.ChangeToDefaultMode(); + // TODO : set panel focused for focused panel. break; - case HomeStatus.SubPanelFocused: - PageMainPanel.SelectPanel(); + + case AppState.HomeMainPanelAppsFocused: + // TODO : remove dependency of MainPanel + PageMainPanel.SetButtonFocus(1); break; - } - } - /// <summary> - /// A method sets selected HomeMenuItem according to parameter - /// </summary> - /// <param name="panelName">Selected HomeMenuItem</param> - private void SelectMenu(HomeMenuItem panelName) - { - foreach (var panelItem in SubPanelDictionary) - { - panelItem.Value.HidePanel(); - } + case AppState.HomeMainPanelRecentFocused: + // TODO : + PageMainPanel.SetButtonFocus(0); + break; - if (panelName == HomeMenuItem.NotSelected) - { - return; - } + case AppState.HomeMainPanelSettingsFocused: + // TODO : + PageMainPanel.SetButtonFocus(2); + break; - SubPanelDictionary[panelName].ShowPanel(); - } - /// <summary> - /// A task for handling BackKey event - /// </summary> - /// <returns>Always returns true</returns> - protected override bool OnBackButtonPressed() - { - if (AppsSubPanel.isMoveMode || AppsSubPanel.isShowOptions) - { - AppsSubPanel.ChangeToDefaultMode(); - } - else if (AppsSubPanel.isFocused) - { - PageMainPanel.SetButtonFocus(1); - } - else if (RecentSubPanel.isFocused) - { - PageMainPanel.SetButtonFocus(0); - } - else if (SettingsSubPanel.isFocused) - { - PageMainPanel.SetButtonFocus(2); - } - else - { - ToggleIconified(); + default: + ToggleIconified(); + break; } return true; diff --git a/TVHome/TVHome/Views/MainPanel.xaml.cs b/TVHome/TVHome/Views/MainPanel.xaml.cs index e0306dd..41003c7 100755 --- a/TVHome/TVHome/Views/MainPanel.xaml.cs +++ b/TVHome/TVHome/Views/MainPanel.xaml.cs @@ -20,6 +20,7 @@ using LibTVRefCommonPortable.DataModels; using TVHome.ViewModels; using Xamarin.Forms; using LibTVRefCommonPortable.Utils; +using System; namespace TVHome.Views { @@ -28,18 +29,13 @@ namespace TVHome.Views /// </summary> public partial class MainPanel : Panel { - public delegate void FocusEventHandler(HomeMenuItem item); - public delegate void SelectEventHandler(HomeMenuItem item); + public static readonly BindableProperty FocusedItemIndexProperty = BindableProperty.Create("FocusedItemIndex", typeof(int), typeof(MainPanel), default(int), BindingMode.TwoWay); - /// <summary> - /// A EventHandler for Item focused event - /// </summary> - public FocusEventHandler OnItemFocusedHandler; - - /// <summary> - /// A EventHandler for Item selected event - /// </summary> - public SelectEventHandler OnItemSelectedHandler; + public int FocusedItemIndex + { + get { return (int)GetValue(FocusedItemIndexProperty); } + set { SetValue(FocusedItemIndexProperty, value); } + } /// <summary> /// Main panel icon's width @@ -61,9 +57,10 @@ namespace TVHome.Views /// </summary> public MainPanel() { + BindingContext = MainPanelViewModel.Instance; InitializeComponent(); InitializeSize(); - PropertyChanged += OnItemsSourcePropertyChanged; + PropertyChanged += OnPropertyChanged; } private void InitializeSize() @@ -84,39 +81,61 @@ namespace TVHome.Views /// </summary> /// <param name="sender">The source of the event</param> /// <param name="e">The event that is occurred when property is changed</param> - private void OnItemsSourcePropertyChanged(object sender, PropertyChangedEventArgs e) + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { - if (e.PropertyName != "ItemsSource") + if (e.PropertyName == "ItemsSource") { - return; - } - HomeMenuItem menuIndex = HomeMenuItem.Recent; - var index = 1; - PanelButtonGrid.Children.Clear(); - foreach (ShortcutInfo item in ItemsSource) - { - var button = new MainPanelButton(); - button.BindingContext = item; - HomeMenuItem ItemName = menuIndex; - button.OnFocusedCommand = new Command(() => - { - ChangeStatusCommand?.Execute(HomeStatus.MainPanelFocused); - OnItemFocusedHandler?.Invoke(ItemName); - FocusPanel(); - }); - button.OnClickedCommand = new Command(() => - { - OnItemSelectedHandler?.Invoke(ItemName); - //item.DoAction(); - }); - PanelButtonGrid.Children.Add(button, index, 0); + HomeMenuItem menuIndex = HomeMenuItem.Recent; + var index = 0; + PanelButtonGrid.Children.Clear(); - index++; - menuIndex++; + foreach (ShortcutInfo item in ItemsSource) + { + int buttonIndex = index; + var button = new MainPanelButton(); + + button.BindingContext = item; + HomeMenuItem ItemName = menuIndex; + var thisButtonInfo = item as HomeMenuAppShortcutInfo; + button.OnFocusedCommand = new Command(() => + { + DebuggingUtils.Dbg("FocusedItemIndex = " + FocusedItemIndex); + DebuggingUtils.Dbg("New FocusedItemIndex = " + buttonIndex); + // TODO : fix + if (FocusedItemIndex == buttonIndex) + { + FocusedItemIndex = 999; + } + + SelectedItem = item; + FocusedItemIndex = buttonIndex; + + DebuggingUtils.Dbg(ItemName + " focused"); + + foreach (var info in ItemsSource) + { + var homeButtonInfo = info as HomeMenuAppShortcutInfo; + homeButtonInfo.ChangeStatus("default"); + } + + thisButtonInfo.ChangeStatus("focused"); + PanelState = PanelState.Focused; + DebuggingUtils.Dbg("End callback........."); + }); + button.OnClickedCommand = new Command(() => + { + DebuggingUtils.Dbg(ItemName + " clicked"); + thisButtonInfo.ChangeStatus("selected"); + }); + PanelButtonGrid.Children.Add(button, index + 1, 0); + + index++; + menuIndex++; + } + + PanelButtonGrid.ForceLayout(); } - - PanelButtonGrid.ForceLayout(); } /// <summary> @@ -124,6 +143,13 @@ namespace TVHome.Views /// </summary> public void InitialFocusing() { + DebuggingUtils.Dbg("InitialFocusing"); + if (PanelButtonGrid.Children.Count < 2) + { + DebuggingUtils.Dbg("InitialFocusing, ignored"); + return; + } + var button = PanelButtonGrid.Children[1]; button.FindByName<Button>("ButtonFocusArea").Focus(); } @@ -142,8 +168,10 @@ namespace TVHome.Views /// <summary> /// A method for translating when panel is focused /// </summary> - public override void FocusPanel() + /// <param name="shouldBeFirstItemFocused">If this flag is true, the first item should be focused.</param> + public override void OnPanelFocusing(bool shouldBeFirstItemFocused = true) { + Scale = 1; AnimationExtensions.AbortAnimation(this, "PanelAnimation"); var currentTranslationY = TranslationY; Animation animation = new Animation(); @@ -155,16 +183,18 @@ namespace TVHome.Views /// <summary> /// A method for scaling panel when panel is hided /// </summary> - public override async void HidePanel() + public override async void OnPanelHiding() { await this.ScaleTo(0, 0); } /// <summary> - /// A method for translating when panel is selected + /// A method for scaling the panel when the panel is showed /// </summary> - public void SelectPanel() + public override void OnPanelShowing() { + Scale = 1; + DebuggingUtils.Dbg("SelectPanel!!!"); AnimationExtensions.AbortAnimation(this, "PanelAnimation"); var currentTranslationY = TranslationY; var diff = selectTransitionHeight - currentTranslationY; @@ -174,12 +204,26 @@ namespace TVHome.Views animation.Commit(this, "PanelAnimation", length: 600); } - /// <summary> - /// A method for scaling the panel when the panel is showed - /// </summary> - public override void ShowPanel() + public override void OnOptionMenuShowing() { - Scale = 1; + this.FadeTo(0, 300); + IsVisible = false; + } + + public override void OnOptionMenuHiding() + { + this.FadeTo(1, 300); + IsVisible = true; + } + + public override void OnMoveStarting() + { + IsVisible = false; + } + + public override void OnMoveFinishing() + { + IsVisible = true; } /// <summary> @@ -202,7 +246,7 @@ namespace TVHome.Views /// <summary> /// A method for handling to hide panel without animation /// </summary> - public override void ForceHidePanel() + public override void OnPanelForcelyHiding() { } } diff --git a/TVHome/TVHome/Views/Panel.cs b/TVHome/TVHome/Views/Panel.cs index 61e9bbe..c51fd62 100755 --- a/TVHome/TVHome/Views/Panel.cs +++ b/TVHome/TVHome/Views/Panel.cs @@ -19,26 +19,60 @@ using System.Windows.Input; using LibTVRefCommonPortable.DataModels; using Xamarin.Forms; using System; +using LibTVRefCommonPortable.Utils; +using System.ComponentModel; namespace TVHome.Views { /// <summary> - /// The Panel is a view for MainPanel and SubPanel of TV Home + /// A enumerations which is realizing Panel status. /// </summary> - public abstract class Panel : ContentView + public enum PanelState { /// <summary> - /// Identifies the ChangeStatusCommand bindable property + /// Panel is iconified. /// </summary> - public static readonly BindableProperty ChangeStatusCommandProperty = BindableProperty.Create("ChangeStatusCommand", typeof(ICommand), typeof(MainPanel)); - + Iconified, + /// <summary> + /// Panel is showing. + /// </summary> + Show, + /// <summary> + /// Panel is focused. + /// </summary> + Focused, /// <summary> - /// A command is executed when panel is focused + /// Panel is hidden. /// </summary> - public ICommand ChangeStatusCommand + Hide, + /// <summary> + /// One of panel button is moving. + /// </summary> + Moving, + /// <summary> + /// A option menu of a panel button is showing. + /// </summary> + ShowingOption, + } + /// <summary> + /// The Panel is a view for MainPanel and SubPanel of TV Home + /// </summary> + public abstract class Panel : ContentView + { + + public static readonly BindableProperty PanelStateProperty = BindableProperty.Create("PanelState", + typeof(PanelState), typeof(Panel), PanelState.Iconified, BindingMode.TwoWay); + + public PanelState PanelState { - get { return (ICommand)GetValue(ChangeStatusCommandProperty); } - set { SetValue(ChangeStatusCommandProperty, value); } + get { return (PanelState)GetValue(PanelStateProperty); } + set { SetValue(PanelStateProperty, value); } + } + + private PanelState previousPanelState + { + get; + set; } /// <summary> @@ -97,6 +131,8 @@ namespace TVHome.Views set { SetValue(OnClearAllVMCommandProperty, value); } } + + /// <summary> /// Identifies the ItemsSource bindable property /// </summary> @@ -126,51 +162,138 @@ namespace TVHome.Views handler?.Invoke(this, e); } - /// <summary> - /// A flag indicates whether the panel is focused or not - /// </summary> - public bool isFocused; + public ShortcutInfo SelectedItem { get; set; } + + //public event EventHandler<ShortcutInfo> ItemSelected; /// <summary> - /// A flag indicates whether the panel is move mode or not + /// A method to make panel focused. /// </summary> - public bool isMoveMode; + /// <param name="shouldBeFirstItemFocused">A flag that make the first item focused if true.</param> + /// <seealso cref="OnPanelHiding"/> + /// <seealso cref="OnPanelShowing"/> + /// <seealso cref="OnPanelForcelyHiding"/> + public abstract void OnPanelFocusing(bool shouldBeFirstItemFocused = true); /// <summary> - /// A flag indicates wheter the ContextPopup Menu is shown or not + /// A method to make panel hide. /// </summary> - public bool isShowOptions; + /// <seealso cref="OnPanelFocusing"/> + /// <seealso cref="OnPanelShowing"/> + /// <seealso cref="OnPanelForcelyHiding"/> + public abstract void OnPanelHiding(); /// <summary> - /// A method for handling panel focused event + /// A method for handling to hide panel without animation /// </summary> - public abstract void FocusPanel(); + /// <seealso cref="OnPanelFocusing"/> + /// <seealso cref="OnPanelHiding"/> + /// <seealso cref="OnPanelShowing"/> + public abstract void OnPanelForcelyHiding(); /// <summary> - /// A method for handling to hide panel + /// A method to make panel show which is a state not focused. /// </summary> - public abstract void HidePanel(); + /// <seealso cref="OnPanelFocusing"/> + /// <seealso cref="OnPanelShowing"/> + /// <seealso cref="OnPanelForcelyHiding"/> + public abstract void OnPanelShowing(); + + public abstract void OnOptionMenuShowing(); + + public abstract void OnOptionMenuHiding(); + + public abstract void OnMoveStarting(); + + public abstract void OnMoveFinishing(); /// <summary> - /// A method for handling to hide panel without animation + /// Constructor /// </summary> - public abstract void ForceHidePanel(); + public Panel() + { + PanelState = PanelState.Iconified; + previousPanelState = PanelState.Iconified; + PropertyChanged += OnPropertyChanged; + } /// <summary> - /// A method for handling to show panel + /// An event handler for handling property changed event /// </summary> - public abstract void ShowPanel(); + /// <param name="sender">A source of event</param> + /// <param name="e">The event that is occurred when property is changed</param> + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "PanelState") + { + DebuggingUtils.Dbg($"[PanelState] {previousPanelState} => {PanelState}"); - public delegate void ItemClickEventHandler(); + if (previousPanelState == PanelState) + { + DebuggingUtils.Dbg("[PanelState] IGNORE"); + return; + } - /// <summary> - /// A EventHandler for handling Item is clicked - /// </summary> - public ItemClickEventHandler OnItemClickEventHandler; + switch (previousPanelState) + { + case PanelState.ShowingOption: + OnOptionMenuHiding(); + break; + case PanelState.Moving: + OnMoveFinishing(); + break; + } + + + switch (PanelState) + { + case PanelState.Show: + OnPanelShowing(); + break; + + case PanelState.Focused: + if (previousPanelState == PanelState.ShowingOption || + previousPanelState == PanelState.Moving) + { + OnPanelFocusing(false); + } + else + { + OnPanelFocusing(); + } + + break; + + case PanelState.Iconified: + OnPanelForcelyHiding(); + break; + + case PanelState.ShowingOption: + OnOptionMenuShowing(); + break; + + case PanelState.Moving: + OnMoveStarting(); + break; + + case PanelState.Hide: + if (previousPanelState == PanelState.Show || + previousPanelState == PanelState.Focused) + { + OnPanelHiding(); + } + + break; + } + + previousPanelState = PanelState; + } + } /// <summary> /// A method for handling when menu key is pressed /// </summary> public abstract void MenuKeyPressed(); + } } diff --git a/TVHome/TVHome/Views/SubPanel.xaml.cs b/TVHome/TVHome/Views/SubPanel.xaml.cs index 630dd7e..c36bbda 100755 --- a/TVHome/TVHome/Views/SubPanel.xaml.cs +++ b/TVHome/TVHome/Views/SubPanel.xaml.cs @@ -35,17 +35,13 @@ namespace TVHome.Views /// <summary> /// A list of PanelButtons. /// </summary> - private List<PanelButton> ButtonList; + private List<PanelButton> ButtonList = new List<PanelButton>(); /// <summary> /// A list of Button's Views. /// </summary> - private List<View> ButtonViewList; + private List<View> ButtonViewList = new List<View>(); - /// <summary> - /// A Command will be executed the option menus are showed. - /// </summary> - public ICommand OnShowOptionsCommand { get; set; } /// <summary> /// SubPanel icon's transition height value when it focused. @@ -56,9 +52,12 @@ namespace TVHome.Views /// A method for getting Panel Buttons /// </summary> /// <returns>A list of panel button views</returns> - public IList<View> GetSubPanelButtons() + public IList<View> SubPanelButtons { - return PanelButtonStack.Children; + get + { + return PanelButtonStack.Children; + } } /// <summary> @@ -67,15 +66,9 @@ namespace TVHome.Views public SubPanel() { InitializeComponent(); - isFocused = false; - isMoveMode = false; - isShowOptions = false; - - ButtonList = new List<PanelButton>(); - ButtonViewList = new List<View>(); InitializeSize(); - PropertyChanged += OnItemsSourcePropertyChanged; + PropertyChanged += OnPropertyChanged; } private void InitializeSize() @@ -89,150 +82,187 @@ namespace TVHome.Views /// </summary> public override void MenuKeyPressed() { - isShowOptions = true; + DebuggingUtils.Dbg("SubPanel MenuKeyPressed"); - if (isFocused) + foreach (var item in ButtonList) { - foreach (var item in ButtonList) + if (item is SubPanelButton) { - if (item is SubPanelButton) + if (item.IsButtonFocused) { - if (item.isFocused) - { - OnShowOptionsCommand?.Execute(isShowOptions); - item.ShowContextPopup(); - item.ChangeShowOptionsMode(isShowOptions); - ChangeIsEnabledProperty(item, false); - } + item.PanelButtonState = PanelButtonState.ShowingOption; + ChangeIsEnabledProperty(item, false); } } } } + public void PanelButtonStateEventHandler(object sender, PanelButtonState panelButtonStateArg) + { + DebuggingUtils.Dbg("PanelButtonStateEventHandler, " + panelButtonStateArg); + switch (panelButtonStateArg) + { + case PanelButtonState.Focused: + if (PanelState != PanelState.Moving && + PanelState != PanelState.Iconified) + { + PanelState = PanelState.Focused; + } + else + { + DebuggingUtils.Dbg("PanelButtonStateEventHandler, Focus ignored"); + } + + break; + + case PanelButtonState.Move: + case PanelButtonState.Moving: + PanelState = PanelState.Moving; + break; + + case PanelButtonState.ShowingOption: + PanelState = PanelState.ShowingOption; + break; + } + } + /// <summary> /// An event handler for handling property changed event /// </summary> /// <param name="sender">A source of event</param> /// <param name="e">The event that is occurred when property is changed</param> - private void OnItemsSourcePropertyChanged(object sender, PropertyChangedEventArgs e) + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { - if (e.PropertyName != "ItemsSource") + if (e.PropertyName == "ItemsSource") { - return; - } - PanelButtonStack.Children.Clear(); - ButtonViewList.Clear(); - ButtonList.Clear(); - foreach (ShortcutInfo item in ItemsSource) - { - PanelButton button; + PanelButtonStack.Children.Clear(); + ButtonViewList.Clear(); + ButtonList.Clear(); - if (item is AppShortcutInfo) + foreach (ShortcutInfo item in ItemsSource) { - if (item.StateDescriptions["default"].Label.Equals("All apps") - || item.StateDescriptions["default"].Label.Equals("Add pin") - || item.StateDescriptions["default"].Label.Equals("Media Hub")) - { - button = new SubPanelAllAppsButton(); - ButtonList.Add(button); - } - else + PanelButton button; + button = MakeSubPanelButton(item); + + button.BindingContext = item; + button.OnPanelButtonStateChanged += PanelButtonStateEventHandler; + button.OnFocusedCommand = new Command(() => { - button = new SubPanelButton(); - button.OnMoveCommand = new Command<string>((direction) => + PanelState = PanelState.Focused; + + SelectedItem = item; + + if (SizeUtils.GetWidthSize((int)button.X) - SizeUtils.GetWidthSize((int)PanelScrollView.ScrollX) < 0) + { + ScrollToLeft(); + } + else if (SizeUtils.GetWidthSize((int)button.X) + SizeUtils.GetWidthSize(216) > SizeUtils.GetWidthSize(1920)) { - if (button.rightMoving || button.leftMoving) - { - return; - } - - int index = ButtonViewList.IndexOf(button); - if (direction.Equals("Right")) - { - button.rightMoving = true; - MoveItemToRight(index, button); - } - else if (direction.Equals("Left")) - { - button.leftMoving = true; - MoveItemToLeft(index, button); - } - }); - - button.OnMoveFinishedCommand = new Command(() => + ScrollToRight(); + } + }); + button.OnClickedCommand = new Command(() => + { + item.DoAction(); + if (!item.StateDescriptions["default"].Label.Equals("Add pin")) { - isMoveMode = !isMoveMode; - isShowOptions = false; + PanelState = PanelState.Iconified; + } + }); + button.OnUnpinCommand = new Command(() => + { + AppShortcutInfo shortcut = (AppShortcutInfo)button.BindingContext; + OnUnpinVMCommand?.Execute(shortcut.AppID); + }); + // TODO : remove + button.OnDefaultModeCommand = new Command(() => + { + ChangeToDefaultMode(); + }); - ChangeIsEnabledProperty(button, false); - button.ChangeMoveMode(isMoveMode, false); + PanelButtonStack.Children.Add(button); + ButtonViewList.Add(button); + } - if (!isMoveMode) - { - OnMoveVMCommand.Execute(ButtonViewList); - } - }); - } + OnItemSourceChanged(EventArgs.Empty); - ButtonList.Add(button); + if (PanelState == PanelState.Hide || + PanelState == PanelState.Iconified) + { + OnPanelHiding(); } else { - button = new SubPanelSettingButton(); + OnPanelFocusing(); } + } + } + + private PanelButton MakeSubPanelButton(ShortcutInfo item) + { + PanelButton button; + + if (!(item is AppShortcutInfo)) + { + return new SubPanelSettingButton(); + } - button.BindingContext = item; - button.OnFocusedCommand = new Command(() => + if (item.StateDescriptions["default"].Label.Equals("All apps") + || item.StateDescriptions["default"].Label.Equals("Add pin") + || item.StateDescriptions["default"].Label.Equals("Media Hub")) + { + button = new SubPanelAllAppsButton(); + ButtonList.Add(button); + } + else + { + button = new SubPanelButton(); + button.OnMoveCommand = new Command<string>((direction) => { - ChangeStatusCommand?.Execute(HomeStatus.SubPanelFocused); - FocusPanel(); - if (SizeUtils.GetWidthSize((int)button.X) - SizeUtils.GetWidthSize((int)PanelScrollView.ScrollX) < 0) + DebuggingUtils.Dbg("OnMoveCommand, " + direction); + + if (button.PanelButtonState != PanelButtonState.Move) { - ScrollToLeft(); + DebuggingUtils.Dbg("OnMoveCommand - ignore"); + return; } - else if (SizeUtils.GetWidthSize((int)button.X) + SizeUtils.GetWidthSize(216) > SizeUtils.GetWidthSize(1920)) + + int index = ButtonViewList.IndexOf(button); + if (direction.Equals("Right")) { - ScrollToRight(); + button.PanelButtonState = PanelButtonState.Moving; + MoveItemToRight(index, button); } - }); - button.OnClickedCommand = new Command(() => - { - item.DoAction(); - if (!item.StateDescriptions["default"].Label.Equals("Add pin")) + else if (direction.Equals("Left")) { - OnItemClickEventHandler?.Invoke(); + button.PanelButtonState = PanelButtonState.Moving; + MoveItemToLeft(index, button); } }); - button.OnUnpinCommand = new Command(() => - { - AppShortcutInfo shortcut = (AppShortcutInfo)button.BindingContext; - OnUnpinVMCommand?.Execute(shortcut.AppID); - }); - button.OnDefaultModeCommand = new Command(() => - { - ChangeToDefaultMode(); - }); - button.OnShowOptionsCommand = new Command<bool>((param) => + + button.OnMoveToggleCommand = new Command(() => { - OnShowOptionsCommand?.Execute(param); - }); + DebuggingUtils.Dbg("OnMoveCommand , " + button.IsButtonMoving); - PanelButtonStack.Children.Add(button); - ButtonViewList.Add(button); + ChangeIsEnabledProperty(button, false); + if (button.PanelButtonState == PanelButtonState.Move) + { + // TODO : unregiste messaging center + button.PanelButtonState = PanelButtonState.Show; + OnMoveVMCommand.Execute(ButtonViewList); + } + else + { + // TODO : subscribe messaging sender + button.PanelButtonState = PanelButtonState.Move; + } + }); } - OnItemSourceChanged(EventArgs.Empty); + ButtonList.Add(button); - if (!isFocused) - { - ShowPanel(); - } - else - { - isFocused = false; - FocusPanel(); - } + return button; } /// <summary> @@ -258,10 +288,11 @@ namespace TVHome.Views /// <summary> /// A method is called when apps subpanel is changed to move mode and change item's IsEnabled property. /// </summary> - /// <param name="selectedBtn">A selected button view to move</param> - /// <param name="isEnabled">TODO : Comment this</param> + /// <param name="selectedBtn">A selected button view to move.</param> + /// <param name="isEnabled">A button's status to be changed.</param> private void ChangeIsEnabledProperty(View selectedBtn, bool isEnabled) { + DebuggingUtils.Dbg("SubPanel ChangeIsEnabledProperty"); foreach (var item in PanelButtonStack.Children) { if (item != selectedBtn) @@ -274,15 +305,14 @@ namespace TVHome.Views /// <summary> /// A method for hiding the panel /// </summary> - public override void HidePanel() + public override void OnPanelHiding() { - isFocused = false; + DebuggingUtils.Dbg("SubPanel HidePanel"); foreach (var item in PanelButtonStack.Children) { item.IsEnabled = false; } - PanelScrollView.ScrollToAsync(0, 0, true); AnimationExtensions.AbortAnimation(this, "PanelAnimation"); var currentTranslationY = TranslationY; var diff = selectTransitionHeight - currentTranslationY; @@ -292,15 +322,19 @@ namespace TVHome.Views Animation fadeAnimation = new Animation(v => Opacity = currentOpacity * (1 - v)); animation.Add(0, 1, translateAnimation); animation.Add(0, 1, fadeAnimation); - animation.Commit(this, "PanelAnimation", length: 300); + animation.Commit(this, "PanelAnimation", length: 300, finished: (percentage, cancel) => + { + PanelScrollView.ScrollToAsync(0, 0, true); + }); + } /// <summary> /// A method for showing the panel /// </summary> - public override void ShowPanel() + public override void OnPanelShowing() { - isFocused = false; + DebuggingUtils.Dbg("SubPanel ShowPanel"); foreach (var item in PanelButtonStack.Children) { item.IsEnabled = true; @@ -323,17 +357,17 @@ namespace TVHome.Views /// <summary> /// A method for handling panel focused event /// </summary> - public override void FocusPanel() + /// <param name="shouldBeFirstItemFocused">If this flag is true, the first item should be focused.</param> + public override void OnPanelFocusing(bool shouldBeFirstItemFocused = true) { - if (isFocused) + DebuggingUtils.Dbg("SubPanel FocusPanel, " + TranslationY); + + if (shouldBeFirstItemFocused) { - return; + var button = PanelButtonStack.Children[1]; + button.FindByName<Button>("ButtonFocusArea").Focus(); } - isFocused = true; - var button = PanelButtonStack.Children[1]; - button.FindByName<Button>("ButtonFocusArea").Focus(); - foreach (var item in PanelButtonStack.Children) { item.FindByName<Image>("ButtonDimmedImage").Scale = 1.0; @@ -351,22 +385,57 @@ namespace TVHome.Views animation.Commit(this, "PanelAnimation", length: 600); } + public override void OnOptionMenuShowing() + { + DebuggingUtils.Dbg("OnShowingOptiongMenu - SubPanel"); + var bounds = Bounds; + bounds.Height += 300; + bounds.Y -= 300; + this.LayoutTo(bounds, 0); + } + + public override void OnOptionMenuHiding() + { + DebuggingUtils.Dbg("OnHidingOptiongMenu - SubPanel"); + var bounds = Bounds; + bounds.Height -= 300; + bounds.Y += 300; + this.LayoutTo(bounds, 0); + } + + public override void OnMoveStarting() + { + DebuggingUtils.Dbg("OnShowingMoving - SubPanel"); + var bounds = Bounds; + bounds.Height += 300; + bounds.Y -= 300; + this.LayoutTo(bounds, 0); + } + + public override void OnMoveFinishing() + { + DebuggingUtils.Dbg("OnHidingMoving - SubPanel"); + var bounds = Bounds; + bounds.Height -= 300; + bounds.Y += 300; + this.LayoutTo(bounds, 0); + } + + /// <summary> /// A method is called when back button is pressed in move mode /// </summary> public void ChangeToDefaultMode() { - if (isMoveMode) + DebuggingUtils.Dbg("SubPanel ChangeToDefaultMode"); + if (PanelState == PanelState.Moving) { - isMoveMode = !isMoveMode; - isShowOptions = false; - foreach (var item in ButtonList) { - if (item.isMoveMode) + if (item.IsButtonMoving) { ChangeIsEnabledProperty(item, true); - item.ChangeMoveMode(isMoveMode, true); + item.PanelButtonState = PanelButtonState.MoveCanceled; } else { @@ -380,15 +449,15 @@ namespace TVHome.Views ButtonViewList.Add(stackItem); } } - else if (isShowOptions) + else if (PanelState == PanelState.ShowingOption) { - isShowOptions = !isShowOptions; + //PanelState = PanelState.Show; foreach (var item in ButtonList) { - if (item.isFocused) + if (item.IsOptionsShowing) { - item.ChangeShowOptionsMode(isShowOptions); + item.ChangeShowOptionsMode(false); ChangeIsEnabledProperty(item, true); } } @@ -407,6 +476,7 @@ namespace TVHome.Views int nextIndex = index + 1; if (nextIndex >= PanelButtonStack.Children.Count - 1) { + btn.PanelButtonState = PanelButtonState.Move; return; } @@ -431,7 +501,7 @@ namespace TVHome.Views animation.Add(0.5, 1, nextScaleUp); animation.Add(0, 1, nextTranslate); - animation.Commit(this, "MoveRightAnimation", 16, 334, null, (v, c) => btn.rightMoving = false); + animation.Commit(this, "MoveRightAnimation", 16, 334, null, (v, c) => btn.PanelButtonState = PanelButtonState.Move); if (SizeUtils.GetWidthSize((int)(originItemView.X + translateX + 216)) - SizeUtils.GetWidthSize((int)PanelScrollView.ScrollX) > SizeUtils.GetWidthSize(1920)) { @@ -455,6 +525,7 @@ namespace TVHome.Views if (prevIndex < 2) { + btn.PanelButtonState = PanelButtonState.Move; return; } @@ -479,7 +550,7 @@ namespace TVHome.Views animation.Add(0.5, 1, prevScaleUp); animation.Add(0, 1, prevTranslate); - animation.Commit(this, "MoveLeftAnimation", 16, 334, null, (v, c) => btn.leftMoving = false); + animation.Commit(this, "MoveLeftAnimation", 16, 334, null, (v, c) => btn.PanelButtonState = PanelButtonState.Move); if (SizeUtils.GetWidthSize((int)(originItemView.X + translateX)) - SizeUtils.GetWidthSize((int)PanelScrollView.ScrollX) < 0) { @@ -493,15 +564,19 @@ namespace TVHome.Views /// <summary> /// A method for handling to hide panel without animation /// </summary> - public override void ForceHidePanel() + public override void OnPanelForcelyHiding() { + DebuggingUtils.Dbg("ForceHidePanel"); + /* foreach (var item in PanelButtonStack.Children) { item.FindByName<Image>("ButtonDimmedImage").Opacity = 0.99; } - - TranslationY = selectTransitionHeight; - Opacity = 1; + Opacity = 0; + */ + OnPanelHiding(); } } + + }
\ No newline at end of file diff --git a/TVHome/TVHome/Views/SubThumbnailPanel.xaml b/TVHome/TVHome/Views/SubThumbnailPanel.xaml index 2dfb598..849ae36 100755 --- a/TVHome/TVHome/Views/SubThumbnailPanel.xaml +++ b/TVHome/TVHome/Views/SubThumbnailPanel.xaml @@ -8,14 +8,13 @@ <ScrollView x:Name="PanelScrollView" Orientation="Horizontal" HorizontalOptions="Center" - IsVisible="true" + IsVisible="false" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}" RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}" RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0}" > <StackLayout x:Name="PanelButtonStack" - Orientation="Horizontal" - IsVisible="true" /> + Orientation="Horizontal" /> </ScrollView> <RelativeLayout x:Name="NoContentInfo" IsVisible="false" diff --git a/TVHome/TVHome/Views/SubThumbnailPanel.xaml.cs b/TVHome/TVHome/Views/SubThumbnailPanel.xaml.cs index d0d9275..a3dad21 100755 --- a/TVHome/TVHome/Views/SubThumbnailPanel.xaml.cs +++ b/TVHome/TVHome/Views/SubThumbnailPanel.xaml.cs @@ -38,18 +38,9 @@ namespace TVHome.Views private List<PanelButton> ButtonList; /// <summary> - /// Identifies the ShowNoContentsInfo bindable property - /// </summary> - public static readonly BindableProperty ShowNoContentsInfoProperty = BindableProperty.Create("ShowNoContentsInfo", typeof(bool), typeof(SubThumbnailPanel), default(bool)); - - /// <summary> /// A flag indicates whether displaying "no content info" is needed or not /// </summary> - public bool ShowNoContentsInfo - { - get { return (bool)GetValue(ShowNoContentsInfoProperty); } - set { SetValue(ShowNoContentsInfoProperty, value); } - } + private bool isShowNoContentsInfo = true; /// <summary> /// SubPanel icon's transition height value when it focused. @@ -57,19 +48,49 @@ namespace TVHome.Views private int selectTransitionHeight = SizeUtils.GetHeightSize(140); /// <summary> + /// A method for getting Panel Buttons + /// </summary> + /// <returns>A list of panel button views</returns> + public IList<View> GetSubPanelButtons + { + get + { + return PanelButtonStack.Children; + } + } + + /// <summary> /// Constructor /// </summary> public SubThumbnailPanel() { InitializeComponent(); InitializeSize(); - isFocused = false; - PropertyChanged += OnItemsSourcePropertyChanged; + + SetPanelDisplay(); + + PropertyChanged += OnPropertyChanged; NoContentInfoText.On<Tizen>().SetFontWeight(FontWeight.Light); ButtonList = new List<PanelButton>(); } + private void SetPanelDisplay() + { + if (isShowNoContentsInfo) + { + DebuggingUtils.Dbg("SetPanelDisplay - TRUE"); + PanelScrollView.IsVisible = false; + NoContentInfo.IsVisible = true; + } + else + { + DebuggingUtils.Dbg("SetPanelDisplay - FALSE"); + PanelScrollView.IsVisible = true; + NoContentInfo.IsVisible = false; + } + } + private void InitializeSize() { PanelButtonStack.Spacing = SizeUtils.GetWidthSizeDouble(27.5); @@ -83,15 +104,31 @@ namespace TVHome.Views /// </summary> public override void MenuKeyPressed() { - if (isFocused) + foreach (var item in ButtonList) { - foreach (var item in ButtonList) + if (item.IsButtonFocused) { - if (item.isFocused) + item.PanelButtonState = PanelButtonState.ShowingOption; + } + } + } + + public void PanelButtonStateEventHandler(object sender, PanelButtonState panelButtonStateArg) + { + DebuggingUtils.Dbg("PanelButtonStateEventHandler, " + panelButtonStateArg); + switch (panelButtonStateArg) + { + case PanelButtonState.Focused: + if (PanelState != PanelState.Moving) { - item.ShowContextPopup(); + PanelState = PanelState.Focused; } - } + + break; + + case PanelButtonState.ShowingOption: + PanelState = PanelState.ShowingOption; + break; } } @@ -100,35 +137,28 @@ namespace TVHome.Views /// </summary> /// <param name="sender">A source of event</param> /// <param name="e">The event that is occurred when property is changed</param> - private void OnItemsSourcePropertyChanged(object sender, PropertyChangedEventArgs e) + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { - if (e.PropertyName == "ShowNoContentsInfo") - { - if (ShowNoContentsInfo) - { - PanelScrollView.IsVisible = false; - NoContentInfo.IsVisible = true; - HidePanel(); - return; - } - else - { - PanelScrollView.IsVisible = true; - NoContentInfo.IsVisible = false; - } - } - else if (e.PropertyName == "ItemsSource") + if (e.PropertyName == "ItemsSource") { + DebuggingUtils.Dbg("SubThumbnailPanel view OnPropertyChanged, ItemSource "); + + isShowNoContentsInfo = true; PanelButtonStack.Children.Clear(); ButtonList.Clear(); + foreach (RecentShortcutInfo item in ItemsSource) { PanelButton button = new SubPanelThumbnailButton(); button.BindingContext = item; + + button.OnPanelButtonStateChanged += PanelButtonStateEventHandler; button.OnFocusedCommand = new Command(() => { - ChangeStatusCommand?.Execute(HomeStatus.SubPanelFocused); - FocusPanel(); + DebuggingUtils.Dbg("SubThumbnailPanel Focused"); + PanelState = PanelState.Focused; + SelectedItem = item; + if (SizeUtils.GetWidthSize((int)button.X) - SizeUtils.GetWidthSize((int)PanelScrollView.ScrollX) < 0) { ScrollToLeft(); @@ -152,16 +182,20 @@ namespace TVHome.Views }); PanelButtonStack.Children.Add(button); ButtonList.Add(button); + + isShowNoContentsInfo = false; } - if (!isFocused) + SetPanelDisplay(); + + if (PanelState == PanelState.Hide || + PanelState == PanelState.Iconified) { - HidePanel(); + OnPanelHiding(); } else { - isFocused = false; - FocusPanel(); + OnPanelFocusing(); } } } @@ -187,97 +221,89 @@ namespace TVHome.Views } /// <summary> - /// A method for getting Panel Buttons - /// </summary> - /// <returns>A list of panel button views</returns> - public IList<View> GetSubPanelButtons() - { - return PanelButtonStack.Children; - } - - /// <summary> /// A method for hiding the panel /// </summary> - public override void HidePanel() + public override void OnPanelHiding() { - if (NoContentInfo.IsVisible) + if (isShowNoContentsInfo) { TranslationY = 0; Opacity = 0; + return; } - else - { - isFocused = false; - foreach (var item in PanelButtonStack.Children) - { - item.IsEnabled = false; - } - PanelScrollView.ScrollToAsync(0, 0, true); - AnimationExtensions.AbortAnimation(this, "PanelAnimation"); - var currentTranslationY = TranslationY; - var diff = selectTransitionHeight - currentTranslationY; - var currentOpacity = Opacity; - Animation animation = new Animation(); - Animation translateAnimation = new Animation(v => TranslationY = (currentTranslationY + diff * v)); - Animation fadeAnimation = new Animation(v => Opacity = currentOpacity * (1 - v)); - animation.Add(0, 1, translateAnimation); - animation.Add(0, 1, fadeAnimation); - animation.Commit(this, "PanelAnimation", length: 300); + foreach (var item in PanelButtonStack.Children) + { + item.IsEnabled = false; } + + AnimationExtensions.AbortAnimation(this, "PanelAnimation"); + var currentTranslationY = TranslationY; + var diff = selectTransitionHeight - currentTranslationY; + var currentOpacity = Opacity; + Animation animation = new Animation(); + Animation translateAnimation = new Animation(v => TranslationY = (currentTranslationY + diff * v)); + Animation fadeAnimation = new Animation(v => Opacity = currentOpacity * (1 - v)); + animation.Add(0, 1, translateAnimation); + animation.Add(0, 1, fadeAnimation); + animation.Commit(this, "PanelAnimation", length: 300, finished: (percentage, cancel) => + { + PanelScrollView.ScrollToAsync(0, 0, true); + }); } /// <summary> /// A method for showing the panel /// </summary> - public override void ShowPanel() + public override void OnPanelShowing() { - if (NoContentInfo.IsVisible) + if (isShowNoContentsInfo) { - NoContentInfo.IsEnabled = false; + TranslationY = 0; Opacity = 1; + return; } - else - { - isFocused = false; - foreach (var item in PanelButtonStack.Children) - { - item.IsEnabled = true; - item.FindByName<Xamarin.Forms.Image>("ThumnailDimLayer").Opacity = 1; - } - AnimationExtensions.AbortAnimation(this, "PanelAnimation"); - var currentTranslationY = TranslationY; - var currentOpacity = Opacity; - var diff = 1 - currentOpacity; - Animation animation = new Animation(); - Animation translateAnimation = new Animation(v => TranslationY = (currentTranslationY * (1 - v))); - Animation fadeAnimation = new Animation(v => Opacity = currentOpacity + diff * v); - animation.Add(0, 1, translateAnimation); - animation.Add(0, 1, fadeAnimation); - animation.Commit(this, "PanelAnimation", length: 300); + foreach (var item in PanelButtonStack.Children) + { + item.IsEnabled = true; + item.FindByName<Xamarin.Forms.Image>("ThumnailDimLayer").Opacity = 1; } + + AnimationExtensions.AbortAnimation(this, "PanelAnimation"); + var currentTranslationY = TranslationY; + var currentOpacity = Opacity; + var diff = 1 - currentOpacity; + Animation animation = new Animation(); + Animation translateAnimation = new Animation(v => TranslationY = (currentTranslationY * (1 - v))); + Animation fadeAnimation = new Animation(v => Opacity = currentOpacity + diff * v); + animation.Add(0, 1, translateAnimation); + animation.Add(0, 1, fadeAnimation); + animation.Commit(this, "PanelAnimation", length: 300); + } /// <summary> /// A method for handling panel focused event /// </summary> - public override void FocusPanel() + /// <param name="shouldBeFirstItemFocused">If this flag is true, the first item should be focused.</param> + public override void OnPanelFocusing(bool shouldBeFirstItemFocused = true) { - if (isFocused || ShowNoContentsInfo) + if (isShowNoContentsInfo) { return; } - isFocused = true; - foreach (var item in PanelButtonStack.Children) { item.FindByName<Xamarin.Forms.Image>("ThumnailDimLayer").Opacity = 0; } - var button = PanelButtonStack.Children[0]; - button.FindByName<Button>("ButtonFocusArea").Focus(); + if (shouldBeFirstItemFocused) + { + var button = PanelButtonStack.Children[0]; + button.FindByName<Button>("ButtonFocusArea").Focus(); + } AnimationExtensions.AbortAnimation(this, "PanelAnimation"); var currentTranslationY = TranslationY; @@ -288,11 +314,40 @@ namespace TVHome.Views animation.Commit(this, "PanelAnimation", length: 600); } + + public override void OnOptionMenuShowing() + { + DebuggingUtils.Dbg("OnShowingOptiongMenu - SubThumbnailPanel"); + var bounds = Bounds; + bounds.Height += 300; + bounds.Y -= 300; + this.LayoutTo(bounds, 0); + } + + public override void OnOptionMenuHiding() + { + DebuggingUtils.Dbg("OnHidingOptiongMenu - SubThumbnailPanel"); + var bounds = Bounds; + bounds.Height -= 300; + bounds.Y += 300; + this.LayoutTo(bounds, 0); + } + + + public override void OnMoveStarting() + { + } + + public override void OnMoveFinishing() + { + } + /// <summary> /// A method for handling to hide panel without animation /// </summary> - public override void ForceHidePanel() + public override void OnPanelForcelyHiding() { + /* foreach (var item in PanelButtonStack.Children) { item.IsEnabled = true; @@ -301,6 +356,8 @@ namespace TVHome.Views this.TranslationY = selectTransitionHeight; Opacity = 1; + */ + OnPanelHiding(); } } }
\ No newline at end of file |