Merge "Usage of CustomeView for ScrollContainer and code refactoring accordingly...
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Fri, 18 Nov 2016 15:09:07 +0000 (07:09 -0800)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Fri, 18 Nov 2016 15:09:07 +0000 (07:09 -0800)
plugins/dali-swig/examples/firstscreen/App.cs
plugins/dali-swig/examples/firstscreen/Constants.cs
plugins/dali-swig/examples/firstscreen/FocusData.cs
plugins/dali-swig/examples/firstscreen/FocusEffect.cs
plugins/dali-swig/examples/firstscreen/IFocusEffect.cs
plugins/dali-swig/examples/firstscreen/Program.cs
plugins/dali-swig/examples/firstscreen/ScrollContainer.cs
plugins/dali-swig/examples/firstscreen/firstscreen.csproj [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/firstscreen.sln [new file with mode: 0644]

index 5f5819f..6c3b676 100644 (file)
@@ -7,33 +7,33 @@ namespace FirstScreen
 {
     public class FirstScreenApp
     {
-        private int _currentPostersContainerID;
-        private int _totalPostersContainers;
-
-        private Application _application;
-        private Stage _stage;
-        private Vector2 _stageSize;
-
-        private List<ScrollContainer> _postersContainer;
-
-        private ScrollContainer _menuContainer;
-        private Vector3 _menuItemSize;
-
-        private Layer _bottomClipLayer;
-        private Layer _topClipLayer;
-        private View _topContainer;
-        private View _bottomContainer;
-
-        private FocusEffect _focusEffect;
-        private string _imagePath;
-
-        private ImageView _keyboardFocusIndicator;
-        private ImageView _launcherSeparator;
-        private ImageView[] launcherIcon;
-        private Animation _showBottomContainerAnimation;
-        private Animation _hideBottomContainerAnimation;
-
-        public FirstScreenApp(Application application)
+        private Application _application;                  // Reference to Dali Application.
+        private Stage _stage;                              // Reference to Dali stage.
+        private Vector2 _stageSize;                        // Reference to Dali stage size.
+
+        private View _topContainer;                        // Top Container added to the Stage will contain Poster ScrollContainers.
+        private View _bottomContainer;                     // Bottom Container added to the Stage will contain Menu ScrollContainer.
+        private int _currentPostersContainerID;            // Current Poster Container ID visible on the Top Container / Stage.
+        private int _totalPostersContainers;               // Number of Poster ScrollContainers to be added on Top Container.
+        private List<ScrollContainer> _postersContainer;   // List collection of Poster ScrollContainers used on the Top Container in this demo application.
+        private ScrollContainer _menuContainer;            // Menu ScrollContainer used on the Bottom Container in this demo application.
+        private Layer _bottomClipLayer;                    // Clip layer (Dali Clip Layer instance) used for Bottom Container.
+        private Layer _topClipLayer;                       // Clip layer (Dali Clip Layer instance) used for Top Container.
+
+        private FocusEffect _focusEffect;                  // FocusEffect is used to apply Focus animation effect on any supplied item/image.
+        private string _imagePath;                         // Contains the physical location of all images used in the demo application.
+
+        private ImageView _keyboardFocusIndicator;         // Reference to the ImageView (Keyboard Focus indicator) applied to the focused item on ScrollContainer.
+        private ImageView _launcherSeparator;              // Reference to the ImageView used for launcher separation (Launcher consists of three image icons on left of Menu ScrollContainer).
+        private ImageView[] launcherIcon;                  // ImageViews used for launcher Icons.
+        private Animation _showBottomContainerAnimation;   // Animation used to show/unhide Bottom Container (Menu ScrollContainer) when it is focused.
+        private Animation _hideBottomContainerAnimation;   // Animation used to hide Bottom Container (Menu ScrollContainer) when it is focused.
+        private Animation _showAnimation;                  // Animation used to move Poster scrollContainer from bottom to top and make it non-transparent.
+        private Animation _hideAnimation;                  // Animation used to make the unused specified Poster scrollContainer transparent.
+        private ScrollContainer _hideScrollContainer;      // The unused Poster scrollContainer which needs to be transparent.
+        KeyboardFocusManager _keyboardFocusManager;        // Reference to Dali KeyboardFocusManager.
+
+        private FirstScreenApp(Application application)
         {
             _application = application;
             _application.Initialized += OnInitialize;
@@ -45,7 +45,7 @@ namespace FirstScreen
             tVApp.MainLoop();
         }
 
-        public void MainLoop()
+        private void MainLoop()
         {
             _application.MainLoop();
         }
@@ -62,23 +62,23 @@ namespace FirstScreen
                     {
                         View item = new ImageView(_imagePath + "/poster"+j+"/"+ (i % 6)+ ".jpg");
                         item.SetName ("poster-item-" + _postersContainer[j].ItemCount);
-                        _postersContainer[j].AddItem(item);
+                        _postersContainer[j].Add(item);
                     }
                     else
                     {
                         View item = new ImageView(_imagePath + "/poster"+j+"/"+ (i % 6)+ ".jpg");
                         item.SetName ("poster-item-" + _postersContainer[j].ItemCount);
-                        _postersContainer[j].AddItem(item);
+                        _postersContainer[j].Add(item);
                     }
                 }
 
                 if (j == 0)
                 {
-                    _postersContainer[j].Show();
+                    Show(_postersContainer[j]);
                 }
                 else
                 {
-                    _postersContainer[j].Hide();
+                    Hide(_postersContainer[j]);
                 }
 
                 _postersContainer[j].SetFocused(false);
@@ -97,13 +97,18 @@ namespace FirstScreen
             {
                 View menuItem = new ImageView(_imagePath + "/menu/" + i % 7 + ".png");
                 menuItem.SetName("menu-item-" + _menuContainer.ItemCount);
-                _menuContainer.AddItem(menuItem);
+                _menuContainer.Add(menuItem);
             }
         }
 
         private Actor OnKeyboardPreFocusChangeSignal(object source, KeyboardFocusManager.PreFocusChangeEventArgs e)
         {
-            Actor actor = _menuContainer.ItemRoot;
+            if (!e.Current && !e.Proposed)
+            {
+                return _menuContainer;
+            }
+
+            Actor actor = _menuContainer.Container;
 
             if (e.Direction == View.KeyboardFocus.Direction.UP)
             {
@@ -116,7 +121,7 @@ namespace FirstScreen
                     HideBottomContainer();
 
                     // Also apply Focus animation on Focused item on Poster ScrollContainer
-                    _postersContainer[_currentPostersContainerID].FocusAnimation(_focusEffect, FocusEffectDirection.BottomToTop);
+                    FocusAnimation(_postersContainer[_currentPostersContainerID], FocusEffectDirection.BottomToTop);
                 }
             }
             else if (e.Direction == View.KeyboardFocus.Direction.DOWN)
@@ -130,56 +135,100 @@ namespace FirstScreen
                     _menuContainer.SetFocused(true);
 
                     // Also apply Focus animation on Focused item on Menu ScrollContainer
-                    _menuContainer.FocusAnimation(_focusEffect, FocusEffectDirection.TopToBottom);
+                    FocusAnimation(_menuContainer, FocusEffectDirection.TopToBottom);
                 }
             }
-            else if (e.Direction == View.KeyboardFocus.Direction.LEFT)
+            else
+            {
+                actor = e.Proposed;
+            }
+
+            if (e.Direction == View.KeyboardFocus.Direction.LEFT)
             {
                 if (_menuContainer.IsFocused)
                 {
-                    // Move the Focus to the left item/image of currently focused item on Menu ScrollContainer
-                    actor = _menuContainer.FocusPrevious();
-
                     int id = _menuContainer.FocusedItemID % _totalPostersContainers;
                     if (id != _currentPostersContainerID)
                     {
-                        _postersContainer[_currentPostersContainerID].Hide();
+                        Hide(_postersContainer[_currentPostersContainerID]);
                         _currentPostersContainerID = id;
 
-                        _postersContainer[_currentPostersContainerID].Show();
+                        Show(_postersContainer[_currentPostersContainerID]);
                     }
                 }
-                else
-                {
-                    // Move the Focus to the left item/image of currently focused item on Poster ScrollContainer
-                    actor = _postersContainer[_currentPostersContainerID].FocusPrevious();
-                }
             }
             else if (e.Direction == View.KeyboardFocus.Direction.RIGHT)
             {
                 if (_menuContainer.IsFocused)
                 {
-                    // Move the Focus to the right item/image of currently focused item on Menu ScrollContainer
-                    actor = _menuContainer.FocusNext();
-
                     int id = _menuContainer.FocusedItemID % _totalPostersContainers;
                     if (id != _currentPostersContainerID)
                     {
-                        _postersContainer[_currentPostersContainerID].Hide();
+                        Hide(_postersContainer[_currentPostersContainerID]);
                         _currentPostersContainerID = id;
-                        _postersContainer[_currentPostersContainerID].Show();
+                        Show(_postersContainer[_currentPostersContainerID]);
                     }
                 }
-                else
-                {
-                    // Move the Focus to the right item/image of currently focused item on Poster ScrollContainer
-                    actor = _postersContainer[_currentPostersContainerID].FocusNext();
-                }
             }
 
             return actor;
         }
 
+        // Perform Focus animation Effect on the current Focused Item on ScrollContainer.
+        private void FocusAnimation(ScrollContainer scrollContainer, FocusEffectDirection direction)
+        {
+            _focusEffect.FocusAnimation(scrollContainer.GetCurrentFocusedActor(), scrollContainer.ItemSize, 1.0f, direction);
+        }
+
+        // Perform Show animation on ScrollContainer (used only for Poster Container)
+        private void Show(ScrollContainer scrollContainer)
+        {
+            scrollContainer.Add(scrollContainer.Container);
+
+            _hideScrollContainer = null;
+            _showAnimation = new Animation (0.35f);
+
+            // This animation will move Poster scrollContainer from bottom to top and make it non-transparent.
+            _showAnimation.AnimateTo(new Dali.Property(scrollContainer.Container, Actor.Property.COLOR_ALPHA), new Dali.Property.Value(1.0f));
+
+            scrollContainer.Container.PositionY = scrollContainer.Container.Position.y + 200.0f;
+            float targetPositionY = scrollContainer.Container.Position.y - 200.0f;
+            _showAnimation.AnimateTo(new Dali.Property(scrollContainer.Container, Actor.Property.POSITION_Y), new Dali.Property.Value(targetPositionY),
+                                     new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR));
+
+            _showAnimation.Play();
+        }
+
+        // Perform Hide animation on ScrollContainer (used only for Poster Container)
+        private void Hide(ScrollContainer scrollContainer)
+        {
+            if (_hideAnimation)
+            {
+                _hideAnimation.Clear();
+                _hideAnimation.Reset();
+            }
+
+            float duration = 0.35f;
+            _hideAnimation = new Animation(duration);
+
+            _hideAnimation.AnimateTo(new Dali.Property(scrollContainer.Container, Actor.Property.COLOR_ALPHA), new Dali.Property.Value(0.0f),
+                                     new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR), new TimePeriod(0.0f, duration * 0.75f));
+
+            _hideAnimation.Finished += OnHideAnimationFinished;
+
+            _hideScrollContainer = scrollContainer;
+            _hideAnimation.Play();
+        }
+
+        // This removes all the items from the specified unused Poster ScrollContainer (hence Stage) to improve performance.
+        private void OnHideAnimationFinished(object source, Animation.FinishedEventArgs e)
+        {
+            if (_hideScrollContainer)
+            {
+                _hideScrollContainer.Remove(_hideScrollContainer.Container);
+            }
+        }
+
         // Hide Bottom Container (Menu ScrollContainer) when it is not focused
         private void HideBottomContainer()
         {
@@ -211,13 +260,14 @@ namespace FirstScreen
         // First screen demo Application initialisation
         private void OnInitialize(object source, AUIApplicationInitEventArgs e)
         {
+            _hideScrollContainer = null;
             _stage = Stage.GetCurrent();
             _stageSize = _stage.GetSize();
-//            _stage.SetBackgroundColor(NDalic.TRANSPARENT);
+            //_stage.SetBackgroundColor(NDalic.TRANSPARENT);
 
             _totalPostersContainers = Constants.TotalPostersContainers;
             _imagePath = "./images/"; // Desktop
-//            _imagePath = "/home/owner/apps_rw/org.tizen.firstscreen/res/images/"; // Target
+            //_imagePath = "/home/owner/apps_rw/org.tizen.firstscreen/res/images/"; // Target
 
             _postersContainer = new List<ScrollContainer> ();
             _menuContainer = new ScrollContainer ();
@@ -297,18 +347,18 @@ namespace FirstScreen
                 }
                 else
                 {
-                    _postersContainer[i].ItemSize = new Vector3(_stageSize.width * Constants.Poster1ItemWidthFactor,
+                    _postersContainer[i].ItemSize = new Vector3((_stageSize.width * Constants.Poster1ItemWidthFactor) - Constants.PostersContainerPadding,
                                                                 _stageSize.height * Constants.PostersItemHeightFactor, 0.0f);
                 }
-                _postersContainer[i].Padding = Constants.PostersContainerPadding;
+                _postersContainer[i].Gap = Constants.PostersContainerPadding;
                 _postersContainer[i].MarginX = Constants.PostersContainerMargin;
-                _postersContainer[i].OffsetY = Constants.PostersContainerOffsetYFactor;
+                _postersContainer[i].OffsetYFator = Constants.PostersContainerOffsetYFactor;
                 _postersContainer[i].Width = _stageSize.width;
                 _postersContainer[i].Height = _stageSize.height * Constants.PostersContainerHeightFactor;
                 _postersContainer[i].ShadowBorder = shadowBorder;
                 _postersContainer[i].ShadowBorder.Position = new Vector3(0.0f, 4.0f, 0.0f);
                 _postersContainer[i].SpotLight = spotLight;
-                _topClipLayer.Add(_postersContainer[i].Container);
+                _topClipLayer.Add(_postersContainer[i]);
             }
 
             // Add a clip layer to Bottom Container
@@ -347,13 +397,13 @@ namespace FirstScreen
             _bottomContainer.Add(_launcherSeparator);
 
             // Create Menu Container and add it to Bottom Clip Layer
-            _menuItemSize = new Vector3((_stageSize.width * Constants.MenuItemWidthFactor) - Constants.MenuContainerPadding,
+            Vector3 menuItemSize = new Vector3((_stageSize.width * Constants.MenuItemWidthFactor) - Constants.MenuContainerPadding,
                                         _stageSize.height * Constants.MenuItemHeightFactor, 0.0f);
             _menuContainer.Container.Name = "menu";
-            _menuContainer.ItemSize = _menuItemSize;
-            _menuContainer.Padding = Constants.MenuContainerPadding;
+            _menuContainer.ItemSize = menuItemSize;
+            _menuContainer.Gap = Constants.MenuContainerPadding;
             _menuContainer.MarginX = Constants.MenuContainerMargin;
-            _menuContainer.OffsetY = Constants.MenuContainerOffsetYFactor;
+            _menuContainer.OffsetYFator = Constants.MenuContainerOffsetYFactor;
             _menuContainer.OffsetX = Constants.LauncherWidth;
             _menuContainer.Width = _stageSize.width - Constants.LauncherWidth;
             _menuContainer.Height = _stageSize.height * Constants.MenuContainerHeightFactor;
@@ -364,14 +414,14 @@ namespace FirstScreen
             _menuContainer.ShadowBorder.ParentOrigin = NDalic.ParentOriginCenter;
             _menuContainer.ShadowBorder.AnchorPoint = NDalic.AnchorPointCenter;
             _menuContainer.SpotLight = spotLight;
-            _bottomClipLayer.Add(_menuContainer.Container);
+            _bottomClipLayer.Add(_menuContainer);
 
             CreatePosters(); // Create Items for Poster ScrollContainer
             CreateMenu();    // Create Items for Menu ScrollContainer
 
             // Initialize PreFocusChange event of KeyboardFocusManager
-            KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.Get();
-            keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChangeSignal;
+            _keyboardFocusManager = KeyboardFocusManager.Get();
+            _keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChangeSignal;
 
             _keyboardFocusIndicator = new ImageView(_imagePath + "/highlight_stroke.9.png");
             _keyboardFocusIndicator.ParentOrigin = NDalic.ParentOriginCenter;
@@ -379,7 +429,12 @@ namespace FirstScreen
             _keyboardFocusIndicator.WidthResizePolicy = "FILL_TO_PARENT";
             _keyboardFocusIndicator.HeightResizePolicy = "FILL_TO_PARENT";
 
-            keyboardFocusManager.SetFocusIndicatorActor(_keyboardFocusIndicator);
+            _keyboardFocusManager.SetFocusIndicatorActor(_keyboardFocusIndicator);
+
+            _keyboardFocusManager.SetAsFocusGroup(_menuContainer, true);
+            _keyboardFocusManager.SetAsFocusGroup(_postersContainer[0], true);
+            _keyboardFocusManager.SetAsFocusGroup(_postersContainer[1], true);
+            _keyboardFocusManager.SetFocusGroupLoop(true);
 
             _focusEffect = new FocusEffect();
 
@@ -390,3 +445,4 @@ namespace FirstScreen
     }
 }
 
+
index 7ada417..42e2c97 100644 (file)
@@ -22,14 +22,14 @@ namespace FirstScreen
         public const float BottomClipLayerHeightFactor = 0.84f;       // Height Factor of stage height used for Bottom Clip layer height
         public const float MenuContainerPadding = 10.0f;              // Padding size used between items / images in Menu ScrollContainer
         public const float MenuContainerMargin = 25.0f;               // Extra margin Padding size used between items / images in Menu ScrollContainer when item / image is focused
-        public const float MenuContainerOffsetYFactor = 0.35f;        // Position Factor of Poster item height used for Menu items / images position
+        public const float MenuContainerOffsetYFactor = 0.35f;        // Position Factor of Menu item height used for Menu items / images position
 
         public const float MenuItemWidthFactor = 0.125f;              // Width Factor (1/8) of stage Width used for Menu items / images Width
         public const float MenuItemHeightFactor = 0.10f;              // Height Factor of stage height used for Menu items / images Height
         public const float MenuItemsCount = 14;                       // Number of Menu items / images used in a Menu ScrollContainer
 
         public const float Poster0ItemWidthFactor = 0.25f;            // Width Factor (1/4) of stage Width used for Poster items / images Width in a Poster ScrollContainer 0
-        public const float Poster1ItemWidthFactor = 0.24f;            // Width Factor of stage Width used for Poster items / images Width in a Poster ScrollContainer 1
+        public const float Poster1ItemWidthFactor = 0.20f;            // Width Factor of stage Width used for Poster items / images Width in a Poster ScrollContainer 1
         public const float PostersItemHeightFactor = 0.24f;           // Height Factor of stage height used for Poster items / images Height
         public const float PostersItemsCount = 24;                    // Number of Menu items / images used in a Poster ScrollContainer
 
@@ -38,6 +38,10 @@ namespace FirstScreen
         public const float LauncherSeparatorWidth = 20.0f;            // Extra area / space to the left of Menu ScrollContainer used for a speration shadow image
         public const float LauncherItemsCount = 3.0f;                 // Total number of Launcher items / images
         public const float LauncherIconWidth = (LauncherWidth - LauncherLeftMargin - LauncherSeparatorWidth) / LauncherItemsCount; // Width of each Launcher item / image
+
+        public const float SpotLightDuration = 5.0f;                  // Duration of Spot Light Animation. 
+        public const float FocusTransitionDuration = 0.35f;           // Duration of Focus Transition Animation. 
+        public const float FocusDuration = 0.35f;                     // Duration of Focus Animation.
+        public const float ScrollDuration = 0.35f;                    // Duration of Scroll Animation.
     }
 }
-
index b1ee188..75a3a96 100644 (file)
@@ -17,7 +17,7 @@ namespace FirstScreen
 
         // Initialize FocusData used for key frame animation
         public FocusData(string name, string imageName, Direction direction, Vector3 parentOrigin, Vector3 initSize,
-                        Vector3 targetSize, float keyFrameStart, float keyFrameEnd)
+                         Vector3 targetSize, float keyFrameStart, float keyFrameEnd)
         {
             _name = name;
             _imageName = imageName;
@@ -29,7 +29,7 @@ namespace FirstScreen
             _direction = direction;
 
             _imageFocus = new ImageView("./images/focuseffect/" + _imageName); // Desktop
-//            _imageFocus = new ImageView("/home/owner/apps_rw/org.tizen.firstscreen/res/images/focuseffect/" + _imageName); // Target
+            // _imageFocus = new ImageView("/home/owner/apps_rw/org.tizen.firstscreen/res/images/focuseffect/" + _imageName); // Target
 
             _imageFocus.ParentOrigin = _parentOrigin;
             _imageFocus.AnchorPoint = NDalic.AnchorPointCenter;
@@ -103,4 +103,3 @@ namespace FirstScreen
         }
     }
 }
-
index d02e483..f34986e 100644 (file)
@@ -1,7 +1,6 @@
 using Dali;
 using System;
 using System.Collections.Generic;
-using System.Collections.Specialized;
 
 namespace FirstScreen
 {
@@ -9,14 +8,14 @@ namespace FirstScreen
     {
         private float _frameThickness;
         private FocusData[] _focusData; // Each FocusData is used for one key frame animation (total 6 key frame animations needed for EddenEffect)
-        private Animation _animation;      // Animation used to apply all six key frame animations
+        private Animation _animation;   // Animation used to apply all six key frame animations
 
         public FocusEffect()
         {
             _frameThickness = 10.0f;
             float _bottomFrameTime = 0.6f; // complete the halo/bottom animation 60% of the way through
-            float _sideFrameTime = 0.8f; // Start the side frame  animation after the bottom animation and complete at 80% of the way through
-            float _topFrameTime = 1.0f; // start the top frame animation after the side frame animation and complete at 100% way through
+            float _sideFrameTime = 0.8f;   // Start the side frame  animation after the bottom animation and complete at 80% of the way through
+            float _topFrameTime = 1.0f;    // start the top frame animation after the side frame animation and complete at 100% way through
 
             // Six key frame animations (FocusData objects) needed for EddenEffect
             // Two key frame animations for top horizontal effect
@@ -25,27 +24,27 @@ namespace FirstScreen
             _focusData = new FocusData[6];
 
             FocusData focusData = new FocusData("halo", "halo.png", FocusData.Direction.Horizontal, NDalic.ParentOriginTopCenter,
-                                             new Vector3(50,20,0),  new Vector3(0.0f, 100.0f , 0.0f), 0.0f, _bottomFrameTime);
+                                                new Vector3(50,20,0),  new Vector3(0.0f, 100.0f , 0.0f), 0.0f, _bottomFrameTime);
             _focusData[0] = focusData;
 
             focusData = new FocusData("bottom", "horizontalFrame.png", FocusData.Direction.Horizontal, NDalic.ParentOriginTopCenter,
-                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f, _frameThickness, 0.0f), 0.0f, _bottomFrameTime);
+                                      new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f, _frameThickness, 0.0f), 0.0f, _bottomFrameTime);
             _focusData[1] = focusData;
 
             focusData = new FocusData("left", "verticalFrame.png", FocusData.Direction.Vertical, NDalic.ParentOriginBottomLeft,
-                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(_frameThickness, 0.0f, 0.0f), _bottomFrameTime, _sideFrameTime);
+                                      new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(_frameThickness, 0.0f, 0.0f), _bottomFrameTime, _sideFrameTime);
             _focusData[2] = focusData;
 
             focusData = new FocusData("right", "verticalFrame.png", FocusData.Direction.Vertical, NDalic.ParentOriginBottomRight,
-                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(_frameThickness, 0.0f, 0.0f), _bottomFrameTime, _sideFrameTime);
+                                      new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(_frameThickness, 0.0f, 0.0f), _bottomFrameTime, _sideFrameTime);
             _focusData[3] = focusData;
 
             focusData = new FocusData("top-left", "horizontalFrame.png", FocusData.Direction.Horizontal, NDalic.ParentOriginBottomLeft,
-                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f ,_frameThickness, 0.0f), _sideFrameTime, _topFrameTime);
+                                      new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f ,_frameThickness, 0.0f), _sideFrameTime, _topFrameTime);
             _focusData[4] = focusData;
 
             focusData = new FocusData("top-right", "horizontalFrame.png", FocusData.Direction.Horizontal, NDalic.ParentOriginBottomRight,
-                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f, _frameThickness, 0.0f), _sideFrameTime, _topFrameTime);
+                                      new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f, _frameThickness, 0.0f), _sideFrameTime, _topFrameTime);
             _focusData[5] = focusData;
         }
 
@@ -200,4 +199,3 @@ namespace FirstScreen
         }
     }
 }
-
index 222c2ed..8e8b9d6 100644 (file)
@@ -14,4 +14,3 @@ namespace FirstScreen
         void FocusAnimation(View parentItem, Vector3 itemSize, float duration, FocusEffectDirection direction);
     }
 }
-
index 633af05..adaee72 100644 (file)
@@ -6,88 +6,37 @@ using System.Collections.Generic;
 
 namespace FirstScreen
 {
-    public class ScrollContainer
+    public class ScrollContainer : CustomView
     {
-        private View _container;
-        private Actor _itemRoot;
-        private Vector3 _itemSize;
-        private List<View> _itemList;
-        private int _itemCount;
-        private int _focusedItem;
-        private PanGestureDetector _panGestureDetector;
-        private float _scrollDisplacement;
-        private float _currentScrollPosition;
-        private float _padding;
-        private float _width;
-        private float _height;
-        private bool _isFocused;
-        private float _marginX;
-        private float _marginY;
-        private float _offsetY;
-        private float _offsetX;
-        private Stage _stage;
-        private Vector2 _stageSize;
-        private ImageView _shadowBorder;
-        private ImageView _spotLight;
-        private Animation _spotLightAnimation;
-        private Animation _showAnimation;
-        private Animation _hideAnimation;
-        private Animation _focusAnimation;
-        private Animation _scrollAnimation;
-        private Animation _focusTransitionAnimation;
-        private Path _circularPath;
-        private bool _shouldHide;
-
-        public ScrollContainer()
+        private View _container;                      // View Container will be the first item added to ScrollContainer and parent to all the items added to the ScrollContainer.
+        private Vector3 _itemSize;                    // Size of the item / images added to the ScrollContainer.
+        private List<View> _itemList;                 // List collection of View items/images  added to the ScrollContainer.
+        private int _itemCount;                       // Number of items / images  added to the ScrollContainer.
+        private int _focusedItem;                     // Index of currently focused View item / image  on the ScrollContainer.
+        private float _scrollDisplacement;            // Used for horizontal pan displacement.
+        private float _currentScrollPosition;         // Used for horizontal scroll position.
+        private float _gap;                           // Used for gap / padding between items / images on the ScrollContainer.
+        private float _width;                         // Width of the ScrollContainer.
+        private float _height;                        // Height of the ScrollContainer.
+        private bool _isFocused;                      // Flag to check if ScrollContainer is enabled or not.
+        private float _marginX;                       // Extra horizontal margin is used to add an extra gap between items / images after a focused and scaled item / image.
+        private float _marginY;                       // Extra vertical margin (not used at the moment).
+        private float _offsetYFactor;                 // Vertical Position offset Factor of item height.
+        private float _offsetX;                       // Horizontal Position offset of ScrollContainer.
+        private Stage _stage;                         // Reference to Dali stage.
+        private Vector2 _stageSize;                   // Reference to Dali stage size.
+        private ImageView _shadowBorder;              // Reference to Shadow border ImageView applied to the focused item on ScrollContainer.
+        private ImageView _spotLight;                 // Reference to SpotLight ImageView applied to the focused item on ScrollContainer.
+        private Animation _spotLightAnimation;        // SpotLight Animation applied to the focused item on ScrollContainer.
+        private Animation _focusAnimation;            // Focused position animation on ScrollContainer.
+        private Animation _scrollAnimation;           // Scroll animation on items of ScrollContainer.
+        private Animation _focusTransitionAnimation;  // Focus Transition (scaling /unscaling) animation on items of ScrollContainer.
+        private Path _circularPath;                   // Circular path used for SpotLight Animation applied to the focused item on ScrollContainer.
+
+        public ScrollContainer() : base(ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS |
+                                        ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT)
         {
-            _itemSize = new Vector3(0.0f, 0.0f, 0.0f);
-            _padding = 0.0f;
-            _width = 0.0f;
-            _height = 0.0f;
-            _currentScrollPosition = 0.0f;
-            _itemCount = 0;
-            _focusedItem = -1;
-            _isFocused = false;
-            _marginX = 50.0f;
-            _marginY = 0.0f;
-            _offsetY = 0.0f;
-            _offsetX = 0.0f;
-
-            _shouldHide = true;
-
-            _container = new View();
-            _itemRoot = new Actor();
-            _container.Add(_itemRoot);
-
-            _itemList = new List<View>();
-
-            if (_panGestureDetector == null)
-            {
-                _panGestureDetector = new PanGestureDetector();
-                _panGestureDetector.Attach(_container);
 
-                _panGestureDetector.Detected += OnPan;
-            }
-
-            _container.ParentOrigin = NDalic.ParentOriginTopLeft;
-            _container.AnchorPoint = NDalic.AnchorPointTopLeft;
-            _itemRoot.ParentOrigin = NDalic.ParentOriginTopLeft;
-            _itemRoot.AnchorPoint = NDalic.AnchorPointTopLeft;
-
-            _container.WidthResizePolicy = "FILL_TO_PARENT";
-            _container.HeightResizePolicy = "FILL_TO_PARENT";
-            _itemRoot.WidthResizePolicy = "FILL_TO_PARENT";
-            _itemRoot.HeightResizePolicy = "FILL_TO_PARENT";
-
-            _stage = Stage.GetCurrent();
-            _stageSize = _stage.GetSize();
-
-            _spotLightAnimation = new Animation(5.0f);
-            _focusTransitionAnimation = new Animation (0.35f);
-            _focusAnimation = new Animation (0.35f);
-            _focusAnimation.SetEndAction(Animation.EndAction.BakeFinal);
-            _scrollAnimation = new Animation (0.35f);
-            _scrollAnimation.SetEndAction(Animation.EndAction.BakeFinal);
         }
 
         public bool IsFocused
@@ -114,14 +63,6 @@ namespace FirstScreen
             }
         }
 
-        public Actor ItemRoot
-        {
-            get
-            {
-                return _itemRoot;
-            }
-        }
-
         public Vector3 ItemSize
         {
             get
@@ -148,16 +89,16 @@ namespace FirstScreen
             }
         }
 
-        public float Padding
+        public float Gap
         {
             get
             {
-                return _padding;
+                return _gap;
             }
 
             set
             {
-                _padding = value;
+                _gap = value;
             }
         }
 
@@ -174,16 +115,16 @@ namespace FirstScreen
             }
         }
 
-        public float OffsetY
+        public float OffsetYFator
         {
             get
             {
-                return _offsetY;
+                return _offsetYFactor;
             }
 
             set
             {
-                _offsetY = value;
+                _offsetYFactor = value;
             }
         }
 
@@ -278,161 +219,168 @@ namespace FirstScreen
             }
         }
 
-        public Actor GetCurrentFocusedActor()
+        // This override method is called automatically after the Control has been initialized.
+        // Any second phase initialization is done here.
+        public override void OnInitialize()
         {
-            if (_focusedItem < 0)
-            {
-                _focusedItem = 0;
-            }
+            _itemSize = new Vector3(0.0f, 0.0f, 0.0f);
+            _gap = 0.0f;
+            _width = 0.0f;
+            _height = 0.0f;
+            _currentScrollPosition = 0.0f;
+            _itemCount = 0;
+            _focusedItem = -1;
+            _isFocused = false;
+            _marginX = 50.0f;
+            _marginY = 0.0f;
+            _offsetYFactor = 0.0f;
+            _offsetX = 0.0f;
 
-            return _itemList[_focusedItem];
-        }
+            _container = new View();
+            this.Add(_container);
 
-        public void AddItem(View item)
-        {
-            item.AnchorPoint = NDalic.AnchorPointBottomCenter;
-            item.ParentOrigin = NDalic.ParentOriginBottomCenter;
+            _itemList = new List<View>();
 
-            item.Size = _itemSize;
-            item.SetKeyboardFocusable(true);
-            item.Position = GetItemPosition(_itemCount, _currentScrollPosition);
+            this.ParentOrigin = NDalic.ParentOriginTopLeft;
+            this.AnchorPoint = NDalic.AnchorPointTopLeft;
+            this.WidthResizePolicy = "FILL_TO_PARENT";
+            this.HeightResizePolicy = "FILL_TO_PARENT";
+            this.SetKeyboardFocusable(true);
 
-            item.Name = _itemCount.ToString();
+            _container.ParentOrigin = NDalic.ParentOriginTopLeft;
+            _container.AnchorPoint = NDalic.AnchorPointTopLeft;
+            _container.WidthResizePolicy = "FILL_TO_PARENT";
+            _container.HeightResizePolicy = "FILL_TO_PARENT";
 
-//          item.ClippingMode = "CLIP_CHILDREN";
+            _stage = Stage.GetCurrent();
+            _stageSize = _stage.GetSize();
+
+            _spotLightAnimation = new Animation(Constants.SpotLightDuration);
+            _focusTransitionAnimation = new Animation(Constants.FocusTransitionDuration);
+            _focusAnimation = new Animation(Constants.FocusDuration);
+            _focusAnimation.SetEndAction(Animation.EndAction.BakeFinal);
+            _scrollAnimation = new Animation(Constants.ScrollDuration);
+            _scrollAnimation.SetEndAction(Animation.EndAction.BakeFinal);
 
-            _itemRoot.Add(item);
-            _itemList.Add(item);
-            _panGestureDetector.Attach(item);
-            _itemCount++;
+            EnableGestureDetection(Gesture.Type.Pan);
         }
 
-        // Perform Show animation on ScrollContainer (used only for Poster Container)
-        public void Show()
+        // This will be invoked automatically if an item/image is added to the ScrollContainer
+        public override void OnChildAdd(Actor actor)
         {
-            Container.Add(ItemRoot);
+            View item = View.DownCast(actor);
 
-            _shouldHide = false;
-            _showAnimation = new Animation (0.35f);
+            if (item is View && item != _container)
+            {
+                item.AnchorPoint = NDalic.AnchorPointBottomCenter;
+                item.ParentOrigin = NDalic.ParentOriginBottomCenter;
 
-            _showAnimation.AnimateTo(new Property(_container, Actor.Property.COLOR_ALPHA), new Property.Value(1.0f));
+                item.Size = _itemSize;
+                item.SetKeyboardFocusable(true);
+                item.Position = GetItemPosition(_itemCount, _currentScrollPosition);
 
-            _container.PositionY = _container.Position.y + 200.0f;
-            float targetPositionY = _container.Position.y - 200.0f;
-            _showAnimation.AnimateTo(new Property(_container, Actor.Property.POSITION_Y), new Property.Value(targetPositionY),
-                                     new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR));
+                item.Name = _itemCount.ToString();
 
-            _showAnimation.Play();
-        }
+                //item.ClippingMode = "CLIP_CHILDREN";
 
-        // Perform Hide animation on ScrollContainer (used only for Poster Container)
-        public void Hide()
-        {
-            if (_hideAnimation)
-            {
-                _hideAnimation.Clear();
-                _hideAnimation.Reset();
-            }
+                _container.Add(item);
+                _itemList.Add(item);
 
-            float duration = 0.35f;
-            _hideAnimation = new Animation(duration);
+                _itemCount++;
+                item.SetKeyboardFocusable(true);
+            }
+        }
 
-            _hideAnimation.AnimateTo(new Property(_container, Actor.Property.COLOR_ALPHA), new Property.Value(0.0f),
-                                     new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR), new TimePeriod(0.0f, duration * 0.75f));
+        // This will be invoked automatically if an item/image is removed from the ScrollContainer
+        public override void OnChildRemove(Actor actor)
+        {
+            View item = View.DownCast(actor);
 
-            _hideAnimation.Finished += OnHideAnimationFinished;
+            if (item is View && item != _container)
+            {
+                _container.Remove(item);
 
-            _shouldHide = true;
-            _hideAnimation.Play();
+                _itemCount--;
+                _itemList.Remove(item);
+            }
         }
 
-        public View Focus(int itemId)
+        // This override function supports two dimensional keyboard navigation.
+        // This function returns the next keyboard focusable actor in ScrollContainer control towards the given direction.
+        public override Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, View.KeyboardFocus.Direction direction, bool loopEnabled)
         {
-            if (itemId < 0)
+            if (direction == View.KeyboardFocus.Direction.LEFT)
             {
-                itemId = 0;
+                return FocusPrevious(loopEnabled);
             }
-            else if (itemId >= _itemList.Count)
+            else if (direction == View.KeyboardFocus.Direction.RIGHT)
             {
-                itemId = _itemList.Count - 1;
+                return FocusNext(loopEnabled);
             }
-
-            _itemList[itemId].Add(_shadowBorder);
-            _itemList[itemId].Add(_spotLight);
-
-            // Perform Spot Light animation
-            if(_focusedItem != itemId && _spotLight != null)
+            else
             {
-                _spotLightAnimation.Clear();
-                _spotLightAnimation.Animate( _spotLight, _circularPath, new Vector3(0.0f, 0.0f, 0.0f) );
-                _spotLightAnimation.SetLooping(true);
-                _spotLightAnimation.Play();
+                return currentFocusedActor;
             }
+        }
 
-            _focusedItem = itemId;
+        // This override function is invoked before chosen focusable actor will be focused.
+        // This allows the application to preform any actions (i.e. Scroll and SpotLight animations) before the focus is actually moved to the chosen actor.
+        public override void OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
+        {
+            Focus(_focusedItem);
+        }
 
-            Vector3 itemPosition = GetItemPosition(_focusedItem, _currentScrollPosition);
+        // This override function is invoked whenever a pan gesture is detected on this control.
+        // Perform Scroll Animation based upon pan gesture velocity / speed.
+        public override void OnPan(PanGesture pan)
+        {
+            switch (pan.state)
+            {
+            case Gesture.State.Started:
+                _scrollDisplacement = 0.0f;
+                break;
 
-            _focusAnimation.Clear();
+            case Gesture.State.Continuing:
+                _scrollDisplacement = pan.displacement.x;
+                break;
 
-            float relativeItemPositionX = itemPosition.x - _itemSize.width * 0.5f + (_stageSize.width * 0.5f) + _offsetX;
-            if (relativeItemPositionX < _marginX + _offsetX + _padding)
-            {
-                float amount = _marginX + _offsetX + _padding - relativeItemPositionX;
-                Scroll(amount, itemId + 1); // Perform Scroll animation
-            }
-            else if (relativeItemPositionX + _itemSize.width + _padding + _marginX > _stageSize.width)
-            {
-                float amount = relativeItemPositionX + _marginX + _padding + _itemSize.width - _stageSize.width;
-                Scroll(-amount, itemId - 1); // Perform Scroll animation
-            }
-            else
-            {
-                for (int i = 0; i < _itemList.Count; ++i)
-                {
-                    Vector3 targetPosition = GetItemPosition(i, _currentScrollPosition);
-                    _focusAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.POSITION),
-                                              new Property.Value(targetPosition),
-                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
-                }
-            }
+            case Gesture.State.Finished:
+            case Gesture.State.Cancelled:
+                float absScrollDistance = _scrollDisplacement;
+                if (absScrollDistance < 0.0f)
+                    absScrollDistance = 0.0f - absScrollDistance;
 
-            for (int i = 0; i < _itemList.Count; ++i)
-            {
-                SetupItemRenderer(_itemList[i], false);
+                float scrollSpeed = pan.velocity.x * pan.velocity.x + pan.velocity.y * pan.velocity.y;
+                float maxScrollSpeed = 40.0f;  // TBD
+                if (scrollSpeed > maxScrollSpeed)
+                    scrollSpeed = maxScrollSpeed;
 
-                // Perform Focus animation
-                if (i == _focusedItem)
-                {
-                    _focusAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.SCALE),
-                                              new Property.Value(new Vector3(1.2f, 1.2f, 1.2f)),
-                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
-                }
-                else
+                if (absScrollDistance > 1.0f && scrollSpeed > 0.05f) // Threshold TBD
                 {
-                    _focusAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.SCALE),
-                                              new Property.Value(new Vector3(1.0f, 1.0f, 1.0f)),
-                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                    if (_scrollDisplacement > 0.0f) // scroll constant distance in constant speed.
+                    {
+                        Scroll((_itemSize.x + _gap) * 2, GetFirstVisibleItemId());
+                    }
+                    else
+                    {
+                        Scroll(-(_itemSize.x + _gap) * 2, GetFirstVisibleItemId());
+                    }
                 }
+                break;
             }
+        }
 
-            _focusAnimation.Play();
-
-            if (_isFocused && _focusedItem >= 0)
+        // This function returns current focused actor
+        public View GetCurrentFocusedActor()
+        {
+            if (_focusedItem < 0)
             {
-                SetupItemRenderer(_itemList[_focusedItem], true);
-                SetupSpotLightRenderer();
+                _focusedItem = 0;
             }
 
             return _itemList[_focusedItem];
         }
 
-        // Perform EddenEffect animation on Focused Item specified
-        public void FocusAnimation(FocusEffect focusEffect, FocusEffectDirection direction)
-        {
-            focusEffect.FocusAnimation(_itemList[_focusedItem], _itemSize, 1.0f, direction);
-        }
-
         public void SetFocused(bool focused)
         {
             _isFocused = focused;
@@ -459,12 +407,12 @@ namespace FirstScreen
                     SetupItemRenderer(_itemList[i], false);
 
                     Vector3 targetPosition = GetItemPosition(i, _currentScrollPosition);
-                    _focusTransitionAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.POSITION),
-                                                        new Property.Value(targetPosition),
+                    _focusTransitionAnimation.AnimateTo(new Dali.Property(_itemList[i], Actor.Property.POSITION),
+                                                        new Dali.Property.Value(targetPosition),
                                                         new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
 
-                    _focusTransitionAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.SCALE),
-                                                        new Property.Value(new Vector3(1.0f, 1.0f, 1.0f)),
+                    _focusTransitionAnimation.AnimateTo(new Dali.Property(_itemList[i], Actor.Property.SCALE),
+                                                        new Dali.Property.Value(new Vector3(1.0f, 1.0f, 1.0f)),
                                                         new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
                 }
 
@@ -477,17 +425,17 @@ namespace FirstScreen
         }
 
         // Obtain ID of first visible item/image on the screen of the ScrollContainer
-        public int GetFirstVisibleItemId()
+        private int GetFirstVisibleItemId()
         {
             int firstItemId = -1;
 
             if (_isFocused)
             {
-                firstItemId = (int)Math.Floor((-1.0 * _currentScrollPosition + _marginX * 2.0f) / (_itemSize.x + _padding));
+                firstItemId = (int)Math.Floor((-1.0 * _currentScrollPosition + _marginX * 2.0f) / (_itemSize.x + _gap));
             }
             else
             {
-                firstItemId = (int)Math.Floor(-1.0 * _currentScrollPosition / (_itemSize.x + _padding));
+                firstItemId = (int)Math.Floor(-1.0 * _currentScrollPosition / (_itemSize.x + _gap));
             }
 
             if (firstItemId < 0)
@@ -499,7 +447,7 @@ namespace FirstScreen
         }
 
         // Obtain ID of last visible item/image on the screen of the ScrollContainer
-        public int GetLastVisibleItemId()
+        private int GetLastVisibleItemId()
         {
             int lastItemId = -1;
 
@@ -522,7 +470,7 @@ namespace FirstScreen
         }
 
         // Obtain Next item/image (Right of the currently focused item) of the ScrollContainer
-        public Actor FocusNext()
+        private Actor FocusNext(bool loopEnabled)
         {
             int nextItem = -1;
 
@@ -535,11 +483,24 @@ namespace FirstScreen
                 nextItem = _focusedItem + 1;
             }
 
-            return Focus(nextItem);
+            if (nextItem >= _itemList.Count)
+            {
+                if (loopEnabled)
+                {
+                    nextItem = 0;
+                }
+                else
+                {
+                    nextItem = _itemList.Count - 1;
+                }
+            }
+
+            _focusedItem = nextItem;
+            return _itemList[_focusedItem];
         }
 
         // Obtain Previous item/image (left of the currently focused item) of the ScrollContainer
-        public Actor FocusPrevious()
+        private Actor FocusPrevious(bool loopEnabled)
         {
             int previousItem = -1;
 
@@ -552,61 +513,27 @@ namespace FirstScreen
                 previousItem = _focusedItem - 1;
             }
 
-            return Focus(previousItem);
-        }
-
-        private void OnHideAnimationFinished(object source, Animation.FinishedEventArgs e)
-        {
-            var currentParent =  ItemRoot.GetParent();
-            if (_shouldHide && currentParent != null)
+            if (previousItem < 0)
             {
-                Container.Remove(ItemRoot);
-            }
-        }
-
-        private void OnPan(object source, PanGestureDetector.DetectedEventArgs e)
-        {
-            switch (e.PanGesture.state)
-            {
-            case Gesture.State.Started:
-                _scrollDisplacement = 0.0f;
-                break;
-
-            case Gesture.State.Continuing:
-                _scrollDisplacement = e.PanGesture.displacement.x;
-                break;
-
-            case Gesture.State.Finished:
-            case Gesture.State.Cancelled:
-                float absScrollDistance = _scrollDisplacement;
-                if (absScrollDistance < 0.0f)
-                    absScrollDistance = 0.0f - absScrollDistance;
-
-                float scrollSpeed = e.PanGesture.velocity.x * e.PanGesture.velocity.x + e.PanGesture.velocity.y * e.PanGesture.velocity.y;
-                float maxScrollSpeed = 40.0f;  // TBD
-                if (scrollSpeed > maxScrollSpeed)
-                    scrollSpeed = maxScrollSpeed;
-
-                if (absScrollDistance > 1.0f && scrollSpeed > 0.05f) // Threshold TBD
+                if (loopEnabled)
                 {
-                    if (_scrollDisplacement > 0.0f) // scroll constant distance in constant speed.
-                    {
-                        Scroll((_itemSize.x + _padding) * 2, GetFirstVisibleItemId());
-                    }
-                    else
-                    {
-                        Scroll(-(_itemSize.x + _padding) * 2, GetFirstVisibleItemId());
-                    }
+                    previousItem = _itemList.Count - 1;
+                }
+                else
+                {
+                    previousItem = 0;
                 }
-                break;
             }
+
+            _focusedItem = previousItem;
+            return _itemList[_focusedItem];
         }
 
         // Perform ScrollAnimation on each item
         private void Scroll(float amount, int baseItem)
         {
             float tagetScrollPosition = _currentScrollPosition + amount;
-            float totalItemSize = _itemList.Count * (_itemSize.width + _padding) + _padding + (_marginX * 2.0f);
+            float totalItemSize = _itemList.Count * (_itemSize.width + _gap) + _gap + (_marginX * 2.0f);
 
             float maxScrollPosition = _width - totalItemSize;
 
@@ -618,14 +545,13 @@ namespace FirstScreen
             {
                 tagetScrollPosition = 0.0f;
             }
-
             _scrollAnimation.Clear();
 
             for (int i = 0; i < _itemList.Count; ++i)
             {
                 Vector3 targetPosition = GetItemPosition(i, tagetScrollPosition);
-                _scrollAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.POSITION),
-                                           new Property.Value(targetPosition),
+                _scrollAnimation.AnimateTo(new Dali.Property(_itemList[i], Actor.Property.POSITION),
+                                           new Dali.Property.Value(targetPosition),
                                            new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
             }
 
@@ -633,6 +559,87 @@ namespace FirstScreen
             _scrollAnimation.Play();
         }
 
+        // This function uses ItemId as next FocusedItem and preforms Scroll and SpotLight animations on that item.
+        private void Focus(int itemId)
+        {
+            if (itemId < 0)
+            {
+                itemId = 0;
+            }
+            else if (itemId >= _itemList.Count)
+            {
+                itemId = _itemList.Count - 1;
+            }
+
+            _itemList[itemId].Add(_shadowBorder);
+            _itemList[itemId].Add(_spotLight);
+
+            // Perform Spot Light animation
+            if(_focusedItem != itemId && _spotLight != null)
+            {
+                _spotLightAnimation.Clear();
+                _spotLightAnimation.Animate( _spotLight, _circularPath, new Vector3(0.0f, 0.0f, 0.0f) );
+                _spotLightAnimation.SetLooping(true);
+                _spotLightAnimation.Play();
+            }
+
+            _focusedItem = itemId;
+
+            Vector3 itemPosition = GetItemPosition(_focusedItem, _currentScrollPosition);
+
+            _focusAnimation.Clear();
+
+            float relativeItemPositionX = itemPosition.x - _itemSize.width * 0.5f + (_stageSize.width * 0.5f) + _offsetX;
+            if (relativeItemPositionX < _marginX + _offsetX + _gap)
+            {
+                float amount = _marginX + _offsetX + _gap - relativeItemPositionX;
+                Scroll(amount, itemId + 1); // Perform Scroll animation
+            }
+            else if (relativeItemPositionX + _itemSize.width + _gap + _marginX > _stageSize.width)
+            {
+                float amount = relativeItemPositionX + _marginX + _gap + _itemSize.width - _stageSize.width;
+                Scroll(-amount, itemId - 1); // Perform Scroll animation
+            }
+            else
+            {
+                // Perform animation when item is focused
+                for (int i = 0; i < _itemList.Count; ++i)
+                {
+                    Vector3 targetPosition = GetItemPosition(i, _currentScrollPosition);
+                    _focusAnimation.AnimateTo(new Dali.Property(_itemList[i], Actor.Property.POSITION),
+                                              new Dali.Property.Value(targetPosition),
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+            }
+
+            for (int i = 0; i < _itemList.Count; ++i)
+            {
+                SetupItemRenderer(_itemList[i], false);
+
+                // Perform scale animation on Focused item
+                if (i == _focusedItem)
+                {
+                    _focusAnimation.AnimateTo(new Dali.Property(_itemList[i], Actor.Property.SCALE),
+                                              new Dali.Property.Value(new Vector3(1.2f, 1.2f, 1.2f)),
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+                else
+                {
+                    _focusAnimation.AnimateTo(new Dali.Property(_itemList[i], Actor.Property.SCALE),
+                                              new Dali.Property.Value(new Vector3(1.0f, 1.0f, 1.0f)),
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+            }
+
+            _focusAnimation.Play();
+
+            if (_isFocused && _focusedItem >= 0)
+            {
+                SetupItemRenderer(_itemList[_focusedItem], true);
+                SetupSpotLightRenderer();
+            }
+        }
+
         // Calculate Position of any item/image of ScrollContainer
         private Vector3 GetItemPosition(int itemId, float scrollPosition)
         {
@@ -642,24 +649,24 @@ namespace FirstScreen
                 // used (_stageSize.width * 0.5f) because of ParentOriginCenter
                 if (_focusedItem > itemId)
                 {
-                    float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
-                    return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+                    float positionX = (_itemSize.width * itemId) + (_gap * (itemId + 1)) + scrollPosition + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                    return new Vector3(positionX, -_itemSize.height * _offsetYFactor, 0.0f);
                 }
                 else if (_focusedItem == itemId)
                 {
-                    float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + _marginX + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
-                    return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+                    float positionX = (_itemSize.width * itemId) + (_gap * (itemId + 1)) + scrollPosition + _marginX + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                    return new Vector3(positionX, -_itemSize.height * _offsetYFactor, 0.0f);
                 }
                 else
                 {
-                    float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + _marginX * 2.0f + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
-                    return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+                    float positionX = (_itemSize.width * itemId) + (_gap * (itemId + 1)) + scrollPosition + _marginX * 2.0f + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                    return new Vector3(positionX, -_itemSize.height * _offsetYFactor, 0.0f);
                 }
             }
             else
             {
-                float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
-                return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+                float positionX = (_itemSize.width * itemId) + (_gap * (itemId + 1)) + scrollPosition + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                return new Vector3(positionX, -_itemSize.height * _offsetYFactor, 0.0f);
             }
         }
 
diff --git a/plugins/dali-swig/examples/firstscreen/firstscreen.csproj b/plugins/dali-swig/examples/firstscreen/firstscreen.csproj
new file mode 100644 (file)
index 0000000..148cd79
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProjectGuid>{7606F35D-21C4-48CE-A38F-A24D6BEDB996}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>firstscreen</RootNamespace>
+    <AssemblyName>firstscreen</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <Compile Include="App.cs" />
+    <Compile Include="Constants.cs" />
+    <Compile Include="FocusData.cs" />
+    <Compile Include="FocusEffect.cs" />
+    <Compile Include="IFocusEffect.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="ScrollContainer.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="NDali">
+      <HintPath>..\..\NDali.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/plugins/dali-swig/examples/firstscreen/firstscreen.sln b/plugins/dali-swig/examples/firstscreen/firstscreen.sln
new file mode 100644 (file)
index 0000000..cbe800d
--- /dev/null
@@ -0,0 +1,17 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 12.00\r
+# Visual Studio 2012\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "firstscreen", "firstscreen.csproj", "{7606F35D-21C4-48CE-A38F-A24D6BEDB996}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|x86 = Debug|x86\r
+               Release|x86 = Release|x86\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {7606F35D-21C4-48CE-A38F-A24D6BEDB996}.Debug|x86.ActiveCfg = Debug|x86\r
+               {7606F35D-21C4-48CE-A38F-A24D6BEDB996}.Debug|x86.Build.0 = Debug|x86\r
+               {7606F35D-21C4-48CE-A38F-A24D6BEDB996}.Release|x86.ActiveCfg = Release|x86\r
+               {7606F35D-21C4-48CE-A38F-A24D6BEDB996}.Release|x86.Build.0 = Release|x86\r
+       EndGlobalSection\r
+EndGlobal\r