TVHome Refactoring 72/136472/3
authorChulSeung Kim <charles0.kim@samsung.com>
Wed, 21 Jun 2017 00:50:28 +0000 (09:50 +0900)
committerChulSeung Kim <charles0.kim@samsung.com>
Mon, 3 Jul 2017 01:55:31 +0000 (10:55 +0900)
- Seperate MainPageViewModel to severals
- Make a connection based on status(AppState, PanelState, PanelButtonState)
- Make it use event notification to change GUI

Change-Id: I7ccd85d15cc56410d9d64720cde1d25325abaf4e

28 files changed:
LibTVRefCommonPortable/Models/AppShortcutController.cs
LibTVRefCommonPortable/Utils/IStatePublisher.cs
LibTVRefCommonTizen/Ports/PackageManagerPort.cs
LibTVRefCommonTizen/Ports/WindowPort.cs
TVApps/TVApps.TizenTV/TVApps.TizenTV.cs
TVApps/TVApps/Controls/AppListView.xaml.cs
TVHome/TVHome.TizenTV/TVHome.TizenTV.cs
TVHome/TVHome/Controls/MainPanelButton.xaml.cs
TVHome/TVHome/Controls/PanelButton.cs
TVHome/TVHome/Controls/SubPanelAllAppsButton.xaml.cs
TVHome/TVHome/Controls/SubPanelButton.xaml.cs
TVHome/TVHome/Controls/SubPanelSettingButton.xaml.cs
TVHome/TVHome/Controls/SubPanelThumbnailButton.xaml.cs
TVHome/TVHome/TVHome.cs
TVHome/TVHome/TVHome.csproj
TVHome/TVHome/ViewModels/AppListViewModel.cs [new file with mode: 0644]
TVHome/TVHome/ViewModels/IHomeViewModel.cs [deleted file]
TVHome/TVHome/ViewModels/MainPageViewModel.cs
TVHome/TVHome/ViewModels/MainPanelViewModel.cs [new file with mode: 0644]
TVHome/TVHome/ViewModels/RecentListViewModel.cs [new file with mode: 0644]
TVHome/TVHome/ViewModels/SettingsViewModel.cs [new file with mode: 0644]
TVHome/TVHome/Views/MainPage.xaml
TVHome/TVHome/Views/MainPage.xaml.cs
TVHome/TVHome/Views/MainPanel.xaml.cs
TVHome/TVHome/Views/Panel.cs
TVHome/TVHome/Views/SubPanel.xaml.cs
TVHome/TVHome/Views/SubThumbnailPanel.xaml
TVHome/TVHome/Views/SubThumbnailPanel.xaml.cs

index 37df5c0..7ec06fd 100755 (executable)
@@ -346,7 +346,7 @@ namespace LibTVRefCommonPortable.Models
             }
             else
             {
-                DebuggingUtils.Dbg("AppShortcutStorage Instance is NULL");
+                DebuggingUtils.Err("AppShortcutStorage Instance is NULL");
             }
         }
     }
index 4600c1a..0c3605d 100644 (file)
@@ -24,8 +24,17 @@ namespace LibTVRefCommonPortable.Utils
 {
     public enum AppState
     {
-
+        HomeMainPanelRecentFocused,
+        HomeMainPanelAppsFocused,
+        HomeMainPanelSettingsFocused,
+        HomeSubPanelRecentFocused,
+        HomeSubPanelAppsFocused,
+        HomeSubPanelSettingsFocused,
+        HomeShowOptions,
+        HomeMove,
+        HomeIconified,
     }
+
     public interface IStatePublisher
     {
         AppState CurrentState
index a8719b7..dff72d8 100644 (file)
@@ -92,10 +92,7 @@ namespace LibTVRefCommonTizen.Ports
         {
             if (e.State == PackageEventState.Completed)
             {
-                if (Notification != null)
-                {
-                    Notification.OnAppInstalled(e.PackageId);
-                }
+                Notification?.OnAppInstalled(e.PackageId);
             }
         }
 
@@ -120,7 +117,7 @@ namespace LibTVRefCommonTizen.Ports
                 result = new string[3];
                 var itemLabel = "No Name";
 
-                if (item.Label != null && item.Label.Length > 0)
+                if (!string.IsNullOrEmpty(item.Label))
                 {
                     itemLabel = item.Label;
                 }
index 3829121..f2213d3 100644 (file)
@@ -97,10 +97,7 @@ namespace LibTVRefCommonTizen.Ports
         /// </remarks>
         public void Active()
         {
-            if (mainWindow != null)
-            {
-                mainWindow.Active();
-            }
+            mainWindow?.Active();
         }
     }
 }
index 72abdc5..067aef0 100755 (executable)
@@ -77,10 +77,7 @@ namespace TVApps.TizenTV
             if (args.KeyName.CompareTo(ElmSharp.EvasKeyEventArgs.PlatformMenuButtonName) == 0 ||
                 args.KeyName.CompareTo("XF86Info") == 0)
             {
-                if (notification != null)
-                {
-                    notification.OnMenuKeyPressed();
-                }
+                notification?.OnMenuKeyPressed();
             }
         }
 
index 7dade6d..09bd061 100755 (executable)
@@ -214,10 +214,7 @@ namespace TVApps.Controls
                 NoContentsView.IsVisible = true;
             }
 
-            if (OnChangeFocusChainingCommand != null)
-            {
-                OnChangeFocusChainingCommand.Execute("");
-            }
+            OnChangeFocusChainingCommand?.Execute("");
         }
 
         /// <summary>
index c83c2c7..78845d8 100755 (executable)
@@ -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("");
                 }
             }
         }
index e7418e0..0d731aa 100755 (executable)
@@ -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)
         {
 
         }
index efc0162..35e735d 100755 (executable)
  * 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;
+            }
+        }
     }
 }
index 17004d1..f7c0804 100755 (executable)
@@ -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)
         {
 
         }
index ce84884..a94d57f 100755 (executable)
@@ -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
index 5d63ae3..f5c6eff 100755 (executable)
@@ -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>
index 9e4aeb6..e3c76e1 100755 (executable)
@@ -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>
index 717e365..642d83e 100755 (executable)
@@ -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,
             });
index 60b177e..23f1885 100755 (executable)
     </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 (file)
index 0000000..509c659
--- /dev/null
@@ -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 (executable)
index d6d374f..0000000
+++ /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);
-    }
-}
index 31be243..11452ee 100755 (executable)
@@ -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 (file)
index 0000000..43bd322
--- /dev/null
@@ -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 (file)
index 0000000..c9150ad
--- /dev/null
@@ -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 (file)
index 0000000..fd30bbd
--- /dev/null
@@ -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;
+            }
+        }
+    }
+}
index dd41bbe..cd3d409 100755 (executable)
@@ -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"
                        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>
index 9daf994..c67c9b6 100755 (executable)
@@ -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;
index e0306dd..41003c7 100755 (executable)
@@ -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()
         {
         }
     }
index 61e9bbe..c51fd62 100755 (executable)
@@ -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();
+
     }
 }
index 630dd7e..c36bbda 100755 (executable)
@@ -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
index 2dfb598..849ae36 100755 (executable)
@@ -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"
index d0d9275..a3dad21 100755 (executable)
@@ -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