Merge remote-tracking branch 'origin/master' into tizen
authoradmin <tizenapi@samsung.com>
Tue, 9 Feb 2021 15:55:09 +0000 (15:55 +0000)
committeradmin <tizenapi@samsung.com>
Tue, 9 Feb 2021 15:55:09 +0000 (15:55 +0000)
188 files changed:
packaging/csapi-tizenfx.spec
packaging/version.txt
src/Tizen.NUI.Components/Controls/Control.cs
src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ICollectionChangedNotifier.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultGridItem.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultTitleItem.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Item/RecyclerViewItem.Internal.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Item/RecyclerViewItem.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSelectionMode.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSizingStrategy.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/EmptySource.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/IItemSource.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ItemsSourceFactory.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ListSource.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/MarshalingObservableCollection.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ObservableGroupedSource.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ObservableItemSource.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/UngroupedItemSource.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/GridLayouter.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/ItemsLayouter.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/LinearLayouter.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/RecyclerView.cs
src/Tizen.NUI.Components/Controls/RecyclerView/SelectionChangedEventArgs.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/SelectionList.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/ScrollableBase.cs
src/Tizen.NUI.Components/Controls/Scrollbar.cs
src/Tizen.NUI.Components/Controls/Slider.Internal.cs
src/Tizen.NUI.Components/Controls/Slider.cs
src/Tizen.NUI.Components/Style/ControlStyle.cs
src/Tizen.NUI.Components/Style/DefaultGridItemStyle.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Style/DefaultLinearItemStyle.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Style/DefaultTitleItemStyle.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Style/RecyclerViewItemStyle.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Style/SliderStyle.cs
src/Tizen.NUI.Components/Theme/DefaultTheme.cs
src/Tizen.NUI.Components/Theme/DefaultThemeMobile.cs
src/Tizen.NUI.Components/res/Theme/Tizen.NUI.Components_Tizen.NUI.Theme.Common.xaml
src/Tizen.NUI.Wearable/src/internal/Theme/DefaultTheme.cs
src/Tizen.NUI.Wearable/src/public/CircularPagination.cs
src/Tizen.NUI.Wearable/src/public/CircularProgress.cs
src/Tizen.NUI.Wearable/src/public/CircularScrollbar.cs
src/Tizen.NUI.Wearable/src/public/CircularSlider.cs
src/Tizen.NUI.Wearable/src/public/RecyclerView/GridRecycleLayoutManager.cs [moved from src/Tizen.NUI.Components/Controls/RecyclerView/GridRecycleLayoutManager.cs with 99% similarity]
src/Tizen.NUI.Wearable/src/public/RecyclerView/LinearRecycleLayoutManager.cs [moved from src/Tizen.NUI.Components/Controls/RecyclerView/LinearRecycleLayoutManager.cs with 99% similarity]
src/Tizen.NUI.Wearable/src/public/RecyclerView/RecycleAdapter.cs [moved from src/Tizen.NUI.Components/Controls/RecyclerView/RecycleAdapter.cs with 98% similarity]
src/Tizen.NUI.Wearable/src/public/RecyclerView/RecycleItem.cs [moved from src/Tizen.NUI.Components/Controls/RecyclerView/RecycleItem.cs with 96% similarity]
src/Tizen.NUI.Wearable/src/public/RecyclerView/RecycleLayoutManager.cs [moved from src/Tizen.NUI.Components/Controls/RecyclerView/RecycleLayoutManager.cs with 99% similarity]
src/Tizen.NUI.Wearable/src/public/RecyclerView/RecyclerView.cs [new file with mode: 0755]
src/Tizen.NUI/Tizen.NUI.csproj
src/Tizen.NUI/src/internal/Application/Application.cs
src/Tizen.NUI/src/internal/Common/Alignment.cs
src/Tizen.NUI/src/internal/Common/AsyncImageLoader.cs
src/Tizen.NUI/src/internal/Common/BaseObject.cs
src/Tizen.NUI/src/internal/Common/CustomActor.cs
src/Tizen.NUI/src/internal/Common/CustomActorImpl.cs
src/Tizen.NUI/src/internal/Common/DefaultRuler.cs
src/Tizen.NUI/src/internal/Common/Disposable.cs
src/Tizen.NUI/src/internal/Common/FixedRuler.cs
src/Tizen.NUI/src/internal/Common/FrameBuffer.cs
src/Tizen.NUI/src/internal/Common/FriendAssembly.cs
src/Tizen.NUI/src/internal/Common/KeyInputFocusManager.cs
src/Tizen.NUI/src/internal/Common/LinearConstrainer.cs
src/Tizen.NUI/src/internal/Common/Model3dView.cs
src/Tizen.NUI/src/internal/Common/NativeImageInterface.cs
src/Tizen.NUI/src/internal/Common/ObjectRegistry.cs
src/Tizen.NUI/src/internal/Common/PathConstrainer.cs
src/Tizen.NUI/src/internal/Common/RenderTask.cs
src/Tizen.NUI/src/internal/Common/RenderTaskList.cs
src/Tizen.NUI/src/internal/Common/Ruler.cs
src/Tizen.NUI/src/internal/Common/ViewImpl.cs
src/Tizen.NUI/src/internal/Common/ViewWrapperImpl.cs
src/Tizen.NUI/src/internal/Interop/Interop.WebView.cs
src/Tizen.NUI/src/internal/Utility/Builder.cs
src/Tizen.NUI/src/internal/Utility/Camera.cs
src/Tizen.NUI/src/internal/Utility/ConnectionTracker.cs
src/Tizen.NUI/src/internal/Utility/ConnectionTrackerInterface.cs
src/Tizen.NUI/src/internal/Utility/GaussianBlurView.cs
src/Tizen.NUI/src/internal/Utility/ItemLayout.cs
src/Tizen.NUI/src/internal/Utility/ItemView.cs
src/Tizen.NUI/src/internal/Utility/PageTurnPortraitView.cs
src/Tizen.NUI/src/internal/Utility/PageTurnView.cs
src/Tizen.NUI/src/internal/WebView/WebView.cs
src/Tizen.NUI/src/internal/Widget/WidgetImpl.cs
src/Tizen.NUI/src/internal/XamlBinding/Internals/IDataTemplate.cs [deleted file]
src/Tizen.NUI/src/public/Accessibility/AccessibilityManager.cs
src/Tizen.NUI/src/public/Animation/Animatable.cs
src/Tizen.NUI/src/public/Animation/Animation.cs
src/Tizen.NUI/src/public/Animation/KeyFrames.cs
src/Tizen.NUI/src/public/Animation/Path.cs
src/Tizen.NUI/src/public/Animation/TransitionData.cs
src/Tizen.NUI/src/public/Application/NUIApplication.cs
src/Tizen.NUI/src/public/BaseComponents/AnimatedVectorImageView.cs
src/Tizen.NUI/src/public/BaseComponents/CustomView.cs
src/Tizen.NUI/src/public/BaseComponents/FlexContainer.cs
src/Tizen.NUI/src/public/BaseComponents/ImageView.cs
src/Tizen.NUI/src/public/BaseComponents/Scrollable.cs
src/Tizen.NUI/src/public/BaseComponents/Style/Selector.cs
src/Tizen.NUI/src/public/BaseComponents/TableView.cs
src/Tizen.NUI/src/public/BaseComponents/TextEditor.cs
src/Tizen.NUI/src/public/BaseComponents/TextField.cs
src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs
src/Tizen.NUI/src/public/BaseComponents/VideoView.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/BaseComponents/ViewPublicMethods.cs
src/Tizen.NUI/src/public/Common/BaseHandle.cs
src/Tizen.NUI/src/public/Common/Container.cs
src/Tizen.NUI/src/public/Common/Layer.cs
src/Tizen.NUI/src/public/Common/PropertyBuffer.cs
src/Tizen.NUI/src/public/Common/PropertyCondition.cs
src/Tizen.NUI/src/public/Common/PropertyNotification.cs
src/Tizen.NUI/src/public/Common/StyleManager.cs
src/Tizen.NUI/src/public/Common/TypeInfo.cs
src/Tizen.NUI/src/public/Common/TypeRegistry.cs
src/Tizen.NUI/src/public/CustomView/CustomViewRegistry.cs
src/Tizen.NUI/src/public/CustomView/ViewWrapper.cs
src/Tizen.NUI/src/public/Events/Gesture.cs
src/Tizen.NUI/src/public/Events/GestureDetector.cs
src/Tizen.NUI/src/public/Events/Hover.cs
src/Tizen.NUI/src/public/Events/LongPressGesture.cs
src/Tizen.NUI/src/public/Events/LongPressGestureDetector.cs
src/Tizen.NUI/src/public/Events/PanGestureDetector.cs
src/Tizen.NUI/src/public/Events/PinchGesture.cs
src/Tizen.NUI/src/public/Events/RotationGesture.cs
src/Tizen.NUI/src/public/Events/TapGesture.cs
src/Tizen.NUI/src/public/Events/TapGestureDetector.cs
src/Tizen.NUI/src/public/Events/Wheel.cs
src/Tizen.NUI/src/public/Images/NativeImageSource.cs
src/Tizen.NUI/src/public/Images/PixelBuffer.cs
src/Tizen.NUI/src/public/Images/PixelData.cs
src/Tizen.NUI/src/public/Input/AutofillContainer.cs
src/Tizen.NUI/src/public/Input/FocusManager.cs
src/Tizen.NUI/src/public/Input/InputMethodContext.cs
src/Tizen.NUI/src/public/Input/Key.cs
src/Tizen.NUI/src/public/Rendering/Geometry.cs
src/Tizen.NUI/src/public/Rendering/Renderer.cs
src/Tizen.NUI/src/public/Rendering/Sampler.cs
src/Tizen.NUI/src/public/Rendering/Shader.cs
src/Tizen.NUI/src/public/Rendering/Texture.cs
src/Tizen.NUI/src/public/Rendering/TextureSet.cs
src/Tizen.NUI/src/public/Rendering/VertexBuffer.cs
src/Tizen.NUI/src/public/Template/DataTemplate.cs [moved from src/Tizen.NUI/src/internal/XamlBinding/DataTemplate.cs with 71% similarity]
src/Tizen.NUI/src/public/Template/DataTemplateExtensions.cs [moved from src/Tizen.NUI/src/internal/XamlBinding/DataTemplateExtensions.cs with 80% similarity]
src/Tizen.NUI/src/public/Template/DataTemplateSelector.cs [moved from src/Tizen.NUI/src/internal/XamlBinding/DataTemplateSelector.cs with 78% similarity]
src/Tizen.NUI/src/public/Template/ElementTemplate.cs [moved from src/Tizen.NUI/src/internal/XamlBinding/ElementTemplate.cs with 96% similarity]
src/Tizen.NUI/src/public/Template/IDataTemplate.cs [new file with mode: 0755]
src/Tizen.NUI/src/public/UIComponents/Button.cs
src/Tizen.NUI/src/public/UIComponents/CheckBoxButton.cs
src/Tizen.NUI/src/public/UIComponents/Popup.cs
src/Tizen.NUI/src/public/UIComponents/ProgressBar.cs
src/Tizen.NUI/src/public/UIComponents/PushButton.cs
src/Tizen.NUI/src/public/UIComponents/RadioButton.cs
src/Tizen.NUI/src/public/UIComponents/ScrollBar.cs
src/Tizen.NUI/src/public/UIComponents/ScrollView.cs
src/Tizen.NUI/src/public/UIComponents/Slider.cs
src/Tizen.NUI/src/public/UIComponents/ToggleButton.cs
src/Tizen.NUI/src/public/Utility/Capture.cs
src/Tizen.NUI/src/public/Utility/CubeTransitionEffect.cs
src/Tizen.NUI/src/public/Utility/FontClient.cs
src/Tizen.NUI/src/public/Utility/Timer.cs
src/Tizen.NUI/src/public/Visuals/VisualBase.cs
src/Tizen.NUI/src/public/Visuals/VisualFactory.cs
src/Tizen.NUI/src/public/Visuals/VisualMaps.cs
src/Tizen.NUI/src/public/Widget/Widget.cs
src/Tizen.NUI/src/public/Widget/WidgetView.cs
src/Tizen.NUI/src/public/Widget/WidgetViewManager.cs [changed mode: 0644->0755]
src/Tizen.NUI/src/public/Window/GLWindow.cs
src/Tizen.NUI/src/public/Window/Window.cs
src/Tizen.NUI/src/public/XamlBinding/Interactivity/DataTrigger.cs
src/Tizen.NUI/src/public/XamlBinding/Trigger.cs
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/CollectionViewGridSample.cs [new file with mode: 0755]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/CollectionViewLinearSample.cs [new file with mode: 0755]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Gallery.cs [new file with mode: 0644]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Group/CollectionViewGridGroupSample.cs [new file with mode: 0644]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Group/CollectionViewLinearGroupSample.cs [new file with mode: 0644]
test/Tizen.NUI.Tests/Tizen.NUI.TCT.sln
test/Tizen.NUI.Tests/Tizen.NUI.TCT/NuiSample.snk [new file with mode: 0755]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/Program.cs
test/Tizen.NUI.Tests/Tizen.NUI.TCT/Properties/Resources.Designer.cs [deleted file]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/Properties/Resources.resx [deleted file]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/Tizen.NUI.Devel.Tests.csproj
test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/etc/TSButtonExample.cs [moved from test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/TSButtonExample.cs with 99% similarity]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/etc/TSLottieAnimationView.cs [moved from test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/TSLottieAnimationView.cs with 98% similarity]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/etc/ViewMemoryLeakTest.cs [moved from test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/ViewMemoryLeakTest.cs with 99% similarity]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/internal/Accessibility/TSAccessibilityActionSignal.cs [new file with mode: 0755]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/internal/Accessibility/TSAccessibilityFocusOvershotSignal.cs [new file with mode: 0755]
test/Tizen.NUI.Tests/Tizen.NUI.TCT/tizen-manifest.xml

index 70d8afe..86bdf3a 100644 (file)
@@ -1,8 +1,8 @@
 # Auto-generated from csapi-tizenfx.spec.in by makespec.sh
 
 %define TIZEN_NET_API_VERSION 9
-%define TIZEN_NET_RPM_VERSION 9.0.0.15936+nui22011
-%define TIZEN_NET_NUGET_VERSION 9.0.0.15936
+%define TIZEN_NET_RPM_VERSION 9.0.0.999+nui22012
+%define TIZEN_NET_NUGET_VERSION 9.0.0.99999
 
 %define DOTNET_ASSEMBLY_PATH /usr/share/dotnet.tizen/framework
 %define DOTNET_ASSEMBLY_DUMMY_PATH %{DOTNET_ASSEMBLY_PATH}/ref
index 86da550..c646cf3 100755 (executable)
@@ -6,4 +6,4 @@ RPM_VERSION=9.0.0.999
 NUGET_VERSION=9.0.0.99999
 
 # RPM Version Suffix
-RPM_VERSION_SUFFIX=nui22011
+RPM_VERSION_SUFFIX=nui22012
index a9a7464..459a349 100755 (executable)
@@ -52,7 +52,7 @@ namespace Tizen.NUI.Components
 
         static Control()
         {
-            ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+            ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
         }
 
         /// <summary>
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs
new file mode 100644 (file)
index 0000000..fc69968
--- /dev/null
@@ -0,0 +1,1068 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Linq;
+using System.Collections;
+using System.Collections.Generic;
+using System.Windows.Input;
+using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// This class provides a View that can layouting items in list and grid with high performance.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CollectionView : RecyclerView
+    {
+        /// <summary>
+        /// Binding Property of selected item in single selection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty SelectedItemProperty =
+            BindableProperty.Create(nameof(SelectedItem), typeof(object), typeof(CollectionView), null,
+                propertyChanged: (bindable, oldValue, newValue)=>
+                {
+                    var colView = (CollectionView)bindable;
+                    oldValue = colView.selectedItem;
+                    colView.selectedItem = newValue;
+                    var args = new SelectionChangedEventArgs(oldValue, newValue);
+
+                    foreach (RecyclerViewItem item in colView.ContentContainer.Children.Where((item) => item is RecyclerViewItem))
+                    {
+                        if (item.BindingContext == null) continue;
+                        if (item.BindingContext == oldValue) item.IsSelected = false;
+                        else if (item.BindingContext == newValue) item.IsSelected = true;
+                    }
+
+                    SelectionPropertyChanged(colView, args);
+                },
+                defaultValueCreator: (bindable)=>
+                {
+                    var colView = (CollectionView)bindable;
+                    return colView.selectedItem;
+                });
+
+        /// <summary>
+        /// Binding Property of selected items list in multiple selection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty SelectedItemsProperty =
+            BindableProperty.Create(nameof(SelectedItems), typeof(IList<object>), typeof(CollectionView), null,
+                propertyChanged: (bindable, oldValue, newValue)=>
+                {
+                    var colView = (CollectionView)bindable;
+                    var oldSelection = colView.selectedItems ?? selectEmpty;
+                    //FIXME : CoerceSelectedItems calls only isCreatedByXaml
+                    var newSelection = (SelectionList)CoerceSelectedItems(colView, newValue);
+                    colView.selectedItems = newSelection;
+                    colView.SelectedItemsPropertyChanged(oldSelection, newSelection);
+                },
+                defaultValueCreator: (bindable) =>
+                {
+                    var colView = (CollectionView)bindable;
+                    colView.selectedItems = colView.selectedItems ?? new SelectionList(colView);
+                    return colView.selectedItems;
+                });
+
+        /// <summary>
+        /// Binding Property of selected items list in multiple selection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty SelectionModeProperty =
+            BindableProperty.Create(nameof(SelectionMode), typeof(ItemSelectionMode), typeof(CollectionView), ItemSelectionMode.None,
+                propertyChanged: (bindable, oldValue, newValue)=>
+                {
+                    var colView = (CollectionView)bindable;
+                    oldValue = colView.selectionMode;
+                    colView.selectionMode = (ItemSelectionMode)newValue;
+                    SelectionModePropertyChanged(colView, oldValue, newValue);
+                },
+                defaultValueCreator: (bindable) =>
+                {
+                    var colView = (CollectionView)bindable;
+                    return colView.selectionMode;
+                });
+
+
+        private static readonly IList<object> selectEmpty = new List<object>(0);
+        private DataTemplate itemTemplate = null;
+        private IEnumerable itemsSource = null;
+        private ItemsLayouter itemsLayouter = null;
+        private DataTemplate groupHeaderTemplate;
+        private DataTemplate groupFooterTemplate;
+        private bool isGrouped;
+        private bool wasRelayouted = false;
+        private bool needInitalizeLayouter = false;
+        private object selectedItem;
+        private SelectionList selectedItems;
+        private bool suppressSelectionChangeNotification;
+        private ItemSelectionMode selectionMode = ItemSelectionMode.None;
+        private RecyclerViewItem header;
+        private RecyclerViewItem footer;
+        private View focusedView;
+        private int prevFocusedDataIndex = 0;
+        private List<RecyclerViewItem> recycleGroupHeaderCache { get; } = new List<RecyclerViewItem>();
+        private List<RecyclerViewItem> recycleGroupFooterCache { get; } = new List<RecyclerViewItem>();
+
+        /// <summary>
+        /// Base constructor.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CollectionView() : base()
+        {
+            FocusGroup = true;
+            SetKeyboardNavigationSupport(true);
+        }
+
+        /// <summary>
+        /// Base constructor with ItemsSource
+        /// </summary>
+        /// <param name="itemsSource">item's data source</param>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        public CollectionView(IEnumerable itemsSource) : this()
+        {
+            ItemsSource = itemsSource;
+        }
+
+        /// <summary>
+        /// Base constructor with ItemsSource, ItemsLayouter and ItemTemplate
+        /// </summary>
+        /// <param name="itemsSource">item's data source</param>
+        /// <param name="layouter">item's layout manager</param>
+        /// <param name="template">item's view template with data bindings</param>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        public CollectionView(IEnumerable itemsSource, ItemsLayouter layouter, DataTemplate template) : this()
+        {
+            ItemsSource = itemsSource;
+            ItemTemplate = template;
+            ItemsLayouter = layouter;
+        }
+
+        /// <summary>
+        /// Event of Selection changed.
+        /// old selection list and new selection will be provided.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<SelectionChangedEventArgs> SelectionChanged;
+
+        /// <summary>
+        /// Align item in the viewport when ScrollTo() calls.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        public enum ItemScrollTo
+        {
+            /// <summary>
+            /// Scroll to show item in nearest viewport on scroll direction.
+            /// item is above the scroll viewport, item will be came into front,
+            /// item is under the scroll viewport, item will be came into end,
+            /// item is in the scroll viewport, no scroll.
+            /// </summary>
+            Nearest,
+            /// <summary>
+            /// Scroll to show item in start of the viewport.
+            /// </summary>
+            Start,
+            /// <summary>
+            /// Scroll to show item in center of the viewport.
+            /// </summary>
+            Center,
+            /// <summary>
+            /// Scroll to show item in end of the viewport.
+            /// </summary>
+            End,
+        }
+
+        /// <summary>
+        /// Item's source data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override IEnumerable ItemsSource
+        {
+            get
+            {
+                return itemsSource;
+            }
+            set
+            {
+
+                itemsSource = value;
+                if (value == null)
+                {
+                    if (InternalItemSource != null) InternalItemSource.Dispose();
+                    //layouter.Clear()
+                    return;
+                }
+                if (InternalItemSource != null) InternalItemSource.Dispose();
+                InternalItemSource = ItemsSourceFactory.Create(this);
+
+                if (itemsLayouter == null) return;
+
+                needInitalizeLayouter = true;
+                Init();
+            }
+        }
+
+        /// <summary>
+        /// DataTemplate for items.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override DataTemplate ItemTemplate
+        {
+            get
+            {
+                return itemTemplate;
+            }
+            set
+            {
+                itemTemplate = value;
+                if (value == null)
+                {
+                    //layouter.clear()
+                    return;
+                }
+
+                needInitalizeLayouter = true;
+                Init();
+            }
+        }
+
+        /// <summary>
+        /// Items Layouter.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual ItemsLayouter ItemsLayouter
+        {
+            get
+            {
+                return itemsLayouter;
+            }
+            set
+            {
+                itemsLayouter = value;
+                base.InternalItemsLayouter = ItemsLayouter;
+                if (value == null)
+                {
+                    needInitalizeLayouter = false;
+                    return;
+                }
+
+                needInitalizeLayouter = true;
+                Init();
+            }
+        }
+
+        /// <summary>
+        /// Scrolling direction to display items layout.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new Direction ScrollingDirection
+        {
+            get
+            {
+                return base.ScrollingDirection;
+            }
+            set
+            {
+                base.ScrollingDirection = value;
+
+                if (ScrollingDirection == Direction.Horizontal)
+                {
+                    ContentContainer.SizeWidth = ItemsLayouter.CalculateLayoutOrientationSize();
+                }
+                else
+                {
+                    ContentContainer.SizeHeight = ItemsLayouter.CalculateLayoutOrientationSize();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Selected item in single selection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object SelectedItem
+        {
+            get => GetValue(SelectedItemProperty);
+            set => SetValue(SelectedItemProperty, value);
+        }
+
+        /// <summary>
+        /// Selected items list in multiple selection.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IList<object> SelectedItems
+        {
+            get => (IList<object>)GetValue(SelectedItemsProperty);
+            // set => SetValue(SelectedItemsProperty, new SelectionList(this, value));
+        }
+
+        /// <summary>
+        /// Selection mode to handle items selection. See ItemSelectionMode for details.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ItemSelectionMode SelectionMode
+        {
+            get => (ItemSelectionMode)GetValue(SelectionModeProperty);
+            set => SetValue(SelectionModeProperty, value);
+        }
+
+        /// <summary>
+        /// Command of selection changed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ICommand SelectionChangedCommand { set; get; }
+
+        /// <summary>
+        /// Command parameter of selection changed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public object SelectionChangedCommandParameter { set; get; }
+
+        /// <summary>
+        /// Size strategy of measuring scroll content. see details in ItemSizingStrategy.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ItemSizingStrategy SizingStrategy { get; set; }
+
+        /// <summary>
+        /// Header item which placed in top-most position.
+        /// note : internal index and count will be increased.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecyclerViewItem Header
+        {
+            get => header;
+            set
+            {
+                if (header != null)
+                {
+                    //ContentContainer.Remove(header);
+                    Utility.Dispose(header);
+                }
+                if (value != null)
+                {
+                    value.Index = 0;
+                    value.ParentItemsView = this;
+                    value.IsHeader = true;
+                    ContentContainer.Add(value);
+                }
+                header = value;
+                needInitalizeLayouter = true;
+                Init();
+            }
+        }
+
+        /// <summary>
+        /// Footer item which placed in bottom-most position.
+        /// note : internal count will be increased.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecyclerViewItem Footer
+        {
+            get => footer;
+            set
+            {
+                if (footer != null)
+                {
+                    //ContentContainer.Remove(footer);
+                    Utility.Dispose(footer);
+                }
+                if (value != null)
+                {
+                    value.Index = InternalItemSource?.Count ?? 0;
+                    value.ParentItemsView = this;
+                    value.IsFooter = true;
+                    ContentContainer.Add(value);
+                }
+                footer = value;
+                needInitalizeLayouter = true;
+                Init();
+            }
+        }
+
+        /// <summary>
+        /// Boolean flag of group feature existence.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsGrouped 
+        { 
+            get => isGrouped;
+            set
+            {
+                isGrouped = value;
+                needInitalizeLayouter = true;
+                //Need to re-intialize Internal Item Source.
+                if (InternalItemSource != null)
+                {
+                    InternalItemSource.Dispose();
+                    InternalItemSource = null;
+                }
+                if (ItemsSource != null)
+                    InternalItemSource = ItemsSourceFactory.Create(this);
+                Init();
+            }
+        }
+
+        /// <summary>
+        ///  DataTemplate of group header. Group feature is not supported yet.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DataTemplate GroupHeaderTemplate
+        {
+            get
+            {
+                return groupHeaderTemplate;
+            }
+            set
+            {
+                groupHeaderTemplate = value;
+                needInitalizeLayouter = true;
+                Init();
+            }
+        }
+
+        /// <summary>
+        /// DataTemplate of group footer. Group feature is not supported yet.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DataTemplate GroupFooterTemplate
+        {
+            get
+            {
+                return groupFooterTemplate;
+            }
+            set
+            {
+                groupFooterTemplate = value;
+                needInitalizeLayouter = true;
+                Init();
+            }
+        }
+
+
+        /// <summary>
+        /// Internal encapsulated items data source.
+        /// </summary>
+        internal new IGroupableItemSource InternalItemSource
+        {
+            get
+            {
+                return (base.InternalItemSource as IGroupableItemSource);
+            }
+            set
+            {
+                base.InternalItemSource = value;
+            }
+        }
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void OnRelayout(Vector2 size, RelayoutContainer container)
+        {
+            base.OnRelayout(size, container);
+
+            wasRelayouted = true;
+            if (needInitalizeLayouter) Init();
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+        {
+            View nextFocusedView = null;
+
+            if (focusedView == null)
+            {
+                // If focusedView is null, find child which has previous data index
+                if (ContentContainer.Children.Count > 0 && InternalItemSource.Count > 0)
+                {
+                    for (int i = 0; i < ContentContainer.Children.Count; i++)
+                    {
+                        RecyclerViewItem item = Children[i] as RecyclerViewItem;
+                        if (item?.Index == prevFocusedDataIndex)
+                        {
+                            nextFocusedView = item;
+                            break;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                // If this is not first focus, request next focus to Layouter
+                nextFocusedView = ItemsLayouter.RequestNextFocusableView(currentFocusedView, direction, loopEnabled);
+            }
+
+            if (nextFocusedView != null)
+            {
+                // Check next focused view is inside of visible area.
+                // If it is not, move scroll position to make it visible.
+                Position scrollPosition = ContentContainer.CurrentPosition;
+                float targetPosition = -(ScrollingDirection == Direction.Horizontal ? scrollPosition.X : scrollPosition.Y);
+
+                float left = nextFocusedView.Position.X;
+                float right = nextFocusedView.Position.X + nextFocusedView.Size.Width;
+                float top = nextFocusedView.Position.Y;
+                float bottom = nextFocusedView.Position.Y + nextFocusedView.Size.Height;
+
+                float visibleRectangleLeft = -scrollPosition.X;
+                float visibleRectangleRight = -scrollPosition.X + Size.Width;
+                float visibleRectangleTop = -scrollPosition.Y;
+                float visibleRectangleBottom = -scrollPosition.Y + Size.Height;
+
+                if (ScrollingDirection == Direction.Horizontal)
+                {
+                    if ((direction == View.FocusDirection.Left || direction == View.FocusDirection.Up) && left < visibleRectangleLeft)
+                    {
+                        targetPosition = left;
+                    }
+                    else if ((direction == View.FocusDirection.Right || direction == View.FocusDirection.Down) && right > visibleRectangleRight)
+                    {
+                        targetPosition = right - Size.Width;
+                    }
+                }
+                else
+                {
+                    if ((direction == View.FocusDirection.Up || direction == View.FocusDirection.Left) && top < visibleRectangleTop)
+                    {
+                        targetPosition = top;
+                    }
+                    else if ((direction == View.FocusDirection.Down || direction == View.FocusDirection.Right) && bottom > visibleRectangleBottom)
+                    {
+                        targetPosition = bottom - Size.Height;
+                    }
+                }
+
+                focusedView = nextFocusedView;
+                prevFocusedDataIndex = (nextFocusedView as RecyclerViewItem)?.Index ?? -1;
+
+                ScrollTo(targetPosition, true);
+            }
+            else
+            {
+                // If nextView is null, it means that we should move focus to outside of Control.
+                // Return FocusableView depending on direction.
+                switch (direction)
+                {
+                    case View.FocusDirection.Left:
+                    {
+                        nextFocusedView = LeftFocusableView;
+                        break;
+                    }
+                    case View.FocusDirection.Right:
+                    {
+                        nextFocusedView = RightFocusableView;
+                        break;
+                    }
+                    case View.FocusDirection.Up:
+                    {
+                        nextFocusedView = UpFocusableView;
+                        break;
+                    }
+                    case View.FocusDirection.Down:
+                    {
+                        nextFocusedView = DownFocusableView;
+                        break;
+                    }
+                }
+
+                if(nextFocusedView != null)
+                {
+                    focusedView = null;
+                }
+                else
+                {
+                    //If FocusableView doesn't exist, not move focus.
+                    nextFocusedView = focusedView;
+                }
+            }
+
+            return nextFocusedView;
+        }
+
+        /// <summary>
+        /// Update selected items list in multiple selection.
+        /// </summary>
+        /// <param name="newSelection">updated selection list by user</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void UpdateSelectedItems(IList<object> newSelection)
+        {
+            var oldSelection = new List<object>(SelectedItems);
+
+            suppressSelectionChangeNotification = true;
+
+            SelectedItems.Clear();
+
+            if (newSelection?.Count > 0)
+            {
+                for (int n = 0; n < newSelection.Count; n++)
+                {
+                    SelectedItems.Add(newSelection[n]);
+                }
+            }
+
+            suppressSelectionChangeNotification = false;
+
+            SelectedItemsPropertyChanged(oldSelection, newSelection);
+        }
+
+        /// <summary>
+        /// Scroll to specific position with or without animation.
+        /// </summary>
+        /// <param name="position">Destination.</param>
+        /// <param name="animate">Scroll with or without animation</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new void ScrollTo(float position, bool animate) => base.ScrollTo(position, animate);
+
+        /// <summary>
+        /// Scroll to specific item's aligned position with or without animation.
+        /// </summary>
+        /// <param name="item">Target item of dataset.</param>
+        /// <param name="animate">Boolean flag of animation.</param>
+        /// <param name="align">Align state of item. see details in ItemScrollTo.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void ScrollTo(object item, bool animate = false, ItemScrollTo align = ItemScrollTo.Nearest)
+        {
+            if (item == null) throw new ArgumentNullException(nameof(item));
+            if (ItemsLayouter == null) throw new Exception("Item Layouter must exist.");
+
+            if (InternalItemSource.GetPosition(item) == -1)
+            {
+                throw new Exception("ScrollTo parameter item is not a member of ItemsSource");
+            }
+
+            float scrollPos, curPos, curSize, curItemSize;
+            (float x, float y) = ItemsLayouter.GetItemPosition(item);
+            (float width, float height) = ItemsLayouter.GetItemSize(item);
+            if (ScrollingDirection == Direction.Horizontal)
+            {
+                scrollPos = x;
+                curPos = ScrollPosition.X;
+                curSize = Size.Width;
+                curItemSize = width;
+            }
+            else
+            {
+                scrollPos = y;
+                curPos = ScrollPosition.Y;
+                curSize = Size.Height;
+                curItemSize = height;
+            }
+
+            //Console.WriteLine("[NUI] ScrollTo [{0}:{1}], curPos{2}, itemPos{3}, curSize{4}, itemSize{5}", InternalItemSource.GetPosition(item), align, curPos, scrollPos, curSize, curItemSize);
+            switch (align)
+            {
+                case ItemScrollTo.Start:
+                    //nothing necessary.
+                break;
+                case ItemScrollTo.Center:
+                    scrollPos = scrollPos - (curSize / 2) + (curItemSize / 2);
+                break;
+                case ItemScrollTo.End:
+                    scrollPos = scrollPos - curSize + curItemSize;
+                break;
+                case ItemScrollTo.Nearest:
+                    if (scrollPos < curPos - curItemSize)
+                    {
+                        // item is placed before the current screen. scrollTo.Top
+                    }
+                    else if (scrollPos >= curPos + curSize + curItemSize)
+                    {
+                        // item is placed after the current screen. scrollTo.End
+                        scrollPos = scrollPos - curSize + curItemSize;
+                    }
+                    else
+                    {
+                        // item is in the scroller. ScrollTo() is ignored.
+                        return;
+                    }
+                break;
+            }
+
+            //Console.WriteLine("[NUI] ScrollTo [{0}]-------------------", scrollPos);
+            base.ScrollTo(scrollPos, animate);
+        }
+
+        // Realize and Decorate the item.
+        internal override RecyclerViewItem RealizeItem(int index)
+        {
+            if (index == 0 && Header != null)
+            {
+                Header.Show();
+                return Header;
+            }
+
+            if (index == InternalItemSource.Count - 1 && Footer != null)
+            {
+                Footer.Show();
+                return Footer;
+            }
+
+            if (isGrouped)
+            {
+                var context = InternalItemSource.GetItem(index);
+                if (InternalItemSource.IsGroupHeader(index))
+                {
+                    DataTemplate templ = (groupHeaderTemplate as DataTemplateSelector)?.SelectDataTemplate(context, this) ?? groupHeaderTemplate;
+
+                    RecyclerViewItem groupHeader = PopRecycleGroupCache(templ, true);
+                    if (groupHeader == null)
+                    {
+                        groupHeader = (RecyclerViewItem)DataTemplateExtensions.CreateContent(groupHeaderTemplate, context, this);
+
+                        groupHeader.ParentItemsView = this;
+                        groupHeader.Template = templ;
+                        groupHeader.isGroupHeader = true;
+                        groupHeader.isGroupFooter = false;
+                        ContentContainer.Add(groupHeader);
+                    }
+                    groupHeader.Index = index;
+                    groupHeader.ParentGroup = context;
+                    groupHeader.BindingContext = context;
+                    //group selection?
+                    return groupHeader;
+                }
+                else if (InternalItemSource.IsGroupFooter(index))
+                {
+                    DataTemplate templ = (groupFooterTemplate as DataTemplateSelector)?.SelectDataTemplate(context, this) ?? groupFooterTemplate;
+
+                    RecyclerViewItem groupFooter = PopRecycleGroupCache(templ, false);
+                    if (groupFooter == null)
+                    {
+                        groupFooter = (RecyclerViewItem)DataTemplateExtensions.CreateContent(groupFooterTemplate, context, this);
+
+                        groupFooter.ParentItemsView = this;
+                        groupFooter.Template = templ;
+                        groupFooter.isGroupHeader = false;
+                        groupFooter.isGroupFooter = true;
+                        ContentContainer.Add(groupFooter);
+                    }
+                    groupFooter.Index = index;
+                    groupFooter.ParentGroup = context;
+                    groupFooter.BindingContext = context;
+
+                    //group selection?
+                    return groupFooter;
+                }
+            }
+
+            RecyclerViewItem item = base.RealizeItem(index);
+            if (isGrouped) item.ParentGroup = InternalItemSource.GetGroupParent(index);
+
+            switch (SelectionMode)
+            {
+                case ItemSelectionMode.SingleSelection:
+                    if (item.BindingContext == SelectedItem) item.IsSelected = true;
+                    break;
+
+                case ItemSelectionMode.MultipleSelections:
+                    if (SelectedItems?.Contains(item.BindingContext) ?? false) item.IsSelected = true;
+                    break;
+                case ItemSelectionMode.None:
+                    item.IsSelectable = false;
+                    break;
+            }
+
+            return item;
+        }
+
+        // Unrealize and caching the item.
+        internal override void UnrealizeItem(RecyclerViewItem item, bool recycle = true)
+        {
+            if (item == Header)
+            {
+                item.Hide();
+                return;
+            }
+            if (item == Footer)
+            {
+                item.Hide();
+                return;
+            }
+            if (item.isGroupHeader || item.isGroupFooter)
+            {
+                if (!recycle || !PushRecycleGroupCache(item))
+                    Utility.Dispose(item);
+                return;
+            }
+
+            item.IsSelected = false;
+            base.UnrealizeItem(item, recycle);
+        }
+
+        internal void SelectedItemsPropertyChanged(IList<object> oldSelection, IList<object> newSelection)
+        {
+            if (suppressSelectionChangeNotification)
+            {
+                return;
+            }
+
+            foreach (RecyclerViewItem item in ContentContainer.Children.Where((item) => item is RecyclerViewItem))
+            {
+                if (item.BindingContext == null) continue;
+                if (newSelection.Contains(item.BindingContext))
+                {
+                    if (!item.IsSelected) item.IsSelected = true;
+                }
+                else
+                {
+                    if (item.IsSelected) item.IsSelected = false;
+                }
+            }
+            SelectionPropertyChanged(this, new SelectionChangedEventArgs(oldSelection, newSelection));
+
+            OnPropertyChanged(SelectedItemsProperty.PropertyName);
+        }
+
+        /// <summary>
+        /// Internal selection callback.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void OnSelectionChanged(SelectionChangedEventArgs args)
+        {
+            //Selection Callback
+        }
+
+        /// <summary>
+        /// Adjust scrolling position by own scrolling rules.
+        /// Override this function when developer wants to change destination of flicking.(e.g. always snap to center of item)
+        /// </summary>
+        /// <param name="position">Scroll position which is calculated by ScrollableBase</param>
+        /// <returns>Adjusted scroll destination</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override float AdjustTargetPositionOfScrollAnimation(float position)
+        {
+            // Destination is depending on implementation of layout manager.
+            // Get destination from layout manager.
+            return ItemsLayouter.CalculateCandidateScrollPosition(position);
+        }
+
+        /// <summary>
+        /// OnScroll event callback.
+        /// </summary>
+        /// <param name="source">Scroll source object</param>
+        /// <param name="args">Scroll event argument</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void OnScrolling(object source, ScrollEventArgs args)
+        {
+            if (disposed) return;
+
+            if (needInitalizeLayouter)
+            {
+                ItemsLayouter.Initialize(this);
+                needInitalizeLayouter = false;
+            }
+            base.OnScrolling(source, args);
+        }
+
+        /// <summary>
+        /// Dispose ItemsView and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                disposed = true;
+                if (InternalItemSource != null)
+                {
+                    InternalItemSource.Dispose();
+                    InternalItemSource = null;
+                }
+                if (Header != null)
+                {
+                    Utility.Dispose(Header);
+                    Header = null;
+                }
+                if (Footer != null)
+                {
+                    Utility.Dispose(Footer);
+                    Footer = null;
+                }
+                groupHeaderTemplate = null;
+                groupFooterTemplate = null;
+                //
+            }
+
+            base.Dispose(type);
+        }
+
+        private static void SelectionPropertyChanged(CollectionView colView, SelectionChangedEventArgs args)
+        {
+            var command = colView.SelectionChangedCommand;
+
+            if (command != null)
+            {
+                var commandParameter = colView.SelectionChangedCommandParameter;
+
+                if (command.CanExecute(commandParameter))
+                {
+                    command.Execute(commandParameter);
+                }
+            }
+            colView.SelectionChanged?.Invoke(colView, args);
+            colView.OnSelectionChanged(args);
+        }
+
+        private static object CoerceSelectedItems(BindableObject bindable, object value)
+        {
+            if (value == null)
+            {
+                return new SelectionList((CollectionView)bindable);
+            }
+
+            if (value is SelectionList)
+            {
+                return value;
+            }
+
+            return new SelectionList((CollectionView)bindable, value as IList<object>);
+        }
+
+        private static void SelectionModePropertyChanged(BindableObject bindable, object oldValue, object newValue)
+        {
+            var colView = (CollectionView)bindable;
+
+            var oldMode = (ItemSelectionMode)oldValue;
+            var newMode = (ItemSelectionMode)newValue;
+
+            IList<object> previousSelection = new List<object>();
+            IList<object> newSelection = new List<object>();
+
+            switch (oldMode)
+            {
+                case ItemSelectionMode.None:
+                    break;
+                case ItemSelectionMode.SingleSelection:
+                    if (colView.SelectedItem != null)
+                    {
+                        previousSelection.Add(colView.SelectedItem);
+                    }
+                    break;
+                case ItemSelectionMode.MultipleSelections:
+                    previousSelection = colView.SelectedItems;
+                    break;
+            }
+
+            switch (newMode)
+            {
+                case ItemSelectionMode.None:
+                    break;
+                case ItemSelectionMode.SingleSelection:
+                    if (colView.SelectedItem != null)
+                    {
+                        newSelection.Add(colView.SelectedItem);
+                    }
+                    break;
+                case ItemSelectionMode.MultipleSelections:
+                    newSelection = colView.SelectedItems;
+                    break;
+            }
+
+            if (previousSelection.Count == newSelection.Count)
+            {
+                if (previousSelection.Count == 0 || (previousSelection[0] == newSelection[0]))
+                {
+                    // Both selections are empty or have the same single item; no reason to signal a change
+                    return;
+                }
+            }
+
+            var args = new SelectionChangedEventArgs(previousSelection, newSelection);
+            SelectionPropertyChanged(colView, args);
+        }
+
+        private void Init()
+        {
+            if (ItemsSource == null) return;
+            if (ItemsLayouter == null) return;
+            if (ItemTemplate == null) return;
+
+            if (disposed) return;
+            if (needInitalizeLayouter)
+            {
+                if (InternalItemSource == null) return;
+
+                InternalItemSource.HasHeader = (header != null);
+                InternalItemSource.HasFooter = (footer != null);
+            }
+
+            if (!wasRelayouted) return;
+
+            if (needInitalizeLayouter)
+            {
+                ItemsLayouter.Initialize(this);
+                needInitalizeLayouter = false;
+            }
+            ItemsLayouter.RequestLayout(0.0f, true);
+
+            if (ScrollingDirection == Direction.Horizontal)
+            {
+                ContentContainer.SizeWidth = ItemsLayouter.CalculateLayoutOrientationSize();
+            }
+            else
+            {
+                ContentContainer.SizeHeight = ItemsLayouter.CalculateLayoutOrientationSize();
+            }
+        }
+
+        private bool PushRecycleGroupCache(RecyclerViewItem item)
+        {
+            if (item == null) throw new ArgumentNullException(nameof(item));
+            if (RecycleCache.Count >= 20) return false;
+            if (item.Template == null) return false;
+            if (item.isGroupHeader)
+            {
+                recycleGroupHeaderCache.Add(item);
+            }
+            else if (item.isGroupFooter)
+            {
+                recycleGroupFooterCache.Add(item);
+            }
+            else return false;
+            item.Hide();
+            item.Index = -1;
+            return true;
+        }
+
+        private RecyclerViewItem PopRecycleGroupCache(DataTemplate Template, bool isHeader)
+        {
+            RecyclerViewItem viewItem = null;
+
+            var Cache = (isHeader ? recycleGroupHeaderCache : recycleGroupFooterCache);
+            for (int i = 0; i < Cache.Count; i++)
+            {
+                viewItem = Cache[i];
+                if (Template == viewItem.Template) break;
+            }
+
+            if (viewItem != null)
+            {
+                Cache.Remove(viewItem);
+                viewItem.Show();
+            }
+            return viewItem;
+        }
+
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ICollectionChangedNotifier.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ICollectionChangedNotifier.cs
new file mode 100644 (file)
index 0000000..d00695d
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// Notify observers about dataset changes of observable items.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public interface ICollectionChangedNotifier
+    {
+
+        /// <summary>
+        /// Notify the dataset is Changed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyDataSetChanged();
+
+        /// <summary>
+        /// Notify the observable item in startIndex is changed.
+        /// </summary>
+        /// <param name="source">dataset source</param>
+        /// <param name="startIndex">changed item index</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyItemChanged(IItemSource source, int startIndex);
+
+        /// <summary>
+        /// Notify the observable item is inserted in dataset.
+        /// </summary>
+        /// <param name="source">dataset source</param>
+        /// <param name="startIndex">Inserted item index</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyItemInserted(IItemSource source, int startIndex);
+
+        /// <summary>
+        /// Notify the observable item is moved from fromPosition to ToPosition.
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="fromPosition"></param>
+        /// <param name="toPosition"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyItemMoved(IItemSource source, int fromPosition, int toPosition);
+
+        /// <summary>
+        /// Notify the range of observable items from start to end are changed.
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="startIndex"></param>
+        /// <param name="endIndex"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyItemRangeChanged(IItemSource source, int startIndex, int endIndex);
+
+        /// <summary>
+        /// Notify the count range of observable items are inserted in startIndex.
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="startIndex"></param>
+        /// <param name="count"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyItemRangeInserted(IItemSource source, int startIndex, int count);
+
+        /// <summary>
+        /// Notify the count range of observable items from the startIndex are removed.
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="startIndex"></param>
+        /// <param name="count"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyItemRangeRemoved(IItemSource source, int startIndex, int count);
+
+        /// <summary>
+        /// Notify the observable item in startIndex is removed.
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="startIndex"></param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        void NotifyItemRemoved(IItemSource source, int startIndex);
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultGridItem.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultGridItem.cs
new file mode 100644 (file)
index 0000000..b618bc7
--- /dev/null
@@ -0,0 +1,517 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+using Tizen.NUI.Accessibility;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// DefaultGridItem is one kind of common component, a DefaultGridItem clearly describes what action will occur when the user selects it.
+    /// DefaultGridItem may contain text or an icon.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DefaultGridItem : RecyclerViewItem
+    {
+        private TextLabel itemCaption;
+        private ImageView itemImage;
+        private View itemBadge;
+        private CaptionOrientation captionOrientation;
+        private bool layoutChanged;
+
+        private DefaultGridItemStyle ItemStyle => ViewStyle as DefaultGridItemStyle;
+
+        /// <summary>
+        /// Return a copied Style instance of DefaultLinearItem
+        /// </summary>
+        /// <remarks>
+        /// It returns copied Style instance and changing it does not effect to the DefaultLinearItem.
+        /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new DefaultGridItemStyle Style
+        {
+            get
+            {
+                var result = new DefaultGridItemStyle(ItemStyle);
+                result.CopyPropertiesFromView(this);
+                if (itemCaption) result.Caption.CopyPropertiesFromView(itemCaption);
+                if (itemImage) result.Image.CopyPropertiesFromView(itemImage);
+                if (itemBadge) result.Badge.CopyPropertiesFromView(itemBadge);
+
+                return result;
+            }
+        }
+
+        static DefaultGridItem() {}
+
+        /// <summary>
+        /// Creates a new instance of DefaultGridItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultGridItem() : base()
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of DefaultGridItem with style
+        /// </summary>
+        /// <param name="style=">Create DefaultGridItem by special style defined in UX.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultGridItem(string style) : base(style)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of DefaultGridItem with style
+        /// </summary>
+        /// <param name="itemStyle=">Create DefaultGridItem by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultGridItem(DefaultGridItemStyle itemStyle) : base(itemStyle)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Caption orientation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public enum CaptionOrientation
+        {
+            /// <summary>
+            /// Outside of image bottom edge.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            OutsideBottom,
+            /// <summary>
+            /// Outside of image top edge.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            OutsideTop,
+            /// <summary>
+            /// inside of image bottom edge.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            InsideBottom,
+            /// <summary>
+            /// inside of image top edge.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            InsideTop,
+        }
+
+        /// <summary>
+        /// DefaultGridItem's icon part.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ImageView Image
+        {
+            get
+            {
+                if ( itemImage == null)
+                {
+                    itemImage = CreateImage(ItemStyle.Image);
+                    if (itemImage != null)
+                    {
+                        Add(itemImage);
+                        itemImage.Relayout += OnImageRelayout;
+                        layoutChanged = true;
+                    }
+                }
+                return itemImage;
+            }
+            internal set
+            {
+                itemImage = value;
+                layoutChanged = true;
+            }
+        }
+
+
+        /// <summary>
+        /// DefaultGridItem's badge object. will be placed in right-top edge.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View Badge
+        {
+            get
+            {
+                return itemBadge;
+
+            }
+            set
+            {
+                if (value == null)
+                {
+                    Remove(itemBadge);
+                }
+                itemBadge = value;
+                if (itemBadge != null)
+                {
+                    itemBadge.ApplyStyle(ItemStyle.Badge);
+                    Add(itemBadge);
+                }
+                layoutChanged = true;
+            }
+        }
+
+/* open when ImageView using Uri not string
+        /// <summary>
+        /// Image image's resource url in DefaultGridItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string ImageUrl
+        {
+            get
+            {
+                return Image.ResourceUrl;
+            }
+            set
+            {
+                Image.ResourceUrl = value;
+            }
+        }
+*/
+
+        /// <summary>
+        /// DefaultGridItem's text part.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabel Caption
+        {
+            get
+            {
+                if (itemCaption == null)
+                {
+                    itemCaption = CreateLabel(ItemStyle.Caption);
+                    if (itemCaption != null)
+                    {
+                        Add(itemCaption);
+                        layoutChanged = true;
+                    }
+                }
+                return itemCaption;
+            }
+            internal set
+            {
+                itemCaption = value;
+                layoutChanged = true;
+                AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemCaption.Text);
+            }
+        }
+
+        /// <summary>
+        /// The text of DefaultGridItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string Text
+        {
+            get
+            {
+                return Caption.Text;
+            }
+            set
+            {
+                Caption.Text = value;
+            }
+        }
+
+        /// <summary>
+        /// Caption relative orientation with image in DefaultGridItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CaptionOrientation CaptionRelativeOrientation
+        {
+            get
+            {
+                return captionOrientation;
+            }
+            set
+            {
+                captionOrientation = value;
+                layoutChanged = true;
+            }
+        }
+
+        /// <summary>
+        /// Apply style to DefaultLinearItemStyle.
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void ApplyStyle(ViewStyle viewStyle)
+        {
+
+            base.ApplyStyle(viewStyle);
+            if (viewStyle != null && viewStyle is DefaultGridItemStyle defaultStyle)
+            {
+                if (itemCaption != null)
+                    itemCaption.ApplyStyle(defaultStyle.Caption);
+                if (itemImage != null)
+                    itemImage.ApplyStyle(defaultStyle.Image);
+                if (itemBadge != null)
+                    itemBadge.ApplyStyle(defaultStyle.Badge);
+            }
+        }
+
+        /// <summary>
+        /// Creates Item's text part.
+        /// </summary>
+        /// <return>The created Item's text part.</return>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual TextLabel CreateLabel(TextLabelStyle textStyle)
+        {
+            return new TextLabel(textStyle)
+            {
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center
+            };
+        }
+
+        /// <summary>
+        /// Creates Item's icon part.
+        /// </summary>
+        /// <return>The created Item's icon part.</return>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual ImageView CreateImage(ImageViewStyle imageStyle)
+        {
+            return new ImageView(imageStyle);
+        }
+
+         /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void MeasureChild()
+        {
+            //nothing to do.
+            if (itemCaption)
+            {
+                var pad = Padding;
+                var margin = itemCaption.Margin;
+                itemCaption.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
+            }
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void LayoutChild()
+        {
+            if (!layoutChanged) return;
+            if (itemImage == null) return;
+
+            layoutChanged = false;
+
+            RelativeLayout.SetLeftTarget(itemImage, this);
+            RelativeLayout.SetLeftRelativeOffset(itemImage, 0.0F);
+            RelativeLayout.SetRightTarget(itemImage, this);
+            RelativeLayout.SetRightRelativeOffset(itemImage, 1.0F);
+            RelativeLayout.SetHorizontalAlignment(itemImage, RelativeLayout.Alignment.Center);
+
+            if (itemCaption != null)
+            {
+                itemCaption.RaiseAbove(itemImage);
+                RelativeLayout.SetLeftTarget(itemCaption, itemImage);
+                RelativeLayout.SetLeftRelativeOffset(itemCaption, 0.0F);
+                RelativeLayout.SetRightTarget(itemCaption, itemImage);
+                RelativeLayout.SetRightRelativeOffset(itemCaption, 1.0F);
+                RelativeLayout.SetHorizontalAlignment(itemCaption, RelativeLayout.Alignment.Center);
+                RelativeLayout.SetFillHorizontal(itemCaption, true);
+            }
+            else
+            {
+                RelativeLayout.SetTopTarget(itemImage, this);
+                RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
+                RelativeLayout.SetBottomTarget(itemImage, this);
+                RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
+                RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
+            }
+
+            if (itemBadge)
+            {
+                RelativeLayout.SetLeftTarget(itemBadge, itemImage);
+                RelativeLayout.SetLeftRelativeOffset(itemBadge, 1.0F);
+                RelativeLayout.SetRightTarget(itemBadge, itemImage);
+                RelativeLayout.SetRightRelativeOffset(itemBadge, 1.0F);
+                RelativeLayout.SetHorizontalAlignment(itemBadge, RelativeLayout.Alignment.End);
+            }
+
+            switch (captionOrientation)
+            {
+                case CaptionOrientation.OutsideBottom:
+                    if (itemCaption != null)
+                    {
+                        RelativeLayout.SetTopTarget(itemCaption, this);
+                        RelativeLayout.SetTopRelativeOffset(itemCaption, 1.0F);
+                        RelativeLayout.SetBottomTarget(itemCaption, this);
+                        RelativeLayout.SetBottomRelativeOffset(itemCaption, 1.0F);
+                        RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.End);
+
+                        RelativeLayout.SetTopTarget(itemImage, this);
+                        RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
+                        RelativeLayout.SetBottomTarget(itemImage, itemCaption);
+                        RelativeLayout.SetBottomRelativeOffset(itemImage, 0.0F);
+                        RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
+                    }
+
+                    if (itemBadge)
+                    {
+                        RelativeLayout.SetTopTarget(itemBadge, itemImage);
+                        RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
+                        RelativeLayout.SetBottomTarget(itemBadge, itemImage);
+                        RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
+                        RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
+                    }
+                    break;
+
+                case CaptionOrientation.OutsideTop:
+                    if (itemCaption != null)
+                    {
+                        RelativeLayout.SetTopTarget(itemCaption, this);
+                        RelativeLayout.SetTopRelativeOffset(itemCaption, 0.0F);
+                        RelativeLayout.SetBottomTarget(itemCaption, this);
+                        RelativeLayout.SetBottomRelativeOffset(itemCaption, 0.0F);
+                        RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.Start);
+
+                        RelativeLayout.SetTopTarget(itemImage, itemCaption);
+                        RelativeLayout.SetTopRelativeOffset(itemImage, 1.0F);
+                        RelativeLayout.SetBottomTarget(itemImage, this);
+                        RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
+                        RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
+                    }
+
+                    if (itemBadge)
+                    {
+                        RelativeLayout.SetTopTarget(itemBadge, itemImage);
+                        RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
+                        RelativeLayout.SetBottomTarget(itemBadge, itemImage);
+                        RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
+                        RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
+                    }
+                    break;
+
+                case CaptionOrientation.InsideBottom:
+                    if (itemCaption != null)
+                    {
+                        RelativeLayout.SetTopTarget(itemCaption, this);
+                        RelativeLayout.SetTopRelativeOffset(itemCaption, 1.0F);
+                        RelativeLayout.SetBottomTarget(itemCaption, this);
+                        RelativeLayout.SetBottomRelativeOffset(itemCaption, 1.0F);
+                        RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.End);
+
+                        RelativeLayout.SetTopTarget(itemImage, this);
+                        RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
+                        RelativeLayout.SetBottomTarget(itemImage, this);
+                        RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
+                        RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
+                    }
+
+                    if (itemBadge)
+                    {
+                        RelativeLayout.SetTopTarget(itemBadge, itemImage);
+                        RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
+                        RelativeLayout.SetBottomTarget(itemBadge, itemImage);
+                        RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
+                        RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
+                    }
+                    break;
+
+                case CaptionOrientation.InsideTop:
+                    if (itemCaption != null)
+                    {
+                        RelativeLayout.SetTopTarget(itemCaption, this);
+                        RelativeLayout.SetTopRelativeOffset(itemCaption, 0.0F);
+                        RelativeLayout.SetBottomTarget(itemCaption, this);
+                        RelativeLayout.SetBottomRelativeOffset(itemCaption, 0.0F);
+                        RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.Start);
+
+                        RelativeLayout.SetTopTarget(itemImage, this);
+                        RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
+                        RelativeLayout.SetBottomTarget(itemImage, this);
+                        RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
+                        RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
+                    }
+
+                    if (itemBadge)
+                    {
+                        RelativeLayout.SetTopTarget(itemBadge, itemImage);
+                        RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
+                        RelativeLayout.SetBottomTarget(itemBadge, itemImage);
+                        RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
+                        RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
+                    }
+                    break;
+            }
+
+
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        private void Initialize()
+        {
+            Layout = new RelativeLayout();
+            layoutChanged = true;
+            LayoutDirectionChanged += OnLayoutDirectionChanged;
+        }
+
+        /// <summary>
+        /// Dispose Item and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                //Extension : Extension?.OnDispose(this);
+
+                if (itemImage != null)
+                {
+                    Utility.Dispose(itemImage);
+                }
+                if (itemCaption != null)
+                {
+                    Utility.Dispose(itemCaption);
+                }
+                if (itemBadge != null)
+                {
+                    Utility.Dispose(itemBadge);
+                }
+            }
+
+            base.Dispose(type);
+        }
+
+        private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }
+        private void OnImageRelayout(object sender, EventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs
new file mode 100644 (file)
index 0000000..0e9972f
--- /dev/null
@@ -0,0 +1,565 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+using Tizen.NUI.Accessibility;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// DefaultLinearItem is one kind of common component, a DefaultLinearItem clearly describes what action will occur when the user selects it.
+    /// DefaultLinearItem may contain text or an icon.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DefaultLinearItem : RecyclerViewItem
+    {
+        private View itemIcon;
+        private TextLabel itemLabel;
+        private TextLabel itemSubLabel;
+        private View itemExtra;
+        private View itemSeperator;
+        private bool layoutChanged;
+        private Size prevSize;
+        private DefaultLinearItemStyle ItemStyle => ViewStyle as DefaultLinearItemStyle;
+
+        /// <summary>
+        /// Return a copied Style instance of DefaultLinearItem
+        /// </summary>
+        /// <remarks>
+        /// It returns copied Style instance and changing it does not effect to the DefaultLinearItem.
+        /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new DefaultLinearItemStyle Style
+        {
+            get
+            {
+                var result = new DefaultLinearItemStyle(ItemStyle);
+                result.CopyPropertiesFromView(this);
+                if (itemLabel) result.Label.CopyPropertiesFromView(itemLabel);
+                if (itemSubLabel) result.SubLabel.CopyPropertiesFromView(itemSubLabel);
+                if (itemIcon) result.Icon.CopyPropertiesFromView(itemIcon);
+                if (itemExtra) result.Extra.CopyPropertiesFromView(itemExtra);
+                if (itemSeperator) result.Seperator.CopyPropertiesFromView(itemSeperator);
+
+                return result;
+            }
+        }
+
+        static DefaultLinearItem() {}
+
+        /// <summary>
+        /// Creates a new instance of DefaultLinearItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultLinearItem() : base()
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultLinearItem with style.
+        /// </summary>
+        /// <param name="style">Create DefaultLinearItem by style defined in UX.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultLinearItem(string style) : base(style)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultLinearItem with style.
+        /// </summary>
+        /// <param name="itemStyle">Create DefaultLinearItem by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultLinearItem(DefaultLinearItemStyle itemStyle) : base(itemStyle)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Icon part of DefaultLinearItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View Icon
+        {
+            get
+            {
+                if (itemIcon == null)
+                {
+                    itemIcon = CreateIcon(ItemStyle?.Icon);
+                    if (itemIcon != null)
+                    {
+                        layoutChanged = true;
+                        Add(itemIcon);
+                        itemIcon.Relayout += OnIconRelayout;
+                    }
+                }
+                return itemIcon;
+            }
+            set
+            {
+                itemIcon = value;
+            }
+        }
+
+        /* open when imageView using Uri not string.
+        /// <summary>
+        /// Icon image's resource url. Only activatable for icon as ImageView.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string IconUrl
+        {
+            get
+            {
+                return (Icon as ImageView)?.ResourceUrl;
+            }
+            set
+            {
+                if (itemIcon != null && !(itemIcon is ImageView))
+                {
+                    // Tizen.Log.Error("IconUrl only can set Icon is ImageView");
+                    return;
+                }
+                (Icon as ImageView).ResourceUrl = value; 
+            }
+        }
+        */
+
+        /// <summary>
+        /// DefaultLinearItem's text part of DefaultLinearItem
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabel Label
+        {
+            get
+            {
+                if (itemLabel == null)
+                {
+                    itemLabel = CreateLabel(ItemStyle?.Label);
+                    if (itemLabel != null)
+                    {
+                        layoutChanged = true;
+                        Add(itemLabel);
+                    }
+                }
+                return itemLabel;
+            }
+            internal set
+            {
+                itemLabel = value;
+                AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemLabel.Text);
+            }
+        }
+
+        /// <summary>
+        /// The text of DefaultLinearItem.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        public string Text
+        {
+            get
+            {
+                return Label.Text;
+            }
+            set
+            {
+                Label.Text = value;
+            }
+        }
+
+        /// <summary>
+        /// DefaultLinearItem's secondary text part of DefaultLinearItem
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabel SubLabel
+        {
+            get
+            {
+                if (itemSubLabel == null)
+                {
+                    itemSubLabel = CreateLabel(ItemStyle?.SubLabel);
+                    if (itemLabel != null)
+                    {
+                        layoutChanged = true;
+                        Add(itemSubLabel);
+                    }
+                }
+                return itemSubLabel;
+            }
+            internal set
+            {
+                itemSubLabel = value;
+                AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemSubLabel.Text);
+            }
+        }
+
+        /// <summary>
+        /// The text of DefaultLinearItem.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        public string SubText
+        {
+            get
+            {
+                return SubLabel.Text;
+            }
+            set
+            {
+                SubLabel.Text = value;
+            }
+        }
+
+        /// <summary>
+        /// Extra icon part of DefaultLinearItem. it will place next of label.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View Extra
+        {
+            get
+            {
+                if (itemExtra == null)
+                {
+                    itemExtra = CreateIcon(ItemStyle?.Extra);
+                    if (itemExtra != null)
+                    {
+                        layoutChanged = true;
+                        Add(itemExtra);
+                        itemExtra.Relayout += OnExtraRelayout;
+                    }
+                }
+                return itemExtra;
+            }
+            set
+            {
+                if (itemExtra != null) Remove(itemExtra);
+                itemExtra = value;
+                Add(itemExtra);
+            }
+        }
+
+        /// <summary>
+        /// Seperator devider of DefaultLinearItem. it will place at the end of item.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View Seperator
+        {
+            get
+            {
+                if (itemSeperator == null)
+                {
+                    itemSeperator = new View(ItemStyle?.Seperator)
+                    {
+                        //need to consider horizontal/vertical!
+                        WidthSpecification = LayoutParamPolicies.MatchParent,
+                        HeightSpecification = 2,
+                        ExcludeLayouting = true
+                    };
+                    layoutChanged = true;
+                    Add(itemSeperator);
+                }
+                return itemSeperator;
+            }
+        }
+
+        /// <summary>
+        /// Apply style to DefaultLinearItemStyle.
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void ApplyStyle(ViewStyle viewStyle)
+        {
+
+            base.ApplyStyle(viewStyle);
+            if (viewStyle != null && viewStyle is DefaultLinearItemStyle defaultStyle)
+            {
+                if (itemLabel != null)
+                    itemLabel.ApplyStyle(defaultStyle.Label);
+                if (itemSubLabel != null)
+                    itemSubLabel.ApplyStyle(defaultStyle.SubLabel);
+                if (itemIcon != null)
+                    itemIcon.ApplyStyle(defaultStyle.Icon);
+                if (itemExtra != null)
+                    itemExtra.ApplyStyle(defaultStyle.Extra);
+                if (itemSeperator != null)
+                    itemSeperator.ApplyStyle(defaultStyle.Seperator);
+            }
+        }
+
+        /// <inheritdoc />
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void OnRelayout(Vector2 size, RelayoutContainer container)
+        {
+            base.OnRelayout(size, container);
+
+            if (prevSize != Size)
+            {
+                prevSize = Size;
+                if (itemSeperator)
+                {
+                    var margin = itemSeperator.Margin;
+                    itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
+                    itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
+                    itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom -itemSeperator.SizeHeight);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Creates Item's text part.
+        /// </summary>
+        /// <return>The created Item's text part.</return>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual TextLabel CreateLabel(TextLabelStyle style)
+        {
+            return new TextLabel(style)
+            {
+                HorizontalAlignment = HorizontalAlignment.Begin,
+                VerticalAlignment = VerticalAlignment.Center
+            };
+        }
+
+        /// <summary>
+        /// Creates Item's icon part.
+        /// </summary>
+        /// <return>The created Item's icon part.</return>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual ImageView CreateIcon(ViewStyle style)
+        {
+            return new ImageView(style);
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void MeasureChild()
+        {
+            var pad = Padding;
+            if (itemLabel)
+            {
+                var margin = itemLabel.Margin;
+                itemLabel.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
+            }
+
+            if (itemSubLabel)
+            {
+                var margin = itemSubLabel.Margin;
+                itemSubLabel.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
+            }
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void LayoutChild()
+        {
+            if (!layoutChanged) return;
+            if (itemLabel == null) return;
+
+            layoutChanged = false;
+
+            if (itemIcon != null)
+            {
+                RelativeLayout.SetLeftTarget(itemIcon, this);
+                RelativeLayout.SetLeftRelativeOffset(itemIcon, 0.0F);
+                RelativeLayout.SetRightTarget(itemIcon, this);
+                RelativeLayout.SetRightRelativeOffset(itemIcon, 0.0F);
+                RelativeLayout.SetTopTarget(itemIcon, this);
+                RelativeLayout.SetTopRelativeOffset(itemIcon, 0.0F);
+                RelativeLayout.SetBottomTarget(itemIcon, this);
+                RelativeLayout.SetBottomRelativeOffset(itemIcon, 1.0F);
+                RelativeLayout.SetVerticalAlignment(itemIcon, RelativeLayout.Alignment.Center);
+                RelativeLayout.SetHorizontalAlignment(itemIcon, RelativeLayout.Alignment.Start);
+            }
+
+            if (itemExtra != null)
+            {
+                RelativeLayout.SetLeftTarget(itemExtra, this);
+                RelativeLayout.SetLeftRelativeOffset(itemExtra, 1.0F);
+                RelativeLayout.SetRightTarget(itemExtra, this);
+                RelativeLayout.SetRightRelativeOffset(itemIcon, 1.0F);
+                RelativeLayout.SetTopTarget(itemExtra, this);
+                RelativeLayout.SetTopRelativeOffset(itemExtra, 0.0F);
+                RelativeLayout.SetBottomTarget(itemExtra, this);
+                RelativeLayout.SetBottomRelativeOffset(itemExtra, 1.0F);
+                RelativeLayout.SetVerticalAlignment(itemExtra, RelativeLayout.Alignment.Center);
+                RelativeLayout.SetHorizontalAlignment(itemExtra, RelativeLayout.Alignment.End);
+            }
+
+            if (itemSubLabel != null)
+            {
+                if (itemIcon)
+                {
+                    RelativeLayout.SetLeftTarget(itemSubLabel, itemIcon);
+                    RelativeLayout.SetLeftRelativeOffset(itemSubLabel, 1.0F);
+                }
+                else
+                {
+                    RelativeLayout.SetLeftTarget(itemSubLabel, this);
+                    RelativeLayout.SetLeftRelativeOffset(itemSubLabel, 0.0F);
+                }
+                if (itemExtra)
+                {
+                    RelativeLayout.SetRightTarget(itemSubLabel, itemExtra);
+                    RelativeLayout.SetRightRelativeOffset(itemSubLabel, 0.0F);
+                }
+                else
+                {
+                    RelativeLayout.SetRightTarget(itemSubLabel, this);
+                    RelativeLayout.SetRightRelativeOffset(itemSubLabel, 1.0F);
+                }
+
+                RelativeLayout.SetTopTarget(itemSubLabel, this);
+                RelativeLayout.SetTopRelativeOffset(itemSubLabel, 1.0F);
+                RelativeLayout.SetBottomTarget(itemSubLabel, this);
+                RelativeLayout.SetBottomRelativeOffset(itemSubLabel, 1.0F);
+                RelativeLayout.SetVerticalAlignment(itemSubLabel, RelativeLayout.Alignment.End);
+
+                RelativeLayout.SetHorizontalAlignment(itemSubLabel, RelativeLayout.Alignment.Center);
+                RelativeLayout.SetFillHorizontal(itemSubLabel, true);
+            }
+
+            if (itemIcon)
+            {
+                RelativeLayout.SetLeftTarget(itemLabel, itemIcon);
+                RelativeLayout.SetLeftRelativeOffset(itemLabel, 1.0F);
+            }
+            else
+            {
+                RelativeLayout.SetLeftTarget(itemLabel, this);
+                RelativeLayout.SetLeftRelativeOffset(itemLabel, 0.0F);
+            }
+            if (itemExtra)
+            {
+                RelativeLayout.SetRightTarget(itemLabel, itemExtra);
+                RelativeLayout.SetRightRelativeOffset(itemLabel, 0.0F);
+            }
+            else
+            {
+                RelativeLayout.SetRightTarget(itemLabel, this);
+                RelativeLayout.SetRightRelativeOffset(itemLabel, 1.0F);
+            }
+
+            RelativeLayout.SetTopTarget(itemLabel, this);
+            RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
+
+            if (itemSubLabel)
+            {
+                RelativeLayout.SetBottomTarget(itemLabel, itemSubLabel);
+                RelativeLayout.SetBottomRelativeOffset(itemLabel, 0.0F);
+            }
+            else
+            {
+                RelativeLayout.SetBottomTarget(itemLabel, this);
+                RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
+            }
+            RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetFillHorizontal(itemLabel, true);
+
+            if (prevSize != Size)
+            {
+                prevSize = Size;
+                if (itemSeperator)
+                {
+                    var margin = itemSeperator.Margin;
+                    itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
+                    itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
+                    itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom -itemSeperator.SizeHeight);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Dispose Item and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                //Extension : Extension?.OnDispose(this);
+
+                if (itemIcon != null)
+                {
+                    Utility.Dispose(itemIcon);
+                }
+                if (itemExtra != null)
+                {
+                    Utility.Dispose(itemExtra);
+                }
+                if (itemLabel != null)
+                {
+                    Utility.Dispose(itemLabel);
+                }
+                if (itemSubLabel != null)
+                {
+                    Utility.Dispose(itemSubLabel);
+                }
+                if (itemSeperator != null)
+                {
+                    Utility.Dispose(itemSeperator);
+                }
+            }
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
+        /// Get DefaultLinearItem style.
+        /// </summary>
+        /// <returns>The default DefaultLinearItem style.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override ViewStyle CreateViewStyle()
+        {
+            return new DefaultLinearItemStyle();
+        }
+
+        private void Initialize()
+        {
+            base.OnInitialize();
+            Layout = new RelativeLayout();
+            var seperator = Seperator;
+            layoutChanged = true;
+            LayoutDirectionChanged += OnLayoutDirectionChanged;
+        }
+
+        private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }
+
+        private void OnIconRelayout(object sender, EventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }
+
+        private void OnExtraRelayout(object sender, EventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }        
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultTitleItem.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultTitleItem.cs
new file mode 100644 (file)
index 0000000..432f61b
--- /dev/null
@@ -0,0 +1,409 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+using Tizen.NUI.Accessibility;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// DefaultTitleItem is one kind of common component, a DefaultTitleItem clearly describes what action will occur when the user selects it.
+    /// DefaultTitleItem may contain text or an icon.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DefaultTitleItem : RecyclerViewItem
+    {
+        private TextLabel itemLabel;
+        private View itemIcon;
+        private View itemSeperator;
+        private bool layoutChanged;
+        private Size prevSize;
+        private DefaultTitleItemStyle ItemStyle => ViewStyle as DefaultTitleItemStyle;
+
+        /// <summary>
+        /// Return a copied Style instance of DefaultTitleItem
+        /// </summary>
+        /// <remarks>
+        /// It returns copied Style instance and changing it does not effect to the DefaultTitleItem.
+        /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new DefaultTitleItemStyle Style
+        {
+            get
+            {
+                var result = new DefaultTitleItemStyle(ItemStyle);
+                result.CopyPropertiesFromView(this);
+                if (itemLabel) result.Label.CopyPropertiesFromView(itemLabel);
+                if (itemIcon) result.Icon.CopyPropertiesFromView(itemIcon);
+                if (itemSeperator) result.Seperator.CopyPropertiesFromView(itemSeperator);
+
+                return result;
+            }
+        }
+
+        static DefaultTitleItem() {}
+
+        /// <summary>
+        /// Creates a new instance of DefaultTitleItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultTitleItem() : base()
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultTitleItem with style.
+        /// </summary>
+        /// <param name="style">Create DefaultTitleItem by style defined in UX.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultTitleItem(string style) : base(style)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultTitleItem with style.
+        /// </summary>
+        /// <param name="itemStyle">Create DefaultTitleItem by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultTitleItem(DefaultTitleItemStyle itemStyle) : base(itemStyle)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Icon part of DefaultTitleItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View Icon
+        {
+            get
+            {
+                if (itemIcon == null)
+                {
+                    itemIcon = CreateIcon(ItemStyle?.Icon);
+                    if (itemIcon != null)
+                    {
+                        layoutChanged = true;
+                        Add(itemIcon);
+                        itemIcon.Relayout += OnIconRelayout;
+                    }
+                }
+                return itemIcon;
+            }
+            set
+            {
+                itemIcon = value;
+            }
+        }
+
+        /* open when imageView using Uri not string.
+        /// <summary>
+        /// Icon image's resource url. Only activatable for icon as ImageView.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string IconUrl
+        {
+            get
+            {
+                return (Icon as ImageView)?.ResourceUrl;
+            }
+            set
+            {
+                if (itemIcon != null && !(itemIcon is ImageView))
+                {
+                    // Tizen.Log.Error("IconUrl only can set Icon is ImageView");
+                    return;
+                }
+                (Icon as ImageView).ResourceUrl = value; 
+            }
+        }
+        */
+
+        /// <summary>
+        /// DefaultTitleItem's text part of DefaultTitleItem
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabel Label
+        {
+            get
+            {
+                if (itemLabel == null)
+                {
+                    itemLabel = CreateLabel(ItemStyle?.Label);
+                    if (itemLabel != null)
+                    {
+                        layoutChanged = true;
+                        Add(itemLabel);
+                    }
+                }
+                return itemLabel;
+            }
+            internal set
+            {
+                itemLabel = value;
+                AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemLabel.Text);
+            }
+        }
+
+        /// <summary>
+        /// The text of DefaultTitleItem.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        public string Text
+        {
+            get
+            {
+                return Label.Text;
+            }
+            set
+            {
+                Label.Text = value;
+            }
+        }
+
+        /// <summary>
+        /// Seperator devider of DefaultTitleItem. it will place at the end of item.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View Seperator
+        {
+            get
+            {
+                if (itemSeperator == null)
+                {
+                    itemSeperator = new View(ItemStyle?.Seperator)
+                    {
+                        //need to consider horizontal/vertical!
+                        WidthSpecification = LayoutParamPolicies.MatchParent,
+                        HeightSpecification = 2,
+                        ExcludeLayouting = true
+                    };
+                    layoutChanged = true;
+                    Add(itemSeperator);
+                }
+                return itemSeperator;
+            }
+        }
+
+        /// <summary>
+        /// Apply style to DefaultTitleItemStyle.
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void ApplyStyle(ViewStyle viewStyle)
+        {
+
+            base.ApplyStyle(viewStyle);
+            if (viewStyle != null && viewStyle is DefaultTitleItemStyle defaultStyle)
+            {
+                if (itemLabel != null)
+                    itemLabel.ApplyStyle(defaultStyle.Label);
+                if (itemIcon != null)
+                    itemIcon.ApplyStyle(defaultStyle.Icon);
+                if (itemSeperator != null)
+                    itemSeperator.ApplyStyle(defaultStyle.Seperator);
+            }
+        }
+
+        /// <inheritdoc />
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void OnRelayout(Vector2 size, RelayoutContainer container)
+        {
+            base.OnRelayout(size, container);
+
+            if (prevSize != Size)
+            {
+                prevSize = Size;
+                if (itemSeperator)
+                {
+                    var margin = itemSeperator.Margin;
+                    itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
+                    itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
+                    itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom -itemSeperator.SizeHeight);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Creates Item's text part.
+        /// </summary>
+        /// <return>The created Item's text part.</return>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual TextLabel CreateLabel(TextLabelStyle style)
+        {
+            return new TextLabel(style)
+            {
+                HorizontalAlignment = HorizontalAlignment.Begin,
+                VerticalAlignment = VerticalAlignment.Center
+            };
+        }
+
+        /// <summary>
+        /// Creates Item's icon part.
+        /// </summary>
+        /// <return>The created Item's icon part.</return>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual ImageView CreateIcon(ViewStyle style)
+        {
+            return new ImageView(style);
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void MeasureChild()
+        {
+            if (itemLabel)
+            {
+                var pad = Padding;
+                var margin = itemLabel.Margin;
+                itemLabel.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
+            }
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void LayoutChild()
+        {
+            if (!layoutChanged) return;
+            if (itemLabel == null) return;
+
+            layoutChanged = false;
+
+            if (itemIcon != null)
+            {
+                RelativeLayout.SetLeftTarget(itemIcon, this);
+                RelativeLayout.SetLeftRelativeOffset(itemIcon, 1.0F);
+                RelativeLayout.SetRightTarget(itemIcon, this);
+                RelativeLayout.SetRightRelativeOffset(itemIcon, 1.0F);
+                RelativeLayout.SetTopTarget(itemIcon, this);
+                RelativeLayout.SetTopRelativeOffset(itemIcon, 0.0F);
+                RelativeLayout.SetBottomTarget(itemIcon, this);
+                RelativeLayout.SetBottomRelativeOffset(itemIcon, 1.0F);
+                RelativeLayout.SetVerticalAlignment(itemIcon, RelativeLayout.Alignment.Center);
+                RelativeLayout.SetHorizontalAlignment(itemIcon, RelativeLayout.Alignment.End);
+            }
+
+            RelativeLayout.SetLeftTarget(itemLabel, this);
+            RelativeLayout.SetLeftRelativeOffset(itemLabel, 0.0F);
+            if (itemIcon)
+            {
+                RelativeLayout.SetRightTarget(itemLabel, itemIcon);
+                RelativeLayout.SetRightRelativeOffset(itemLabel, 0.0F);
+            }
+            else
+            {
+                RelativeLayout.SetRightTarget(itemLabel, this);
+                RelativeLayout.SetRightRelativeOffset(itemLabel, 1.0F);
+            }
+
+            RelativeLayout.SetTopTarget(itemLabel, this);
+            RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
+            RelativeLayout.SetBottomTarget(itemLabel, this);
+            RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
+            RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
+            RelativeLayout.SetFillHorizontal(itemLabel, true);
+
+            if (prevSize != Size)
+            {
+                prevSize = Size;
+                if (itemSeperator)
+                {
+                    var margin = itemSeperator.Margin;
+                    itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
+                    itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
+                    itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom -itemSeperator.SizeHeight);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Dispose Item and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                //Extension : Extension?.OnDispose(this);
+
+                if (itemIcon != null)
+                {
+                    Utility.Dispose(itemIcon);
+                }
+                if (itemLabel != null)
+                {
+                    Utility.Dispose(itemLabel);
+                }
+                if (itemSeperator != null)
+                {
+                    Utility.Dispose(itemSeperator);
+                }
+            }
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
+        /// Get DefaultTitleItem style.
+        /// </summary>
+        /// <returns>The default DefaultTitleItem style.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override ViewStyle CreateViewStyle()
+        {
+            return new DefaultTitleItemStyle();
+        }
+
+        private void Initialize()
+        {
+            base.OnInitialize();
+            Layout = new RelativeLayout();
+            var seperator = Seperator;
+            layoutChanged = true;
+            LayoutDirectionChanged += OnLayoutDirectionChanged;
+        }
+
+        private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }
+
+        private void OnIconRelayout(object sender, EventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }
+
+        private void OnExtraRelayout(object sender, EventArgs e)
+        {
+            MeasureChild();
+            LayoutChild();
+        }        
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Item/RecyclerViewItem.Internal.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Item/RecyclerViewItem.Internal.cs
new file mode 100644 (file)
index 0000000..980dca2
--- /dev/null
@@ -0,0 +1,280 @@
+using System;
+using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components.Extension;
+using Tizen.NUI.Accessibility; // To use AccessibilityManager
+
+namespace Tizen.NUI.Components
+{
+    public partial class RecyclerViewItem
+    {
+        internal RecyclerView ParentItemsView = null;
+        internal object ParentGroup = null;
+        internal bool isGroupHeader;
+        internal bool isGroupFooter;
+        private bool styleApplied = false;
+
+        /// <summary>
+        /// Update ViewItem State.
+        /// </summary>
+        internal void UpdateState()
+        {
+            if (!styleApplied) return;
+
+            ControlState sourceState = ControlState;
+            ControlState targetState;
+
+            // Normal, Disabled
+            targetState = IsEnabled ? ControlState.Normal : ControlState.Disabled;
+
+            // Selected, DisabledSelected
+            if (IsSelected) targetState += ControlState.Selected;
+
+            // Pressed, PressedSelected
+            if (IsPressed) targetState += ControlState.Pressed;
+
+            // Focused, FocusedPressed, FocusedPressedSelected, DisabledFocused, DisabledSelectedFocused
+            if (IsFocused) targetState += ControlState.Focused;
+
+            if (sourceState != targetState)
+            {
+                ControlState = targetState;
+                OnUpdate();
+            }
+        }
+
+        internal override bool OnAccessibilityActivated()
+        {
+            if (!IsEnabled)
+            {
+                return false;
+            }
+
+            // Touch Down
+            IsPressed = true;
+            UpdateState();
+
+            // Touch Up
+            bool clicked = IsPressed && IsEnabled;
+            IsPressed = false;
+
+            if (IsSelectable)
+            {
+                //IsSelected = !IsSelected;
+            }
+            else
+            {
+                UpdateState();
+            }
+
+            if (clicked)
+            {
+                ClickedEventArgs eventArgs = new ClickedEventArgs();
+                OnClickedInternal(eventArgs);
+            }
+            return true;
+        }
+
+        /// <summary>
+        /// Called when the ViewItem is Clicked by a user
+        /// </summary>
+        /// <param name="eventArgs">The click information.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void OnClicked(ClickedEventArgs eventArgs)
+        {
+            //Console.WriteLine("On Clicked Called {0}", this.Index);
+        }
+
+        /// <summary>
+        /// Called when the ViewItem need to be updated
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void OnUpdate()
+        {
+            base.OnUpdate();
+            UpdateContent();
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override bool HandleControlStateOnTouch(Touch touch)
+        {
+            if (!IsEnabled || null == touch)
+            {
+                return false;
+            }
+
+            PointStateType state = touch.GetState(0);
+
+            switch (state)
+            {
+                case PointStateType.Down:
+                    IsPressed = true;
+                    UpdateState();
+                    return true;
+                case PointStateType.Interrupted:
+                    IsPressed = false;
+                    UpdateState();
+                    return true;
+                case PointStateType.Up:
+                    {
+                        bool clicked = IsPressed && IsEnabled;
+                        IsPressed = false;
+
+                        if (!clicked) return true;
+
+                        if (IsSelectable)
+                        {
+                            if (ParentItemsView as CollectionView)
+                            {
+                                CollectionView colView = ParentItemsView as CollectionView;
+                                switch (colView.SelectionMode)
+                                {
+                                    case ItemSelectionMode.SingleSelection :
+                                        colView.SelectedItem = IsSelected ? null : BindingContext;
+                                        break;
+                                    case ItemSelectionMode.MultipleSelections :
+                                        var selectedItems = colView.SelectedItems;
+                                        if (selectedItems.Contains(BindingContext)) selectedItems.Remove(BindingContext);
+                                        else selectedItems.Add(BindingContext);
+                                        break;
+                                    case ItemSelectionMode.None :
+                                        break;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            // Extension : Extension?.SetTouchInfo(touch);
+                            UpdateState();
+                        }
+
+                        if (clicked)
+                        {
+                            ClickedEventArgs eventArgs = new ClickedEventArgs();
+                            OnClickedInternal(eventArgs);
+                        }
+
+                        return true;
+                    }
+                default:
+                    break;
+            }
+            return base.HandleControlStateOnTouch(touch);
+        }
+
+
+        /// <summary>
+        /// Measure child, it can be override.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void MeasureChild()
+        {
+        }
+
+        /// <summary>
+        /// Layout child, it can be override.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void LayoutChild()
+        {
+        }
+
+        /// <summary>
+        /// Dispose Item and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                //
+            }
+
+            base.Dispose(type);
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
+        {
+            if (controlStateChangedInfo == null) throw new ArgumentNullException(nameof(controlStateChangedInfo));
+            base.OnControlStateChanged(controlStateChangedInfo);
+
+            var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled);
+
+            if (IsEnabled != stateEnabled)
+            {
+                IsEnabled = stateEnabled;
+            }
+
+            var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed);
+
+            if (IsPressed != statePressed)
+            {
+                IsPressed = statePressed;
+            }
+        }
+
+        /// <summary>
+        /// Get ViewItem style.
+        /// </summary>
+        /// <returns>The default ViewItem style.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override ViewStyle CreateViewStyle()
+        {
+            return new RecyclerViewItemStyle();
+        }
+
+        /// <summary>
+        /// It is hijack by using protected, style copy problem when class inherited from Button.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        private void Initialize()
+        {
+            //FIXME!
+            IsCreateByXaml = true;
+            Layout = new AbsoluteLayout();
+            UpdateState();
+
+            AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "ViewItem");
+        }
+
+        /// <summary>
+        /// Update the Content. it can be override.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void UpdateContent()
+        {
+            MeasureChild();
+            LayoutChild();
+
+            Sensitive = IsEnabled;
+        }
+
+
+        /// FIXME!! This has to be done in Element or View class.
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void OnBindingContextChanged()
+        {
+            foreach (View child in Children)
+            {
+                SetChildInheritedBindingContext(child, BindingContext);
+            }
+        }
+
+        private void OnClickedInternal(ClickedEventArgs eventArgs)
+        {
+            Command?.Execute(CommandParameter);
+            OnClicked(eventArgs);
+
+            Clicked?.Invoke(this, eventArgs);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Item/RecyclerViewItem.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Item/RecyclerViewItem.cs
new file mode 100644 (file)
index 0000000..5f3e882
--- /dev/null
@@ -0,0 +1,328 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+using Tizen.NUI.Accessibility;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// This class provides a basic item for CollectionView.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public partial class RecyclerViewItem : Control
+    {
+        /// <summary>
+        /// Property of boolean Enable flag.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(RecyclerViewItem), true, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (RecyclerViewItem)bindable;
+            if (newValue != null)
+            {
+                bool newEnabled = (bool)newValue;
+                if (instance.isEnabled != newEnabled)
+                {
+                    instance.isEnabled = newEnabled;
+                    if (instance.ItemStyle != null)
+                    {
+                        instance.ItemStyle.IsEnabled = newEnabled;
+                    }
+                    instance.UpdateState();
+                }
+            }
+        },
+        defaultValueCreator: (bindable) => ((RecyclerViewItem)bindable).isEnabled);
+
+        /// <summary>
+        /// Property of boolean Selected flag.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(RecyclerViewItem), true, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (RecyclerViewItem)bindable;
+            if (newValue != null)
+            {
+                bool newSelected = (bool)newValue;
+                if (instance.isSelected != newSelected)
+                {
+                    instance.isSelected = newSelected;
+
+                    if (instance.ItemStyle != null)
+                    {
+                        instance.ItemStyle.IsSelected = newSelected;
+                    }
+
+                    if (instance.isSelectable)
+                    {
+                        instance.UpdateState();
+                    }
+                }
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var instance = (RecyclerViewItem)bindable;
+            return instance.isSelectable && instance.isSelected;
+        });
+
+        /// <summary>
+        /// Property of boolean Selectable flag.
+        /// </summary>      
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(RecyclerViewItem), true, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (RecyclerViewItem)bindable;
+            if (newValue != null)
+            {
+                bool newSelectable = (bool)newValue;
+                if (instance.isSelectable != newSelectable)
+                {
+                    instance.isSelectable = newSelectable;
+
+                    if (instance.ItemStyle != null)
+                    {
+                        instance.ItemStyle.IsSelectable = newSelectable;
+                    }
+
+                    instance.UpdateState();
+                }
+            }
+        },
+        defaultValueCreator: (bindable) => ((RecyclerViewItem)bindable).isSelectable);
+
+        private bool isSelected = false;
+        private bool isSelectable = true;
+        private bool isEnabled = true;
+        private RecyclerViewItemStyle ItemStyle => ViewStyle as RecyclerViewItemStyle;
+
+        /// <summary>
+        /// Return a copied Style instance of Toast
+        /// </summary>
+        /// <remarks>
+        /// It returns copied Style instance and changing it does not effect to the Toast.
+        /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new RecyclerViewItemStyle Style
+        {
+            get
+            {
+                var result = new RecyclerViewItemStyle(ItemStyle);
+                result.CopyPropertiesFromView(this);
+                return result;
+            }
+        }
+
+        static RecyclerViewItem() {}
+
+        /// <summary>
+        /// Creates a new instance of RecyclerViewItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecyclerViewItem() : base()
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of RecyclerViewItem with style.
+        /// </summary>
+        /// <param name="style">Create RecyclerViewItem by special style defined in UX.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecyclerViewItem(string style) : base(style)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of a RecyclerViewItem with style.
+        /// </summary>
+        /// <param name="itemStyle">Create RecyclerViewItem by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecyclerViewItem(RecyclerViewItemStyle itemStyle) : base(itemStyle)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// An event for the RecyclerViewItem clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<ClickedEventArgs> Clicked;
+
+        /// <summary>
+        /// Flag to decide RecyclerViewItem can be selected or not.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsSelectable
+        {
+            get => (bool)GetValue(IsSelectableProperty);
+            set => SetValue(IsSelectableProperty, value);
+        }
+
+        /// <summary>
+        /// Flag to decide selected state in RecyclerViewItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsSelected
+        {
+            get => (bool)GetValue(IsSelectedProperty);
+            set => SetValue(IsSelectedProperty, value);
+        }
+
+        /// <summary>
+        /// Flag to decide enable or disable in RecyclerViewItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsEnabled
+        {
+            get =>  (bool)GetValue(IsEnabledProperty);
+            set =>  SetValue(IsEnabledProperty, value);
+        }
+
+        /// <summary>
+        /// Data index which is binded to item.
+        /// Can access to data using this index.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Index { get; internal set; } = 0;
+
+        /// <summary>
+        /// DataTemplate of this view object
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DataTemplate Template { get; internal set; }
+
+        /// <summary>
+        /// State of Realization
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsRealized { get; internal set; }
+        internal bool IsHeader { get; set; }
+        internal bool IsFooter { get; set; }
+        internal bool IsPressed  { get; set; } = false;
+
+        /// <summary>
+        /// Called after a key event is received by the view that has had its focus set.
+        /// </summary>
+        /// <param name="key">The key event.</param>
+        /// <returns>True if the key event should be consumed.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override bool OnKey(Key key)
+        {
+            if (!IsEnabled || null == key)
+            {
+                return false;
+            }
+
+            if (key.State == Key.StateType.Down)
+            {
+                if (key.KeyPressedName == "Return")
+                {
+                    IsPressed = true;
+                    UpdateState();
+                }
+            }
+            else if (key.State == Key.StateType.Up)
+            {
+                if (key.KeyPressedName == "Return")
+                {
+                    bool clicked = IsPressed && IsEnabled;
+
+                    IsPressed = false;
+
+                    if (IsSelectable)
+                    {
+                        // Extension : Extension?.SetTouchInfo(touch);
+                        if (ParentItemsView as CollectionView)
+                        {
+                            CollectionView colView = ParentItemsView as CollectionView;
+                            switch (colView.SelectionMode)
+                            {
+                                case ItemSelectionMode.SingleSelection :
+                                    colView.SelectedItem = IsSelected ? null : BindingContext;
+                                    break;
+                                case ItemSelectionMode.MultipleSelections :
+                                    var selectedItems = colView.SelectedItems;
+                                    if (selectedItems.Contains(BindingContext)) selectedItems.Remove(BindingContext);
+                                    else selectedItems.Add(BindingContext);
+                                    break;
+                                case ItemSelectionMode.None :
+                                    break;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        UpdateState();
+                    }
+
+                    if (clicked)
+                    {
+                        ClickedEventArgs eventArgs = new ClickedEventArgs();
+                        OnClickedInternal(eventArgs);
+                    }
+                }
+            }
+            return base.OnKey(key);
+        }
+
+        /// <summary>
+        /// Called when the control gain key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is gained.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void OnFocusGained()
+        {
+            base.OnFocusGained();
+            UpdateState();
+        }
+
+        /// <summary>
+        /// Called when the control loses key input focus. 
+        /// Should be overridden by derived classes if they need to customize
+        /// what happens when the focus is lost.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void OnFocusLost()
+        {
+            base.OnFocusLost();
+            UpdateState();
+        }
+
+        /// <summary>
+        /// Apply style to RecyclerViewItem.
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void ApplyStyle(ViewStyle viewStyle)
+        {
+            styleApplied = false;
+
+            base.ApplyStyle(viewStyle);
+            if (viewStyle != null)
+            {
+                //Extension = RecyclerViewItemStyle.CreateExtension();
+            }
+
+            styleApplied = true;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSelectionMode.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSelectionMode.cs
new file mode 100644 (file)
index 0000000..3156bf2
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// Selection mode of CollecitonView.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum ItemSelectionMode
+    {
+        /// <summary>
+        /// None of item can be selected.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        None,
+        /// <summary>
+        /// Single selection. select item exculsively so previous selected item will be unselected.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        SingleSelection,
+        /// <summary>
+        /// Multiple selections. select multiple items and previous selected item still remains selected.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        MultipleSelections
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSizingStrategy.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSizingStrategy.cs
new file mode 100644 (file)
index 0000000..006da23
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// Size calculation strategy for CollectionView.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum ItemSizingStrategy
+    {
+
+        /// <summary>
+        /// Measure all items in advanced.
+        /// Estimate first item size for all, and when scroll reached position,
+        /// measure strictly. Note : This will make scroll bar trembling.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        MeasureAll,
+        /// <summary>
+        /// Measure first item and deligate size for all items.
+        /// if template is selector, the size of first item from each template will be deligated.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        MeasureFirst,
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/EmptySource.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/EmptySource.cs
new file mode 100644 (file)
index 0000000..d348b00
--- /dev/null
@@ -0,0 +1,63 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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;
+
+namespace Tizen.NUI.Components
+{
+    internal sealed class EmptySource : IItemSource
+    {
+        public int Count => 0;
+
+        public bool HasHeader { get; set; }
+        public bool HasFooter { get; set; }
+
+        public void Dispose()
+        {
+
+        }
+
+        public bool IsHeader(int index)
+        {
+            return HasHeader && index == 0;
+        }
+
+        public bool IsFooter(int index)
+        {
+            if (!HasFooter)
+            {
+                return false;
+            }
+
+            if (HasHeader)
+            {
+                return index == 1;
+            }
+
+            return index == 0;
+        }
+
+        public int GetPosition(object item)
+        {
+            return -1;
+        }
+
+        public object GetItem(int position)
+        {
+            throw new IndexOutOfRangeException("IItemSource is empty");
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/IItemSource.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/IItemSource.cs
new file mode 100644 (file)
index 0000000..4a4d86b
--- /dev/null
@@ -0,0 +1,105 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// Base interface for encapsulated data source in RecyclerView.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public interface IItemSource : IDisposable
+    {
+        /// <summary>
+        /// Count of data source.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        int Count { get; }
+
+        /// <summary>
+        /// Position integer value of data object.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        int GetPosition(object item);
+
+        /// <summary>
+        /// Item object in position.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        object GetItem(int position);
+
+        /// <summary>
+        /// Flag of header existence.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        bool HasHeader { get; set; }
+
+        /// <summary>
+        /// Flag of Footer existence.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        bool HasFooter { get; set; }
+
+        /// <summary>
+        /// Boolean checker for position is header or not.
+        /// 0 index will be header if header exist.
+        /// warning: if header exist, all item index will be increased.
+        /// </summary>
+        /// <param name="position">The position for checking header.</param>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        bool IsHeader(int position);
+
+        /// <summary>
+        /// Boolean checker for position is footer or not.
+        /// last index will be footer if footer exist.
+        /// warning: footer will be place original data count or data count + 1.
+        /// </summary>
+        /// <param name="position">The position for checking footer.</param>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        bool IsFooter(int position);
+    }
+
+    /// <summary>
+    /// Base interface for encapsulated data source with group structure in CollectionView.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public interface IGroupableItemSource : IItemSource
+    {
+        /// <summary>
+        /// Boolean checker for position is group header or not
+        /// </summary>
+        /// <param name="position">The position for checking group header.</param>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        bool IsGroupHeader(int position);
+
+        /// <summary>
+        /// Boolean checker for position is group footer or not
+        /// </summary>
+        /// <param name="position">The position for checking group footer.</param>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        bool IsGroupFooter(int position);
+
+        /// <summary>
+        /// Boolean checker for position is group footer or not
+        /// </summary>
+        /// <param name="position">The position for checking group footer.</param>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        object GetGroupParent(int position);
+
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ItemsSourceFactory.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ItemsSourceFactory.cs
new file mode 100644 (file)
index 0000000..f3df899
--- /dev/null
@@ -0,0 +1,62 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+//using AndroidX.RecyclerView.Widget; ??? need to find whot it needs? adapter?
+
+namespace Tizen.NUI.Components
+{
+    internal static class ItemsSourceFactory
+    {
+        public static IItemSource Create(IEnumerable itemsSource, ICollectionChangedNotifier notifier)
+        {
+            if (itemsSource == null)
+            {
+                return new EmptySource();
+            }
+
+            switch (itemsSource)
+            {
+                case IList list when itemsSource is INotifyCollectionChanged:
+                    return new ObservableItemSource(new MarshalingObservableCollection(list), notifier);
+                case IEnumerable _ when itemsSource is INotifyCollectionChanged:
+                    return new ObservableItemSource(itemsSource, notifier);
+                case IEnumerable<object> generic:
+                    return new ListSource(generic);
+            }
+
+            return new ListSource(itemsSource);
+        }
+
+        public static IItemSource Create(RecyclerView recyclerView)
+        {
+            return Create(recyclerView.ItemsSource, recyclerView);
+        }
+
+        public static IGroupableItemSource Create(CollectionView colView)
+        {
+            var source = colView.ItemsSource;
+
+            if (colView.IsGrouped && source != null)
+                return new ObservableGroupedSource(colView, colView);
+
+            else
+                return new UngroupedItemSource(Create(colView.ItemsSource, colView));
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ListSource.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ListSource.cs
new file mode 100644 (file)
index 0000000..41835ad
--- /dev/null
@@ -0,0 +1,154 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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;
+using System.Collections.Generic;
+
+namespace Tizen.NUI.Components
+{
+    sealed class ListSource : IItemSource, IList
+    {
+        IList _itemsSource;
+
+        public ListSource()
+        {
+        }
+
+        public ListSource(IEnumerable<object> enumerable)
+        {
+            _itemsSource = new List<object>(enumerable);
+        }
+
+        public ListSource(IEnumerable enumerable)
+        {
+            _itemsSource = new List<object>();
+
+            if (enumerable == null)
+                return;
+
+            foreach (object item in enumerable)
+            {
+                _itemsSource.Add(item);
+            }
+        }
+
+        public int Count => _itemsSource.Count + (HasHeader ? 1 : 0) + (HasFooter ? 1 : 0);
+
+        public bool HasHeader { get; set; }
+        public bool HasFooter { get; set; }
+
+        public bool IsReadOnly => _itemsSource.IsReadOnly;
+
+        public bool IsFixedSize => _itemsSource.IsFixedSize;
+
+        public object SyncRoot => _itemsSource.SyncRoot;
+
+        public bool IsSynchronized => _itemsSource.IsSynchronized;
+
+        object IList.this[int index] { get => _itemsSource[index]; set => _itemsSource[index] = value; }
+
+        public void Dispose()
+        {
+
+        }
+
+        public bool IsFooter(int index)
+        {
+            return HasFooter && index == Count - 1;
+        }
+
+        public bool IsHeader(int index)
+        {
+            return HasHeader && index == 0;
+        }
+
+        public int GetPosition(object item)
+        {
+            for (int n = 0; n < _itemsSource.Count; n++)
+            {
+                var elementByIndex = _itemsSource[n];
+                var isEqual = elementByIndex == item || (elementByIndex != null && item != null && elementByIndex.Equals(item));
+
+                if (isEqual)
+                {
+                    return AdjustPosition(n);
+                }
+            }
+
+            return -1;
+        }
+
+        public object GetItem(int position)
+        {
+            return _itemsSource[AdjustIndexRequest(position)];
+        }
+
+        int AdjustIndexRequest(int index)
+        {
+            return index - (HasHeader ? 1 : 0);
+        }
+
+        int AdjustPosition(int index)
+        {
+            return index + (HasHeader ? 1 : 0);
+        }
+        public int Add(object value)
+        {
+            return _itemsSource.Add(value);
+        }
+
+        public bool Contains(object value)
+        {
+            return _itemsSource.Contains(value);
+        }
+
+        public void Clear()
+        {
+            _itemsSource.Clear();
+        }
+
+        public int IndexOf(object value)
+        {
+            return _itemsSource.IndexOf(value);
+        }
+
+        public void Insert(int index, object value)
+        {
+            _itemsSource.Insert(index, value);
+        }
+
+        public void Remove(object value)
+        {
+            _itemsSource.Remove(value);
+        }
+
+        public void RemoveAt(int index)
+        {
+            _itemsSource.RemoveAt(index);
+        }
+
+        public void CopyTo(Array array, int index)
+        {
+            _itemsSource.CopyTo(array, index);
+        }
+
+        public IEnumerator GetEnumerator()
+        {
+            return _itemsSource.GetEnumerator();
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/MarshalingObservableCollection.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/MarshalingObservableCollection.cs
new file mode 100644 (file)
index 0000000..92fac69
--- /dev/null
@@ -0,0 +1,176 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace Tizen.NUI.Components
+{
+    // Wraps a List which implements INotifyCollectionChanged (usually an ObservableCollection)
+    // and marshals all of the list modifications to the main thread. Modifications to the underlying 
+    // collection which are made off of the main thread remain invisible to consumers on the main thread
+    // until they have been processed by the main thread.
+
+    internal class MarshalingObservableCollection : List<object>, INotifyCollectionChanged
+    {
+        readonly IList internalCollection;
+
+        public MarshalingObservableCollection(IList list)
+        {
+            if (!(list is INotifyCollectionChanged incc))
+            {
+                throw new ArgumentException($"{nameof(list)} must implement {nameof(INotifyCollectionChanged)}");
+            }
+
+            internalCollection = list;
+            incc.CollectionChanged += InternalCollectionChanged;
+
+            foreach (var item in internalCollection)
+            {
+                Add(item);
+            }
+        }
+
+        class ResetNotifyCollectionChangedEventArgs : NotifyCollectionChangedEventArgs
+        {
+            public IList Items { get; }
+            public ResetNotifyCollectionChangedEventArgs(IList items)
+                : base(NotifyCollectionChangedAction.Reset) => Items = items;
+        }
+
+        public event NotifyCollectionChangedEventHandler CollectionChanged;
+
+        void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
+        {
+            CollectionChanged?.Invoke(this, args);
+        }
+
+        void InternalCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
+        {
+            if (args.Action == NotifyCollectionChangedAction.Reset)
+            {
+                var items = new List<object>();
+                for (int n = 0; n < internalCollection.Count; n++)
+                {
+                    items.Add(internalCollection[n]);
+                }
+
+                args = new ResetNotifyCollectionChangedEventArgs(items);
+            }
+/*
+            if (Device.IsInvokeRequired)
+            {
+                Device.BeginInvokeOnMainThread(() => HandleCollectionChange(args));
+            }
+            else
+            {
+                HandleCollectionChange(args);
+            }
+*/
+
+            HandleCollectionChange(args);
+        }
+
+        void HandleCollectionChange(NotifyCollectionChangedEventArgs args)
+        {
+            switch (args.Action)
+            {
+                case NotifyCollectionChangedAction.Add:
+                    Add(args);
+                    break;
+                case NotifyCollectionChangedAction.Move:
+                    Move(args);
+                    break;
+                case NotifyCollectionChangedAction.Remove:
+                    Remove(args);
+                    break;
+                case NotifyCollectionChangedAction.Replace:
+                    Replace(args);
+                    break;
+                case NotifyCollectionChangedAction.Reset:
+                    Reset(args);
+                    break;
+            }
+        }
+
+        void Move(NotifyCollectionChangedEventArgs args)
+        {
+            var count = args.OldItems.Count;
+
+            for (int n = 0; n < count; n++)
+            {
+                var toMove = this[args.OldStartingIndex];
+                RemoveAt(args.OldStartingIndex);
+                Insert(args.NewStartingIndex, toMove);
+            }
+
+            OnCollectionChanged(args);
+        }
+
+        void Remove(NotifyCollectionChangedEventArgs args)
+        {
+            var startIndex = args.OldStartingIndex + args.OldItems.Count - 1;
+            for (int n = startIndex; n >= args.OldStartingIndex; n--)
+            {
+                RemoveAt(n);
+            }
+
+            OnCollectionChanged(args);
+        }
+
+        void Replace(NotifyCollectionChangedEventArgs args)
+        {
+            var startIndex = args.NewStartingIndex;
+            foreach (var item in args.NewItems)
+            {
+                this[startIndex] = item;
+                startIndex += 1;
+            }
+
+            OnCollectionChanged(args);
+        }
+
+        void Add(NotifyCollectionChangedEventArgs args)
+        {
+            var startIndex = args.NewStartingIndex;
+            foreach (var item in args.NewItems)
+            {
+                Insert(startIndex, item);
+                startIndex += 1;
+            }
+
+            OnCollectionChanged(args);
+        }
+
+        void Reset(NotifyCollectionChangedEventArgs args)
+        {
+            if (!(args is ResetNotifyCollectionChangedEventArgs resetArgs))
+            {
+                throw new InvalidOperationException($"Cannot guarantee collection accuracy for Resets which do not use {nameof(ResetNotifyCollectionChangedEventArgs)}");
+            }
+
+            Clear();
+            foreach (var item in resetArgs.Items)
+            {
+                Add(item);
+            }
+
+            OnCollectionChanged(args);
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ObservableGroupedSource.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ObservableGroupedSource.cs
new file mode 100644 (file)
index 0000000..0602f87
--- /dev/null
@@ -0,0 +1,466 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace Tizen.NUI.Components
+{
+    internal class ObservableGroupedSource : IGroupableItemSource, ICollectionChangedNotifier
+    {
+        readonly ICollectionChangedNotifier notifier;
+        readonly IList groupSource;
+        readonly List<IItemSource> groups = new List<IItemSource>();
+        readonly bool hasGroupHeaders;
+        readonly bool hasGroupFooters;
+        bool disposed;
+
+        public int Count
+        {
+            get
+            {
+                var groupContents = 0;
+
+                for (int n = 0; n < groups.Count; n++)
+                {
+                    groupContents += groups[n].Count;
+                }
+
+                return (HasHeader ? 1 : 0)
+                     + (HasFooter ? 1 : 0)
+                     + groupContents;
+            }
+        }
+
+        public bool HasHeader { get; set; }
+        public bool HasFooter { get; set; }
+
+        public ObservableGroupedSource(CollectionView colView, ICollectionChangedNotifier changedNotifier)
+        {
+            var source = colView.ItemsSource;
+
+            notifier = changedNotifier;
+            groupSource = source as IList ?? new ListSource(source);
+
+            hasGroupFooters = colView.GroupFooterTemplate != null;
+            hasGroupHeaders = colView.GroupHeaderTemplate != null;
+            HasHeader = colView.Header != null;
+            HasFooter = colView.Footer != null;
+
+            if (groupSource is INotifyCollectionChanged incc)
+            {
+                incc.CollectionChanged += CollectionChanged;
+            }
+
+            UpdateGroupTracking();
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        public bool IsFooter(int position)
+        {
+            if (!HasFooter)
+            {
+                return false;
+            }
+
+            return position == Count - 1;
+        }
+
+        public bool IsHeader(int position)
+        {
+            return HasHeader && position == 0;
+        }
+
+        public bool IsGroupHeader(int position)
+        {
+            if (IsFooter(position) || IsHeader(position))
+            {
+                return false;
+            }
+
+            var (group, inGroup) = GetGroupAndIndex(position);
+
+            return groups[group].IsHeader(inGroup);
+        }
+
+        public bool IsGroupFooter(int position)
+        {
+            if (IsFooter(position) || IsHeader(position))
+            {
+                return false;
+            }
+
+            var (group, inGroup) = GetGroupAndIndex(position);
+
+            return groups[group].IsFooter(inGroup);
+        }
+
+        public int GetPosition(object item)
+        {
+            int previousGroupsOffset = 0;
+
+            for (int groupIndex = 0; groupIndex < groupSource.Count; groupIndex++)
+            {
+                if (groupSource[groupIndex].Equals(item))
+                {
+                    return AdjustPositionForHeader(groupIndex);
+                }
+
+                var group = groups[groupIndex];
+                var inGroup = group.GetPosition(item);
+
+                if (inGroup > -1)
+                {
+                    return AdjustPositionForHeader(previousGroupsOffset + inGroup);
+                }
+
+                previousGroupsOffset += group.Count;
+            }
+
+            return -1;
+        }
+
+        public object GetItem(int position)
+        {
+            var (group, inGroup) = GetGroupAndIndex(position);
+
+            if (IsGroupFooter(position) || IsGroupHeader(position))
+            {
+                // This is looping to find the group/index twice, need to make it less inefficient
+                return groupSource[group];
+            }
+
+            return groups[group].GetItem(inGroup);
+        }
+
+        public object GetGroupParent(int position)
+        {
+            var (group, inGroup) = GetGroupAndIndex(position);
+            return groupSource[group];
+        }
+
+        // The ICollectionChangedNotifier methods are called by child observable items sources (i.e., the groups)
+        // This class can then translate their local changes into global positions for upstream notification 
+        // (e.g., to the actual RecyclerView.Adapter, so that it can notify the RecyclerView and handle animating
+        // the changes)
+        public void NotifyDataSetChanged()
+        {
+            Reload();
+        }
+
+        public void NotifyItemChanged(IItemSource group, int localIndex)
+        {
+            localIndex = GetAbsolutePosition(group, localIndex);
+            notifier.NotifyItemChanged(this, localIndex);
+        }
+
+        public void NotifyItemInserted(IItemSource group, int localIndex)
+        {
+            localIndex = GetAbsolutePosition(group, localIndex);
+            notifier.NotifyItemInserted(this, localIndex);
+        }
+
+        public void NotifyItemMoved(IItemSource group, int localFromIndex, int localToIndex)
+        {
+            localFromIndex = GetAbsolutePosition(group, localFromIndex);
+            localToIndex = GetAbsolutePosition(group, localToIndex);
+            notifier.NotifyItemMoved(this, localFromIndex, localToIndex);
+        }
+
+        public void NotifyItemRangeChanged(IItemSource group, int localStartIndex, int localEndIndex)
+        {
+            localStartIndex = GetAbsolutePosition(group, localStartIndex);
+            localEndIndex = GetAbsolutePosition(group, localEndIndex);
+            notifier.NotifyItemRangeChanged(this, localStartIndex, localEndIndex);
+        }
+
+        public void NotifyItemRangeInserted(IItemSource group, int localIndex, int count)
+        {
+            localIndex = GetAbsolutePosition(group, localIndex);
+            notifier.NotifyItemRangeInserted(this, localIndex, count);
+        }
+
+        public void NotifyItemRangeRemoved(IItemSource group, int localIndex, int count)
+        {
+            localIndex = GetAbsolutePosition(group, localIndex);
+            notifier.NotifyItemRangeRemoved(this, localIndex, count);
+        }
+
+        public void NotifyItemRemoved(IItemSource group, int localIndex)
+        {
+            localIndex = GetAbsolutePosition(group, localIndex);
+            notifier.NotifyItemRemoved(this, localIndex);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+           disposed = true;
+
+            if (disposing)
+            {
+                ClearGroupTracking();
+
+                if (groupSource is INotifyCollectionChanged notifyCollectionChanged)
+                {
+                    notifyCollectionChanged.CollectionChanged -= CollectionChanged;
+                }
+                if (groupSource is IDisposable dispoableSource) dispoableSource.Dispose();
+            }
+        }
+
+        void UpdateGroupTracking()
+        {
+            ClearGroupTracking();
+
+            for (int n = 0; n < groupSource.Count; n++)
+            {
+                var source = ItemsSourceFactory.Create(groupSource[n] as IEnumerable, this);
+                source.HasFooter = hasGroupFooters;
+                source.HasHeader = hasGroupHeaders;
+                groups.Add(source);
+            }
+        }
+
+        void ClearGroupTracking()
+        {
+            for (int n = groups.Count - 1; n >= 0; n--)
+            {
+                groups[n].Dispose();
+                groups.RemoveAt(n);
+            }
+        }
+
+        void CollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
+        {/*
+            if (Device.IsInvokeRequired)
+            {
+                Device.BeginInvokeOnMainThread(() => CollectionChanged(args));
+            }
+            else
+            {
+                */
+                CollectionChanged(args);
+            //}
+        }
+
+        void CollectionChanged(NotifyCollectionChangedEventArgs args)
+        {
+            switch (args.Action)
+            {
+                case NotifyCollectionChangedAction.Add:
+                    Add(args);
+                    break;
+                case NotifyCollectionChangedAction.Remove:
+                    Remove(args);
+                    break;
+                case NotifyCollectionChangedAction.Replace:
+                    Replace(args);
+                    break;
+                case NotifyCollectionChangedAction.Move:
+                    Move(args);
+                    break;
+                case NotifyCollectionChangedAction.Reset:
+                    Reload();
+                    break;
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(args));
+            }
+        }
+
+        void Reload()
+        {
+            UpdateGroupTracking();
+            notifier.NotifyDataSetChanged();
+        }
+
+        void Add(NotifyCollectionChangedEventArgs args)
+        {
+            var groupIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : groupSource.IndexOf(args.NewItems[0]);
+            var groupCount = args.NewItems.Count;
+
+            UpdateGroupTracking();
+
+            // Determine the absolute starting position and the number of items in the groups being added
+            var absolutePosition = GetAbsolutePosition(groups[groupIndex], 0);
+            var itemCount = CountItemsInGroups(groupIndex, groupCount);
+
+            if (itemCount == 1)
+            {
+                notifier.NotifyItemInserted(this, absolutePosition);
+                return;
+            }
+
+            notifier.NotifyItemRangeInserted(this, absolutePosition, itemCount);
+        }
+
+        void Remove(NotifyCollectionChangedEventArgs args)
+        {
+            var groupIndex = args.OldStartingIndex;
+
+            if (groupIndex < 0)
+            {
+                // INCC implementation isn't giving us enough information to know where the removed groups was in the
+                // collection. So the best we can do is a full reload.
+                Reload();
+                return;
+            }
+
+            // If we have a start index, we can be more clever about removing the group(s) (and get the nifty animations)
+            var groupCount = args.OldItems.Count;
+
+            var absolutePosition = GetAbsolutePosition(groups[groupIndex], 0);
+
+            // Figure out how many items are in the groups we're removing
+            var itemCount = CountItemsInGroups(groupIndex, groupCount);
+
+            if (itemCount == 1)
+            {
+                notifier.NotifyItemRemoved(this, absolutePosition);
+
+                UpdateGroupTracking();
+
+                return;
+            }
+
+            notifier.NotifyItemRangeRemoved(this, absolutePosition, itemCount);
+
+            UpdateGroupTracking();
+        }
+
+        void Replace(NotifyCollectionChangedEventArgs args)
+        {
+            var groupCount = args.NewItems.Count;
+
+            if (groupCount != args.OldItems.Count)
+            {
+                // The original and replacement sets are of unequal size; this means that most everything currently in 
+                // view will have to be updated. So just reload the whole thing.
+                Reload();
+                return;
+            }
+
+            var newStartIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : groupSource.IndexOf(args.NewItems[0]);
+            var oldStartIndex = args.OldStartingIndex > -1 ? args.OldStartingIndex : groupSource.IndexOf(args.OldItems[0]);
+
+            var newItemCount = CountItemsInGroups(newStartIndex, groupCount);
+            var oldItemCount = CountItemsInGroups(oldStartIndex, groupCount);
+
+            if (newItemCount != oldItemCount)
+            {
+                // The original and replacement sets are of unequal size; this means that most everything currently in 
+                // view will have to be updated. So just reload the whole thing.
+                Reload();
+                return;
+            }
+
+            // We are replacing one set of items with a set of equal size; we can do a simple item or range notification 
+            var firstGroupIndex = Math.Min(newStartIndex, oldStartIndex);
+            var absolutePosition = GetAbsolutePosition(groups[firstGroupIndex], 0);
+
+            if (newItemCount == 1)
+            {
+                notifier.NotifyItemChanged(this, absolutePosition);
+                UpdateGroupTracking();
+            }
+            else
+            {
+                notifier.NotifyItemRangeChanged(this, absolutePosition, newItemCount * 2);
+                UpdateGroupTracking();
+            }
+        }
+
+        void Move(NotifyCollectionChangedEventArgs args)
+        {
+            var start = Math.Min(args.OldStartingIndex, args.NewStartingIndex);
+            var end = Math.Max(args.OldStartingIndex, args.NewStartingIndex) + args.NewItems.Count;
+
+            var itemCount = CountItemsInGroups(start, end - start);
+            var absolutePosition = GetAbsolutePosition(groups[start], 0);
+
+            notifier.NotifyItemRangeChanged(this, absolutePosition, itemCount);
+
+            UpdateGroupTracking();
+        }
+
+        int GetAbsolutePosition(IItemSource group, int indexInGroup)
+        {
+            var groupIndex = groups.IndexOf(group);
+
+            var runningIndex = 0;
+
+            for (int n = 0; n < groupIndex; n++)
+            {
+                runningIndex += groups[n].Count;
+            }
+
+            return AdjustPositionForHeader(runningIndex + indexInGroup);
+        }
+
+        (int, int) GetGroupAndIndex(int absolutePosition)
+        {
+            absolutePosition = AdjustIndexForHeader(absolutePosition);
+
+            var group = 0;
+            var localIndex = 0;
+
+            while (absolutePosition > 0)
+            {
+                localIndex += 1;
+
+                if (localIndex == groups[group].Count)
+                {
+                    group += 1;
+                    localIndex = 0;
+                }
+
+                absolutePosition -= 1;
+            }
+
+            return (group, localIndex);
+        }
+
+        int AdjustIndexForHeader(int index)
+        {
+            return index - (HasHeader ? 1 : 0);
+        }
+
+        int AdjustPositionForHeader(int position)
+        {
+            return position + (HasHeader ? 1 : 0);
+        }
+
+        int CountItemsInGroups(int groupStartIndex, int groupCount)
+        {
+            var itemCount = 0;
+            for (int n = 0; n < groupCount; n++)
+            {
+                itemCount += groups[groupStartIndex + n].Count;
+            }
+            return itemCount;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ObservableItemSource.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/ObservableItemSource.cs
new file mode 100644 (file)
index 0000000..f5581a4
--- /dev/null
@@ -0,0 +1,271 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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;
+using System.Collections.Specialized;
+
+namespace Tizen.NUI.Components
+{
+    internal class ObservableItemSource : IItemSource
+    {
+        readonly IEnumerable itemsSource;
+        readonly ICollectionChangedNotifier notifier;
+        bool disposed;
+
+        public ObservableItemSource(IEnumerable itemSource, ICollectionChangedNotifier changedNotifier)
+        {
+            itemsSource = itemSource as IList ?? itemSource as IEnumerable;
+            notifier = changedNotifier;
+
+            ((INotifyCollectionChanged)itemSource).CollectionChanged += CollectionChanged;
+        }
+
+
+        internal event NotifyCollectionChangedEventHandler CollectionItemsSourceChanged;
+
+        public int Count => ItemsCount() + (HasHeader ? 1 : 0) + (HasFooter ? 1 : 0);
+
+        public bool HasHeader { get; set; }
+        public bool HasFooter { get; set; }
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        public bool IsFooter(int index)
+        {
+            return HasFooter && index == Count - 1;
+        }
+
+        public bool IsHeader(int index)
+        {
+            return HasHeader && index == 0;
+        }
+
+        public int GetPosition(object item)
+        {
+            for (int n = 0; n < ItemsCount(); n++)
+            {
+                var elementByIndex = ElementAt(n);
+                var isEqual = elementByIndex == item || (elementByIndex != null && item != null && elementByIndex.Equals(item));
+
+                if (isEqual)
+                {
+                    return AdjustPositionForHeader(n);
+                }
+            }
+
+            return -1;
+        }
+
+        public object GetItem(int position)
+        {
+            return ElementAt(AdjustIndexForHeader(position));
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            disposed = true;
+
+            if (disposing)
+            {
+                ((INotifyCollectionChanged)itemsSource).CollectionChanged -= CollectionChanged;
+            }
+        }
+
+        int AdjustIndexForHeader(int index)
+        {
+            return index - (HasHeader ? 1 : 0);
+        }
+
+        int AdjustPositionForHeader(int position)
+        {
+            return position + (HasHeader ? 1 : 0);
+        }
+
+        void CollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
+        {/*
+            if (Device.IsInvokeRequired)
+            {
+                Device.BeginInvokeOnMainThread(() => CollectionChanged(args));
+            }
+            else
+            {*/
+                CollectionChanged(args);
+            //}
+
+        }
+
+        void CollectionChanged(NotifyCollectionChangedEventArgs args)
+        {
+            switch (args.Action)
+            {
+                case NotifyCollectionChangedAction.Add:
+                    Add(args);
+                    break;
+                case NotifyCollectionChangedAction.Remove:
+                    Remove(args);
+                    break;
+                case NotifyCollectionChangedAction.Replace:
+                    Replace(args);
+                    break;
+                case NotifyCollectionChangedAction.Move:
+                    Move(args);
+                    break;
+                case NotifyCollectionChangedAction.Reset:
+                    notifier.NotifyDataSetChanged();
+                    break;
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(args));
+            }
+            CollectionItemsSourceChanged?.Invoke(this, args);
+        }
+
+        void Move(NotifyCollectionChangedEventArgs args)
+        {
+            var count = args.NewItems.Count;
+
+            if (count == 1)
+            {
+                // For a single item, we can use NotifyItemMoved and get the animation
+                notifier.NotifyItemMoved(this, AdjustPositionForHeader(args.OldStartingIndex), AdjustPositionForHeader(args.NewStartingIndex));
+                return;
+            }
+
+            var start = AdjustPositionForHeader(Math.Min(args.OldStartingIndex, args.NewStartingIndex));
+            var end = AdjustPositionForHeader(Math.Max(args.OldStartingIndex, args.NewStartingIndex) + count);
+            notifier.NotifyItemRangeChanged(this, start, end);
+        }
+
+        void Add(NotifyCollectionChangedEventArgs args)
+        {
+            var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
+            startIndex = AdjustPositionForHeader(startIndex);
+            var count = args.NewItems.Count;
+
+            if (count == 1)
+            {
+                notifier.NotifyItemInserted(this, startIndex);
+                return;
+            }
+
+            notifier.NotifyItemRangeInserted(this, startIndex, count);
+        }
+
+        void Remove(NotifyCollectionChangedEventArgs args)
+        {
+            var startIndex = args.OldStartingIndex;
+
+            if (startIndex < 0)
+            {
+                // INCC implementation isn't giving us enough information to know where the removed items were in the
+                // collection. So the best we can do is a NotifyDataSetChanged()
+                notifier.NotifyDataSetChanged();
+                return;
+            }
+
+            startIndex = AdjustPositionForHeader(startIndex);
+
+            // If we have a start index, we can be more clever about removing the item(s) (and get the nifty animations)
+            var count = args.OldItems.Count;
+
+            if (count == 1)
+            {
+                notifier.NotifyItemRemoved(this, startIndex);
+                return;
+            }
+
+            notifier.NotifyItemRangeRemoved(this, startIndex, count);
+        }
+
+        void Replace(NotifyCollectionChangedEventArgs args)
+        {
+            var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : IndexOf(args.NewItems[0]);
+            startIndex = AdjustPositionForHeader(startIndex);
+            var newCount = args.NewItems.Count;
+
+            if (newCount == args.OldItems.Count)
+            {
+                // We are replacing one set of items with a set of equal size; we can do a simple item or range 
+                // notification to the adapter
+                if (newCount == 1)
+                {
+                    notifier.NotifyItemChanged(this, startIndex);
+                }
+                else
+                {
+                    notifier.NotifyItemRangeChanged(this, startIndex, newCount);
+                }
+
+                return;
+            }
+
+            // The original and replacement sets are of unequal size; this means that everything currently in view will 
+            // have to be updated. So we just have to use NotifyDataSetChanged and let the RecyclerView update everything
+            notifier.NotifyDataSetChanged();
+        }
+
+        internal int ItemsCount()
+        {
+            if (itemsSource is IList list)
+                return list.Count;
+
+            int count = 0;
+            foreach (var item in itemsSource)
+                count++;
+            return count;
+        }
+
+        internal object ElementAt(int index)
+        {
+            if (itemsSource is IList list)
+                return list[index];
+
+            int count = 0;
+            foreach (var item in itemsSource)
+            {
+                if (count == index)
+                    return item;
+                count++;
+            }
+
+            return -1;
+        }
+
+        internal int IndexOf(object item)
+        {
+            if (itemsSource is IList list)
+                return list.IndexOf(item);
+
+            int count = 0;
+            foreach (var i in itemsSource)
+            {
+                if (i == item)
+                    return count;
+                count++;
+            }
+
+            return -1;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/UngroupedItemSource.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/ItemSource/UngroupedItemSource.cs
new file mode 100644 (file)
index 0000000..32f0340
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI.Components
+{
+    internal class UngroupedItemSource : IGroupableItemSource
+    {
+        readonly IItemSource source;
+
+        public UngroupedItemSource(IItemSource itemSource)
+        {
+            source = itemSource;
+        }
+
+        public int Count => source.Count;
+
+        public bool HasHeader { get => source.HasHeader; set => source.HasHeader = value; }
+        public bool HasFooter { get => source.HasFooter; set => source.HasFooter = value; }
+
+        public void Dispose()
+        {
+            source.Dispose();
+        }
+
+        public object GetItem(int position)
+        {
+            return source.GetItem(position);
+        }
+
+        public int GetPosition(object item)
+        {
+            return source.GetPosition(item);
+        }
+
+        public bool IsFooter(int position)
+        {
+            return source.IsFooter(position);
+        }
+
+        public bool IsGroupFooter(int position)
+        {
+            return false;
+        }
+
+        public bool IsGroupHeader(int position)
+        {
+            return false;
+        }
+
+        public bool IsHeader(int position)
+        {
+            return source.IsHeader(position);
+        }
+
+        public object GetGroupParent(int position)
+        {
+            return null;
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/GridLayouter.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/GridLayouter.cs
new file mode 100644 (file)
index 0000000..7e98751
--- /dev/null
@@ -0,0 +1,724 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI.BaseComponents;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// This class implements a grid box layout.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class GridLayouter : ItemsLayouter
+    {
+        private CollectionView colView;
+        private Size2D sizeCandidate;
+        private int spanSize = 1;
+        private float align = 0.5f;
+        private bool hasHeader;
+        private float headerSize;
+        private bool hasFooter;
+        private float footerSize;
+        private bool isGrouped;
+        private readonly List<GroupInfo> groups = new List<GroupInfo>();
+        private float groupHeaderSize;
+        private float groupFooterSize;
+        private GroupInfo Visited;
+
+        /// <summary>
+        /// Clean up ItemsLayouter.
+        /// </summary>
+        /// <param name="view"> ItemsView of layouter. </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void Initialize(RecyclerView view)
+        {
+            colView = view as CollectionView;
+            if (colView == null)
+            {
+                throw new ArgumentException("GridLayouter only can be applied CollectionView.", nameof(view));
+            }
+
+            // 1. Clean Up
+            foreach (RecyclerViewItem item in VisibleItems)
+            {
+                colView.UnrealizeItem(item, false);
+            }
+            VisibleItems.Clear();
+            groups.Clear();
+
+            FirstVisible = 0;
+            LastVisible = 0;
+
+            IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
+
+            RecyclerViewItem header = colView?.Header;
+            RecyclerViewItem footer = colView?.Footer;
+            float width, height;
+            int count = colView.InternalItemSource.Count;
+            int pureCount = count - (header ? 1 : 0) - (footer ? 1 : 0);
+
+            // 2. Get the header / footer and size deligated item and measure the size.
+            if (header != null)
+            {
+                MeasureChild(colView, header);
+
+                width = header.Layout != null ? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = header.Layout != null ? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+
+                headerSize = IsHorizontal ? width : height;
+                hasHeader = true;
+
+                colView.UnrealizeItem(header);
+            }
+
+            if (footer != null)
+            {
+                MeasureChild(colView, footer);
+
+                width = footer.Layout != null ? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = footer.Layout != null ? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+
+                footerSize = IsHorizontal ? width : height;
+                footer.Index = count - 1;
+                hasFooter = true;
+
+                colView.UnrealizeItem(footer);
+            }
+
+            int firstIndex = header ? 1 : 0;
+
+            if (colView.IsGrouped)
+            {
+                isGrouped = true;
+
+                if (colView.GroupHeaderTemplate != null)
+                {
+                    while (!colView.InternalItemSource.IsGroupHeader(firstIndex)) firstIndex++;
+                    //must be always true
+                    if (colView.InternalItemSource.IsGroupHeader(firstIndex))
+                    {
+                        RecyclerViewItem groupHeader = colView.RealizeItem(firstIndex);
+                        firstIndex++;
+
+                        if (groupHeader == null) throw new Exception("[" + firstIndex + "] Group Header failed to realize!");
+
+                        // Need to Set proper hieght or width on scroll direciton.
+                        if (groupHeader.Layout == null)
+                        {
+                            width = groupHeader.WidthSpecification;
+                            height = groupHeader.HeightSpecification;
+                        }
+                        else
+                        {
+                            MeasureChild(colView, groupHeader);
+
+                            width = groupHeader.Layout.MeasuredWidth.Size.AsRoundedValue();
+                            height = groupHeader.Layout.MeasuredHeight.Size.AsRoundedValue();
+                        }
+                        //Console.WriteLine("[NUI] GroupHeader Size {0} :{0}", width, height);
+                        // pick the StepCandidate.
+                        groupHeaderSize = IsHorizontal ? width : height;
+                        colView.UnrealizeItem(groupHeader);
+                    }
+                }
+                else
+                {
+                    groupHeaderSize = 0F;
+                }
+
+                if (colView.GroupFooterTemplate != null)
+                {
+                    int firstFooter = firstIndex;
+                    while (!colView.InternalItemSource.IsGroupFooter(firstFooter)) firstFooter++;
+                    //must be always true
+                    if (colView.InternalItemSource.IsGroupFooter(firstFooter))
+                    {
+                        RecyclerViewItem groupFooter = colView.RealizeItem(firstFooter);
+
+                        if (groupFooter == null) throw new Exception("[" + firstFooter + "] Group Footer failed to realize!");
+                        // Need to Set proper hieght or width on scroll direciton.
+                        if (groupFooter.Layout == null)
+                        {
+                            width = groupFooter.WidthSpecification;
+                            height = groupFooter.HeightSpecification;
+                        }
+                        else
+                        {
+                            MeasureChild(colView, groupFooter);
+
+                            width = groupFooter.Layout.MeasuredWidth.Size.AsRoundedValue();
+                            height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
+                        }
+                        // pick the StepCandidate.
+                        groupFooterSize = IsHorizontal ? width : height;
+
+                        colView.UnrealizeItem(groupFooter);
+                    }
+                }
+                else
+                {
+                    groupFooterSize = 0F;
+                }
+            }
+            else isGrouped = false;
+
+            bool failed = false;
+            //Final Check of FirstIndex
+            while (colView.InternalItemSource.IsHeader(firstIndex) ||
+                    colView.InternalItemSource.IsGroupHeader(firstIndex) ||
+                    colView.InternalItemSource.IsGroupFooter(firstIndex))
+            {
+                if (colView.InternalItemSource.IsFooter(firstIndex))
+                {
+                    StepCandidate = 0F;
+                    failed = true;
+                    break;
+                }
+                firstIndex++;
+            }
+
+            sizeCandidate = new Size2D(0, 0);
+            if (!failed)
+            {
+                // Get Size Deligate. FIXME if group exist index must be changed.
+                RecyclerViewItem sizeDeligate = colView.RealizeItem(firstIndex);
+                if (sizeDeligate == null)
+                {
+                    throw new Exception("Cannot create content from DatTemplate.");
+                }
+                sizeDeligate.BindingContext = colView.InternalItemSource.GetItem(firstIndex);
+
+                // Need to Set proper hieght or width on scroll direciton.
+                if (sizeDeligate.Layout == null)
+                {
+                    width = sizeDeligate.WidthSpecification;
+                    height = sizeDeligate.HeightSpecification;
+                }
+                else
+                {
+                    MeasureChild(colView, sizeDeligate);
+
+                    width = sizeDeligate.Layout.MeasuredWidth.Size.AsRoundedValue();
+                    height = sizeDeligate.Layout.MeasuredHeight.Size.AsRoundedValue();
+                }
+                //Console.WriteLine("[NUI] item Size {0} :{1}", width, height);
+
+                // pick the StepCandidate.
+                StepCandidate = IsHorizontal ? width : height;
+                spanSize = IsHorizontal ? Convert.ToInt32(Math.Truncate((double)(colView.Size.Height / height))) :
+                                        Convert.ToInt32(Math.Truncate((double)(colView.Size.Width / width)));
+
+                sizeCandidate = new Size2D(Convert.ToInt32(width), Convert.ToInt32(height));
+
+                colView.UnrealizeItem(sizeDeligate);
+            }
+
+            if (StepCandidate < 1) StepCandidate = 1;
+            if (spanSize < 1) spanSize = 1;
+
+            if (isGrouped)
+            {
+                float Current = 0.0F;
+                IGroupableItemSource source = colView.InternalItemSource;
+                GroupInfo currentGroup = null;
+
+                for (int i = 0; i < count; i++)
+                {
+                    if (i == 0 && hasHeader)
+                    {
+                        Current += headerSize;
+                    }
+                    else if (i == count - 1 && hasFooter)
+                    {
+                        Current += footerSize;
+                    }
+                    else
+                    {
+                        //GroupHeader must always exist in group usage.
+                        if (source.IsGroupHeader(i))
+                        {
+                            currentGroup = new GroupInfo()
+                            {
+                                GroupParent = source.GetGroupParent(i),
+                                StartIndex = i,
+                                Count = 1,
+                                GroupSize = groupHeaderSize,
+                                GroupPosition = Current
+                            };
+                            groups.Add(currentGroup);
+                            Current += groupHeaderSize;
+                        }
+                        //optional
+                        else if (source.IsGroupFooter(i))
+                        {
+                            //currentGroup.hasFooter = true;
+                            currentGroup.Count++;
+                            currentGroup.GroupSize += groupFooterSize;
+                            Current += groupFooterSize;
+                        }
+                        else
+                        {
+                            currentGroup.Count++;
+                            int index = i - currentGroup.StartIndex - 1; // groupHeader must always exist.
+                            if ((index % spanSize) == 0)
+                            {
+                                currentGroup.GroupSize += StepCandidate;
+                                Current += StepCandidate;
+                            }
+                        }
+                    }
+                }
+                ScrollContentSize = Current;
+            }
+            else
+            {
+                // 3. Measure the scroller content size.
+                ScrollContentSize = StepCandidate * Convert.ToInt32(Math.Ceiling((double)pureCount / (double)spanSize));
+                if (hasHeader) ScrollContentSize += headerSize;
+                if (hasFooter) ScrollContentSize += footerSize;
+            }
+
+            if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
+            else colView.ContentContainer.SizeHeight = ScrollContentSize;
+
+            base.Initialize(colView);
+            //Console.WriteLine("Init Done, StepCnadidate{0}, spanSize{1}, Scroll{2}", StepCandidate, spanSize, ScrollContentSize);
+        }
+
+        /// <summary>
+        /// This is called to find out where items are lain out according to current scroll position.
+        /// </summary>
+        /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
+        /// <param name="force">boolean force flag to layouting forcely.</param>
+        public override void RequestLayout(float scrollPosition, bool force = false)
+        {
+            // Layouting is only possible after once it intialized.
+            if (!IsInitialized) return;
+            int LastIndex = colView.InternalItemSource.Count;
+
+            if (!force && PrevScrollPosition == Math.Abs(scrollPosition)) return;
+            PrevScrollPosition = Math.Abs(scrollPosition);
+
+            int prevFirstVisible = FirstVisible;
+            int prevLastVisible = LastVisible;
+            bool IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
+
+            (float X, float Y) visibleArea = (PrevScrollPosition,
+                PrevScrollPosition + (IsHorizontal ? colView.Size.Width : colView.Size.Height)
+            );
+
+            //Console.WriteLine("[NUI] itemsView [{0},{1}] [{2},{3}]", colView.Size.Width, colView.Size.Height, colView.ContentContainer.Size.Width, colView.ContentContainer.Size.Height);
+
+            // 1. Set First/Last Visible Item Index. 
+            (int start, int end) = FindVisibleItems(visibleArea);
+            FirstVisible = start;
+            LastVisible = end;
+
+            //Console.WriteLine("[NUI] {0} :visibleArea before [{1},{2}] after [{3},{4}]", scrollPosition, prevFirstVisible, prevLastVisible, FirstVisible, LastVisible);
+
+            // 2. Unrealize invisible items.
+            List<RecyclerViewItem> unrealizedItems = new List<RecyclerViewItem>();
+            foreach (RecyclerViewItem item in VisibleItems)
+            {
+                if (item.Index < FirstVisible || item.Index > LastVisible)
+                {
+                    //Console.WriteLine("[NUI] Unrealize{0}!", item.Index);
+                    unrealizedItems.Add(item);
+                    colView.UnrealizeItem(item);
+                }
+            }
+            VisibleItems.RemoveAll(unrealizedItems.Contains);
+
+            //Console.WriteLine("Realize Begin [{0} to {1}]", FirstVisible, LastVisible);
+            // 3. Realize and placing visible items.
+            for (int i = FirstVisible; i <= LastVisible; i++)
+            {
+                //Console.WriteLine("[NUI] Realize!");
+                RecyclerViewItem item = null;
+                // 4. Get item if visible or realize new.
+                if (i >= prevFirstVisible && i <= prevLastVisible)
+                {
+                    item = GetVisibleItem(i);
+                    if (item) continue;
+                }
+                if (item == null) item = colView.RealizeItem(i);
+                VisibleItems.Add(item);
+
+                (float x, float y) = GetItemPosition(i);
+                // 5. Placing item.
+                item.Position = new Position(x, y);
+                //Console.WriteLine("[NUI] ["+item.Index+"] ["+item.Position.X+", "+item.Position.Y+" ==== \n");
+            }
+            //Console.WriteLine("Realize Done");
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override (float X, float Y) GetItemPosition(object item)
+        {
+            if (item == null) throw new ArgumentNullException(nameof(item));
+            if (colView == null) return (0, 0);
+
+            return GetItemPosition(colView.InternalItemSource.GetPosition(item));
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override (float X, float Y) GetItemSize(object item)
+        {
+            if (item == null) throw new ArgumentNullException(nameof(item));
+            if (sizeCandidate == null) return (0, 0);
+
+            if (isGrouped)
+            {
+                int index = colView.InternalItemSource.GetPosition(item);
+                float view = (IsHorizontal ? colView.Size.Height : colView.Size.Width);
+
+                if (colView.InternalItemSource.IsGroupHeader(index))
+                {
+                    return (IsHorizontal ? (groupHeaderSize, view) : (view, groupHeaderSize));
+                }
+                else if (colView.InternalItemSource.IsGroupFooter(index))
+                {
+                    return (IsHorizontal ? (groupFooterSize, view) : (view, groupFooterSize));
+                }
+            }
+
+            return (sizeCandidate.Width, sizeCandidate.Height);
+        }
+
+        /// <inheritdoc/>
+        public override void NotifyItemSizeChanged(RecyclerViewItem item)
+        {
+            // All Item size need to be same in grid!
+            // if you want to change item size, change dataTemplate to re-initing.
+            return;
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override float CalculateLayoutOrientationSize()
+        {
+            //Console.WriteLine("[NUI] Calculate Layout ScrollContentSize {0}", ScrollContentSize);
+            return ScrollContentSize;
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override float CalculateCandidateScrollPosition(float scrollPosition)
+        {
+            //Console.WriteLine("[NUI] Calculate Candidate ScrollContentSize {0}", ScrollContentSize);
+            return scrollPosition;
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override View RequestNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+        {
+            if (currentFocusedView == null)
+                throw new ArgumentNullException(nameof(currentFocusedView));
+
+            View nextFocusedView = null;
+            int targetSibling = -1;
+            bool IsHorizontal = colView.ScrollingDirection == ScrollableBase.Direction.Horizontal;
+
+            switch (direction)
+            {
+                case View.FocusDirection.Left:
+                    {
+                        targetSibling = IsHorizontal ? currentFocusedView.SiblingOrder - 1 : targetSibling;
+                        break;
+                    }
+                case View.FocusDirection.Right:
+                    {
+                        targetSibling = IsHorizontal ? currentFocusedView.SiblingOrder + 1 : targetSibling;
+                        break;
+                    }
+                case View.FocusDirection.Up:
+                    {
+                        targetSibling = IsHorizontal ? targetSibling : currentFocusedView.SiblingOrder - 1;
+                        break;
+                    }
+                case View.FocusDirection.Down:
+                    {
+                        targetSibling = IsHorizontal ? targetSibling : currentFocusedView.SiblingOrder + 1;
+                        break;
+                    }
+            }
+
+            if (targetSibling > -1 && targetSibling < Container.Children.Count)
+            {
+                RecyclerViewItem candidate = Container.Children[targetSibling] as RecyclerViewItem;
+                if (candidate.Index >= 0 && candidate.Index < colView.InternalItemSource.Count)
+                {
+                    nextFocusedView = candidate;
+                }
+            }
+            return nextFocusedView;
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override (int start, int end) FindVisibleItems((float X, float Y) visibleArea)
+        {
+            int MaxIndex = colView.InternalItemSource.Count - 1 - (hasFooter ? 1 : 0);
+            int adds = spanSize * 2;
+            int skipGroup = -1;
+            (int start, int end) found = (0, 0);
+
+            // Header is Showing
+            if (hasHeader && visibleArea.X < headerSize)
+            {
+                found.start = 0;
+            }
+            else
+            {
+                if (isGrouped)
+                {
+                    bool failed = true;
+                    foreach (GroupInfo gInfo in groups)
+                    {
+                        skipGroup++;
+                        // in the Group
+                        if (gInfo.GroupPosition <= visibleArea.X &&
+                            gInfo.GroupPosition + gInfo.GroupSize >= visibleArea.X)
+                        {
+                            if (gInfo.GroupPosition + groupHeaderSize >= visibleArea.X)
+                            {
+                                found.start = gInfo.StartIndex - adds;
+                                failed = false;
+                            }
+                            //can be step in spanSize...
+                            for (int i = 1; i < gInfo.Count; i++)
+                            {
+                                if (!failed) break;
+                                // Reach last index of group.
+                                if (i == (gInfo.Count - 1))
+                                {
+                                    found.start = gInfo.StartIndex + i - adds;
+                                    failed = false;
+                                    break;
+
+                                }
+                                else if ((((i - 1) / spanSize) * StepCandidate) + StepCandidate >= visibleArea.X - gInfo.GroupPosition - groupHeaderSize)
+                                {
+                                    found.start = gInfo.StartIndex + i - adds;
+                                    failed = false;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    //footer only shows?
+                    if (failed)
+                    {
+                        found.start = MaxIndex;
+                    }
+                }
+                else
+                {
+                    float visibleAreaX = visibleArea.X - (hasHeader ? headerSize : 0);
+                    found.start = (Convert.ToInt32(Math.Abs(visibleAreaX / StepCandidate)) - 1) * spanSize;
+                    if (hasHeader) found.start += 1;
+                }
+                if (found.start < 0) found.start = 0;
+            }
+
+            if (hasFooter && visibleArea.Y > ScrollContentSize - footerSize)
+            {
+                found.end = MaxIndex + 1;
+            }
+            else
+            {
+                if (isGrouped)
+                {
+                    bool failed = true;
+                    // can it be start from founded group...?
+                    //foreach(GroupInfo gInfo in groups.Skip(skipGroup))
+                    foreach (GroupInfo gInfo in groups)
+                    {
+                        // in the Group
+                        if (gInfo.GroupPosition <= visibleArea.Y &&
+                            gInfo.GroupPosition + gInfo.GroupSize >= visibleArea.Y)
+                        {
+                            if (gInfo.GroupPosition + groupHeaderSize >= visibleArea.Y)
+                            {
+                                found.end = gInfo.StartIndex + adds;
+                                failed = false;
+                            }
+                            //can be step in spanSize...
+                            for (int i = 1; i < gInfo.Count; i++)
+                            {
+                                if (!failed) break;
+                                // Reach last index of group.
+                                if (i == (gInfo.Count - 1))
+                                {
+                                    found.end = gInfo.StartIndex + i + adds;
+                                    failed = false;
+                                    break;
+                                }
+                                else if ((((i - 1) / spanSize) * StepCandidate) + StepCandidate >= visibleArea.Y - gInfo.GroupPosition - groupHeaderSize)
+                                {
+                                    found.end = gInfo.StartIndex + i + adds;
+                                    failed = false;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    //footer only shows?
+                    if (failed)
+                    {
+                        found.start = MaxIndex;
+                    }
+                }
+                else
+                {
+                    float visibleAreaY = visibleArea.Y - (hasHeader ? headerSize : 0);
+                    //Need to Consider GroupHeight!!!!
+                    found.end = (Convert.ToInt32(Math.Abs(visibleAreaY / StepCandidate)) + 1) * spanSize + adds;
+                    if (hasHeader) found.end += 1;
+                }
+                if (found.end > (MaxIndex)) found.end = MaxIndex;
+            }
+            return found;
+        }
+
+        private (float X, float Y) GetItemPosition(int index)
+        {
+            float xPos, yPos;
+            if (sizeCandidate == null) return (0, 0);
+
+            if (hasHeader && index == 0)
+            {
+                return (0, 0);
+            }
+            if (hasFooter && index == colView.InternalItemSource.Count - 1)
+            {
+                xPos = IsHorizontal ? ScrollContentSize - footerSize : 0;
+                yPos = IsHorizontal ? 0 : ScrollContentSize - footerSize;
+                return (xPos, yPos);
+            }
+            if (isGrouped)
+            {
+                GroupInfo myGroup = GetGroupInfo(index);
+                if (colView.InternalItemSource.IsGroupHeader(index))
+                {
+                    xPos = IsHorizontal ? myGroup.GroupPosition : 0;
+                    yPos = IsHorizontal ? 0 : myGroup.GroupPosition;
+                }
+                else if (colView.InternalItemSource.IsGroupFooter(index))
+                {
+                    xPos = IsHorizontal ? myGroup.GroupPosition + myGroup.GroupSize - groupFooterSize : 0;
+                    yPos = IsHorizontal ? 0 : myGroup.GroupPosition + myGroup.GroupSize - groupFooterSize;
+                }
+                else
+                {
+                    int pureIndex = index - myGroup.StartIndex - 1;
+                    int division = pureIndex / spanSize;
+                    int remainder = pureIndex % spanSize;
+                    int emptyArea = IsHorizontal ? (int)(colView.Size.Height - (sizeCandidate.Height * spanSize)) :
+                                                    (int)(colView.Size.Width - (sizeCandidate.Width * spanSize));
+                    if (division < 0) division = 0;
+                    if (remainder < 0) remainder = 0;
+
+                    xPos = IsHorizontal ? division * sizeCandidate.Width + myGroup.GroupPosition + groupHeaderSize : emptyArea * align + remainder * sizeCandidate.Width;
+                    yPos = IsHorizontal ? emptyArea * align + remainder * sizeCandidate.Height : division * sizeCandidate.Height + myGroup.GroupPosition + groupHeaderSize;
+                }
+            }
+            else
+            {
+                int pureIndex = index - (colView.Header ? 1 : 0);
+                // int convert must be truncate value.
+                int division = pureIndex / spanSize;
+                int remainder = pureIndex % spanSize;
+                int emptyArea = IsHorizontal ? (int)(colView.Size.Height - (sizeCandidate.Height * spanSize)) :
+                                                (int)(colView.Size.Width - (sizeCandidate.Width * spanSize));
+                if (division < 0) division = 0;
+                if (remainder < 0) remainder = 0;
+
+                xPos = IsHorizontal ? division * sizeCandidate.Width + (hasHeader ? headerSize : 0) : emptyArea * align + remainder * sizeCandidate.Width;
+                yPos = IsHorizontal ? emptyArea * align + remainder * sizeCandidate.Height : division * sizeCandidate.Height + (hasHeader ? headerSize : 0);
+            }
+
+            return (xPos, yPos);
+        }
+
+        private RecyclerViewItem GetVisibleItem(int index)
+        {
+            foreach (RecyclerViewItem item in VisibleItems)
+            {
+                if (item.Index == index) return item;
+            }
+
+            return null;
+        }
+
+        private GroupInfo GetGroupInfo(int index)
+        {
+            if (Visited != null)
+            {
+                if (Visited.StartIndex <= index && Visited.StartIndex + Visited.Count > index)
+                    return Visited;
+            }
+            if (hasHeader && index == 0) return null;
+            foreach (GroupInfo group in groups)
+            {
+                if (group.StartIndex <= index && group.StartIndex + group.Count > index)
+                {
+                    Visited = group;
+                    return group;
+                }
+            }
+            Visited = null;
+            return null;
+        }
+
+        /*
+        private object GetGroupParent(int index)
+        {
+            if (Visited != null)
+            {
+                if (Visited.StartIndex <= index && Visited.StartIndex + Visited.Count > index)
+                return Visited.GroupParent;
+            }
+            if (hasHeader && index == 0) return null;
+            foreach (GroupInfo group in groups)
+            {
+                if (group.StartIndex <= index && group.StartIndex + group.Count > index)
+                {
+                    Visited = group;
+                    return group.GroupParent;
+                }
+            }
+            Visited = null;
+            return null;
+        }
+        */
+
+        class GroupInfo
+        {
+            public object GroupParent;
+            public int StartIndex;
+            public int Count;
+            public float GroupSize;
+            public float GroupPosition;
+            //Items relative position from the GroupPosition
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/ItemsLayouter.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/ItemsLayouter.cs
new file mode 100644 (file)
index 0000000..19b1a19
--- /dev/null
@@ -0,0 +1,350 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI.BaseComponents;
+using System.Collections.Generic;
+using System.ComponentModel;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// Default layout manager for CollectionView.
+    /// Lay out ViewItem and recycle ViewItem.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public abstract class ItemsLayouter : ICollectionChangedNotifier, IDisposable
+    {
+        private bool disposed = false;
+
+        /// <summary>
+        /// Container which contains ViewItems.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected View Container{ get ; set; }
+
+        /// <summary>
+        /// Parent ItemsView.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected RecyclerView ItemsView{ get; set; }
+
+        /// <summary>
+        /// The last scrolled position which is calculated by ScrollableBase. The value should be updated in the Recycle() method.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected float PrevScrollPosition { get; set; }
+
+        /// <summary>
+        /// First index of visible items.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected int FirstVisible { get; set; } = -1;
+
+        /// <summary>
+        /// Last index of visible items.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected int LastVisible { get; set; } = -1;
+
+        /// <summary>
+        /// Visible ViewItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected List<RecyclerViewItem> VisibleItems { get; } = new List<RecyclerViewItem>();
+
+        /// <summary>
+        /// Flag of layouter initialization.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected bool IsInitialized { get; set; } = false;
+
+        /// <summary>
+        /// Candidate item step size for scroll size measure.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected float StepCandidate { get; set; }
+
+        /// <summary>
+        /// Content size of scrollable.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected float ScrollContentSize { get; set; }
+
+        /// <summary>
+        /// boolean flag of scrollable horizontal direction.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected bool IsHorizontal { get; set; }
+
+        /// <summary>
+        /// Clean up ItemsLayouter.
+        /// </summary>
+        /// <param name="view"> ItemsView of layouter.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void Initialize(RecyclerView view)
+        {
+            ItemsView = view ?? throw new ArgumentNullException(nameof(view));
+            Container = view.ContentContainer;
+            PrevScrollPosition = 0.0f;
+
+            IsHorizontal = (view.ScrollingDirection == ScrollableBase.Direction.Horizontal);
+
+            IsInitialized = true;
+        }
+
+        /// <summary>
+        /// This is called to find out where items are lain out according to current scroll position.
+        /// </summary>
+        /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
+        /// <param name="force">boolean force flag to layouting forcely.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void RequestLayout(float scrollPosition, bool force = false)
+        {
+           // Layouting Items in scrollPosition.
+        }
+
+        /// <summary>
+        /// Clear the current screen and all properties.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void Clear()
+        {
+            foreach (RecyclerViewItem item in VisibleItems)
+            {
+                if (ItemsView != null) ItemsView.UnrealizeItem(item, false);
+            }
+            VisibleItems.Clear();
+            ItemsView = null;
+            Container = null;
+        }
+
+        /// <summary>
+        /// Position of layouting item.
+        /// </summary>
+        /// <param name="item">item of dataset.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual (float X, float Y) GetItemPosition(object item)
+        {
+           if (item == null) throw new ArgumentNullException(nameof(item));
+           // Layouting Items in scrollPosition.
+           return (0, 0);
+        }
+
+        /// <summary>
+        /// Size of layouting item.
+        /// </summary>
+        /// <param name="item">item of dataset.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual (float X, float Y) GetItemSize(object item)
+        {
+           if (item == null) throw new ArgumentNullException(nameof(item));
+           // Layouting Items in scrollPosition.
+           return (0, 0);
+        }
+
+        /// <summary>
+        /// This is called to find out how much container size can be.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual float CalculateLayoutOrientationSize()
+        {
+            return 0.0f;
+        }
+
+        /// <summary>
+        /// Adjust scrolling position by own scrolling rules.
+        /// </summary>
+        /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual float CalculateCandidateScrollPosition(float scrollPosition)
+        {
+            return scrollPosition;
+        }
+
+        /// <summary>
+        /// Notify the relayout of ViewItem.
+        /// </summary>
+        /// <param name="item">updated ViewItem.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemSizeChanged(RecyclerViewItem item)
+        {
+        }
+
+        /// <summary>
+        /// Notify the dataset is Changed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyDataSetChanged()
+        {
+            Initialize(ItemsView);
+        }
+
+        /// <summary>
+        /// Notify the observable item in startIndex is changed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Changed item index.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemChanged(IItemSource source, int startIndex)
+        {
+        }
+
+        /// <summary>
+        /// Notify the observable item is inserted in dataset.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Inserted item index.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemInserted(IItemSource source, int startIndex)
+        {
+        }
+
+        /// <summary>
+        /// Notify the observable item is moved from fromPosition to ToPosition.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="fromPosition">Previous item position.</param>
+        /// <param name="toPosition">Moved item position.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemMoved(IItemSource source, int fromPosition, int toPosition)
+        {
+        }
+
+        /// <summary>
+        /// Notify the range of observable items from start to end are changed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startRange">Start index of changed items range.</param>
+        /// <param name="endRange">End index of changed items range.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemRangeChanged(IItemSource source, int startRange, int endRange)
+        {
+        }
+
+        /// <summary>
+        /// Notify the count range of observable items are inserted in startIndex.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Start index of inserted items range.</param>
+        /// <param name="count">The number of inserted items.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemRangeInserted(IItemSource source, int startIndex, int count)
+        {
+        }
+
+        /// <summary>
+        /// Notify the count range of observable items from the startIndex are removed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Start index of removed items range.</param>
+        /// <param name="count">The number of removed items</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemRangeRemoved(IItemSource source, int startIndex, int count)
+        {
+        }
+
+        /// <summary>
+        /// Notify the observable item in startIndex is removed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Index of removed item.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual void NotifyItemRemoved(IItemSource source, int startIndex)
+        {
+        }
+
+        /// <summary>
+        /// Gets the next keyboard focusable view in this control towards the given direction.<br />
+        /// A control needs to override this function in order to support two dimensional keyboard navigation.<br />
+        /// </summary>
+        /// <param name="currentFocusedView">The current focused view.</param>
+        /// <param name="direction">The direction to move the focus towards.</param>
+        /// <param name="loopEnabled">Whether the focus movement should be looped within the control.</param>
+        /// <returns>The next keyboard focusable view in this control or an empty handle if no view can be focused.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual View RequestNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+        {
+            return null;
+        }
+
+        /// <summary>
+        /// Dispose ItemsLayouter and all children on it.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Measure the size of chlid ViewItem manually.
+        /// </summary>
+        /// <param name="parent">Parent ItemsView.</param>
+        /// <param name="child">Child ViewItem to Measure()</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void MeasureChild(RecyclerView parent, RecyclerViewItem child)
+        {
+            if (parent == null) throw new ArgumentNullException(nameof(parent));
+            if (child == null) throw new ArgumentNullException(nameof(child));
+
+            if (child.Layout == null) return;
+
+            //FIXME: This measure can be restricted size of child to be less than parent size.
+            // but in some multiple-line TextLabel can be long enough to over the it's parent size.
+
+            MeasureSpecification childWidthMeasureSpec = LayoutGroup.GetChildMeasureSpecification(
+                        new MeasureSpecification(new LayoutLength(parent.Size.Width), MeasureSpecification.ModeType.Exactly),
+                        new LayoutLength(0),
+                        new LayoutLength(child.WidthSpecification));
+
+            MeasureSpecification childHeightMeasureSpec = LayoutGroup.GetChildMeasureSpecification(
+                        new MeasureSpecification(new LayoutLength(parent.Size.Height), MeasureSpecification.ModeType.Exactly),
+                        new LayoutLength(0),
+                        new LayoutLength(child.HeightSpecification));
+
+            child.Layout.Measure(childWidthMeasureSpec, childHeightMeasureSpec);
+        }
+
+        /// <summary>
+        /// Find consecutive visible items index.
+        /// </summary>
+        /// <param name="visibleArea">float turple of visible area start position to end position. </param>
+        /// <return>int turple of start index to end index</return>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual (int start, int end) FindVisibleItems((float X, float Y) visibleArea)
+        {
+            return (0, 0);
+        }
+
+        /// <summary>
+        /// Dispose ItemsLayouter and all children on it.
+        /// </summary>
+        /// <param name="disposing">true when it disposed by Dispose(). </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            disposed = true;
+            if (disposing) Clear();
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/LinearLayouter.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/LinearLayouter.cs
new file mode 100644 (file)
index 0000000..a247d0e
--- /dev/null
@@ -0,0 +1,743 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.Linq;
+using Tizen.NUI.BaseComponents;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Components
+{
+
+
+    /// <summary>
+    /// [Draft] This class implements a linear box layout.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class LinearLayouter : ItemsLayouter
+    {
+        private readonly List<float> ItemPosition = new List<float>();
+        private readonly List<float> ItemSize = new List<float>();
+        private int ItemSizeChanged = -1;
+        private CollectionView colView;
+        private bool hasHeader;
+        private float headerSize;
+        private bool hasFooter;
+        private float footerSize;
+        private bool isGrouped;
+        private readonly List<GroupInfo> groups = new List<GroupInfo>();
+        private float groupHeaderSize;
+        private float groupFooterSize;
+        private GroupInfo Visited;
+
+        /// <summary>
+        /// Clean up ItemsLayouter.
+        /// </summary>
+        /// <param name="view"> ItemsView of layouter.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void Initialize(RecyclerView view)
+        {
+            colView = view as CollectionView;
+            if (colView == null)
+            {
+                throw new ArgumentException("LinearLayouter only can be applied CollectionView.", nameof(view));
+            }
+            // 1. Clean Up
+            foreach (RecyclerViewItem item in VisibleItems)
+            {
+                colView.UnrealizeItem(item, false);
+            }
+            VisibleItems.Clear();
+            ItemPosition.Clear();
+            ItemSize.Clear();
+            groups.Clear();
+
+            FirstVisible = 0;
+            LastVisible = 0;
+
+            IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
+
+            RecyclerViewItem header = colView?.Header;
+            RecyclerViewItem footer = colView?.Footer;
+            float width, height;
+            int count = colView.InternalItemSource.Count;
+
+            if (header != null)
+            {
+                MeasureChild(colView, header);
+
+                width = header.Layout != null ? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = header.Layout != null ? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+
+                headerSize = IsHorizontal ? width : height;
+                hasHeader = true;
+                
+                colView.UnrealizeItem(header);
+            }
+            else hasHeader = false;
+
+            if (footer != null)
+            {
+                MeasureChild(colView, footer);
+
+                width = footer.Layout != null ? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = footer.Layout != null ? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+
+                footerSize = IsHorizontal ? width : height;
+                footer.Index = count - 1;
+                hasFooter = true;
+                
+                colView.UnrealizeItem(footer);
+            }
+            else hasFooter = false;
+
+            //No Internal Source exist.
+            if (count == (hasHeader? (hasFooter? 2 : 1) : 0)) return;
+
+            int firstIndex = hasHeader ? 1 : 0;
+
+            if (colView.IsGrouped)
+            {
+                isGrouped = true;
+
+                if (colView.GroupHeaderTemplate != null)
+                {
+                    while (!colView.InternalItemSource.IsGroupHeader(firstIndex)) firstIndex++;
+                    //must be always true
+                    if (colView.InternalItemSource.IsGroupHeader(firstIndex))
+                    {
+                        RecyclerViewItem groupHeader = colView.RealizeItem(firstIndex);
+                        firstIndex++;
+
+                        if (groupHeader == null) throw new Exception("["+firstIndex+"] Group Header failed to realize!");
+
+                        // Need to Set proper hieght or width on scroll direciton.
+                        if (groupHeader.Layout == null)
+                        {
+                            width =  groupHeader.WidthSpecification;
+                            height = groupHeader.HeightSpecification;
+                        }
+                        else
+                        {
+                            MeasureChild(colView, groupHeader);
+
+                            width = groupHeader.Layout.MeasuredWidth.Size.AsRoundedValue();
+                            height = groupHeader.Layout.MeasuredHeight.Size.AsRoundedValue();
+                        }
+                        //Console.WriteLine("[NUI] GroupHeader Size {0} :{0}", width, height);
+                        // pick the StepCandidate.
+                        groupHeaderSize = IsHorizontal ? width : height;
+                        colView.UnrealizeItem(groupHeader);
+                    }
+                }
+                else
+                {
+                    groupHeaderSize = 0F;
+                }
+
+                if (colView.GroupFooterTemplate != null)
+                {
+                    int firstFooter = firstIndex;
+                    while (!colView.InternalItemSource.IsGroupFooter(firstFooter)) firstFooter++;
+                    //must be always true
+                    if (colView.InternalItemSource.IsGroupFooter(firstFooter))
+                    {
+                        RecyclerViewItem groupFooter = colView.RealizeItem(firstFooter);
+
+                        if (groupFooter == null) throw new Exception("["+firstFooter+"] Group Footer failed to realize!");
+                        // Need to Set proper hieght or width on scroll direciton.
+                        if (groupFooter.Layout == null)
+                        {
+                            width =  groupFooter.WidthSpecification;
+                            height = groupFooter.HeightSpecification;
+                        }
+                        else
+                        {
+                            MeasureChild(colView, groupFooter);
+
+                            width = groupFooter.Layout.MeasuredWidth.Size.AsRoundedValue();
+                            height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
+                        }
+                        // pick the StepCandidate.
+                        groupFooterSize = IsHorizontal ? width : height;
+
+                        colView.UnrealizeItem(groupFooter);
+                    }
+                }
+                else
+                {
+                    groupFooterSize = 0F;
+                }
+            }
+            else isGrouped = false;
+
+            bool failed = false;
+            //Final Check of FirstIndex
+            while (colView.InternalItemSource.IsHeader(firstIndex) ||
+                    colView.InternalItemSource.IsGroupHeader(firstIndex) ||
+                    colView.InternalItemSource.IsGroupFooter(firstIndex))
+            {
+                if (colView.InternalItemSource.IsFooter(firstIndex))
+                {
+                    StepCandidate = 0F;
+                    failed = true;
+                    break;
+                }
+                firstIndex++;
+            }
+
+            if (!failed)
+            {
+                RecyclerViewItem sizeDeligate = colView.RealizeItem(firstIndex);
+                if (sizeDeligate == null)
+                {
+                    // error !
+                    throw new Exception("Cannot create content from DatTemplate.");
+                }
+
+                sizeDeligate.BindingContext = colView.InternalItemSource.GetItem(firstIndex);
+
+                // Need to Set proper hieght or width on scroll direciton.
+                if (sizeDeligate.Layout == null)
+                {
+                    width =  sizeDeligate.WidthSpecification;
+                    height = sizeDeligate.HeightSpecification;
+                }
+                else
+                {
+                    MeasureChild(colView, sizeDeligate);
+
+                    width = sizeDeligate.Layout.MeasuredWidth.Size.AsRoundedValue();
+                    height = sizeDeligate.Layout.MeasuredHeight.Size.AsRoundedValue();
+                }
+                //Console.WriteLine("[NUI] Layout Size {0} :{0}", width, height);
+                // pick the StepCandidate.
+                StepCandidate = IsHorizontal ? width : height;
+                if (StepCandidate == 0) StepCandidate = 1; //????
+                
+                colView.UnrealizeItem(sizeDeligate);
+            }
+
+            float Current = 0.0F;
+            IGroupableItemSource source = colView.InternalItemSource;
+            GroupInfo currentGroup = null;
+            for (int i = 0; i < count; i++)
+            {
+                if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                {
+                    if (i == 0 && hasHeader)
+                        ItemSize.Add(headerSize);
+                    else if (i == count -1 && hasFooter)
+                        ItemSize.Add(footerSize);
+                    else if (source.IsGroupHeader(i))
+                        ItemSize.Add(groupHeaderSize);
+                    else if (source.IsGroupFooter(i))
+                        ItemSize.Add(groupFooterSize);
+                    else ItemSize.Add(StepCandidate);
+                }
+                if (isGrouped)
+                {
+                    if (i == 0 && hasHeader)
+                    {
+                        //ItemPosition.Add(Current);
+                        Current += headerSize;
+                    }
+                    else if (i == count -1 && hasFooter)
+                    {
+                        //ItemPosition.Add(Current);
+                        Current += footerSize;
+                    }
+                    else
+                    {
+                        //GroupHeader must always exist in group usage.
+                        if (source.IsGroupHeader(i))
+                        {
+                            currentGroup = new GroupInfo()
+                            {
+                                GroupParent = source.GetGroupParent(i),
+                                //hasHeader = true,
+                                //hasFooter = false,
+                                StartIndex = i,
+                                Count = 1,
+                                GroupSize = groupHeaderSize,
+                                GroupPosition = Current
+                            };
+                            currentGroup.ItemPosition.Add(0);
+                            groups.Add(currentGroup);
+                            Current += groupHeaderSize;
+                        }
+                        //optional
+                        else if (source.IsGroupFooter(i))
+                        {
+                            //currentGroup.hasFooter = true;
+                            currentGroup.Count++;
+                            currentGroup.GroupSize += groupFooterSize;
+                            currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
+                            Current += groupFooterSize;
+                        }
+                        else
+                        {
+                            currentGroup.Count++;
+                            currentGroup.GroupSize += StepCandidate;
+                            currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
+                            Current += StepCandidate;
+                        }
+                    }
+                }
+                else
+                {
+                    ItemPosition.Add(Current);
+
+                    if (i == 0 && hasHeader) Current += headerSize;
+                    else if (i == count -1 && hasFooter) Current += footerSize;
+                    else Current += StepCandidate;
+                }
+            }
+
+            ScrollContentSize = Current;
+            if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
+            else colView.ContentContainer.SizeHeight = ScrollContentSize;
+
+
+            base.Initialize(view);
+            //Console.WriteLine("[NUI] Init Done, StepCnadidate{0}, Scroll{1}", StepCandidate, ScrollContentSize);
+        }
+
+        /// <summary>
+        /// This is called to find out where items are lain out according to current scroll position.
+        /// </summary>
+        /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
+        /// <param name="force">boolean force flag to layouting forcely.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void RequestLayout(float scrollPosition, bool force = false)
+        {
+            // Layouting is only possible after once it intialized.
+            if (!IsInitialized) return;
+            int LastIndex = colView.InternalItemSource.Count -1;
+
+            if (!force && PrevScrollPosition == Math.Abs(scrollPosition)) return;
+            PrevScrollPosition = Math.Abs(scrollPosition);
+
+            if (ItemSizeChanged >= 0)
+            {
+                for (int i = ItemSizeChanged; i <= LastIndex; i++)
+                    UpdatePosition(i);
+                ScrollContentSize = ItemPosition[LastIndex - 1] + GetItemSize(LastIndex);
+            }
+
+            int prevFirstVisible = FirstVisible;
+            int prevLastVisible = LastVisible;
+
+            (float X, float Y) visibleArea = (PrevScrollPosition,
+                PrevScrollPosition + ( IsHorizontal ? colView.Size.Width : colView.Size.Height)
+            );
+
+            // 1. Set First/Last Visible Item Index. 
+            (int start, int end) = FindVisibleItems(visibleArea);
+            FirstVisible = start;
+            LastVisible = end;
+
+            // 2. Unrealize invisible items.
+            List<RecyclerViewItem> unrealizedItems = new List<RecyclerViewItem>();
+            foreach (RecyclerViewItem item in VisibleItems)
+            {
+                if (item.Index < FirstVisible || item.Index > LastVisible)
+                {
+                   //Console.WriteLine("[NUI] Unrealize{0}!", item.Index);
+                   unrealizedItems.Add(item);
+                   colView.UnrealizeItem(item);
+                }
+            }
+            VisibleItems.RemoveAll(unrealizedItems.Contains);
+
+            // 3. Realize and placing visible items.
+            for (int i = FirstVisible; i <= LastVisible; i++)
+            {
+                RecyclerViewItem item = null;
+                // 4. Get item if visible or realize new.
+                if (i >= prevFirstVisible && i <= prevLastVisible)
+                {
+                    item = GetVisibleItem(i);
+                    if (item) continue;
+                }
+                if (item == null) item = colView.RealizeItem(i);
+
+                VisibleItems.Add(item);
+
+                // 5. Placing item.
+                float posX = 0F, posY = 0F;
+                if (isGrouped)
+                {
+                    //isHeader?
+                    if (colView.Header == item)
+                    {
+                        posX = 0F;
+                        posY = 0F;
+                    }
+                    else if (colView.Footer == item)
+                    {
+                        posX = (IsHorizontal ? ScrollContentSize - item.SizeWidth : 0F);
+                        posY =(IsHorizontal ? 0F : ScrollContentSize - item.SizeHeight); 
+                    }
+                    else
+                    {
+                        GroupInfo gInfo = GetGroupInfo(i);
+                        posX = (IsHorizontal ? gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex] : 0F);
+                        posY = (IsHorizontal ? 0F : gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex]);
+                    }
+                }
+                else
+                {
+                    posX = (IsHorizontal ? ItemPosition[i] : 0F);
+                    posY = (IsHorizontal ? 0F : ItemPosition[i]);
+                }
+
+                item.Position = new Position(posX, posY);
+                //Console.WriteLine("[NUI] ["+item+"]["+item.Index+"] :: ["+item.Position.X+", "+item.Position.Y+"] ==== \n");
+            }
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override (float X, float Y) GetItemPosition(object item)
+        {
+           if (item == null) throw new ArgumentNullException(nameof(item));
+           // Layouting Items in scrollPosition.
+           float pos = ItemPosition[colView.InternalItemSource.GetPosition(item)];
+
+           return (IsHorizontal ? (pos, 0.0F) : (0.0F, pos));
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override (float X, float Y) GetItemSize(object item)
+        {
+           if (item == null) throw new ArgumentNullException(nameof(item));
+           // Layouting Items in scrollPosition.
+           float size = GetItemSize(colView.InternalItemSource.GetPosition(item));
+           float view = (IsHorizontal ? colView.Size.Height : colView.Size.Width);
+
+           return (IsHorizontal ? (size, view) : (view, size));
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void NotifyItemSizeChanged(RecyclerViewItem item)
+        {
+            if (item == null)
+                throw new ArgumentNullException(nameof(item));
+
+            if (!IsInitialized ||
+                (colView.SizingStrategy == ItemSizingStrategy.MeasureFirst &&
+                item.Index != 0) ||
+                (item.Index < 0))
+                return;
+
+            float PrevSize, CurrentSize;
+            if (item.Index == (colView.InternalItemSource.Count-1))
+            {
+                PrevSize = ScrollContentSize - ItemPosition[item.Index];
+            }
+            else
+            {
+                PrevSize = ItemPosition[item.Index + 1] - ItemPosition[item.Index];
+            }
+
+            CurrentSize = (IsHorizontal ? item.Size.Width : item.Size.Height);
+
+            if (CurrentSize != PrevSize)
+            {
+                if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                  ItemSize[item.Index] = CurrentSize;
+                else
+                  StepCandidate = CurrentSize;
+            }
+            if (ItemSizeChanged == -1) ItemSizeChanged = item.Index;
+            else ItemSizeChanged = Math.Min(ItemSizeChanged, item.Index);
+
+            //ScrollContentSize += Diff; UpdateOnce?
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override float CalculateLayoutOrientationSize()
+        {
+            //Console.WriteLine("[NUI] Calculate Layout ScrollContentSize {0}", ScrollContentSize);
+            return ScrollContentSize;
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override float CalculateCandidateScrollPosition(float scrollPosition)
+        {
+            //Console.WriteLine("[NUI] Calculate Candidate ScrollContentSize {0}", ScrollContentSize);
+            return scrollPosition;
+        }
+
+        /// <Inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override View RequestNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+        {
+            if (currentFocusedView == null)
+                throw new ArgumentNullException(nameof(currentFocusedView));
+
+            View nextFocusedView = null;
+            int targetSibling = -1;
+
+            switch(direction)
+            {
+                case View.FocusDirection.Left :
+                {
+                    targetSibling = IsHorizontal ? currentFocusedView.SiblingOrder - 1 : targetSibling;
+                    break;
+                }
+                case View.FocusDirection.Right :
+                {
+                    targetSibling = IsHorizontal ? currentFocusedView.SiblingOrder + 1 : targetSibling;
+                    break;
+                }
+                case View.FocusDirection.Up :
+                {
+                    targetSibling = IsHorizontal ? targetSibling : currentFocusedView.SiblingOrder - 1;
+                    break;
+                }
+                case View.FocusDirection.Down :
+                {
+                    targetSibling = IsHorizontal ? targetSibling : currentFocusedView.SiblingOrder + 1;
+                    break;
+                }
+            }
+
+            if(targetSibling > -1 && targetSibling < Container.Children.Count)
+            {
+                RecyclerViewItem candidate = Container.Children[targetSibling] as RecyclerViewItem;
+                if(candidate.Index >= 0 && candidate.Index < colView.InternalItemSource.Count)
+                {
+                    nextFocusedView = candidate;
+                }
+            }
+
+            return nextFocusedView;
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override (int start, int end) FindVisibleItems((float X, float Y) visibleArea)
+        {
+            int MaxIndex = colView.InternalItemSource.Count - 1 - (hasFooter ? 1 : 0);
+            int adds = 5;
+            int skipGroup = -2;
+            (int start, int end) found = (0, 0);
+
+            // 1. Find the start index.
+            // Header is Showing
+            if (hasHeader && visibleArea.X <= headerSize)
+            {
+                found.start = 0;
+            }
+            else
+            {
+                if (isGrouped)
+                {
+                    bool failed = true;
+                    foreach(GroupInfo gInfo in groups)
+                    {
+                        skipGroup++;
+                        // in the Group
+                        if (gInfo.GroupPosition <= visibleArea.X &&
+                            gInfo.GroupPosition + gInfo.GroupSize >= visibleArea.X)
+                        {
+                            for (int i = 0; i < gInfo.Count; i++)
+                            {
+                                // Reach last index of group.
+                                if (i == (gInfo.Count - 1))
+                                {
+                                    found.start = gInfo.StartIndex + i - adds;
+                                    failed = false;
+                                    break;
+                                    
+                                }
+                                else if (gInfo.ItemPosition[i] <= visibleArea.X - gInfo.GroupPosition &&
+                                        gInfo.ItemPosition[i + 1] >= visibleArea.X - gInfo.GroupPosition)
+                                {
+                                    found.start = gInfo.StartIndex + i - adds;
+                                    failed = false;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    //footer only shows?
+                    if (failed)
+                    {
+                        found.start = MaxIndex;
+                    }
+                }
+                else
+                {
+                    float visibleAreaX = visibleArea.X - (hasHeader ? headerSize : 0);
+                    found.start = (Convert.ToInt32(Math.Abs(visibleAreaX / StepCandidate)) - adds);
+                }
+
+                if (found.start < 0) found.start = 0;
+            }
+
+            if (hasFooter && visibleArea.Y > ScrollContentSize - footerSize)
+            {
+                found.end = MaxIndex + 1;
+            }
+            else
+            {
+                if (isGrouped)
+                {
+                    bool failed = true;
+                    // can it be start from founded group...?
+                    //foreach(GroupInfo gInfo in groups.Skip(skipGroup))
+                    foreach(GroupInfo gInfo in groups)
+                    {
+                        // in the Group
+                        if (gInfo.GroupPosition <= visibleArea.Y &&
+                            gInfo.GroupPosition + gInfo.GroupSize >= visibleArea.Y)
+                        {
+                            for (int i = 0; i < gInfo.Count; i++)
+                            {
+                                if (i == (gInfo.Count - 1))
+                                {
+                                    //Sould be groupFooter!
+                                    found.end = gInfo.StartIndex + i + adds;
+                                    failed = false;
+                                    break;
+                                    
+                                }
+                                else if (gInfo.ItemPosition[i] <= visibleArea.Y - gInfo.GroupPosition &&
+                                        gInfo.ItemPosition[i + 1] >= visibleArea.Y - gInfo.GroupPosition)
+                                {
+                                    found.end = gInfo.StartIndex + i + adds;
+                                    failed = false;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if (failed) found.end = MaxIndex;
+                }
+                else
+                {
+                float visibleAreaY = visibleArea.Y - (hasHeader ? headerSize : 0);
+                    found.end = (Convert.ToInt32(Math.Abs(visibleAreaY / StepCandidate)) + adds);
+                    if (hasHeader) found.end += 1;
+                }
+                if (found.end > (MaxIndex)) found.end = MaxIndex;
+            }
+            return found;
+        }
+
+        private float GetItemSize(int index)
+        {
+            if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+            {
+                return ItemSize[index];
+            }
+            else
+            {
+                if (index == 0 && hasHeader)
+                    return headerSize;
+                if (index == colView.InternalItemSource.Count - 1 && hasFooter)
+                    return footerSize;
+                return StepCandidate;
+            }
+        }
+
+        private void UpdatePosition(int index)
+        {
+            bool IsGroup = (colView.InternalItemSource is IGroupableItemSource);
+
+            if (index <= 0) return;
+            if (index >= colView.InternalItemSource.Count)
+
+            if (IsGroup)
+            {
+                //IsGroupHeader = (colView.InternalItemSource as IGroupableItemSource).IsGroupHeader(index);
+                //IsGroupFooter = (colView.InternalItemSource as IGroupableItemSource).IsGroupFooter(index);
+                //Do Something
+            }
+
+            ItemPosition[index] = ItemPosition[index-1] + GetItemSize(index-1);
+        }
+
+        private RecyclerViewItem GetVisibleItem(int index)
+        {
+            foreach (RecyclerViewItem item in VisibleItems)
+            {
+                if (item.Index == index) return item;
+            }
+            return null;
+        }
+
+        private GroupInfo GetGroupInfo(int index)
+        {
+            if (Visited != null)
+            {
+                if (Visited.StartIndex <= index && Visited.StartIndex + Visited.Count > index)
+                return Visited;
+            }
+            if (hasHeader && index == 0) return null;
+            foreach (GroupInfo group in groups)
+            {
+                if (group.StartIndex <= index && group.StartIndex + group.Count > index)
+                {
+                    Visited = group;
+                    return group;
+                }
+            }
+            Visited = null;
+            return null;
+        }
+/*
+        private object GetGroupParent(int index)
+        {
+            if (Visited != null)
+            {
+                if (Visited.StartIndex <= index && Visited.StartIndex + Visited.Count > index)
+                return Visited.GroupParent;
+            }
+            if (hasHeader && index == 0) return null;
+            foreach (GroupInfo group in groups)
+            {
+                if (group.StartIndex <= index && group.StartIndex + group.Count > index)
+                {
+                    Visited = group;
+                    return group.GroupParent;
+                }
+            }
+            Visited = null;
+            return null;
+        }
+*/
+        class GroupInfo
+        {
+            public object GroupParent;
+            public int StartIndex;
+            public int Count;
+            public float GroupSize;
+            public float GroupPosition; 
+            //Items relative position from the GroupPosition
+            public List<float> ItemPosition = new List<float>();
+        }
+    }
+}
index 6cd7779..548aea0 100755 (executable)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 using System;
-using Tizen.NUI.BaseComponents;
+using System.Linq;
+using System.Collections;
 using System.Collections.Generic;
 using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
 
 namespace Tizen.NUI.Components
 {
     /// <summary>
-    /// [Draft] This class provides a View that can recycle items to improve performance.
+    /// [Draft] This class provides a View that can layouting items in list and grid with high performance.
     /// </summary>
-    /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
     [EditorBrowsable(EditorBrowsableState.Never)]
-    public class RecyclerView : ScrollableBase
+    public abstract class RecyclerView : ScrollableBase, ICollectionChangedNotifier
     {
-        private RecycleAdapter adapter;
-        private RecycleLayoutManager layoutManager;
-        private int totalItemCount = 15;
-        private List<PropertyNotification> notifications = new List<PropertyNotification>();
-
+        /// <summary>
+        /// Base Constructor
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
         public RecyclerView() : base()
         {
-            Initialize(new RecycleAdapter(), new RecycleLayoutManager());
+            Scrolling += OnScrolling;
         }
 
         /// <summary>
-        /// Default constructor.
+        /// Item's source data.
         /// </summary>
-        /// <param name="adapter">Recycle adapter of RecyclerView.</param>
-        /// <param name="layoutManager">Recycle layoutManager of RecyclerView.</param>
-        /// <since_tizen> 8 </since_tizen>
-        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public RecyclerView(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
-        {
-            Initialize(adapter, layoutManager);
-        }
+        public virtual IEnumerable ItemsSource { get; set; }
 
-        private void Initialize(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
-        {
-            FocusGroup = true;
-            SetKeyboardNavigationSupport(true);
-            Scrolling += OnScrolling;
+        /// <summary>
+        /// DataTemplate for items.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual DataTemplate ItemTemplate { get; set; }
 
-            this.adapter = adapter;
-            this.adapter.OnDataChanged += OnAdapterDataChanged;
+        /// <summary>
+        /// Internal encapsulated items data source.
+        /// </summary>
+        internal IItemSource InternalItemSource { get; set;}
 
-            this.layoutManager = layoutManager;
-            this.layoutManager.Container = ContentContainer;
-            this.layoutManager.ItemSize = this.adapter.CreateRecycleItem().Size;
-            this.layoutManager.DataCount = this.adapter.Data.Count;
+        /// <summary>
+        /// RecycleCache of ViewItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected List<RecyclerViewItem> RecycleCache { get; } = new List<RecyclerViewItem>();
 
-            InitializeItems();
-        }
+        /// <summary>
+        /// Internal Items Layouter.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected ItemsLayouter InternalItemsLayouter {get; set; }
 
-        private void OnItemSizeChanged(object source, PropertyNotification.NotifyEventArgs args)
-        {
-            layoutManager.Layout(ScrollingDirection == Direction.Horizontal ? ContentContainer.CurrentPosition.X : ContentContainer.CurrentPosition.Y);
-        }
+        /// <summary>
+        /// Max size of RecycleCache. Default is 50.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected int CacheMax { get; set; } = 50;
 
-        public int TotalItemCount
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void OnRelayout(Vector2 size, RelayoutContainer container)
         {
-            get
-            {
-                return totalItemCount;
-            }
-            set
+            //Console.WriteLine("[NUI] On ReLayout [{0} {0}]", size.X, size.Y);
+            base.OnRelayout(size, container);
+            if (InternalItemsLayouter != null && ItemsSource != null && ItemTemplate != null) 
             {
-                totalItemCount = value;
-                InitializeItems();
+                InternalItemsLayouter.Initialize(this);
+                InternalItemsLayouter.RequestLayout(ScrollingDirection == Direction.Horizontal ? ContentContainer.CurrentPosition.X : ContentContainer.CurrentPosition.Y, true);
             }
         }
 
-        private void InitializeItems()
+        /// <summary>
+        /// Notify Dataset is Changed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void NotifyDataSetChanged()
         {
-            for (int i = Children.Count - 1; i > -1; i--)
-            {
-                Children[i].Unparent();
-                notifications[i].Notified -= OnItemSizeChanged;
-                notifications.RemoveAt(i);
-            }
-
-            for (int i = 0; i < totalItemCount; i++)
+            //Need to update view.
+            if (InternalItemsLayouter != null)
             {
-                RecycleItem item = adapter.CreateRecycleItem();
-                item.DataIndex = i;
-                item.Name = "[" + i + "] recycle";
-
-                if (i < adapter.Data.Count)
+                InternalItemsLayouter.NotifyDataSetChanged();
+                if (ScrollingDirection == Direction.Horizontal)
                 {
-                    adapter.BindData(item);
+                    ContentContainer.SizeWidth =
+                        InternalItemsLayouter.CalculateLayoutOrientationSize();
+                }
+                else
+                {
+                    ContentContainer.SizeHeight =
+                        InternalItemsLayouter.CalculateLayoutOrientationSize();
                 }
-                Add(item);
-
-                PropertyNotification noti = item.AddPropertyNotification("size", PropertyCondition.Step(0.1f));
-                noti.Notified += OnItemSizeChanged;
-                notifications.Add(noti);
             }
+        }
 
-            layoutManager.Layout(0.0f);
-
-            if (ScrollingDirection == Direction.Horizontal)
-            {
-                ContentContainer.SizeWidth = layoutManager.CalculateLayoutOrientationSize();
-            }
-            else
+        /// <summary>
+        /// Notify observable item is changed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Changed item index.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void NotifyItemChanged(IItemSource source, int startIndex)
+        {
+            if (InternalItemsLayouter != null)
             {
-                ContentContainer.SizeHeight = layoutManager.CalculateLayoutOrientationSize();
+                InternalItemsLayouter.NotifyItemChanged(source, startIndex);
             }
         }
 
-
-        public new Direction ScrollingDirection
+        /// <summary>
+        /// Notify observable item is inserted in dataset.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Inserted item index.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void NotifyItemInserted(IItemSource source, int startIndex)
         {
-            get
+            if (InternalItemsLayouter != null)
             {
-                return base.ScrollingDirection;
-            }
-            set
-            {
-                base.ScrollingDirection = value;
-
-                if (ScrollingDirection == Direction.Horizontal)
-                {
-                    ContentContainer.SizeWidth = layoutManager.CalculateLayoutOrientationSize();
-                }
-                else
-                {
-                    ContentContainer.SizeHeight = layoutManager.CalculateLayoutOrientationSize();
-                }
+                InternalItemsLayouter.NotifyItemInserted(source, startIndex);
             }
         }
 
         /// <summary>
-        /// Recycler adpater.
+        /// Notify observable item is moved from fromPosition to ToPosition.
         /// </summary>
-        /// <since_tizen> 8 </since_tizen>
-        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        /// <param name="source">Dataset source.</param>
+        /// <param name="fromPosition">Previous item position.</param>
+        /// <param name="toPosition">Moved item position.</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public RecycleAdapter Adapter
+        public void NotifyItemMoved(IItemSource source, int fromPosition, int toPosition)
         {
-            get
+            if (InternalItemsLayouter != null)
             {
-                return adapter;
+                InternalItemsLayouter.NotifyItemMoved(source, fromPosition, toPosition);
             }
-            set
-            {
-                if (adapter != null)
-                {
-                    adapter.OnDataChanged -= OnAdapterDataChanged;
-                }
+        }
 
-                adapter = value;
-                adapter.OnDataChanged += OnAdapterDataChanged;
-                layoutManager.ItemSize = adapter.CreateRecycleItem().Size;
-                layoutManager.DataCount = adapter.Data.Count;
-                InitializeItems();
+        /// <summary>
+        /// Notify range of observable items from start to end are changed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="start">Start index of changed items range.</param>
+        /// <param name="end">End index of changed items range.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void NotifyItemRangeChanged(IItemSource source, int start, int end)
+        {
+            if (InternalItemsLayouter != null)
+            {
+                InternalItemsLayouter.NotifyItemRangeChanged(source, start, end);
             }
         }
 
         /// <summary>
-        /// Recycler layoutManager.
+        /// Notify count range of observable count items are inserted in startIndex.
         /// </summary>
-        /// <since_tizen> 8 </since_tizen>
-        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Start index of inserted items range.</param>
+        /// <param name="count">The number of inserted items.</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public RecycleLayoutManager LayoutManager
+        public void NotifyItemRangeInserted(IItemSource source, int startIndex, int count)
         {
-            get
+            if (InternalItemsLayouter != null)
             {
-                return layoutManager;
+                InternalItemsLayouter.NotifyItemRangeInserted(source, startIndex, count);
             }
-            set
+        }
+
+        /// <summary>
+        /// Notify the count range of observable items from the startIndex are removed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Start index of removed items range.</param>
+        /// <param name="count">The number of removed items</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void NotifyItemRangeRemoved(IItemSource source, int startIndex, int count)
+        {
+            if (InternalItemsLayouter != null)
             {
-                layoutManager = value;
-                layoutManager.Container = ContentContainer;
-                layoutManager.ItemSize = adapter.CreateRecycleItem().Size;
-                layoutManager.DataCount = adapter.Data.Count;
-                InitializeItems();
+                InternalItemsLayouter.NotifyItemRangeRemoved(source, startIndex, count);
             }
         }
 
-        private void OnScrolling(object source, ScrollEventArgs args)
+        /// <summary>
+        /// Notify the observable item in startIndex is removed.
+        /// </summary>
+        /// <param name="source">Dataset source.</param>
+        /// <param name="startIndex">Index of removed item.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void NotifyItemRemoved(IItemSource source, int startIndex)
         {
-            layoutManager.Layout(ScrollingDirection == Direction.Horizontal ? args.Position.X : args.Position.Y);
-            List<RecycleItem> recycledItemList = layoutManager.Recycle(ScrollingDirection == Direction.Horizontal ? args.Position.X : args.Position.Y);
-            BindData(recycledItemList);
+            if (InternalItemsLayouter != null)
+            {
+                InternalItemsLayouter.NotifyItemRemoved(source, startIndex);
+            }
         }
 
-        private void OnAdapterDataChanged(object source, EventArgs args)
+        /// <summary>
+        /// Realize indexed item.
+        /// </summary>
+        /// <param name="index"> Index position of realizing item </param>
+        internal virtual RecyclerViewItem RealizeItem(int index)
         {
-            List<RecycleItem> changedData = new List<RecycleItem>();
+            object context = InternalItemSource.GetItem(index);
+            // Check DataTemplate is Same!
+            if (ItemTemplate is DataTemplateSelector)
+            {
+                // Need to implements for caching of selector!
+            }
+            else
+            {
+               // pop item
+               RecyclerViewItem item = PopRecycleCache(ItemTemplate);
+               if (item != null)
+               {
+                    DecorateItem(item, index, context);
+                    return item;
+               }
+            }
 
-            foreach (RecycleItem item in Children)
+            object content = DataTemplateExtensions.CreateContent(ItemTemplate, context, (BindableObject)this) ?? throw new Exception("Template return null object.");
+            if (content is RecyclerViewItem)
             {
-                changedData.Add(item);
+                RecyclerViewItem item = (RecyclerViewItem)content;
+                ContentContainer.Add(item);
+                DecorateItem(item, index, context);
+                return item;
+            }
+            else
+            {
+                throw new Exception("Template content must be type of ViewItem");
             }
 
-            BindData(changedData);
         }
 
-        private void BindData(List<RecycleItem> changedData)
+        /// <summary>
+        /// Unrealize indexed item.
+        /// </summary>
+        /// <param name="item"> Target item for unrealizing </param>
+        /// <param name="recycle"> Allow recycle. default is true </param>
+        internal virtual void UnrealizeItem(RecyclerViewItem item, bool recycle = true)
         {
-            foreach (RecycleItem item in changedData)
+            item.Index = -1;
+            item.ParentItemsView = null;
+            // Remove BindingContext null set for performance improving.
+            //item.BindingContext = null; 
+            item.IsPressed = false;
+            item.IsSelected = false;
+            item.IsEnabled = true;
+            // Remove Update Style on default for performance improving.
+            //item.UpdateState();
+            item.Relayout -= OnItemRelayout;
+
+            if (!recycle || !PushRecycleCache(item))
             {
-                if (item.DataIndex > -1 && item.DataIndex < adapter.Data.Count)
-                {
-                    item.Show();
-                    item.Name = "[" + item.DataIndex + "]";
-                    adapter.BindData(item);
-                }
-                else
-                {
-                    item.Hide();
-                }
+                //ContentContainer.Remove(item);
+                Utility.Dispose(item);
             }
         }
 
@@ -234,138 +278,116 @@ namespace Tizen.NUI.Components
         /// Adjust scrolling position by own scrolling rules.
         /// Override this function when developer wants to change destination of flicking.(e.g. always snap to center of item)
         /// </summary>
-        /// <param name="position">Scroll position which is calculated by ScrollableBase</param>
+        /// <param name="position">Scroll position which is calculated by ScrollableBase.</param>
         /// <returns>Adjusted scroll destination</returns>
-        /// <since_tizen> 8 </since_tizen>
-        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected override float AdjustTargetPositionOfScrollAnimation(float position)
         {
             // Destination is depending on implementation of layout manager.
             // Get destination from layout manager.
-            return layoutManager.CalculateCandidateScrollPosition(position);
+            return InternalItemsLayouter.CalculateCandidateScrollPosition(position);
         }
 
-        private View focusedView;
-        private int prevFocusedDataIndex = 0;
+        /// <summary>
+        /// Push the item into the recycle cache. this item will be reused in view update.
+        /// </summary>
+        /// <param name="item"> Target item to push into recycle cache. </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual bool PushRecycleCache(RecyclerViewItem item)
+        {
+            if (item == null) throw new ArgumentNullException(nameof(item));
+            if (RecycleCache.Count >= CacheMax) return false;
+            if (item.Template == null) return false;
+            item.Hide();
+            item.Index = -1;
+            RecycleCache.Add(item);
+            return true;
+        }
 
-        public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+        /// <summary>
+        /// Pop the item from the recycle cache.
+        /// </summary>
+        /// <param name="Template"> Template of wanted item. </param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual RecyclerViewItem PopRecycleCache(DataTemplate Template)
         {
-            View nextFocusedView = null;
+           for (int i = 0; i < RecycleCache.Count; i++)
+           {
+               RecyclerViewItem item = RecycleCache[i];
+               if (item.Template == Template)
+               {
+                   RecycleCache.Remove(item);
+                   item.Show();
+                   return item;
+               }
+           }
+           return null;
+        }
 
-            if (!focusedView)
+        /// <summary>
+        /// On scroll event callback.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void OnScrolling(object source, ScrollEventArgs args)
+        {
+            if (args == null) throw new ArgumentNullException(nameof(args));
+            if (!disposed && InternalItemsLayouter != null && ItemsSource != null && ItemTemplate != null)
             {
-                // If focusedView is null, find child which has previous data index
-                if (Children.Count > 0 && Adapter.Data.Count > 0)
-                {
-                    for (int i = 0; i < Children.Count; i++)
-                    {
-                        RecycleItem item = Children[i] as RecycleItem;
-                        if (item.DataIndex == prevFocusedDataIndex)
-                        {
-                            nextFocusedView = item;
-                            break;
-                        }
-                    }
-                }
+                //Console.WriteLine("[NUI] On Scrolling! {0} => {1}", ScrollPosition.Y, args.Position.Y);
+                InternalItemsLayouter.RequestLayout(ScrollingDirection == Direction.Horizontal ? args.Position.X : args.Position.Y);
             }
-            else
+        }
+
+        /// <summary>
+        /// Dispose ItemsView and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
             {
-                // If this is not first focus, request next focus to LayoutManager
-                if (LayoutManager != null)
-                {
-                    nextFocusedView = LayoutManager.RequestNextFocusableView(currentFocusedView, direction, loopEnabled);
-                }
+                return;
             }
 
-            if (nextFocusedView != null)
+            if (type == DisposeTypes.Explicit)
             {
-                // Check next focused view is inside of visible area.
-                // If it is not, move scroll position to make it visible.
-                Position scrollPosition = ContentContainer.CurrentPosition;
-                float targetPosition = -(ScrollingDirection == Direction.Horizontal ? scrollPosition.X : scrollPosition.Y);
-
-                float left = nextFocusedView.Position.X;
-                float right = nextFocusedView.Position.X + nextFocusedView.Size.Width;
-                float top = nextFocusedView.Position.Y;
-                float bottom = nextFocusedView.Position.Y + nextFocusedView.Size.Height;
-
-                float visibleRectangleLeft = -scrollPosition.X;
-                float visibleRectangleRight = -scrollPosition.X + Size.Width;
-                float visibleRectangleTop = -scrollPosition.Y;
-                float visibleRectangleBottom = -scrollPosition.Y + Size.Height;
-
-                if (ScrollingDirection == Direction.Horizontal)
-                {
-                    if ((direction == View.FocusDirection.Left || direction == View.FocusDirection.Up) && left < visibleRectangleLeft)
-                    {
-                        targetPosition = left;
-                    }
-                    else if ((direction == View.FocusDirection.Right || direction == View.FocusDirection.Down) && right > visibleRectangleRight)
-                    {
-                        targetPosition = right - Size.Width;
-                    }
-                }
-                else
+                disposed = true;
+                // call the clear!
+                if (RecycleCache != null)
                 {
-                    if ((direction == View.FocusDirection.Up || direction == View.FocusDirection.Left) && top < visibleRectangleTop)
-                    {
-                        targetPosition = top;
-                    }
-                    else if ((direction == View.FocusDirection.Down || direction == View.FocusDirection.Right) && bottom > visibleRectangleBottom)
+                    foreach (RecyclerViewItem item in RecycleCache)
                     {
-                        targetPosition = bottom - Size.Height;
+                        //ContentContainer.Remove(item);
+                        Utility.Dispose(item);
                     }
+                    RecycleCache.Clear();
                 }
-
-                focusedView = nextFocusedView;
-                if ((nextFocusedView as RecycleItem) != null)
-                {
-                    prevFocusedDataIndex = (nextFocusedView as RecycleItem).DataIndex;
-                }
-
-                ScrollTo(targetPosition, true);
+                InternalItemsLayouter.Clear();
+                InternalItemsLayouter = null;
+                ItemsSource = null;
+                ItemTemplate = null;
+                if (InternalItemSource != null) InternalItemSource.Dispose();
+                //
             }
-            else
-            {
-                // If nextView is null, it means that we should move focus to outside of Control.
-                // Return FocusableView depending on direction.
-                switch (direction)
-                {
-                    case View.FocusDirection.Left:
-                        {
-                            nextFocusedView = LeftFocusableView;
-                            break;
-                        }
-                    case View.FocusDirection.Right:
-                        {
-                            nextFocusedView = RightFocusableView;
-                            break;
-                        }
-                    case View.FocusDirection.Up:
-                        {
-                            nextFocusedView = UpFocusableView;
-                            break;
-                        }
-                    case View.FocusDirection.Down:
-                        {
-                            nextFocusedView = DownFocusableView;
-                            break;
-                        }
-                }
 
-                if (nextFocusedView)
-                {
-                    focusedView = null;
-                }
-                else
-                {
-                    //If FocusableView doesn't exist, not move focus.
-                    nextFocusedView = focusedView;
-                }
-            }
+            base.Dispose(type);
+        }
 
-            return nextFocusedView;
+        private void OnItemRelayout(object sender, EventArgs e)
+        {
+            //FIXME: we need to skip the first relayout and only call size changed when real size change happen.
+            //InternalItemsLayouter.NotifyItemSizeChanged((sender as ViewItem));
+            //InternalItemsLayouter.RequestLayout(ScrollingDirection == Direction.Horizontal ? ContentContainer.CurrentPosition.X : ContentContainer.CurrentPosition.Y);
+        }
+
+        private void DecorateItem(RecyclerViewItem item, int index, object context)
+        {
+            item.Index = index;
+            item.ParentItemsView = this;
+            item.Template = (ItemTemplate as DataTemplateSelector)?.SelectDataTemplate(InternalItemSource.GetItem(index), this) ?? ItemTemplate;
+            item.BindingContext = context;
+            item.Relayout += OnItemRelayout;
         }
     }
 }
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/SelectionChangedEventArgs.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/SelectionChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..6041b22
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using System.Collections.Generic;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// Selection changed event. this might be deprecated.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class SelectionChangedEventArgs : EventArgs
+    {
+        static readonly IReadOnlyList<object> selectEmpty = new List<object>(0);
+
+        /// <summary>
+        /// Previous selection list.
+        /// </summary>
+       [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<object> PreviousSelection { get; }
+
+        /// <summary>
+        /// Current selection list.    
+        ///  </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public IReadOnlyList<object> CurrentSelection { get; }
+
+
+        internal SelectionChangedEventArgs(object previousSelection, object currentSelection)
+        {
+            PreviousSelection = previousSelection != null ? new List<object>(1) { previousSelection } : selectEmpty;
+            CurrentSelection = currentSelection != null ? new List<object>(1) { currentSelection } : selectEmpty;
+        }
+
+        internal SelectionChangedEventArgs(IList<object> previousSelection, IList<object> currentSelection)
+        {
+            PreviousSelection = new List<object>(previousSelection ?? throw new ArgumentNullException(nameof(previousSelection)));
+            CurrentSelection = new List<object>(currentSelection ?? throw new ArgumentNullException(nameof(currentSelection)));
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/SelectionList.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/SelectionList.cs
new file mode 100644 (file)
index 0000000..c328fca
--- /dev/null
@@ -0,0 +1,157 @@
+/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace Tizen.NUI.Components
+{
+    // Used by the CollectionView to keep track of (and respond to changes in) the SelectedItems property
+    internal class SelectionList : IList<object>
+    {
+        static readonly IList<object> selectEmpty = new List<object>(0);
+        readonly CollectionView ColView;
+        readonly IList<object> internalList;
+        IList<object> shadowList;
+        bool externalChange;
+
+        public SelectionList(CollectionView colView, IList<object> items = null)
+        {
+            ColView = colView ?? throw new ArgumentNullException(nameof(colView));
+            internalList = items ?? new List<object>();
+            shadowList = Copy();
+
+            if (items is INotifyCollectionChanged incc)
+            {
+                incc.CollectionChanged += OnCollectionChanged;
+            }
+        }
+
+        public object this[int index] { get => internalList[index]; set => internalList[index] = value; }
+
+        public int Count => internalList.Count;
+
+        public bool IsReadOnly => false;
+
+        public void Add(object item)
+        {
+            externalChange = true;
+            internalList.Add(item);
+            externalChange = false;
+
+            ColView.SelectedItemsPropertyChanged(shadowList, internalList);
+            shadowList.Add(item);
+        }
+
+        public void Clear()
+        {
+            externalChange = true;
+            internalList.Clear();
+            externalChange = false;
+
+            ColView.SelectedItemsPropertyChanged(shadowList, selectEmpty);
+            shadowList.Clear();
+        }
+
+        public bool Contains(object item)
+        {
+            return internalList.Contains(item);
+        }
+
+        public void CopyTo(object[] array, int arrayIndex)
+        {
+            internalList.CopyTo(array, arrayIndex);
+        }
+
+        public IEnumerator<object> GetEnumerator()
+        {
+            return internalList.GetEnumerator();
+        }
+
+        public int IndexOf(object item)
+        {
+            return internalList.IndexOf(item);
+        }
+
+        public void Insert(int index, object item)
+        {
+            externalChange = true;
+            internalList.Insert(index, item);
+            externalChange = false;
+
+            ColView.SelectedItemsPropertyChanged(shadowList, internalList);
+            shadowList.Insert(index, item);
+        }
+
+        public bool Remove(object item)
+        {
+            externalChange = true;
+            var removed = internalList.Remove(item);
+            externalChange = false;
+
+            if (removed)
+            {
+                ColView.SelectedItemsPropertyChanged(shadowList, internalList);
+                shadowList.Remove(item);
+            }
+
+            return removed;
+        }
+
+        public void RemoveAt(int index)
+        {
+            externalChange = true;
+            internalList.RemoveAt(index);
+            externalChange = false;
+
+            ColView.SelectedItemsPropertyChanged(shadowList, internalList);
+            shadowList.RemoveAt(index);
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return internalList.GetEnumerator();
+        }
+
+        List<object> Copy()
+        {
+            var items = new List<object>();
+            for (int n = 0; n < internalList.Count; n++)
+            {
+                items.Add(internalList[n]);
+            }
+
+            return items;
+        }
+
+        void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
+        {
+            if (externalChange)
+            {
+                // If this change was initiated by a renderer or direct manipulation of ColllectionView.SelectedItems,
+                // we don't need to send a selection change notification
+                return;
+            }
+
+            // This change is coming from a bound viewmodel property
+            // Emit a selection change notification, then bring the shadow copy up-to-date
+            ColView.SelectedItemsPropertyChanged(shadowList, internalList);
+            shadowList = Copy();
+        }
+    }
+}
index 90efec2..337b1f9 100755 (executable)
@@ -372,7 +372,7 @@ namespace Tizen.NUI.Components
             {
                 if (scrollBar)
                 {
-                    scrollBar.Unparent();
+                    base.Remove(scrollBar);
                 }
                 scrollBar = value;
 
index bb62a64..094ca9d 100755 (executable)
@@ -21,6 +21,9 @@ using Tizen.NUI.Binding;
 
 namespace Tizen.NUI.Components
 {
+    // Represents padding data : Start, End, Top, Bottom
+    using PaddingType = ValueTuple<ushort, ushort, ushort, ushort>;
+
     /// <summary>
     /// The Scrollbar is a component that contains track and thumb to indicate the current scrolled position of a scrollable object.
     /// </summary>
@@ -201,6 +204,8 @@ namespace Tizen.NUI.Components
 
         /// <summary>
         /// The padding value of the track.
+        /// Note that when the scrollbar is for vertical direction, Start value is ignored.
+        /// In case of horizontal direction, Top value is ignored.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public Extents TrackPadding
@@ -233,55 +238,38 @@ namespace Tizen.NUI.Components
             thumbSizeAnimation?.Stop();
             thumbSizeAnimation = null;
 
-            Size trackSize = calculator.CalculateTrackSize(TrackThickness, containerSize, TrackPadding);
-            Vector2 trackPosition = calculator.CalculateTrackPosition(TrackPadding);
+            PaddingType ensuredPadding = EnsurePadding(TrackPadding);
+            Size trackSize = calculator.CalculateTrackSize(TrackThickness, containerSize, ensuredPadding);
+            Vector2 trackPosition = calculator.CalculateTrackPosition(ensuredPadding);
             Size thumbSize = calculator.CalculateThumbSize(ThumbThickness, trackSize);
-            Vector2 thumbPosition = calculator.CalculateThumbPosition(trackSize, thumbSize, TrackPadding);
-
-            if (trackVisual == null)
-            {
-                trackVisual = new ColorVisual
-                {
-                    SuppressUpdateVisual = true,
-                    MixColor = TrackColor,
-                    SizePolicy = VisualTransformPolicyType.Absolute,
-                    Origin = calculator.CalculatorTrackAlign(),
-                    AnchorPoint = calculator.CalculatorTrackAlign(),
-                    Size = trackSize,
-                    Position = trackPosition,
-                };
-
-                AddVisual("Track", trackVisual);
-            }
-            else
-            {
-                trackVisual.Size = trackSize;
-                trackVisual.Position = trackPosition;
-                trackVisual.UpdateVisual(true);
-            }
-
-            if (thumbVisual == null)
-            {
-                thumbVisual = new ColorVisual
-                {
-                    SuppressUpdateVisual = true,
-                    MixColor = ThumbColor,
-                    SizePolicy = VisualTransformPolicyType.Absolute,
-                    Origin = calculator.CalculatorThumbAlign(),
-                    AnchorPoint = calculator.CalculatorThumbAlign(),
-                    Opacity = calculator.CalculateThumbVisibility() ? 1.0f : 0.0f,
-                    Size = thumbSize,
-                    Position = thumbPosition,
-                };
-
-                AddVisual("Thumb", thumbVisual);
-            }
-            else
-            {
-                thumbVisual.Size = thumbSize;
-                thumbVisual.Position = thumbPosition;
-                thumbVisual.UpdateVisual(true);
-            }
+            Vector2 thumbPosition = calculator.CalculateThumbPosition(trackSize, thumbSize, ensuredPadding);
+
+            trackVisual = new ColorVisual
+            {
+                SuppressUpdateVisual = true,
+                MixColor = TrackColor,
+                SizePolicy = VisualTransformPolicyType.Absolute,
+                Origin = calculator.CalculatorTrackAlign(),
+                AnchorPoint = calculator.CalculatorTrackAlign(),
+                Size = trackSize,
+                Position = trackPosition,
+            };
+
+            AddVisual("Track", trackVisual);
+
+            thumbVisual = new ColorVisual
+            {
+                SuppressUpdateVisual = true,
+                MixColor = ThumbColor,
+                SizePolicy = VisualTransformPolicyType.Absolute,
+                Origin = calculator.CalculatorThumbAlign(),
+                AnchorPoint = calculator.CalculatorThumbAlign(),
+                Opacity = calculator.CalculateThumbVisibility() ? 1.0f : 0.0f,
+                Size = thumbSize,
+                Position = thumbPosition,
+            };
+
+            AddVisual("Thumb", thumbVisual);
         }
 
         /// <inheritdoc/>
@@ -299,7 +287,7 @@ namespace Tizen.NUI.Components
             calculator.currentPosition = position;
 
             thumbVisual.Size = calculator.CalculateThumbSize(ThumbThickness, trackVisual.Size);
-            thumbVisual.Position = calculator.CalculateThumbScrollPosition(trackVisual.Size, thumbVisual.Position, TrackPadding);
+            thumbVisual.Position = calculator.CalculateThumbScrollPosition(trackVisual.Size, thumbVisual.Position, EnsurePadding(TrackPadding));
             thumbVisual.Opacity = calculator.CalculateThumbVisibility() ? 1.0f : 0.0f;
 
             if (durationMs == 0)
@@ -338,7 +326,7 @@ namespace Tizen.NUI.Components
 
             previousPosition = calculator.currentPosition;
             calculator.currentPosition = position;
-            thumbVisual.Position = calculator.CalculateThumbScrollPosition(trackVisual.Size, thumbVisual.Position, TrackPadding);
+            thumbVisual.Position = calculator.CalculateThumbScrollPosition(trackVisual.Size, thumbVisual.Position, EnsurePadding(TrackPadding));
 
             if (durationMs == 0)
             {
@@ -373,10 +361,11 @@ namespace Tizen.NUI.Components
                 return;
             }
 
-            trackVisual.Size = calculator.CalculateTrackSize(TrackThickness, containerSize, TrackPadding);
-            trackVisual.Position = calculator.CalculateTrackPosition(TrackPadding);
+            PaddingType ensuredPadding = EnsurePadding(TrackPadding);
+            trackVisual.Size = calculator.CalculateTrackSize(TrackThickness, containerSize, ensuredPadding);
+            trackVisual.Position = calculator.CalculateTrackPosition(ensuredPadding);
             thumbVisual.Size = calculator.CalculateThumbSize(ThumbThickness, trackVisual.Size);
-            thumbVisual.Position = calculator.CalculateThumbPosition(trackVisual.Size, thumbVisual.Size, TrackPadding);
+            thumbVisual.Position = calculator.CalculateThumbPosition(trackVisual.Size, thumbVisual.Size, ensuredPadding);
 
             trackVisual.UpdateVisual(true);
             thumbVisual.UpdateVisual(true);
@@ -386,8 +375,6 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         public override void ApplyStyle(ViewStyle viewStyle)
         {
-            base.ApplyStyle(viewStyle);
-
             if (viewStyle is ScrollbarStyle scrollbarStyle)
             {
                 // Apply essential look.
@@ -399,6 +386,8 @@ namespace Tizen.NUI.Components
                 if (scrollbarStyle.WidthResizePolicy == null) scrollbarStyle.WidthResizePolicy = ResizePolicyType.FillToParent;
                 if (scrollbarStyle.HeightResizePolicy == null) scrollbarStyle.HeightResizePolicy = ResizePolicyType.FillToParent;
             }
+
+            base.ApplyStyle(viewStyle);
         }
 
         /// <inheritdoc/>
@@ -420,7 +409,7 @@ namespace Tizen.NUI.Components
                 return;
             }
 
-            trackVisual.Size = calculator.CalculateTrackSize(thickness, containerSize, TrackPadding);
+            trackVisual.Size = calculator.CalculateTrackSize(thickness, containerSize, EnsurePadding(TrackPadding));
             trackVisual.UpdateVisual(true);
         }
 
@@ -483,10 +472,11 @@ namespace Tizen.NUI.Components
                 return;
             }
 
-            trackVisual.Size = calculator.CalculateTrackSize(TrackThickness, containerSize, trackPadding);
-            trackVisual.Position = calculator.CalculateTrackPosition(trackPadding);
+            PaddingType ensuredPadding = EnsurePadding(trackPadding);
+            trackVisual.Size = calculator.CalculateTrackSize(TrackThickness, containerSize, ensuredPadding);
+            trackVisual.Position = calculator.CalculateTrackPosition(ensuredPadding);
             thumbVisual.Size = calculator.CalculateThumbSize(ThumbThickness, trackVisual.Size);
-            thumbVisual.Position = calculator.CalculateThumbPaddingPosition(trackVisual.Size, thumbVisual.Size, thumbVisual.Position, trackPadding);
+            thumbVisual.Position = calculator.CalculateThumbPaddingPosition(trackVisual.Size, thumbVisual.Size, thumbVisual.Position, ensuredPadding);
 
             trackVisual.UpdateVisual(true);
             thumbVisual.UpdateVisual(true);
@@ -565,6 +555,8 @@ namespace Tizen.NUI.Components
             }
         }
 
+        private PaddingType EnsurePadding(Extents padding) => padding == null ? new PaddingType(0, 0, 0 ,0) : new PaddingType(padding.Start, padding.End, padding.Top, padding.Bottom);
+
         #endregion Methods
 
 
@@ -590,12 +582,12 @@ namespace Tizen.NUI.Components
 
             public abstract Visual.AlignType CalculatorTrackAlign();
             public abstract Visual.AlignType CalculatorThumbAlign();
-            public abstract Size CalculateTrackSize(float thickness, Size containerSize, Extents trackPadding);
-            public abstract Vector2 CalculateTrackPosition(Extents trackPadding);
+            public abstract Size CalculateTrackSize(float thickness, Size containerSize, PaddingType trackPadding);
+            public abstract Vector2 CalculateTrackPosition(PaddingType trackPadding);
             public abstract Size CalculateThumbSize(float thickness, Size trackSize);
-            public abstract Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, Extents trackPadding);
-            public abstract Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, Extents trackPadding);
-            public abstract Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbCurrentPosition, Extents trackPadding);
+            public abstract Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, PaddingType trackPadding);
+            public abstract Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, PaddingType trackPadding);
+            public abstract Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbCurrentPosition, PaddingType trackPadding);
         }
 
         private class HorizontalCalculator : Calculator
@@ -606,7 +598,7 @@ namespace Tizen.NUI.Components
 
             public override Visual.AlignType CalculatorTrackAlign()
             {
-                return Visual.AlignType.BottomCenter;
+                return Visual.AlignType.BottomBegin;
             }
 
             public override Visual.AlignType CalculatorThumbAlign()
@@ -614,14 +606,14 @@ namespace Tizen.NUI.Components
                 return Visual.AlignType.BottomBegin;
             }
 
-            public override Size CalculateTrackSize(float thickness, Size containerSize, Extents trackPadding)
+            public override Size CalculateTrackSize(float thickness, Size containerSize, PaddingType trackPadding)
             {
-                return new Size(containerSize.Width - trackPadding?.Start ?? 0 - trackPadding?.End ?? 0, thickness);
+                return new Size(containerSize.Width - trackPadding.Item1 - trackPadding.Item2, thickness);
             }
 
-            public override Vector2 CalculateTrackPosition(Extents trackPadding)
+            public override Vector2 CalculateTrackPosition(PaddingType trackPadding)
             {
-                return new Vector2(0, -trackPadding?.Bottom ?? 0);
+                return new Vector2(trackPadding.Item1, -trackPadding.Item4);
             }
 
             public override Size CalculateThumbSize(float thickness, Size trackSize)
@@ -629,23 +621,23 @@ namespace Tizen.NUI.Components
                 return new Size(trackSize.Width * visibleLength / contentLength, thickness);
             }
 
-            public override Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, Extents trackPadding)
+            public override Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, PaddingType trackPadding)
             {
-                float padding = ((trackSize.Height - thumbSize.Height) / 2.0f) + trackPadding?.Bottom ?? 0;
+                float padding = ((trackSize.Height - thumbSize.Height) / 2.0f) + trackPadding.Item4;
                 float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
-                return new Vector2((trackPadding?.Start ?? 0) + trackSize.Width * pos / contentLength, -padding);
+                return new Vector2(trackPadding.Item1 + trackSize.Width * pos / contentLength, -padding);
             }
 
-            public override Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, Extents trackPadding)
+            public override Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, PaddingType trackPadding)
             {
-                float padding = ((trackSize.Height - thumbSize.Height) / 2.0f) + trackPadding?.Bottom ?? 0;
+                float padding = ((trackSize.Height - thumbSize.Height) / 2.0f) + trackPadding.Item4;
                 return new Vector2(thumbCurrentPosition.X, -padding);
             }
 
-            public override Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbCurrentPosition, Extents trackPadding)
+            public override Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbCurrentPosition, PaddingType trackPadding)
             {
                 float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
-                return new Vector2((trackPadding?.Start ?? 0) + trackSize.Width * pos / contentLength, thumbCurrentPosition.Y);
+                return new Vector2(trackPadding.Item1 + trackSize.Width * pos / contentLength, thumbCurrentPosition.Y);
             }
         }
 
@@ -657,7 +649,7 @@ namespace Tizen.NUI.Components
 
             public override Visual.AlignType CalculatorTrackAlign()
             {
-                return Visual.AlignType.CenterEnd;
+                return Visual.AlignType.TopEnd;
             }
 
             public override Visual.AlignType CalculatorThumbAlign()
@@ -665,14 +657,14 @@ namespace Tizen.NUI.Components
                 return Visual.AlignType.TopEnd;
             }
 
-            public override Size CalculateTrackSize(float thickness, Size containerSize, Extents trackPadding)
+            public override Size CalculateTrackSize(float thickness, Size containerSize, PaddingType trackPadding)
             {
-                return new Size(thickness, containerSize.Height - trackPadding?.Top ?? 0 - trackPadding?.Bottom ?? 0);
+                return new Size(thickness, containerSize.Height - trackPadding.Item3 - trackPadding.Item4);
             }
 
-            public override Vector2 CalculateTrackPosition(Extents trackPadding)
+            public override Vector2 CalculateTrackPosition(PaddingType trackPadding)
             {
-                return new Vector2(-trackPadding?.End ?? 0, 0);
+                return new Vector2(-trackPadding.Item2, trackPadding.Item3);
             }
 
             public override Size CalculateThumbSize(float thickness, Size trackSize)
@@ -680,23 +672,23 @@ namespace Tizen.NUI.Components
                 return new Size(thickness, trackSize.Height * visibleLength / contentLength);
             }
 
-            public override Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, Extents trackPadding)
+            public override Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, PaddingType trackPadding)
             {
-                float padding = ((trackSize.Width - thumbSize.Width) / 2.0f) + trackPadding?.End ?? 0;
+                float padding = ((trackSize.Width - thumbSize.Width) / 2.0f) + trackPadding.Item2;
                 float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
-                return new Vector2(-padding, trackPadding?.Top ?? 0 + trackSize.Height * pos / contentLength);
+                return new Vector2(-padding, trackPadding.Item3 + trackSize.Height * pos / contentLength);
             }
 
-            public override Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, Extents trackPadding)
+            public override Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, PaddingType trackPadding)
             {
-                float padding = ((trackSize.Width - thumbSize.Width) / 2.0f) + trackPadding?.End ?? 0;
+                float padding = ((trackSize.Width - thumbSize.Width) / 2.0f) + trackPadding.Item2;
                 return new Vector2(-padding, thumbCurrentPosition.Y);
             }
 
-            public override Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbPosition, Extents trackPadding)
+            public override Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbPosition, PaddingType trackPadding)
             {
                 float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
-                return new Vector2(thumbPosition.X, trackPadding?.Top ?? 0 + trackSize.Height * pos / contentLength);
+                return new Vector2(thumbPosition.X, trackPadding.Item1 + trackSize.Height * pos / contentLength);
             }
         }
 
index a03745b..6471f17 100755 (executable)
@@ -10,6 +10,10 @@ namespace Tizen.NUI.Components
         private ImageView bgTrackImage = null;
         // the slided track image object
         private ImageView slidedTrackImage = null;
+        // the warning track image object
+        private ImageView warningTrackImage = null;
+        // the warning slided track image object
+        private ImageView warningSlidedTrackImage = null;
         // the thumb image object
         private ImageView thumbImage = null;
         // the low indicator image object
@@ -31,6 +35,8 @@ namespace Tizen.NUI.Components
         private float maxValue = 100;
         // the current value
         private float curValue = 0;
+        // the warning start value
+        private float warningStartValue = 100;
         // the size of the low indicator
         private Size lowIndicatorSize = null;
         // the size of the high indicator
@@ -46,6 +52,21 @@ namespace Tizen.NUI.Components
         // the value indicator image object
         private ImageView valueIndicatorImage = null;
 
+        // To store the thumb size of normal state
+        private Size thumbSize = null;
+        // To store the thumb image url of normal state
+        private string thumbImageUrl = null;
+        // To store the thumb image url selector of normal state
+        private Selector<string> thumbImageUrlSelector = null;
+        // To store the thumb color of normal state
+        private Color thumbColor = Color.White;
+        // To store the thumb image url of warning state
+        private string warningThumbImageUrl = null;
+        // To store the thumb image url selector of warning state
+        private Selector<string> warningThumbImageUrlSelector = null;
+        // To store the thumb color of warning state
+        private Color warningThumbColor = null;
+
         private PanGestureDetector panGestureDetector = null;
         private float currentSlidedOffset;
         private EventHandler<ValueChangedArgs> valueChangedHandler;
@@ -89,14 +110,57 @@ namespace Tizen.NUI.Components
                 {
                     bgTrackImage.Add(slidedTrackImage);
                 }
+            }
 
-                if (null != thumbImage)
+            return slidedTrackImage;
+        }
+
+        private ImageView CreateWarningTrack()
+        {
+            if (null == warningTrackImage)
+            {
+                warningTrackImage = new ImageView()
+                {
+                    WidthResizePolicy = ResizePolicyType.Fixed,
+                    HeightResizePolicy = ResizePolicyType.Fixed
+                };
+
+                if (bgTrackImage != null)
+                {
+                    bgTrackImage.Add(warningTrackImage);
+                }
+
+                if (warningSlidedTrackImage != null)
                 {
-                    slidedTrackImage.Add(thumbImage);
+                    warningTrackImage.Add(warningSlidedTrackImage);
+                }
+
+                if (slidedTrackImage != null)
+                {
+                    warningTrackImage.RaiseAbove(slidedTrackImage);
                 }
             }
 
-            return slidedTrackImage;
+            return warningTrackImage;
+        }
+
+        private ImageView CreateWarningSlidedTrack()
+        {
+            if (null == warningSlidedTrackImage)
+            {
+                warningSlidedTrackImage = new ImageView()
+                {
+                    WidthResizePolicy = ResizePolicyType.Fixed,
+                    HeightResizePolicy = ResizePolicyType.Fixed
+                };
+
+                if (warningTrackImage != null)
+                {
+                    warningTrackImage.Add(warningSlidedTrackImage);
+                }
+            }
+
+            return warningSlidedTrackImage;
         }
 
         private TextLabel CreateLowIndicatorText()
@@ -147,6 +211,15 @@ namespace Tizen.NUI.Components
                 {
                     bgTrackImage.Add(slidedTrackImage);
                 }
+                if (null != warningTrackImage)
+                {
+                    bgTrackImage.Add(warningTrackImage);
+                }
+                if (null != thumbImage)
+                {
+                    bgTrackImage.Add(thumbImage);
+                    thumbImage.RaiseToTop();
+                }
 
                 bgTrackImage.TouchEvent += OnTouchEventForBgTrack;
             }
@@ -166,10 +239,11 @@ namespace Tizen.NUI.Components
                     PivotPoint = NUI.PivotPoint.Center,
                     PositionUsesPivotPoint = true
                 };
-                if (slidedTrackImage != null)
+                if (bgTrackImage != null)
                 {
-                    slidedTrackImage.Add(thumbImage);
+                    bgTrackImage.Add(thumbImage);
                 }
+                thumbImage.RaiseToTop();
                 thumbImage.TouchEvent += OnTouchEventForThumb;
             }
 
@@ -178,7 +252,7 @@ namespace Tizen.NUI.Components
 
         private ImageView CreateValueIndicator()
         {
-            if (null == valueIndicatorImage)
+            if (valueIndicatorImage == null)
             {
                 valueIndicatorImage = new ImageView()
                 {
@@ -294,9 +368,21 @@ namespace Tizen.NUI.Components
                     slidedTrackImage.PivotPoint = NUI.PivotPoint.CenterLeft;
                     slidedTrackImage.PositionUsesPivotPoint = true;
                 }
+                if (warningTrackImage != null)
+                {
+                    warningTrackImage.ParentOrigin = NUI.ParentOrigin.CenterRight;
+                    warningTrackImage.PivotPoint = NUI.PivotPoint.CenterRight;
+                    warningTrackImage.PositionUsesPivotPoint = true;
+                }
+                if (warningSlidedTrackImage != null)
+                {
+                    warningSlidedTrackImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
+                    warningSlidedTrackImage.PivotPoint = NUI.PivotPoint.CenterLeft;
+                    warningSlidedTrackImage.PositionUsesPivotPoint = true;
+                }
                 if (thumbImage != null)
                 {
-                    thumbImage.ParentOrigin = NUI.ParentOrigin.CenterRight;
+                    thumbImage.ParentOrigin = NUI.ParentOrigin.CenterLeft;
                     thumbImage.PivotPoint = NUI.PivotPoint.Center;
                     thumbImage.PositionUsesPivotPoint = true;
                 }
@@ -354,9 +440,21 @@ namespace Tizen.NUI.Components
                     slidedTrackImage.PivotPoint = NUI.PivotPoint.BottomCenter;
                     slidedTrackImage.PositionUsesPivotPoint = true;
                 }
+                if (warningTrackImage != null)
+                {
+                    warningTrackImage.ParentOrigin = NUI.ParentOrigin.TopCenter;
+                    warningTrackImage.PivotPoint = NUI.PivotPoint.TopCenter;
+                    warningTrackImage.PositionUsesPivotPoint = true;
+                }
+                if (warningSlidedTrackImage != null)
+                {
+                    warningSlidedTrackImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
+                    warningSlidedTrackImage.PivotPoint = NUI.PivotPoint.BottomCenter;
+                    warningSlidedTrackImage.PositionUsesPivotPoint = true;
+                }
                 if (thumbImage != null)
                 {
-                    thumbImage.ParentOrigin = NUI.ParentOrigin.TopCenter;
+                    thumbImage.ParentOrigin = NUI.ParentOrigin.BottomCenter;
                     thumbImage.PivotPoint = NUI.PivotPoint.Center;
                     thumbImage.PositionUsesPivotPoint = true;
                 }
@@ -581,6 +679,8 @@ namespace Tizen.NUI.Components
                 }
                 float slidedTrackLength = (float)BgTrackLength() * ratio;
                 slidedTrackImage.Size2D = new Size2D((int)(slidedTrackLength + round), (int)curTrackThickness); //Add const round to reach Math.Round function.
+                thumbImage.Position = new Position(slidedTrackImage.Size2D.Width, 0);
+                thumbImage.RaiseToTop();
 
                 if (isValueShown)
                 {
@@ -590,13 +690,49 @@ namespace Tizen.NUI.Components
             else if (direction == DirectionType.Vertical)
             {
                 float slidedTrackLength = (float)BgTrackLength() * ratio;
-                slidedTrackImage.Size2D = new Size2D((int)(curTrackThickness + round), (int)slidedTrackLength); //Add const round to reach Math.Round function.
+                slidedTrackImage.Size2D = new Size2D((int)curTrackThickness, (int)(slidedTrackLength + round)); //Add const round to reach Math.Round function.
+                thumbImage.Position = new Position(0, -slidedTrackImage.Size2D.Height);
+                thumbImage.RaiseToTop();
 
                 if (isValueShown)
                 {
                     valueIndicatorImage.Position = new Position(0, -(slidedTrackImage.Size2D.Height + thumbImage.Size.Height / 2));
                 }
             }
+
+            // Update the track and thumb when the value is over warning value.
+            if (curValue >= warningStartValue)
+            {
+                if (direction == DirectionType.Horizontal)
+                {
+                    warningSlidedTrackImage.Size2D = new Size2D((int)(((curValue - warningStartValue) / 100) * this.Size2D.Width), (int)curTrackThickness);
+                }
+                else if (direction == DirectionType.Vertical)
+                {
+                    warningSlidedTrackImage.Size2D = new Size2D((int)curTrackThickness, (int)(((curValue - warningStartValue) / 100) * this.Size2D.Height));
+                }
+
+                if (warningThumbColor != null && thumbImage.Color.NotEqualTo(warningThumbColor))
+                {
+                    thumbImage.Color = warningThumbColor;
+                }
+                if (warningThumbImageUrl != null && !thumbImage.ResourceUrl.Equals(warningThumbImageUrl))
+                {
+                    thumbImage.ResourceUrl = warningThumbImageUrl;
+                }
+            }
+            else
+            {
+                warningSlidedTrackImage.Size2D = new Size2D(0, 0);
+                if (warningThumbColor != null && thumbImage.Color.EqualTo(warningThumbColor))
+                {
+                    thumbImage.Color = thumbColor;
+                }
+                if (warningThumbImageUrl != null && thumbImage.ResourceUrl.Equals(warningThumbImageUrl))
+                {
+                    thumbImage.ResourceUrl = thumbImageUrl;
+                }
+            }
         }
 
         private uint CurrentTrackThickness()
@@ -633,6 +769,27 @@ namespace Tizen.NUI.Components
             return curSpace;
         }
 
+        private void UpdateWarningTrackSize()
+        {
+            if (warningTrackImage == null)
+            {
+                return;
+            }
+
+            int curTrackThickness = (int)CurrentTrackThickness();
+            float warningTrackLength = maxValue - warningStartValue;
+            if (direction == DirectionType.Horizontal)
+            {
+                warningTrackLength = (warningTrackLength / 100) * this.Size2D.Width;
+                warningTrackImage.Size2D = new Size2D((int)warningTrackLength, curTrackThickness);
+            }
+            else if (direction == DirectionType.Vertical)
+            {
+                warningTrackLength = (warningTrackLength / 100) * this.Size2D.Height;
+                warningTrackImage.Size2D = new Size2D(curTrackThickness, (int)warningTrackLength);
+            }
+        }
+
         private IndicatorType CurrentIndicatorType()
         {
             IndicatorType type = IndicatorType.None;
index 24d7fe7..de51ed3 100755 (executable)
@@ -66,6 +66,9 @@ namespace Tizen.NUI.Components
     /// <since_tizen> 6 </since_tizen>
     public partial class Slider : Control
     {
+        /// <summary>
+        /// IndicatorTypeProperty
+        /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty IndicatorTypeProperty = BindableProperty.Create("IndicatorType", typeof(IndicatorType), typeof(Slider), IndicatorType.None, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -80,6 +83,10 @@ namespace Tizen.NUI.Components
             var instance = (Slider)bindable;
             return instance.privateIndicatorType;
         });
+
+        /// <summary>
+        /// SpaceBetweenTrackAndIndicatorProperty
+        /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty SpaceBetweenTrackAndIndicatorProperty = BindableProperty.Create(nameof(SpaceBetweenTrackAndIndicator), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -94,6 +101,10 @@ namespace Tizen.NUI.Components
             var instance = (Slider)bindable;
             return instance.privateSpaceBetweenTrackAndIndicator;
         });
+
+        /// <summary>
+        /// TrackThicknessProperty
+        /// </summary>       
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty TrackThicknessProperty = BindableProperty.Create(nameof(TrackThickness), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -108,6 +119,10 @@ namespace Tizen.NUI.Components
             var instance = (Slider)bindable;
             return instance.privateTrackThickness;
         });
+
+        /// <summary>
+        /// IsValueShownProperty
+        /// </summary> 
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty IsValueShownProperty = BindableProperty.Create(nameof(IsValueShown), typeof(bool), typeof(Slider), true, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -126,6 +141,10 @@ namespace Tizen.NUI.Components
             var instance = (Slider)bindable;
             return instance.isValueShown;
         });
+
+        /// <summary>
+        /// ValueIndicatorTextProperty
+        /// </summary> 
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty ValueIndicatorTextProperty = BindableProperty.Create(nameof(ValueIndicatorText), typeof(string), typeof(Slider), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -366,6 +385,7 @@ namespace Tizen.NUI.Components
                 RelayoutBaseComponent(false);
                 UpdateBgTrackSize();
                 UpdateBgTrackPosition();
+                UpdateWarningTrackSize();
                 UpdateValue();
             }
         }
@@ -452,6 +472,7 @@ namespace Tizen.NUI.Components
                 if (null != thumbImage)
                 {
                     thumbImage.Size = value;
+                    thumbSize = value;
                     sliderStyle.Thumb.Size = value;
                 }
             }
@@ -459,6 +480,8 @@ namespace Tizen.NUI.Components
 
         /// <summary>
         /// Gets or sets the resource url of the thumb image object.
+        ///
+        /// Please use ThumbImageUri property.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
         public string ThumbImageURL
@@ -472,6 +495,7 @@ namespace Tizen.NUI.Components
                 if (null != thumbImage)
                 {
                     thumbImage.ResourceUrl = value;
+                    thumbImageUrl = value;
                     sliderStyle.Thumb.ResourceUrl = value;
                 }
             }
@@ -480,6 +504,8 @@ namespace Tizen.NUI.Components
         /// <summary>
         /// Gets or sets the resource url selector of the thumb image object.
         /// Getter returns copied selector value if exist, null otherwise.
+        ///
+        /// Please use ThumbImageUri property.
         /// </summary>
         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
         /// <since_tizen> 6 </since_tizen>
@@ -495,6 +521,41 @@ namespace Tizen.NUI.Components
                 else
                 {
                     thumbImage.SetValue(ImageView.ResourceUrlSelectorProperty, value);
+                    thumbImageUrlSelector = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the Uri of the thumb image.
+        /// </summary>
+        /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Selector<Uri> ThumbImageUri
+        {
+            get
+            {
+                if (thumbImage == null)
+                {
+                    return null;
+                }
+                else
+                {
+                    return ((Selector<string>)thumbImage.GetValue(ImageView.ResourceUrlSelectorProperty)).Clone<Uri>(str => { return new Uri(str); });
+                }
+            }
+            set
+            {
+                if (value == null || thumbImage == null)
+                {
+                    throw new NullReferenceException("Slider.ThumbImageUri is null");
+                }
+                else
+                {
+                    Selector<string> stringValue = value.Clone<string>(m => m?.AbsoluteUri);
+                    thumbImage.SetValue(ImageView.ResourceUrlSelectorProperty, stringValue);
+                    thumbImageUrlSelector = stringValue;
                 }
             }
         }
@@ -514,6 +575,7 @@ namespace Tizen.NUI.Components
                 if (null != thumbImage)
                 {
                     thumbImage.Color = value;
+                    thumbColor = value;
                     sliderStyle.Thumb.Color = value;
                 }
             }
@@ -576,6 +638,125 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
+        /// Gets or sets the warning start value between minimum value and maximum value of slider.
+        /// </summary>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float WarningStartValue
+        {
+            get
+            {
+                return warningStartValue;
+            }
+            set
+            {
+                warningStartValue = value;
+                UpdateValue();
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the color of the warning track image object.
+        /// </summary>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color WarningTrackColor
+        {
+            get
+            {
+                return warningTrackImage?.BackgroundColor;
+            }
+            set
+            {
+                if (null != warningTrackImage)
+                {
+                    warningTrackImage.BackgroundColor = value;
+                    sliderStyle.WarningTrack.BackgroundColor = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the color of the warning slided track image object.
+        /// </summary>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color WarningSlidedTrackColor
+        {
+            get
+            {
+                return warningSlidedTrackImage?.BackgroundColor;
+            }
+            set
+            {
+                if (null != warningSlidedTrackImage)
+                {
+                    warningSlidedTrackImage.BackgroundColor = value;
+                    sliderStyle.WarningProgress.BackgroundColor = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the resource url of the warning thumb image object.
+        /// </summary>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string WarningThumbImageUrl
+        {
+            get
+            {
+                return warningThumbImageUrl;
+            }
+            set
+            {
+                warningThumbImageUrl = value;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the Uri of the warning thumb image.
+        /// </summary>
+        /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Selector<Uri> WarningThumbImageUri
+        {
+            get
+            {
+                return warningThumbImageUrlSelector?.Clone<Uri>(str => { return new Uri(str); });
+            }
+            set
+            {
+                 if (value == null || thumbImage == null)
+                {
+                    throw new NullReferenceException("Slider.WarningThumbImageUri is null");
+                }
+                else
+                {
+                    warningThumbImageUrlSelector = value.Clone<string>(m => m?.AbsoluteUri);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the color of the warning thumb image object.
+        /// </summary>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color WarningThumbColor
+        {
+            get
+            {
+                return warningThumbColor;
+            }
+            set
+            {
+                warningThumbColor = value;
+            }
+        }
+
+        /// <summary>
         /// Gets or sets the resource url of the low indicator image object.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
@@ -851,6 +1032,28 @@ namespace Tizen.NUI.Components
                         slidedTrackImage.SizeWidth = (float)trackThickness.Value;
                     }
                 }
+                if (warningTrackImage != null)
+                {
+                    if (direction == DirectionType.Horizontal)
+                    {
+                        warningTrackImage.SizeHeight = (float)trackThickness.Value;
+                    }
+                    else if (direction == DirectionType.Vertical)
+                    {
+                        warningTrackImage.SizeWidth = (float)trackThickness.Value;
+                    }
+                }
+                if (warningSlidedTrackImage != null)
+                {
+                    if (direction == DirectionType.Horizontal)
+                    {
+                        warningSlidedTrackImage.SizeHeight = (float)trackThickness.Value;
+                    }
+                    else if (direction == DirectionType.Vertical)
+                    {
+                        warningSlidedTrackImage.SizeWidth = (float)trackThickness.Value;
+                    }
+                }
             }
         }
 
@@ -951,6 +1154,16 @@ namespace Tizen.NUI.Components
                 CreateValueIndicator().ApplyStyle(sliderStyle.ValueIndicatorImage);
             }
 
+            if (null != sliderStyle?.WarningTrack)
+            {
+                CreateWarningTrack().ApplyStyle(sliderStyle.WarningTrack);
+            }
+
+            if (null != sliderStyle?.WarningProgress)
+            {
+                CreateWarningSlidedTrack().ApplyStyle(sliderStyle.WarningProgress);
+            }
+
             EnableControlStatePropagation = true;
         }
 
@@ -991,6 +1204,8 @@ namespace Tizen.NUI.Components
                     thumbImage.TouchEvent -= OnTouchEventForThumb;
                     Utility.Dispose(thumbImage);
                 }
+                Utility.Dispose(warningSlidedTrackImage);
+                Utility.Dispose(warningTrackImage);
                 Utility.Dispose(slidedTrackImage);
                 if (null != bgTrackImage)
                 {
@@ -1021,6 +1236,7 @@ namespace Tizen.NUI.Components
             UpdateComponentByIndicatorTypeChanged();
             UpdateBgTrackSize();
             UpdateBgTrackPosition();
+            UpdateWarningTrackSize();
             UpdateLowIndicatorSize();
             UpdateValue();
         }
@@ -1158,6 +1374,8 @@ namespace Tizen.NUI.Components
             if (!isFocused && !isPressed)
             {
                 ControlState = ControlState.Normal;
+                thumbImage.ResourceUrl = thumbImageUrlSelector?.Normal;
+
                 if (stateChangedHandler != null)
                 {
                     StateChangedArgs args = new StateChangedArgs();
@@ -1168,6 +1386,7 @@ namespace Tizen.NUI.Components
             else if (isPressed)
             {
                 ControlState = ControlState.Pressed;
+                thumbImage.ResourceUrl = thumbImageUrlSelector?.Pressed;
 
                 if (stateChangedHandler != null)
                 {
@@ -1179,6 +1398,7 @@ namespace Tizen.NUI.Components
             else if (!isPressed && isFocused)
             {
                 ControlState = ControlState.Focused;
+                thumbImage.ResourceUrl = thumbImageUrlSelector?.Focused;
 
                 if (stateChangedHandler != null)
                 {
index 7593717..ed364e7 100755 (executable)
@@ -29,7 +29,7 @@ namespace Tizen.NUI.Components
     {
         static ControlStyle()
         {
-            ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+            ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
         }
 
         /// <summary>
diff --git a/src/Tizen.NUI.Components/Style/DefaultGridItemStyle.cs b/src/Tizen.NUI.Components/Style/DefaultGridItemStyle.cs
new file mode 100644 (file)
index 0000000..1149b28
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// DefaultGridItemStyle is a class which saves DefaultLinearItem's ux data.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DefaultGridItemStyle : RecyclerViewItemStyle
+    {
+    
+        static DefaultGridItemStyle() { }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultGridItemStyle.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public DefaultGridItemStyle() : base()
+        {
+        }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultGridItemStyle with style.
+        /// </summary>
+        /// <param name="style">Create DefaultGridItemStyle by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultGridItemStyle(DefaultGridItemStyle style) : base(style)
+        {
+        }
+
+
+        /// <summary>
+        /// Label Text's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabelStyle Caption { get; set; } = new TextLabelStyle();
+
+        /// <summary>
+        /// Icon's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ImageViewStyle Image { get; set; } = new ImageViewStyle();
+
+        /// <summary>
+        /// Extra's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ViewStyle Badge { get; set; } = new ViewStyle();
+
+        /// <summary>
+        /// Style's clone function.
+        /// </summary>
+        /// <param name="bindableObject">The style that need to copy.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void CopyFrom(BindableObject bindableObject)
+        {
+            base.CopyFrom(bindableObject);
+
+            if (bindableObject is DefaultGridItemStyle RecyclerViewItemStyle)
+            {
+                Caption.CopyFrom(RecyclerViewItemStyle.Caption);
+                Image.CopyFrom(RecyclerViewItemStyle.Image);
+                Badge.CopyFrom(RecyclerViewItemStyle.Badge);
+                //Border.CopyFrom(RecyclerViewItemStyle.Border);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Style/DefaultLinearItemStyle.cs b/src/Tizen.NUI.Components/Style/DefaultLinearItemStyle.cs
new file mode 100644 (file)
index 0000000..f990a7c
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// DefaultLinearItemStyle is a class which saves DefaultLinearItem's ux data.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DefaultLinearItemStyle : RecyclerViewItemStyle
+    {
+        static DefaultLinearItemStyle() { }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultLinearItemStyle.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public DefaultLinearItemStyle() : base()
+        {
+        }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultLinearItemStyle with style.
+        /// </summary>
+        /// <param name="style">Create DefaultLinearItemStyle by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultLinearItemStyle(DefaultLinearItemStyle style) : base(style)
+        {
+        }
+
+        /// <summary>
+        /// Label Text's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabelStyle Label { get; set; } = new TextLabelStyle();
+
+        /// <summary>
+        /// Sublabel Text's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabelStyle SubLabel { get; set; } = new TextLabelStyle();
+
+        /// <summary>
+        /// Icon's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ViewStyle Icon { get; set; } = new ViewStyle();
+
+        /// <summary>
+        /// Extra's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ViewStyle Extra { get; set; } = new ViewStyle();
+
+        /// <summary>
+        /// Seperator's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ViewStyle Seperator { get; set; } = new ViewStyle();
+
+        /// <summary>
+        /// Style's clone function.
+        /// </summary>
+        /// <param name="bindableObject">The style that need to copy.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void CopyFrom(BindableObject bindableObject)
+        {
+            base.CopyFrom(bindableObject);
+
+            if (bindableObject is DefaultLinearItemStyle RecyclerViewItemStyle)
+            {
+                Label.CopyFrom(RecyclerViewItemStyle.Label);
+                SubLabel.CopyFrom(RecyclerViewItemStyle.SubLabel);
+                Icon.CopyFrom(RecyclerViewItemStyle.Icon);
+                Extra.CopyFrom(RecyclerViewItemStyle.Extra);
+                Seperator.CopyFrom(RecyclerViewItemStyle.Seperator);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Style/DefaultTitleItemStyle.cs b/src/Tizen.NUI.Components/Style/DefaultTitleItemStyle.cs
new file mode 100644 (file)
index 0000000..d68c2b9
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// DefaultTitleItemStyle is a class which saves DefaultLinearItem's ux data.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DefaultTitleItemStyle : RecyclerViewItemStyle
+    {
+        static DefaultTitleItemStyle() { }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultTitleItemStyle.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public DefaultTitleItemStyle() : base()
+        {
+        }
+
+        /// <summary>
+        /// Creates a new instance of a DefaultTitleItemStyle with style.
+        /// </summary>
+        /// <param name="style">Create DefaultTitleItemStyle by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public DefaultTitleItemStyle(DefaultTitleItemStyle style) : base(style)
+        {
+        }
+
+        /// <summary>
+        /// Label Text's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabelStyle Label { get; set; } = new TextLabelStyle();
+
+        /// <summary>
+        /// Icon's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ViewStyle Icon { get; set; } = new ViewStyle();
+
+        /// <summary>
+        /// Seperator's style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ViewStyle Seperator { get; set; } = new ViewStyle();
+
+        /// <summary>
+        /// Style's clone function.
+        /// </summary>
+        /// <param name="bindableObject">The style that need to copy.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void CopyFrom(BindableObject bindableObject)
+        {
+            base.CopyFrom(bindableObject);
+
+            if (bindableObject is DefaultTitleItemStyle RecyclerViewItemStyle)
+            {
+                Label.CopyFrom(RecyclerViewItemStyle.Label);
+                Icon.CopyFrom(RecyclerViewItemStyle.Icon);
+                Seperator.CopyFrom(RecyclerViewItemStyle.Seperator);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.NUI.Components/Style/RecyclerViewItemStyle.cs b/src/Tizen.NUI.Components/Style/RecyclerViewItemStyle.cs
new file mode 100644 (file)
index 0000000..8fa6311
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components.Extension;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// RecyclerViewItemStyle is a class which saves RecyclerViewItem's ux data.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class RecyclerViewItemStyle : ControlStyle
+    {
+        /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool?), typeof(RecyclerViewItemStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var RecyclerViewItemStyle = (RecyclerViewItemStyle)bindable;
+            RecyclerViewItemStyle.isSelectable = (bool?)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var RecyclerViewItemStyle = (RecyclerViewItemStyle)bindable;
+            return RecyclerViewItemStyle.isSelectable;
+        });
+        /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool?), typeof(RecyclerViewItemStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var RecyclerViewItemStyle = (RecyclerViewItemStyle)bindable;
+            RecyclerViewItemStyle.isSelected = (bool?)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var RecyclerViewItemStyle = (RecyclerViewItemStyle)bindable;
+            return RecyclerViewItemStyle.isSelected;
+        });
+        /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool?), typeof(RecyclerViewItemStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var RecyclerViewItemStyle = (RecyclerViewItemStyle)bindable;
+            RecyclerViewItemStyle.isEnabled = (bool?)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var RecyclerViewItemStyle = (RecyclerViewItemStyle)bindable;
+            return RecyclerViewItemStyle.isEnabled;
+        });
+
+        private bool? isSelectable;
+        private bool? isSelected;
+        private bool? isEnabled;
+
+        static RecyclerViewItemStyle() { }
+
+        /// <summary>
+        /// Creates a new instance of a RecyclerViewItemStyle.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public RecyclerViewItemStyle() : base()
+        {
+        }
+
+        /// <summary>
+        /// Creates a new instance of a RecyclerViewItemStyle with style.
+        /// </summary>
+        /// <param name="style">Create RecyclerViewItemStyle by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecyclerViewItemStyle(RecyclerViewItemStyle style) : base(style)
+        {
+        }
+
+        /// <summary>
+        /// Flag to decide RecyclerViewItem can be selected or not.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool? IsSelectable
+        {
+            get => (bool?)GetValue(IsSelectableProperty);
+            set => SetValue(IsSelectableProperty, value);
+        }
+
+        /// <summary>
+        /// Flag to decide selected state in RecyclerViewItem.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool? IsSelected
+        {
+            get => (bool?)GetValue(IsSelectedProperty);
+            set => SetValue(IsSelectedProperty, value);
+        }
+
+        /// <summary>
+        /// Flag to decide RecyclerViewItem can be selected or not.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool? IsEnabled
+        {
+            get => (bool?)GetValue(IsEnabledProperty);
+            set => SetValue(IsEnabledProperty, value);
+        }
+
+        /// <summary>
+        /// Style's clone function.
+        /// </summary>
+        /// <param name="bindableObject">The style that need to copy.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void CopyFrom(BindableObject bindableObject)
+        {
+            base.CopyFrom(bindableObject);
+
+            /*
+            if (bindableObject is RecyclerViewItemStyle RecyclerViewItemStyle)
+            {
+                //
+            }
+            */
+        }
+    }
+}
index 26a87a6..ac459b6 100755 (executable)
@@ -27,6 +27,9 @@ namespace Tizen.NUI.Components
     /// <since_tizen> 8 </since_tizen>
     public class SliderStyle : ControlStyle
     {
+        /// <summary>
+        /// IndicatorTypeProperty
+        /// </summary> 
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty IndicatorTypeProperty = BindableProperty.Create(nameof(IndicatorType), typeof(IndicatorType?), typeof(SliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -41,6 +44,10 @@ namespace Tizen.NUI.Components
             var instance = (SliderStyle)bindable;
             return instance.privateIndicatorType;
         });
+
+        /// <summary>
+        /// SpaceBetweenTrackAndIndicatorProperty
+        /// </summary> 
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty SpaceBetweenTrackAndIndicatorProperty = BindableProperty.Create(nameof(SpaceBetweenTrackAndIndicator), typeof(uint?), typeof(SliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -55,6 +62,10 @@ namespace Tizen.NUI.Components
             var instance = (SliderStyle)bindable;
             return instance.privateSpaceBetweenTrackAndIndicator;
         });
+
+        /// <summary>
+        /// TrackThicknessProperty
+        /// </summary> 
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty TrackThicknessProperty = BindableProperty.Create(nameof(TrackThickness), typeof(uint?), typeof(SliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -69,6 +80,10 @@ namespace Tizen.NUI.Components
             var instance = (SliderStyle)bindable;
             return instance.privateTrackThickness;
         });
+
+        /// <summary>
+        /// TrackPaddingProperty
+        /// </summary> 
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty TrackPaddingProperty = BindableProperty.Create(nameof(TrackPadding), typeof(Extents), typeof(SliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
         {
@@ -123,6 +138,20 @@ namespace Tizen.NUI.Components
         public ImageViewStyle Thumb { get; set; } = new ImageViewStyle();
 
         /// <summary>
+        /// Get or set background warning track.
+        /// </summary>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ImageViewStyle WarningTrack { get; set; } = new ImageViewStyle();
+
+        /// <summary>
+        /// Get or set slided warning track.
+        /// </summary>
+        /// This will be public opened later after ACR done. Before ACR, need to be hidden as inhouse API.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ImageViewStyle WarningProgress { get; set; } = new ImageViewStyle();
+
+        /// <summary>
         /// Get or set low indicator image.
         /// </summary>
         /// <since_tizen> 8 </since_tizen>
@@ -214,6 +243,8 @@ namespace Tizen.NUI.Components
                 Track.CopyFrom(sliderStyle.Track);
                 Progress.CopyFrom(sliderStyle.Progress);
                 Thumb.CopyFrom(sliderStyle.Thumb);
+                WarningTrack.CopyFrom(sliderStyle.WarningTrack);
+                WarningProgress.CopyFrom(sliderStyle.WarningProgress);
                 LowIndicatorImage.CopyFrom(sliderStyle.LowIndicatorImage);
                 HighIndicatorImage.CopyFrom(sliderStyle.HighIndicatorImage);
                 LowIndicator.CopyFrom(sliderStyle.LowIndicator);
index 8571d94..9910996 100644 (file)
@@ -26,6 +26,10 @@ namespace Tizen.NUI.Components
     // It is a C# version of res/Tizen.NUI.Components_Tizen.NUI.Theme.Common.xaml
     internal class DefaultThemeCreator : IThemeCreator
     {
+        private DefaultThemeCreator() { }
+
+        public static IThemeCreator Instance { get; set; } = new DefaultThemeCreator();
+
         public ResourceDictionary CreateThemeResource() => new ResourceDictionary()
         {
             ["ButtonBackgroundColorNormal"] = new Color(0.039f, 0.055f, 0.29f, 1),
@@ -93,6 +97,11 @@ namespace Tizen.NUI.Components
             ["PaginationIndicatorImageUrlSelected"] = FrameworkInformation.ResourcePath + "nui_component_default_pagination_focus_dot.png",
             ["ScrollbarTrackColor"] = new Color(1, 1, 1, 0.15f),
             ["ScrollbarThumbColor"] = new Color(0.6f, 0.6f, 0.6f, 1.0f),
+            ["RecyclerViewItemBackgroundColorNormal"] = new Color(1, 1, 1, 1),
+            ["RecyclerViewItemBackgroundColorPressed"] = new Color(0.85f, 0.85f, 0.85f, 1),
+            ["RecyclerViewItemBackgroundColorDisabled"] = new Color(0.70f, 0.70f, 0.70f, 1),
+            ["RecyclerViewItemBackgroundColorSelected"] = new Color(0.701f, 0.898f, 0.937f, 1),
+            ["TitleBackgroundColorNormal"] = new Color(0.78f, 0.78f, 0.78f, 1),
         };
 
         public Theme Create() => Create(null);
@@ -368,6 +377,90 @@ namespace Tizen.NUI.Components
                 TrackPadding = 4
             });
 
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.RecyclerViewItem", new RecyclerViewItemStyle()
+            {
+                BackgroundColor = new Selector<Color>()
+                {
+                    Normal = (Color)theme.Resources["RecyclerViewItemBackgroundColorNormal"],
+                    Pressed = (Color)theme.Resources["RecyclerViewItemBackgroundColorPressed"],
+                    Disabled = (Color)theme.Resources["RecyclerViewItemBackgroundColorDisabled"],
+                    Selected = (Color)theme.Resources["RecyclerViewItemBackgroundColorSelected"],
+                },
+            });
+            
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.DefaultLinearItem", new DefaultLinearItemStyle()
+            {
+                SizeHeight = 130,
+                Padding = new Extents(20, 20, 5, 5),
+                BackgroundColor = new Selector<Color>()
+                {
+                    Normal = (Color)theme.Resources["RecyclerViewItemBackgroundColorNormal"],
+                    Pressed = (Color)theme.Resources["RecyclerViewItemBackgroundColorPressed"],
+                    Disabled = (Color)theme.Resources["RecyclerViewItemBackgroundColorDisabled"],
+                    Selected = (Color)theme.Resources["RecyclerViewItemBackgroundColorSelected"],
+                },
+                Label = new TextLabelStyle()
+                {
+                    PointSize = 10,
+                    Ellipsis = true,
+                },
+                SubLabel = new TextLabelStyle()
+                {
+                    PointSize = 6,
+                    Ellipsis = true,
+                },
+                Icon = new ViewStyle()
+                {
+                    Margin = new Extents(0, 20, 0, 0)
+                },
+                Extra = new ViewStyle()
+                {
+                    Margin = new Extents(20, 0, 0, 0)
+                },
+                Seperator = new ViewStyle()
+                {
+                    Margin = new Extents(5, 5, 0, 0),
+                    BackgroundColor = new Color(0.78f, 0.78f, 0.78f, 1),
+                },
+            });
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.DefaultGridItem", new DefaultGridItemStyle()
+            {
+                Padding = new Extents(5, 5, 5, 5),
+                Caption = new TextLabelStyle()
+                {
+                    PointSize = 9,
+                    Ellipsis = true,
+                },
+                Badge = new ViewStyle()
+                {
+                    Margin = new Extents(5, 5, 5, 5),
+                },
+            });
+
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.DefaultTitleItem", new DefaultTitleItemStyle()
+            {
+                SizeHeight = 90,
+                Padding = new Extents(10, 10, 5, 5),
+                BackgroundColor = new Selector<Color>()
+                {
+                    Normal = (Color)theme.Resources["TitleBackgroundColorNormal"],
+                },
+                Label = new TextLabelStyle()
+                {
+                    PointSize = 10,
+                    Ellipsis = true,
+                },
+                Icon = new ViewStyle()
+                {
+                    Margin = new Extents(10, 0, 0, 0)
+                },
+                Seperator = new ViewStyle()
+                {
+                    Margin = new Extents(0, 0, 0, 0),
+                    BackgroundColor = new Color(0.85f, 0.85f, 0.85f, 1),
+                },
+            });
+
             return theme;
         }
     }
index 4a83806..ddc52c1 100644 (file)
@@ -92,6 +92,11 @@ namespace Tizen.NUI.Components
             ["PaginationIndicatorImageUrlSelected"] = FrameworkInformation.ResourcePath + "nui_component_default_pagination_focus_dot.png",
             ["ScrollbarTrackColor"] = new Color(1, 1, 1, 0.15f),
             ["ScrollbarThumbColor"] = new Color(0.6f, 0.6f, 0.6f, 1.0f),
+            ["RecyclerViewItemBackgroundColorNormal"] = new Color(1, 1, 1, 1),
+            ["RecyclerViewItemBackgroundColorPressed"] = new Color(0.85f, 0.85f, 0.85f, 1),
+            ["RecyclerViewItemBackgroundColorDisabled"] = new Color(0.70f, 0.70f, 0.70f, 1),
+            ["RecyclerViewItemBackgroundColorSelected"] = new Color(0.701f, 0.898f, 0.937f, 1),
+            ["TitleBackgroundColorNormal"] = new Color(0.78f, 0.78f, 0.78f, 1),
         };
 
         public Theme Create() => Create(null);
@@ -366,6 +371,90 @@ namespace Tizen.NUI.Components
                 TrackPadding = 4
             });
 
+                        theme.AddStyleWithoutClone("Tizen.NUI.Components.RecyclerViewItem", new RecyclerViewItemStyle()
+            {
+                BackgroundColor = new Selector<Color>()
+                {
+                    Normal = (Color)theme.Resources["RecyclerViewItemBackgroundColorNormal"],
+                    Pressed = (Color)theme.Resources["RecyclerViewItemBackgroundColorPressed"],
+                    Disabled = (Color)theme.Resources["RecyclerViewItemBackgroundColorDisabled"],
+                    Selected = (Color)theme.Resources["RecyclerViewItemBackgroundColorSelected"],
+                },
+            });
+            
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.DefaultLinearItem", new DefaultLinearItemStyle()
+            {
+                SizeHeight = 160,
+                Padding = new Extents(10, 10, 20, 20),
+                BackgroundColor = new Selector<Color>()
+                {
+                    Normal = (Color)theme.Resources["RecyclerViewItemBackgroundColorNormal"],
+                    Pressed = (Color)theme.Resources["RecyclerViewItemBackgroundColorPressed"],
+                    Disabled = (Color)theme.Resources["RecyclerViewItemBackgroundColorDisabled"],
+                    Selected = (Color)theme.Resources["RecyclerViewItemBackgroundColorSelected"],
+                },
+                Label = new TextLabelStyle()
+                {
+                    PointSize = 20,
+                    Ellipsis = true,
+                },
+                SubLabel = new TextLabelStyle()
+                {
+                    PointSize = 12,
+                    Ellipsis = true,
+                },
+                Icon = new ViewStyle()
+                {
+                    Margin = new Extents(0, 10, 0, 0)
+                },
+                Extra = new ViewStyle()
+                {
+                    Margin = new Extents(10, 0, 0, 0)
+                },
+                Seperator = new ViewStyle()
+                {
+                    Margin = new Extents(5, 5, 0, 0),
+                    BackgroundColor = new Color(0.78f, 0.78f, 0.78f, 1),
+                },
+            });
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.DefaultGridItem", new DefaultGridItemStyle()
+            {
+                Padding = new Extents(5, 5, 5, 5),
+                Caption = new TextLabelStyle()
+                {
+                    PointSize = 9,
+                    Ellipsis = true,
+                },
+                Badge = new ViewStyle()
+                {
+                    Margin = new Extents(5, 5, 5, 5),
+                },
+            });
+
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.DefaultTitleItem", new DefaultTitleItemStyle()
+            {
+                SizeHeight = 50,
+                Padding = new Extents(10, 10, 5, 5),
+                BackgroundColor = new Selector<Color>()
+                {
+                    Normal = (Color)theme.Resources["TitleBackgroundColorNormal"],
+                },
+                Label = new TextLabelStyle()
+                {
+                    PointSize = 15,
+                    Ellipsis = true,
+                },
+                Icon = new ViewStyle()
+                {
+                    Margin = new Extents(10, 0, 0, 0)
+                },
+                Seperator = new ViewStyle()
+                {
+                    Margin = new Extents(0, 0, 0, 0),
+                    BackgroundColor = new Color(0.85f, 0.85f, 0.85f, 1),
+                },
+            });
+
             return theme;
         }
     }
index afdd2ca..57a36a5 100644 (file)
   </c:PaginationStyle>
 
   <!--Scrollbar-->
-  <c:ScrollbarStyle x:Key="Tizen.NUI.Components.Scrollbar" TrackThickness="6" ThumbThickness="6" TrackColor="1, 1, 1, 0.15" ThumbColor="0.6, 0.6, 0.6, 1.0" TrackPadding="4" />
+  <c:ScrollbarStyle x:Key="Tizen.NUI.Components.Scrollbar" TrackThickness="8" ThumbThickness="8" TrackColor="0.435, 0.435, 0.435, 0.1" ThumbColor="0, 0, 0, 0.2" TrackPadding="8" />
 
 </Theme>
\ No newline at end of file
index 8eec8d6..0caa06d 100644 (file)
@@ -22,6 +22,10 @@ namespace Tizen.NUI.Wearable
 {
     internal class DefaultThemeCreator : IThemeCreator
     {
+        private DefaultThemeCreator() { }
+
+        public static IThemeCreator Instance { get; set; } = new DefaultThemeCreator();
+
         public Theme Create() => Create(null);
 
         public Theme Create(IEnumerable<KeyValuePair<string, string>> changedResources)
index 923ea7e..68c0038 100755 (executable)
@@ -64,7 +64,7 @@ namespace Tizen.NUI.Wearable
 
         static CircularPagination()
         {
-            ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+            ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
         }
 
         /// <summary>
index 855d63d..f8e1d87 100755 (executable)
@@ -160,7 +160,7 @@ namespace Tizen.NUI.Wearable
 
         static CircularProgress()
         {
-            ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+            ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
         }
 
         /// <summary>
index a44d367..fafcd7b 100755 (executable)
@@ -137,7 +137,7 @@ namespace Tizen.NUI.Wearable
         /// </summary>
         static CircularScrollbar()
         {
-            ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+            ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
         }
 
         #endregion Constructors
index 39499bd..4f2dfa4 100755 (executable)
@@ -215,7 +215,7 @@ namespace Tizen.NUI.Wearable
 
         static CircularSlider()
         {
-            ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+            ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
         }
 
         /// <summary>
  */
 using System;
 using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
 using System.Collections.Generic;
 using System.ComponentModel;
 
-namespace Tizen.NUI.Components
+namespace Tizen.NUI.Wearable
 {
     /// <summary>
     /// [Draft] This class implements a grid box layout.
  */
 using System;
 using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
 using System.Collections.Generic;
 using System.ComponentModel;
 
-namespace Tizen.NUI.Components
+namespace Tizen.NUI.Wearable
 {
     /// <summary>
     /// [Draft] This class implements a linear box layout.
@@ -16,8 +16,9 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using Tizen.NUI.Components;
 
-namespace Tizen.NUI.Components
+namespace Tizen.NUI.Wearable
 {
     /// <summary>
     /// [Draft] Defalt adapter for RecyclerView.
@@ -14,8 +14,9 @@
  *
  */
 using System.ComponentModel;
+using Tizen.NUI.Components;
 
-namespace Tizen.NUI.Components
+namespace Tizen.NUI.Wearable
 {
     /// <summary>
     /// [Draft] This class provides a basic item for RecyclerView.
  *
  */
 using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
 using System.Collections.Generic;
 using System.ComponentModel;
 
-namespace Tizen.NUI.Components
+namespace Tizen.NUI.Wearable
 {
     /// <summary>
     /// [Draft] Defalt layout manager for RecyclerView.
diff --git a/src/Tizen.NUI.Wearable/src/public/RecyclerView/RecyclerView.cs b/src/Tizen.NUI.Wearable/src/public/RecyclerView/RecyclerView.cs
new file mode 100755 (executable)
index 0000000..903d9d3
--- /dev/null
@@ -0,0 +1,372 @@
+/* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace Tizen.NUI.Wearable
+{
+    /// <summary>
+    /// [Draft] This class provides a View that can recycle items to improve performance.
+    /// </summary>
+    /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class RecyclerView : ScrollableBase
+    {
+        private RecycleAdapter adapter;
+        private RecycleLayoutManager layoutManager;
+        private int totalItemCount = 15;
+        private List<PropertyNotification> notifications = new List<PropertyNotification>();
+
+        public RecyclerView() : base()
+        {
+            Initialize(new RecycleAdapter(), new RecycleLayoutManager());
+        }
+
+        /// <summary>
+        /// Default constructor.
+        /// </summary>
+        /// <param name="adapter">Recycle adapter of RecyclerView.</param>
+        /// <param name="layoutManager">Recycle layoutManager of RecyclerView.</param>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecyclerView(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
+        {
+            Initialize(adapter, layoutManager);
+        }
+
+        private void Initialize(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
+        {
+            FocusGroup = true;
+            SetKeyboardNavigationSupport(true);
+            Scrolling += OnScrolling;
+
+            this.adapter = adapter;
+            this.adapter.OnDataChanged += OnAdapterDataChanged;
+
+            this.layoutManager = layoutManager;
+            this.layoutManager.Container = ContentContainer;
+            this.layoutManager.ItemSize = this.adapter.CreateRecycleItem().Size;
+            this.layoutManager.DataCount = this.adapter.Data.Count;
+
+            InitializeItems();
+        }
+
+        private void OnItemSizeChanged(object source, PropertyNotification.NotifyEventArgs args)
+        {
+            layoutManager.Layout(ScrollingDirection == Direction.Horizontal ? ContentContainer.CurrentPosition.X : ContentContainer.CurrentPosition.Y);
+        }
+
+        public int TotalItemCount
+        {
+            get
+            {
+                return totalItemCount;
+            }
+            set
+            {
+                totalItemCount = value;
+                InitializeItems();
+            }
+        }
+
+        private void InitializeItems()
+        {
+            for (int i = Children.Count - 1; i > -1; i--)
+            {
+                Children[i].Unparent();
+                notifications[i].Notified -= OnItemSizeChanged;
+                notifications.RemoveAt(i);
+            }
+
+            for (int i = 0; i < totalItemCount; i++)
+            {
+                RecycleItem item = adapter.CreateRecycleItem();
+                item.DataIndex = i;
+                item.Name = "[" + i + "] recycle";
+
+                if (i < adapter.Data.Count)
+                {
+                    adapter.BindData(item);
+                }
+                Add(item);
+
+                PropertyNotification noti = item.AddPropertyNotification("size", PropertyCondition.Step(0.1f));
+                noti.Notified += OnItemSizeChanged;
+                notifications.Add(noti);
+            }
+
+            layoutManager.Layout(0.0f);
+
+            if (ScrollingDirection == Direction.Horizontal)
+            {
+                ContentContainer.SizeWidth = layoutManager.CalculateLayoutOrientationSize();
+            }
+            else
+            {
+                ContentContainer.SizeHeight = layoutManager.CalculateLayoutOrientationSize();
+            }
+        }
+
+
+        public new Direction ScrollingDirection
+        {
+            get
+            {
+                return base.ScrollingDirection;
+            }
+            set
+            {
+                base.ScrollingDirection = value;
+
+                if (ScrollingDirection == Direction.Horizontal)
+                {
+                    ContentContainer.SizeWidth = layoutManager.CalculateLayoutOrientationSize();
+                }
+                else
+                {
+                    ContentContainer.SizeHeight = layoutManager.CalculateLayoutOrientationSize();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Recycler adpater.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecycleAdapter Adapter
+        {
+            get
+            {
+                return adapter;
+            }
+            set
+            {
+                if (adapter != null)
+                {
+                    adapter.OnDataChanged -= OnAdapterDataChanged;
+                }
+
+                adapter = value;
+                adapter.OnDataChanged += OnAdapterDataChanged;
+                layoutManager.ItemSize = adapter.CreateRecycleItem().Size;
+                layoutManager.DataCount = adapter.Data.Count;
+                InitializeItems();
+            }
+        }
+
+        /// <summary>
+        /// Recycler layoutManager.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public RecycleLayoutManager LayoutManager
+        {
+            get
+            {
+                return layoutManager;
+            }
+            set
+            {
+                layoutManager = value;
+                layoutManager.Container = ContentContainer;
+                layoutManager.ItemSize = adapter.CreateRecycleItem().Size;
+                layoutManager.DataCount = adapter.Data.Count;
+                InitializeItems();
+            }
+        }
+
+        private void OnScrolling(object source, ScrollEventArgs args)
+        {
+            layoutManager.Layout(ScrollingDirection == Direction.Horizontal ? args.Position.X : args.Position.Y);
+            List<RecycleItem> recycledItemList = layoutManager.Recycle(ScrollingDirection == Direction.Horizontal ? args.Position.X : args.Position.Y);
+            BindData(recycledItemList);
+        }
+
+        private void OnAdapterDataChanged(object source, EventArgs args)
+        {
+            List<RecycleItem> changedData = new List<RecycleItem>();
+
+            foreach (RecycleItem item in Children)
+            {
+                changedData.Add(item);
+            }
+
+            BindData(changedData);
+        }
+
+        private void BindData(List<RecycleItem> changedData)
+        {
+            foreach (RecycleItem item in changedData)
+            {
+                if (item.DataIndex > -1 && item.DataIndex < adapter.Data.Count)
+                {
+                    item.Show();
+                    item.Name = "[" + item.DataIndex + "]";
+                    adapter.BindData(item);
+                }
+                else
+                {
+                    item.Hide();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Adjust scrolling position by own scrolling rules.
+        /// Override this function when developer wants to change destination of flicking.(e.g. always snap to center of item)
+        /// </summary>
+        /// <param name="position">Scroll position which is calculated by ScrollableBase</param>
+        /// <returns>Adjusted scroll destination</returns>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override float AdjustTargetPositionOfScrollAnimation(float position)
+        {
+            // Destination is depending on implementation of layout manager.
+            // Get destination from layout manager.
+            return layoutManager.CalculateCandidateScrollPosition(position);
+        }
+
+        private View focusedView;
+        private int prevFocusedDataIndex = 0;
+
+        public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+        {
+            View nextFocusedView = null;
+
+            if (!focusedView)
+            {
+                // If focusedView is null, find child which has previous data index
+                if (Children.Count > 0 && Adapter.Data.Count > 0)
+                {
+                    for (int i = 0; i < Children.Count; i++)
+                    {
+                        RecycleItem item = Children[i] as RecycleItem;
+                        if (item.DataIndex == prevFocusedDataIndex)
+                        {
+                            nextFocusedView = item;
+                            break;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                // If this is not first focus, request next focus to LayoutManager
+                if (LayoutManager != null)
+                {
+                    nextFocusedView = LayoutManager.RequestNextFocusableView(currentFocusedView, direction, loopEnabled);
+                }
+            }
+
+            if (nextFocusedView != null)
+            {
+                // Check next focused view is inside of visible area.
+                // If it is not, move scroll position to make it visible.
+                Position scrollPosition = ContentContainer.CurrentPosition;
+                float targetPosition = -(ScrollingDirection == Direction.Horizontal ? scrollPosition.X : scrollPosition.Y);
+
+                float left = nextFocusedView.Position.X;
+                float right = nextFocusedView.Position.X + nextFocusedView.Size.Width;
+                float top = nextFocusedView.Position.Y;
+                float bottom = nextFocusedView.Position.Y + nextFocusedView.Size.Height;
+
+                float visibleRectangleLeft = -scrollPosition.X;
+                float visibleRectangleRight = -scrollPosition.X + Size.Width;
+                float visibleRectangleTop = -scrollPosition.Y;
+                float visibleRectangleBottom = -scrollPosition.Y + Size.Height;
+
+                if (ScrollingDirection == Direction.Horizontal)
+                {
+                    if ((direction == View.FocusDirection.Left || direction == View.FocusDirection.Up) && left < visibleRectangleLeft)
+                    {
+                        targetPosition = left;
+                    }
+                    else if ((direction == View.FocusDirection.Right || direction == View.FocusDirection.Down) && right > visibleRectangleRight)
+                    {
+                        targetPosition = right - Size.Width;
+                    }
+                }
+                else
+                {
+                    if ((direction == View.FocusDirection.Up || direction == View.FocusDirection.Left) && top < visibleRectangleTop)
+                    {
+                        targetPosition = top;
+                    }
+                    else if ((direction == View.FocusDirection.Down || direction == View.FocusDirection.Right) && bottom > visibleRectangleBottom)
+                    {
+                        targetPosition = bottom - Size.Height;
+                    }
+                }
+
+                focusedView = nextFocusedView;
+                if ((nextFocusedView as RecycleItem) != null)
+                {
+                    prevFocusedDataIndex = (nextFocusedView as RecycleItem).DataIndex;
+                }
+
+                ScrollTo(targetPosition, true);
+            }
+            else
+            {
+                // If nextView is null, it means that we should move focus to outside of Control.
+                // Return FocusableView depending on direction.
+                switch (direction)
+                {
+                    case View.FocusDirection.Left:
+                        {
+                            nextFocusedView = LeftFocusableView;
+                            break;
+                        }
+                    case View.FocusDirection.Right:
+                        {
+                            nextFocusedView = RightFocusableView;
+                            break;
+                        }
+                    case View.FocusDirection.Up:
+                        {
+                            nextFocusedView = UpFocusableView;
+                            break;
+                        }
+                    case View.FocusDirection.Down:
+                        {
+                            nextFocusedView = DownFocusableView;
+                            break;
+                        }
+                }
+
+                if (nextFocusedView)
+                {
+                    focusedView = null;
+                }
+                else
+                {
+                    //If FocusableView doesn't exist, not move focus.
+                    nextFocusedView = focusedView;
+                }
+            }
+
+            return nextFocusedView;
+        }
+    }
+}
index bcffc90..c0e3b97 100644 (file)
@@ -17,6 +17,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\..\internals\src\Tizen.Applications.ThemeManager\Tizen.Applications.ThemeManager.csproj" />
     <ProjectReference Include="..\Tizen.Applications.Common\Tizen.Applications.Common.csproj" />
     <ProjectReference Include="..\Tizen.Applications.ComponentBased\Tizen.Applications.ComponentBased.csproj" />
     <ProjectReference Include="..\Tizen.System.Information\Tizen.System.Information.csproj" />
index 8670d46..c1f958e 100755 (executable)
@@ -427,7 +427,7 @@ namespace Tizen.NUI
         }
 
 
-        internal Application(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicPINVOKE.ApplicationUpcast(cPtr), cMemoryOwn)
+        internal Application(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
             SetCurrentApplication(this);
 
index e1809c8..89791c7 100755 (executable)
@@ -23,7 +23,7 @@ namespace Tizen.NUI
     internal class Alignment : View
     {
 
-        internal Alignment(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Alignment.Upcast(cPtr), cMemoryOwn)
+        internal Alignment(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index d5c3d56..b521b59 100755 (executable)
@@ -20,7 +20,7 @@ namespace Tizen.NUI
     internal class AsyncImageLoader : BaseHandle
     {
 
-        internal AsyncImageLoader(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.AsyncImageLoader.Upcast(cPtr), cMemoryOwn)
+        internal AsyncImageLoader(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 94b985a..5970b56 100755 (executable)
@@ -21,7 +21,7 @@ namespace Tizen.NUI
     internal class BaseObject : RefObject
     {
 
-        internal BaseObject(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.BaseObject.Upcast(cPtr), cMemoryOwn)
+        internal BaseObject(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 77ce97d..0c2e1bf 100755 (executable)
@@ -20,7 +20,7 @@ namespace Tizen.NUI
     internal class CustomActor : Animatable
     {
 
-        internal CustomActor(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CustomActorImpl.CustomActorUpcast(cPtr), cMemoryOwn)
+        internal CustomActor(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 75325d2..b93d4bf 100755 (executable)
@@ -21,7 +21,7 @@ namespace Tizen.NUI
     internal class CustomActorImpl : RefObject
     {
 
-        internal CustomActorImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CustomActorImpl.Upcast(cPtr), cMemoryOwn)
+        internal CustomActorImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 403b534..430c8d2 100755 (executable)
@@ -24,7 +24,7 @@ namespace Tizen.NUI
     public class DefaultRuler : Ruler
     {
 
-        internal DefaultRuler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Ruler.DefaultRulerUpcast(cPtr), cMemoryOwn)
+        internal DefaultRuler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index d6d9675..80b952c 100755 (executable)
@@ -14,6 +14,7 @@
  * limitations under the License.
  *
  */
+using System;
 using System.ComponentModel;
 
 namespace Tizen.NUI
@@ -28,6 +29,8 @@ namespace Tizen.NUI
         /// A Flag to check if it is already disposed.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use Disposed")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected bool disposed = false;
 
         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
index 02671e1..eb9bd92 100755 (executable)
@@ -24,7 +24,7 @@ namespace Tizen.NUI
     public class FixedRuler : Ruler
     {
 
-        internal FixedRuler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Ruler.FixedRulerUpcast(cPtr), cMemoryOwn)
+        internal FixedRuler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index fc785ee..0a70e71 100755 (executable)
@@ -24,7 +24,7 @@ namespace Tizen.NUI
     public class FrameBuffer : BaseHandle
     {
 
-        internal FrameBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.FrameBuffer.Upcast(cPtr), cMemoryOwn)
+        internal FrameBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 6ca5163..7037dbe 100755 (executable)
@@ -37,6 +37,7 @@ using System.Runtime.CompilerServices;
 [assembly: InternalsVisibleTo("Tizen.TV.NUI.Example, " + Tizen.NUI.PublicKey.TizenTV)]
 
 [assembly: InternalsVisibleTo("NuiSample, " + Tizen.NUI.PublicKey.Sample)]
+[assembly: InternalsVisibleTo("Tizen.NUI.Devel.Tests, " + Tizen.NUI.PublicKey.Sample)]
 
 namespace Tizen.NUI
 {
index 0eed1fa..11cad4a 100755 (executable)
@@ -22,7 +22,7 @@ namespace Tizen.NUI
     internal class KeyInputFocusManager : BaseHandle
     {
 
-        internal KeyInputFocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.KeyInputFocusManager.Upcast(cPtr), cMemoryOwn)
+        internal KeyInputFocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index c44a92e..432dc5e 100755 (executable)
@@ -20,7 +20,7 @@ namespace Tizen.NUI
     internal class LinearConstrainer : BaseHandle
     {
 
-        internal LinearConstrainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.LinearConstrainer.Upcast(cPtr), cMemoryOwn)
+        internal LinearConstrainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index ff91589..67ca06b 100755 (executable)
@@ -22,7 +22,7 @@ namespace Tizen.NUI
     internal class Model3dView : View
     {
 
-        internal Model3dView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Model3DView.Model3dViewUpcast(cPtr), cMemoryOwn)
+        internal Model3dView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index e418e8b..0cb11f8 100755 (executable)
@@ -23,7 +23,7 @@ namespace Tizen.NUI
     public class NativeImageInterface : RefObject
     {
 
-        internal NativeImageInterface(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.NativeImageInterface.Upcast(cPtr), cMemoryOwn)
+        internal NativeImageInterface(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 53f944f..d1dfcfb 100755 (executable)
@@ -22,7 +22,7 @@ namespace Tizen.NUI
     internal class ObjectRegistry : BaseHandle
     {
 
-        internal ObjectRegistry(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ObjectRegistry.Upcast(cPtr), cMemoryOwn)
+        internal ObjectRegistry(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index da41fde..8c82574 100755 (executable)
@@ -20,7 +20,7 @@ namespace Tizen.NUI
     internal class PathConstrainer : BaseHandle
     {
 
-        internal PathConstrainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PathConstrainer.Upcast(cPtr), cMemoryOwn)
+        internal PathConstrainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 578ee5c..a07109b 100755 (executable)
@@ -25,7 +25,7 @@ namespace Tizen.NUI
     public class RenderTask : Animatable
     {
 
-        internal RenderTask(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.RenderTask.Upcast(cPtr), cMemoryOwn)
+        internal RenderTask(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -297,14 +297,14 @@ namespace Tizen.NUI
             return ret;
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use ClearColor property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use ClearColor property instead!")]
         public void SetClearColor(Vector4 color)
         {
             Interop.RenderTask.SetClearColor(SwigCPtr, Vector4.getCPtr(color));
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use ClearColor property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use ClearColor property instead!")]
         public Vector4 GetClearColor()
         {
             Vector4 ret = new Vector4(Interop.RenderTask.GetClearColor(SwigCPtr), true);
index a997645..d485abb 100755 (executable)
@@ -20,7 +20,7 @@ namespace Tizen.NUI
     internal class RenderTaskList : BaseHandle
     {
 
-        internal RenderTaskList(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.RenderTask.RenderTaskListUpcast(cPtr), cMemoryOwn)
+        internal RenderTaskList(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 42d689a..2bb916b 100755 (executable)
@@ -24,7 +24,7 @@ namespace Tizen.NUI
     public class Ruler : RefObject
     {
 
-        internal Ruler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Ruler.Upcast(cPtr), cMemoryOwn)
+        internal Ruler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 57d7f29..f83a52f 100755 (executable)
@@ -25,7 +25,7 @@ namespace Tizen.NUI
     internal class ViewImpl : CustomActorImpl
     {
 
-        internal ViewImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ViewImpl.Upcast(cPtr), cMemoryOwn)
+        internal ViewImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 859d28a..8fc5259 100755 (executable)
@@ -130,7 +130,7 @@ namespace Tizen.NUI
         public new OnTapDelegate OnTap;
         public new OnLongPressDelegate OnLongPress;
 
-        internal ViewWrapperImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ViewWrapperImpl.Upcast(cPtr), cMemoryOwn)
+        internal ViewWrapperImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 9ac1dd1..075db2c 100755 (executable)
@@ -15,6 +15,9 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_New_2")]
             public static extern global::System.IntPtr New2(string jarg1, string jarg2);
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_New_3")]
+            public static extern global::System.IntPtr New3(int jarg1, string[] jarg2);
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_new_WebView__SWIG_1")]
             public static extern global::System.IntPtr NewWebView(global::System.Runtime.InteropServices.HandleRef jarg1);
 
@@ -54,6 +57,15 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_Property_CONTENT_SIZE_get")]
             public static extern int ContentSizeGet();
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_Property_TITLE_get")]
+            public static extern int TitleGet();
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_Property_VIDEO_HOLE_ENABLED_get")]
+            public static extern int VideoHoleEnabledGet();
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_GetFavicon")]
+            public static extern global::System.IntPtr GetFavicon(global::System.Runtime.InteropServices.HandleRef jarg1);
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_LoadUrl")]
             public static extern void LoadUrl(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2);
 
@@ -93,6 +105,9 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_AddJavaScriptMessageHandler")]
             public static extern void AddJavaScriptMessageHandler(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2, global::System.Runtime.InteropServices.HandleRef jarg3);
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_ClearAllTilesResources")]
+            public static extern void ClearAllTilesResources(global::System.Runtime.InteropServices.HandleRef jarg1);
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_WebView_ClearHistory")]
             public static extern void ClearHistory(global::System.Runtime.InteropServices.HandleRef jarg1);
 
index 6032936..d5f01fa 100755 (executable)
@@ -24,7 +24,7 @@ namespace Tizen.NUI
     internal class Builder : BaseHandle
     {
 
-        internal Builder(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Builder.Upcast(cPtr), cMemoryOwn)
+        internal Builder(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 4b1df2a..819315a 100755 (executable)
@@ -25,7 +25,7 @@ namespace Tizen.NUI
     public class Camera : View
     {
 
-        internal Camera(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CameraActor.Upcast(cPtr), cMemoryOwn)
+        internal Camera(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -116,14 +116,14 @@ namespace Tizen.NUI
             return ret;
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use FieldOfView property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use FieldOfView property instead!")]
         public void SetFieldOfView(float fieldOfView)
         {
             Interop.CameraActor.SetFieldOfView(SwigCPtr, fieldOfView);
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use FieldOfView property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use FieldOfView property instead!")]
         public float GetFieldOfView()
         {
             float ret = Interop.CameraActor.GetFieldOfView(SwigCPtr);
@@ -131,14 +131,14 @@ namespace Tizen.NUI
             return ret;
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use AspectRatio property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use AspectRatio property instead!")]
         public void SetAspectRatio(float aspectRatio)
         {
             Interop.CameraActor.SetAspectRatio(SwigCPtr, aspectRatio);
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use AspectRatio property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use AspectRatio property instead!")]
         public float GetAspectRatio()
         {
             float ret = Interop.CameraActor.GetAspectRatio(SwigCPtr);
@@ -172,14 +172,14 @@ namespace Tizen.NUI
             return ret;
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use TargetPosition property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use TargetPosition property instead!")]
         public void SetTargetPosition(Vector3 targetPosition)
         {
             Interop.CameraActor.SetTargetPosition(SwigCPtr, Vector3.getCPtr(targetPosition));
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use TargetPosition property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use TargetPosition property instead!")]
         public Vector3 GetTargetPosition()
         {
             Vector3 ret = new Vector3(Interop.CameraActor.GetTargetPosition(SwigCPtr), true);
@@ -187,14 +187,14 @@ namespace Tizen.NUI
             return ret;
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use InvertYAxis property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use InvertYAxis property instead!")]
         public void SetInvertYAxis(bool invertYAxis)
         {
             Interop.CameraActor.SetInvertYAxis(SwigCPtr, invertYAxis);
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use InvertYAxis property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use InvertYAxis property instead!")]
         public bool GetInvertYAxis()
         {
             bool ret = Interop.CameraActor.GetInvertYAxis(SwigCPtr);
index 2183b02..0a66d81 100755 (executable)
@@ -20,7 +20,7 @@ namespace Tizen.NUI
     internal class ConnectionTracker : ConnectionTrackerInterface
     {
 
-        internal ConnectionTracker(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ConnectionTracker.Upcast(cPtr), cMemoryOwn)
+        internal ConnectionTracker(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index de88ac4..c9d78d9 100755 (executable)
@@ -23,7 +23,7 @@ namespace Tizen.NUI
     internal class ConnectionTrackerInterface : SignalObserver
     {
 
-        internal ConnectionTrackerInterface(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ConnectionTracker.ConnectionTrackerInterfaceUpcast(cPtr), cMemoryOwn)
+        internal ConnectionTrackerInterface(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 9f338d1..4698521 100755 (executable)
@@ -49,7 +49,7 @@ namespace Tizen.NUI
         });
         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
 
-        internal GaussianBlurView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.GaussianBlurView.Upcast(cPtr), cMemoryOwn)
+        internal GaussianBlurView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
         }
index 53205d5..d89e88e 100755 (executable)
@@ -25,7 +25,7 @@ namespace Tizen.NUI
     public class ItemLayout : RefObject
     {
 
-        internal ItemLayout(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ItemLayout.Upcast(cPtr), cMemoryOwn)
+        internal ItemLayout(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index f552d46..4b2f8ef 100755 (executable)
@@ -28,7 +28,7 @@ namespace Tizen.NUI
     public class ItemView : Scrollable
     {
 
-        internal ItemView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ItemView.Upcast(cPtr), cMemoryOwn)
+        internal ItemView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 9d75f78..f001f1c 100755 (executable)
@@ -20,7 +20,7 @@ namespace Tizen.NUI
     internal class PageTurnPortraitView : PageTurnView
     {
 
-        internal PageTurnPortraitView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PageTurnPortraitView.Upcast(cPtr), cMemoryOwn)
+        internal PageTurnPortraitView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 9ff5d6f..719ce08 100755 (executable)
@@ -23,7 +23,7 @@ namespace Tizen.NUI
     internal class PageTurnView : View
     {
 
-        internal PageTurnView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PageTurnView.Upcast(cPtr), cMemoryOwn)
+        internal PageTurnView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 9ff2550..3555f8b 100755 (executable)
@@ -55,7 +55,7 @@ namespace Tizen.NUI
         private EventHandler<WebViewScrollEdgeReachedEventArgs> scrollEdgeReachedEventHandler;
         private WebViewScrollEdgeReachedCallbackDelegate scrollEdgeReachedCallback;
 
-        internal WebView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.WebView.Upcast(cPtr), cMemoryOwn)
+        internal WebView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
             pageLoadStartedSignal = new WebViewPageLoadSignal(Interop.WebView.NewWebViewPageLoadSignalPageLoadStarted(SwigCPtr));
             pageLoadFinishedSignal = new WebViewPageLoadSignal(Interop.WebView.NewWebViewPageLoadSignalPageLoadFinished(SwigCPtr));
@@ -168,6 +168,8 @@ namespace Tizen.NUI
             internal static readonly int ScrollPosition = Interop.WebView.ScrollPositionGet();
             internal static readonly int ScrollSize = Interop.WebView.ScrollSizeGet();
             internal static readonly int ContentSize = Interop.WebView.ContentSizeGet();
+            internal static readonly int Title = Interop.WebView.TitleGet();
+            internal static readonly int VideoHoleEnabled = Interop.WebView.VideoHoleEnabledGet();
         }
 
         private static readonly BindableProperty UrlProperty = BindableProperty.Create(nameof(Url), typeof(string), typeof(WebView), string.Empty, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
@@ -213,7 +215,7 @@ namespace Tizen.NUI
         defaultValueCreator: (bindable) =>
         {
             var webview = (WebView)bindable;
-            Vector2 temp = new Vector2(0.0f, 0.0f); ;
+            Vector2 temp = new Vector2(0.0f, 0.0f);
             Tizen.NUI.Object.GetProperty(webview.SwigCPtr, WebView.Property.ScrollPosition).Get(temp);
             return temp;
         });
@@ -221,7 +223,7 @@ namespace Tizen.NUI
         private static readonly BindableProperty ScrollSizeProperty = BindableProperty.Create(nameof(ScrollSize), typeof(Vector2), typeof(WebView), null, defaultValueCreator: (bindable) =>
         {
             var webview = (WebView)bindable;
-            Vector2 temp = new Vector2(0.0f, 0.0f); ;
+            Vector2 temp = new Vector2(0.0f, 0.0f);
             Tizen.NUI.Object.GetProperty(webview.SwigCPtr, WebView.Property.ScrollSize).Get(temp);
             return temp;
         });
@@ -229,13 +231,37 @@ namespace Tizen.NUI
         private static readonly BindableProperty ContentSizeProperty = BindableProperty.Create(nameof(ContentSize), typeof(Vector2), typeof(WebView), null, defaultValueCreator: (bindable) =>
         {
             var webview = (WebView)bindable;
-            Vector2 temp = new Vector2(0.0f, 0.0f); ;
+            Vector2 temp = new Vector2(0.0f, 0.0f);
             Tizen.NUI.Object.GetProperty(webview.SwigCPtr, WebView.Property.ContentSize).Get(temp);
             return temp;
         });
 
+        private static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(WebView), null, defaultValueCreator: (bindable) =>
+        {
+            var webview = (WebView)bindable;
+            string title;
+            Tizen.NUI.Object.GetProperty(webview.SwigCPtr, WebView.Property.Title).Get(out title);
+            return title;
+        });
+
+        private static readonly BindableProperty VideoHoleEnabledProperty = BindableProperty.Create(nameof(VideoHoleEnabled), typeof(bool), typeof(WebView), true, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var webview = (WebView)bindable;
+            if (newValue != null)
+            {
+                Tizen.NUI.Object.SetProperty(webview.SwigCPtr, WebView.Property.VideoHoleEnabled, new Tizen.NUI.PropertyValue((bool)newValue));
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var webview = (WebView)bindable;
+            bool temp;
+            Tizen.NUI.Object.GetProperty(webview.SwigCPtr, WebView.Property.VideoHoleEnabled).Get(out temp);
+            return temp;
+        });
+
         /// <summary>
-        /// Creates an uninitialized WebView.
+        /// Creates a WebView.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public WebView() : this(Interop.WebView.New(), true)
@@ -244,9 +270,9 @@ namespace Tizen.NUI
         }
 
         /// <summary>
-        /// Creates an uninitialized WebView.
-        /// <param name="locale">The locale of Web</param>
-        /// <param name="timezoneId">The timezoneId of Web</param>
+        /// Creates a WebView with local language and time zone.
+        /// <param name="locale">The locale language of Web</param>
+        /// <param name="timezoneId">The time zone Id of Web</param>
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public WebView(string locale, string timezoneId) : this(Interop.WebView.New2(locale, timezoneId), true)
@@ -255,6 +281,16 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// Creates a WebView with an args list.
+        /// <param name="args">args array. The first value of array must be program's name.</param>
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public WebView(string[] args) : this(Interop.WebView.New3(args?.Length ?? 0, args), true)
+        {
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        /// <summary>
         /// Copy constructor.
         /// <param name="webView">WebView to copy. The copied WebView will point at the same implementation</param>
         /// </summary>
@@ -469,6 +505,23 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// Whether video hole is enabled or not.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool VideoHoleEnabled
+        {
+            get
+            {
+                return (bool)GetValue(VideoHoleEnabledProperty);
+            }
+            set
+            {
+                SetValue(VideoHoleEnabledProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        /// <summary>
         /// Event for the PageLoadStarted signal which can be used to subscribe or unsubscribe the event handler.<br />
         /// This signal is emitted when page loading has started.<br />
         /// </summary>
@@ -573,6 +626,33 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// Gets title of web page.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string Title
+        {
+            get
+            {
+                return (string)GetValue(TitleProperty);
+            }
+        }
+
+        /// <summary>
+        /// Gets fav icon.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ImageView Favicon
+        {
+            get
+            {
+                global::System.IntPtr imageView = Interop.WebView.GetFavicon(SwigCPtr);
+                if (NDalicPINVOKE.SWIGPendingException.Pending)
+                    return null;
+                return new ImageView(imageView, false);
+            }
+        }
+
+        /// <summary>
         /// Loads a html.
         /// <param name="url">The path of Web</param>
         /// </summary>
@@ -744,6 +824,16 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// Clears title resources of current WebView.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ClearAllTilesResources()
+        {
+            Interop.WebView.ClearAllTilesResources(SwigCPtr);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        /// <summary>
         /// Clears the history of current WebView.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
index f2424dc..8476cad 100755 (executable)
@@ -28,7 +28,7 @@ namespace Tizen.NUI
             SwigDirectorConnect();
         }
 
-        internal WidgetImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.WidgetImpl.Upcast(cPtr), cMemoryOwn)
+        internal WidgetImpl(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
diff --git a/src/Tizen.NUI/src/internal/XamlBinding/Internals/IDataTemplate.cs b/src/Tizen.NUI/src/internal/XamlBinding/Internals/IDataTemplate.cs
deleted file mode 100755 (executable)
index 168ed7e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.ComponentModel;
-
-namespace Tizen.NUI.Binding.Internals
-{
-    internal interface IDataTemplate
-    {
-        Func<object> LoadTemplate { get; set; }
-    }
-}
index 4295847..28a9419 100755 (executable)
@@ -33,7 +33,7 @@ namespace Tizen.NUI.Accessibility
     {
         private static readonly AccessibilityManager instance = AccessibilityManager.Get();
 
-        internal AccessibilityManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.AccessibilityManager.Upcast(cPtr), cMemoryOwn)
+        internal AccessibilityManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 7ce4779..56b83a9 100755 (executable)
@@ -37,7 +37,7 @@ namespace Tizen.NUI
 
         }
 
-        internal Animatable(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Handle.Upcast(cPtr), cMemoryOwn)
+        internal Animatable(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 0c27f70..ba73b32 100755 (executable)
@@ -75,7 +75,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Animation(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Animation.Upcast(cPtr), cMemoryOwn)
+        internal Animation(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
 
             _animationFinishedEventCallback = OnFinished;
index 905e532..3d3de9f 100755 (executable)
@@ -39,7 +39,7 @@ namespace Tizen.NUI
 
         }
 
-        internal KeyFrames(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.KeyFrames.Upcast(cPtr), cMemoryOwn)
+        internal KeyFrames(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 2d1416c..9525728 100755 (executable)
@@ -38,7 +38,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Path(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Path.Upcast(cPtr), cMemoryOwn)
+        internal Path(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 6c30075..fa8a452 100755 (executable)
@@ -58,7 +58,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal TransitionData(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.TransitionData.Upcast(cPtr), cMemoryOwn)
+        internal TransitionData(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 735a3d9..6a679b8 100644 (file)
@@ -24,6 +24,8 @@ using Tizen.Applications;
 using Tizen.Applications.CoreBackend;
 using Tizen.NUI.Binding;
 using Tizen.NUI.Xaml;
+using Tizen.Applications.ThemeManager;
+using System.Collections.Generic;
 
 namespace Tizen.NUI
 {
@@ -45,6 +47,7 @@ namespace Tizen.NUI
         internal static NUIApplication me;
 
         private static bool isPreLoad = false;
+        private readonly ThemeLoader themeLoader = new ThemeLoader();
 
         /// <summary>
         /// The default constructor.
@@ -54,6 +57,7 @@ namespace Tizen.NUI
         {
             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
             me = this;
+            themeLoader.ThemeChanged += TizenThemeChanged;
         }
 
         /// <summary>
@@ -67,6 +71,7 @@ namespace Tizen.NUI
         public NUIApplication(Size2D windowSize, Position2D windowPosition) : base(new NUICoreBackend("", WindowMode.Opaque, windowSize, windowPosition))
         {
             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
+            themeLoader.ThemeChanged += TizenThemeChanged;
             _windowSize2D = windowSize;
             _windowPosition2D = windowPosition;
             me = this;
@@ -81,6 +86,7 @@ namespace Tizen.NUI
         {
             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
             me = this;
+            themeLoader.ThemeChanged += TizenThemeChanged;
         }
 
         /// <summary>
@@ -95,6 +101,7 @@ namespace Tizen.NUI
         public NUIApplication(string styleSheet, Size2D windowSize, Position2D windowPosition) : base(new NUICoreBackend(styleSheet, WindowMode.Opaque, windowSize, windowPosition))
         {
             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
+            themeLoader.ThemeChanged += TizenThemeChanged;
             _windowSize2D = windowSize;
             _windowPosition2D = windowPosition;
             me = this;
@@ -110,6 +117,7 @@ namespace Tizen.NUI
         {
             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
             me = this;
+            themeLoader.ThemeChanged += TizenThemeChanged;
         }
 
         /// <summary>
@@ -125,6 +133,7 @@ namespace Tizen.NUI
         public NUIApplication(string styleSheet, WindowMode windowMode, Size2D windowSize, Position2D windowPosition) : base(new NUICoreBackend(styleSheet, windowMode, windowSize, windowPosition))
         {
             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
+            themeLoader.ThemeChanged += TizenThemeChanged;
             _windowSize2D = windowSize;
             _windowPosition2D = windowPosition;
             me = this;
@@ -151,6 +160,7 @@ namespace Tizen.NUI
             if (windowPosition != null) { _windowPosition2D = windowPosition; }
             Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
             me = this;
+            themeLoader.ThemeChanged += TizenThemeChanged;
         }
 
         /// <summary>
@@ -436,6 +446,27 @@ namespace Tizen.NUI
                 transitionOptions = value;
             }
         }
+        private void TizenThemeChanged(object sender, ThemeEventArgs e)
+        {
+            string prefix = "/theme/";
+
+            Dictionary<string, string> changedResources = new Dictionary<string, string>();
+            foreach (string key in ThemeManager.DefaultTheme.Resources.Keys)
+            {
+                // NOTE Need improve this code by checking HasKey
+                string newValue = null;
+                try
+                {
+                    newValue = e.Theme.GetString(prefix + key);
+                }
+                catch { }
+                if (newValue != null)
+                {
+                    changedResources[key] = newValue;
+                }
+            }
+            ThemeManager.UpdateCurrentThemeResources(changedResources);
+        }
 
         /// <summary>
         /// Check if it is loaded as dotnet-loader-nui.
index 511a274..b1be0da 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public AnimatedVectorImageView() : base()
         {
-            tlog.Fatal(tag, $"[VAV START[ constuctor objId={GetId()} ]VAV END]");
+            tlog.Fatal(tag, $"[AnimatedVectorImageView START[ constuctor objId={GetId()} ] END]");
         }
 
         /// <summary>
@@ -47,7 +47,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public AnimatedVectorImageView(float scale) : base(scale)
         {
-            tlog.Fatal(tag, $"[VAV START[ constuctor scale={scale}) objId={GetId()} ]VAV END]");
+            tlog.Fatal(tag, $"[AnimatedVectorImageView START[ constuctor scale={scale}) objId={GetId()} ] END]");
         }
 
         /// <summary>
@@ -61,7 +61,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 return;
             }
-            tlog.Fatal(tag, $"[VAV START[ [{GetId()}] type={type})");
+            tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] type={type})");
 
             //Release your own unmanaged resources here.
             //You should not access any managed member here except static instance.
@@ -69,7 +69,7 @@ namespace Tizen.NUI.BaseComponents
 
             base.Dispose(type);
 
-            tlog.Fatal(tag, $"]VAV END]");
+            tlog.Fatal(tag, $"]AnimatedVectorImageView END]");
         }
         #endregion Constructor, Distructor, Dispose
 
@@ -78,46 +78,46 @@ namespace Tizen.NUI.BaseComponents
         /// <summary>
         /// Set Resource URL
         /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]
         // Suppress warning : This has been being used by users, so that the interface can not be changed.
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1056:Uri properties should not be strings", Justification = "<Pending>")]
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public string ResourceURL
         {
             set
             {
-                tlog.Fatal(tag, $"[VAV START[ [{GetId()}] ResourceURL SET");
+                tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] ResourceURL SET");
 
-                if (value == resourceURL)
+                if (value == resourceUrl)
                 {
                     tlog.Fatal(tag, $"set same URL! ");
                     return;
                 }
-                resourceURL = (value == null) ? "" : value;
-                URL = resourceURL;
-                isMinMaxSet = minMaxSetTypes.NotSetByUser;
+                resourceUrl = (value == null) ? "" : value;
+                URL = resourceUrl;
+                isMinMaxFrameSet = minMaxSetTypes.NotSetByUser;
                 totalFrameNum = base.TotalFrame;
-                tlog.Fatal(tag, $" [{GetId()}] resourceURL={resourceURL}) ]VAV END]");
+                tlog.Fatal(tag, $" [{GetId()}] resourceUrl={resourceUrl}) ]AnimatedVectorImageView END]");
             }
-            get => resourceURL;
+            get => resourceUrl;
         }
 
         /// <summary>
         /// Set Resource URL
         /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]
         // Suppress warning : This has been being used by users, so that the interface can not be changed.
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1056:Uri properties should not be strings", Justification = "<Pending>")]
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public new string ResourceUrl
         {
             set
             {
-                tlog.Fatal(tag, $"[VAV START[ [{GetId()}] ResourceUrl SET");
+                tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] ResourceUrl SET");
                 this.ResourceURL = value;
-                tlog.Fatal(tag, $" [{GetId()}] value={value}) ]VAV END]");
+                tlog.Fatal(tag, $" [{GetId()}] value={value}) ]AnimatedVectorImageView END]");
             }
             get
             {
-                tlog.Fatal(tag, $"[VAV [ [{GetId()}] ResourceUrl GET");
+                tlog.Fatal(tag, $"[AnimatedVectorImageView [ [{GetId()}] ResourceUrl GET");
                 return this.ResourceURL;
             }
         }
@@ -135,14 +135,14 @@ namespace Tizen.NUI.BaseComponents
         {
             set
             {
-                tlog.Fatal(tag, $"[VAV START[ [{GetId()}] RepeatCount SET");
+                tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] RepeatCount SET");
 
-                repeatCount = (value < -1) ? -1 : value;
-                LoopCount = (repeatCount < 0) ? repeatCount : repeatCount + 1;
+                repeatCnt = (value < -1) ? -1 : value;
+                LoopCount = (repeatCnt < 0) ? repeatCnt : repeatCnt + 1;
 
-                tlog.Fatal(tag, $"[{GetId()}] repeatCount={repeatCount} ]VAV END]");
+                tlog.Fatal(tag, $"[{GetId()}] repeatCnt={repeatCnt} ]AnimatedVectorImageView END]");
             }
-            get => repeatCount;
+            get => repeatCnt;
         }
 
         /// <summary>
@@ -163,9 +163,9 @@ namespace Tizen.NUI.BaseComponents
         {
             set
             {
-                tlog.Fatal(tag, $"[VAV START[ [{GetId()}] CurrentFrame SET");
+                tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] CurrentFrame SET");
 
-                if (string.IsNullOrEmpty(resourceURL))
+                if (string.IsNullOrEmpty(resourceUrl))
                 {
                     throw new InvalidOperationException("Resource Url not yet Set");
                 }
@@ -179,15 +179,15 @@ namespace Tizen.NUI.BaseComponents
                     value = totalFrameNum - 1;
                 }
 
-                currentFrame = value;
+                innerCurrentFrame = value;
                 AnimationState = AnimationStates.Paused;
 
                 base.SetMinMaxFrame(0, totalFrameNum - 1);
-                base.CurrentFrame = currentFrame;
+                base.CurrentFrame = innerCurrentFrame;
 
-                tlog.Fatal(tag, $" [{GetId()}] currentFrame={currentFrame}) ]VAV END]");
+                tlog.Fatal(tag, $" [{GetId()}] innerCurrentFrame={innerCurrentFrame}) ]AnimatedVectorImageView END]");
             }
-            get => currentFrame;
+            get => innerCurrentFrame;
         }
 
         /// <summary>
@@ -198,7 +198,7 @@ namespace Tizen.NUI.BaseComponents
         {
             set
             {
-                tlog.Fatal(tag, $"[VAV START[ [{GetId()}] RepeatMode SET");
+                tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] RepeatMode SET");
                 repeatMode = value;
 
                 switch (repeatMode)
@@ -214,41 +214,12 @@ namespace Tizen.NUI.BaseComponents
                         break;
                 }
 
-                tlog.Fatal(tag, $" [{GetId()}] repeatMode={repeatMode}) ]VAV END]");
+                tlog.Fatal(tag, $" [{GetId()}] repeatMode={repeatMode}) ]AnimatedVectorImageView END]");
             }
             get => repeatMode;
         }
 
         /// <summary>
-        /// Repeat of animation.
-        /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public RepeatModeType Repeat
-        {
-            set
-            {
-                tlog.Fatal(tag, $"[VAV START[ [{GetId()}] Repeat SET");
-                repeat = value;
-
-                switch (repeat)
-                {
-                    case RepeatModeType.Restart:
-                        LoopingMode = LoopingModeType.Restart;
-                        break;
-                    case RepeatModeType.Reverse:
-                        LoopingMode = LoopingModeType.AutoReverse;
-                        break;
-                    default:
-                        LoopingMode = LoopingModeType.Restart;
-                        break;
-                }
-
-                tlog.Fatal(tag, $" [{GetId()}] repeat={repeat}) ]VAV END]");
-            }
-            get => repeat;
-        }
-
-        /// <summary>
         /// Get state of animation.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
@@ -282,28 +253,28 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public void SetMinAndMaxFrame(int minFrame, int maxFrame)
         {
-            tlog.Fatal(tag, $"[VAV START[ [{GetId()}] SetMinAndMaxFrame({minFrame}, {maxFrame})");
+            tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] SetMinAndMaxFrame({minFrame}, {maxFrame})");
 
-            minFrame = (minFrame) > 0 ? minFrame : 0;
-            mMaxFrame = (maxFrame) > 0 ? maxFrame : 0;
-            isMinMaxSet = minMaxSetTypes.SetByMinAndMaxFrameMethod;
+            minimumFrame = (minFrame) > 0 ? minFrame : 0;
+            maximumFrame = (maxFrame) > 0 ? maxFrame : 0;
+            isMinMaxFrameSet = minMaxSetTypes.SetByMinAndMaxFrameMethod;
 
-            if (minFrame >= totalFrameNum)
+            if (minimumFrame >= totalFrameNum)
             {
-                minFrame = totalFrameNum - 1;
+                minimumFrame = totalFrameNum - 1;
             }
 
-            if (mMaxFrame >= totalFrameNum)
+            if (maximumFrame >= totalFrameNum)
             {
-                mMaxFrame = totalFrameNum - 1;
+                maximumFrame = totalFrameNum - 1;
             }
 
-            if (minFrame > mMaxFrame)
+            if (minimumFrame > maximumFrame)
             {
                 return;
             }
 
-            tlog.Fatal(tag, $" [{GetId()}] minFrame:{minFrame}, mMaxFrame:{mMaxFrame}) ]VAV END]");
+            tlog.Fatal(tag, $" [{GetId()}] minimumFrame:{minimumFrame}, maximumFrame:{maximumFrame}) ]AnimatedVectorImageView END]");
         }
 
         /// <summary>
@@ -316,25 +287,25 @@ namespace Tizen.NUI.BaseComponents
         {
             tlog.Fatal(tag, $"SetMinMaxFrame({minFrame}, {maxFrame})!!!");
 
-            minFrame = (minFrame) > 0 ? minFrame : 0;
-            mMaxFrame = (maxFrame) > 0 ? maxFrame : 0;
-            isMinMaxSet = minMaxSetTypes.SetByBaseSetMinMaxFrameMethod;
+            minimumFrame = (minFrame) > 0 ? minFrame : 0;
+            maximumFrame = (maxFrame) > 0 ? maxFrame : 0;
+            isMinMaxFrameSet = minMaxSetTypes.SetByBaseSetMinMaxFrameMethod;
 
-            if (minFrame >= totalFrameNum)
+            if (minimumFrame >= totalFrameNum)
             {
-                minFrame = totalFrameNum - 1;
+                minimumFrame = totalFrameNum - 1;
             }
 
-            if (mMaxFrame >= totalFrameNum)
+            if (maximumFrame >= totalFrameNum)
             {
-                mMaxFrame = totalFrameNum - 1;
+                maximumFrame = totalFrameNum - 1;
             }
 
-            base.SetMinMaxFrame(minFrame, mMaxFrame);
+            base.SetMinMaxFrame(minimumFrame, maximumFrame);
         }
 
         /// <summary>
-        /// A marker has its start frame and end frame.
+        /// A marker has its start frame and end frame. 
         /// Animation will play between the start frame and the end frame of the marker if one marker is specified.
         /// Or animation will play between the start frame of the first marker and the end frame of the second marker if two markers are specified.   *
         /// </summary>
@@ -344,7 +315,7 @@ namespace Tizen.NUI.BaseComponents
         public new void SetMinMaxFrameByMarker(string marker1, string marker2 = null)
         {
             tlog.Fatal(tag, $"SetMinMaxFrameByMarker({marker1}, {marker2})");
-            isMinMaxSet = minMaxSetTypes.SetByMarker;
+            isMinMaxFrameSet = minMaxSetTypes.SetByMarker;
             base.SetMinMaxFrameByMarker(marker1, marker2);
         }
 
@@ -354,14 +325,14 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public new void Play()
         {
-            tlog.Fatal(tag, $"[VAV START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
+            tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
 
-            if (string.IsNullOrEmpty(resourceURL))
+            if (string.IsNullOrEmpty(resourceUrl))
             {
                 throw new InvalidOperationException("Resource Url not yet Set");
             }
 
-            switch (isMinMaxSet)
+            switch (isMinMaxFrameSet)
             {
                 case minMaxSetTypes.NotSetByUser:
                     base.SetMinMaxFrame(0, totalFrameNum - 1);
@@ -369,8 +340,8 @@ namespace Tizen.NUI.BaseComponents
                     break;
 
                 case minMaxSetTypes.SetByMinAndMaxFrameMethod:
-                    base.SetMinMaxFrame(minFrame, mMaxFrame);
-                    base.CurrentFrame = minFrame;
+                    base.SetMinMaxFrame(minimumFrame, maximumFrame);
+                    base.CurrentFrame = minimumFrame;
                     break;
 
                 case minMaxSetTypes.SetByMarker:
@@ -387,7 +358,7 @@ namespace Tizen.NUI.BaseComponents
             base.Play();
             AnimationState = AnimationStates.Playing;
 
-            tlog.Fatal(tag, $" [{GetId()}] isMinMaxSet={isMinMaxSet}) ]VAV END]");
+            tlog.Fatal(tag, $" [{GetId()}] isMinMaxFrameSet={isMinMaxFrameSet}) ]AnimatedVectorImageView END]");
         }
 
         /// <summary>
@@ -396,9 +367,9 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public new void Pause()
         {
-            tlog.Fatal(tag, $"[VAV START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
+            tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
 
-            if (string.IsNullOrEmpty(resourceURL))
+            if (string.IsNullOrEmpty(resourceUrl))
             {
                 throw new InvalidOperationException("Resource Url not yet Set");
             }
@@ -406,7 +377,7 @@ namespace Tizen.NUI.BaseComponents
             base.Pause();
             AnimationState = AnimationStates.Paused;
 
-            tlog.Fatal(tag, $" [{GetId()}] ]VAV END]");
+            tlog.Fatal(tag, $" [{GetId()}] ]AnimatedVectorImageView END]");
         }
 
         /// <summary>
@@ -420,9 +391,9 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public void Stop(EndActions endAction = EndActions.Cancel)
         {
-            tlog.Fatal(tag, $"[VAV START[ [{GetId()}] endAction:({endAction}), PlayState={PlayState}");
+            tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] endAction:({endAction}), PlayState={PlayState}");
 
-            if (string.IsNullOrEmpty(resourceURL))
+            if (string.IsNullOrEmpty(resourceUrl))
             {
                 throw new InvalidOperationException("Resource Url not yet Set");
             }
@@ -432,9 +403,9 @@ namespace Tizen.NUI.BaseComponents
                 return;
             }
 
-            if (internalEndAction != endAction)
+            if (innerEndAction != endAction)
             {
-                internalEndAction = endAction;
+                innerEndAction = endAction;
                 switch (endAction)
                 {
                     case EndActions.Cancel:
@@ -457,23 +428,23 @@ namespace Tizen.NUI.BaseComponents
 
             if (endAction == EndActions.StopFinal)
             {
-                switch (isMinMaxSet)
+                switch (isMinMaxFrameSet)
                 {
                     case minMaxSetTypes.NotSetByUser:
                         if (base.CurrentFrame != totalFrameNum - 1)
                         {
-                            tlog.Fatal(tag, $"isMinMaxSet:{isMinMaxSet}, CurrentFrameNumber:{base.CurrentFrame}, totalFrameNum:{ totalFrameNum}");
+                            tlog.Fatal(tag, $"isMinMaxFrameSet:{isMinMaxFrameSet}, CurrentFrameNumber:{base.CurrentFrame}, totalFrameNum:{ totalFrameNum}");
                             base.CurrentFrame = totalFrameNum - 1;
-                            tlog.Fatal(tag, $"set CurrentFrameNumber({base.CurrentFrame}) as totalFrameNum({mMaxFrame}) - 1 !");
+                            tlog.Fatal(tag, $"set CurrentFrameNumber({base.CurrentFrame}) as totalFrameNum({maximumFrame}) - 1 !");
                         }
                         break;
 
                     case minMaxSetTypes.SetByMinAndMaxFrameMethod:
-                        if (base.CurrentFrame != mMaxFrame)
+                        if (base.CurrentFrame != maximumFrame)
                         {
-                            tlog.Fatal(tag, $"isMinMaxSet:{isMinMaxSet}, CurrentFrameNumber:{base.CurrentFrame}, mMaxFrame:{ mMaxFrame}");
-                            base.CurrentFrame = mMaxFrame;
-                            tlog.Fatal(tag, $"set CurrentFrameNumber({base.CurrentFrame}) as mMaxFrame({mMaxFrame})!!!");
+                            tlog.Fatal(tag, $"isMinMaxFrameSet:{isMinMaxFrameSet}, CurrentFrameNumber:{base.CurrentFrame}, maximumFrame:{ maximumFrame}");
+                            base.CurrentFrame = maximumFrame;
+                            tlog.Fatal(tag, $"set CurrentFrameNumber({base.CurrentFrame}) as maximumFrame({maximumFrame})!!!");
                         }
                         break;
                     case minMaxSetTypes.SetByBaseSetMinMaxFrameMethod:
@@ -483,7 +454,7 @@ namespace Tizen.NUI.BaseComponents
                         break;
                 }
             }
-            tlog.Fatal(tag, $" [{GetId()}] ]VAV END]");
+            tlog.Fatal(tag, $" [{GetId()}] ]AnimatedVectorImageView END]");
         }
         #endregion Method
 
@@ -492,39 +463,18 @@ namespace Tizen.NUI.BaseComponents
         /// <summary>
         /// RepeatMode of animation.
         /// </summary>
-        [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.RepeatModeType instead!")]
-        [EditorBrowsable(EditorBrowsableState.Never)]
         // Suppress warning : This has been being used by users, so that the interface can not be changed.
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
-        public enum RepeatModes
-        {
-            /// <summary>
-            /// When the animation reaches the end and RepeatCount is nonZero, the animation restarts from the beginning.
-            /// </summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.RepeatModeType.Restart instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Restart = LoopingModeType.Restart,
-            /// <summary>
-            /// When the animation reaches the end and RepeatCount nonZero, the animation reverses direction on every animation cycle.
-            /// </summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.RepeatModeType.Reverse instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Reverse = LoopingModeType.AutoReverse
-        }
-
-        /// <summary>
-        /// RepeatMode type of animation.
-        /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public enum RepeatModeType
+        public enum RepeatModes
         {
             /// <summary>
-            /// When the animation reaches the end and RepeatCount is nonZero, the animation restarts from the beginning.
+            /// When the animation reaches the end and RepeatCount is nonZero, the animation restarts from the beginning. 
             /// </summary>
             [EditorBrowsable(EditorBrowsableState.Never)]
             Restart = LoopingModeType.Restart,
             /// <summary>
-            /// When the animation reaches the end and RepeatCount nonZero, the animation reverses direction on every animation cycle.
+            /// When the animation reaches the end and RepeatCount nonZero, the animation reverses direction on every animation cycle. 
             /// </summary>
             [EditorBrowsable(EditorBrowsableState.Never)]
             Reverse = LoopingModeType.AutoReverse
@@ -533,31 +483,10 @@ namespace Tizen.NUI.BaseComponents
         /// <summary>
         /// EndActions of animation.
         /// </summary>
-        [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.EndAction instead!")]
-        [EditorBrowsable(EditorBrowsableState.Never)]
         // Suppress warning : This has been being used by users, so that the interface can not be changed.
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
-        public enum EndActions
-        {
-            /// <summary> End action is Cancel, Animation Stops at the Current Frame.</summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.EndAction.Cancel instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Cancel = 0,
-            /// <summary>  End action is Discard, Animation Stops at the Min Frame</summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.EndAction.Discard instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Discard = 1,
-            /// <summary> End action is StopFinal, Animation Stops at the Max Frame</summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.EndAction.StopFinal instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            StopFinal = 2
-        }
-
-        /// <summary>
-        /// EndAction of animation.
-        /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public enum EndAction
+        public enum EndActions
         {
             /// <summary> End action is Cancel, Animation Stops at the Current Frame.</summary>
             [EditorBrowsable(EditorBrowsableState.Never)]
@@ -571,33 +500,12 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
-        /// AnimationState of animation.
+        /// AnimationStates of animation.
         /// </summary>
-        [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.State instead!")]
-        [EditorBrowsable(EditorBrowsableState.Never)]
         // Suppress warning : This has been being used by users, so that the interface can not be changed.
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
-        public enum AnimationStates
-        {
-            /// <summary> The animation has stopped.</summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.State.Stopped instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Stopped = PlayStateType.Stopped,
-            /// <summary> The animation is playing.</summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.State.Playing instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Playing = PlayStateType.Playing,
-            /// <summary> The animation is paused.</summary>
-            [Obsolete("Please do not use! This will be removed. Please use AnimatedVectorImageView.State.Paused instead!")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Paused = PlayStateType.Paused
-        }
-
-        /// <summary>
-        /// Animation State of animation.
-        /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public new enum State
+        public enum AnimationStates
         {
             /// <summary> The animation has stopped.</summary>
             [EditorBrowsable(EditorBrowsableState.Never)]
@@ -611,19 +519,20 @@ namespace Tizen.NUI.BaseComponents
         }
         #endregion Event, Enum, Struct, ETC
 
+
         #region Internal
         #endregion Internal
 
+
         #region Private
-        private string resourceURL = null;
-        private int repeatCount = 0;
+        private string resourceUrl = null;
+        private int repeatCnt = 0;
         private int totalFrameNum = 0;
-        private int minFrame = -1, mMaxFrame = -1;
-        private minMaxSetTypes isMinMaxSet = minMaxSetTypes.NotSetByUser;
-        private int currentFrame = -1;
-        private EndActions internalEndAction = EndActions.Cancel;
-        private RepeatModeType repeat = RepeatModeType.Restart;
         private RepeatModes repeatMode = RepeatModes.Restart;
+        private int minimumFrame = -1, maximumFrame = -1;
+        private minMaxSetTypes isMinMaxFrameSet = minMaxSetTypes.NotSetByUser;
+        private int innerCurrentFrame = -1;
+        private EndActions innerEndAction = EndActions.Cancel;
         private enum minMaxSetTypes
         {
             NotSetByUser,
index 87120d4..2cbd4b9 100755 (executable)
@@ -339,7 +339,7 @@ namespace Tizen.NUI.BaseComponents
         /// <param name="width">Width to use</param>
         /// <returns>The height based on the width</returns>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use HeightForWidth property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use HeightForWidth property instead!")]
         public new virtual float GetHeightForWidth(float width)
         {
             return viewWrapperImpl.GetHeightForWidthBase(width);
@@ -352,7 +352,7 @@ namespace Tizen.NUI.BaseComponents
         /// <param name="height">Height to use</param>
         /// <returns>The width based on the width</returns>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use WidthForHeight property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use WidthForHeight property instead!")]
         public new virtual float GetWidthForHeight(float height)
         {
             return viewWrapperImpl.GetWidthForHeightBase(height);
index 21867c5..72b31ba 100755 (executable)
@@ -146,7 +146,7 @@ namespace Tizen.NUI.BaseComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal FlexContainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.FlexContainer.Upcast(cPtr), cMemoryOwn)
+        internal FlexContainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 0396915..fdfc64a 100755 (executable)
@@ -334,7 +334,7 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
-        internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(Interop.ImageView.Upcast(cPtr), cMemoryOwn, viewStyle)
+        internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(cPtr, cMemoryOwn, viewStyle)
         {
             if (!shown)
             {
@@ -342,7 +342,7 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
-        internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(Interop.ImageView.Upcast(cPtr), cMemoryOwn, null)
+        internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn, null)
         {
             if (!shown)
             {
@@ -1244,9 +1244,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 if (_resourceUrl != null)
                 {
-                  Size2D originalImageSize = ImageLoading.GetOriginalImageSize(_resourceUrl);
-                  Size2D imageSize = originalImageSize;
-                  originalImageSize?.Dispose();
+                  Size2D imageSize = ImageLoading.GetOriginalImageSize(_resourceUrl);
 
                   int adjustedDesiredWidth, adjustedDesiredHeight;
                   float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
index bce42a6..14182eb 100755 (executable)
@@ -216,7 +216,7 @@ namespace Tizen.NUI.BaseComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Scrollable(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Scrollable.Upcast(cPtr), cMemoryOwn)
+        internal Scrollable(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 6b98170..ef66f0a 100755 (executable)
@@ -1,5 +1,5 @@
 ï»¿/*
- * Copyright(c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -45,7 +45,11 @@ namespace Tizen.NUI.BaseComponents
         /// <param name="state">The state.</param>
         /// <param name="value">The value associated with state.</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public void Add(ControlState state, T value) => SelectorItems.Add(new SelectorItem<T>(state, value));
+        public void Add(ControlState state, T value)
+        {
+            SelectorItems.Add(new SelectorItem<T>(state, value));
+            All = default;
+        }
 
         /// <summary>
         /// Adds the specified state and value to the <see cref="SelectorItems"/>.
@@ -298,6 +302,22 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
+        /// Clone with type converter.
+        /// </summary>
+        /// <exception cref="ArgumentNullException"> Thrown when converter is null. </exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Selector<TOut> Clone<TOut>(Converter<T, TOut> converter)
+        {
+            if (converter == null) throw new ArgumentNullException(nameof(converter));
+
+            Selector<TOut> result = new Selector<TOut>();
+            result.All = converter(All);
+            result.SelectorItems = SelectorItems.ConvertAll<SelectorItem<TOut>>(m => new SelectorItem<TOut>(m.State, converter(m.Value)));
+
+            return result;
+        }
+
+        /// <summary>
         /// Copy values from other selector.
         /// </summary>
         /// <exception cref="ArgumentNullException"> Thrown when other is null. </exception>
@@ -520,9 +540,12 @@ namespace Tizen.NUI.BaseComponents
         /// <param name="list">The list for adding state-value pair.</param>
         /// <param name="state">The state.</param>
         /// <param name="value">The value associated with state.</param>
+        /// <exception cref="ArgumentNullException"> Thrown when given list is null. </exception>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static void Add<T>(this IList<SelectorItem<T>> list, ControlState state, T value)
         {
+            if (list == null) throw new ArgumentNullException(nameof(list));
+
             list.Add(new SelectorItem<T>(state, value));
         }
     }
index 99d95f3..e3c7c6c 100755 (executable)
@@ -149,7 +149,7 @@ namespace Tizen.NUI.BaseComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal TableView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.TableView.Upcast(cPtr), cMemoryOwn)
+        internal TableView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -395,7 +395,7 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <param name="padding">Width and height.</param>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use CellPadding property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use CellPadding property instead!")]
         public void SetCellPadding(Size2D padding)
         {
             Interop.TableView.SetCellPadding(SwigCPtr, Size2D.getCPtr(padding));
@@ -407,7 +407,7 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <returns>The current padding as width and height.</returns>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use CellPadding property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use CellPadding property instead!")]
         public Vector2 GetCellPadding()
         {
             Vector2 ret = new Vector2(Interop.TableView.GetCellPadding(SwigCPtr), true);
index efc7b27..524fa72 100755 (executable)
@@ -68,7 +68,7 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
-        internal TextEditor(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(Interop.TextEditor.Upcast(cPtr), cMemoryOwn)
+        internal TextEditor(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn)
         {
             if (!shown)
             {
index cb8ac85..797f0d0 100755 (executable)
@@ -70,7 +70,7 @@ namespace Tizen.NUI.BaseComponents
             return new TextFieldStyle();
         }
 
-        internal TextField(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(Interop.TextField.Upcast(cPtr), cMemoryOwn, viewStyle)
+        internal TextField(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(cPtr, cMemoryOwn, viewStyle)
         {
             if (!shown)
             {
@@ -78,7 +78,7 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
-        internal TextField(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(Interop.TextField.Upcast(cPtr), cMemoryOwn, null)
+        internal TextField(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn, null)
         {
             if (!shown)
             {
index 17e4a83..dfde963 100755 (executable)
@@ -147,7 +147,7 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
-        internal TextLabel(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(Interop.TextLabel.Upcast(cPtr), cMemoryOwn, viewStyle)
+        internal TextLabel(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(cPtr, cMemoryOwn, viewStyle)
         {
             if (!shown)
             {
@@ -155,7 +155,7 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
-        internal TextLabel(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(Interop.TextLabel.Upcast(cPtr), cMemoryOwn, null)
+        internal TextLabel(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn, null)
         {
             if (!shown)
             {
index 7a3dfbf..1bd5f3a 100755 (executable)
@@ -208,7 +208,7 @@ namespace Tizen.NUI.BaseComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal VideoView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.VideoView.Upcast(cPtr), cMemoryOwn)
+        internal VideoView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 7694cb0..ac055fb 100755 (executable)
@@ -94,7 +94,7 @@ namespace Tizen.NUI.BaseComponents
             InitializeStyle(viewStyle);
         }
 
-        internal View(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(Interop.View.Upcast(cPtr), cMemoryOwn)
+        internal View(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn)
         {
             if (HasBody())
             {
index 63f5397..7560872 100755 (executable)
@@ -181,7 +181,7 @@ namespace Tizen.NUI.BaseComponents
             if (child == null || child.GetParent() == null) // Early out if child null.
                 return;
 
-            if (child.Parent != this)
+            if (child.GetParent() != this)
             {
                 throw new System.InvalidOperationException("You have deleted a view that is not a child of this view.");
             }
@@ -221,7 +221,7 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <seealso cref="Container.GetChildCount" />
         /// <since_tizen> 4 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
         public override uint GetChildCount()
         {
             return Convert.ToUInt32(Children.Count);
@@ -262,7 +262,7 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <param name="styleName">A string matching a style described in a stylesheet.</param>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use StyleName property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use StyleName property instead!")]
         public void SetStyleName(string styleName)
         {
             Interop.View.SetStyleName(SwigCPtr, styleName);
@@ -274,7 +274,7 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <returns>A string matching a style, or an empty string.</returns>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use StyleName property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use StyleName property instead!")]
         public string GetStyleName()
         {
             string ret = Interop.View.GetStyleName(SwigCPtr);
@@ -468,7 +468,7 @@ namespace Tizen.NUI.BaseComponents
         /// <param name="width">The width to use.</param>
         /// <returns>The height based on the width.</returns>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use HeightForWidth property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use HeightForWidth property instead!")]
         public float GetHeightForWidth(float width)
         {
             float ret = Interop.Actor.GetHeightForWidth(SwigCPtr, width);
@@ -485,7 +485,7 @@ namespace Tizen.NUI.BaseComponents
         /// <param name="height">The height to use.</param>
         /// <returns>The width based on the height.</returns>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use WidthForHeight property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use WidthForHeight property instead!")]
         public float GetWidthForHeight(float height)
         {
             float ret = Interop.Actor.GetWidthForHeight(SwigCPtr, height);
@@ -526,7 +526,7 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <param name="paddingOut">the value of padding for the view</param>
         /// <since_tizen> 3 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use Padding property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use Padding property instead!")]
         public void GetPadding(PaddingType paddingOut)
         {
             Interop.Actor.GetPadding(SwigCPtr, PaddingType.getCPtr(paddingOut));
index 71304d5..5da1eae 100755 (executable)
@@ -33,12 +33,16 @@ namespace Tizen.NUI
         /// swigCMemOwn
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use SwigCMemOwn")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected bool swigCMemOwn;
 
         /// <summary>
         /// A flag to check if it is already disposed.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use Disposed")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected bool disposed = false;
 
         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
index 55a0d55..2c8e6af 100755 (executable)
@@ -123,7 +123,7 @@ namespace Tizen.NUI
         /// <pre>The container has been initialized.</pre>
         /// <returns>The number of children.</returns>
         /// <since_tizen> 4 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
         public abstract UInt32 GetChildCount();
 
         internal abstract View FindCurrentChildById(uint id);
index 503579f..9abbe28 100755 (executable)
@@ -40,7 +40,7 @@ namespace Tizen.NUI
             this.SetResizePolicy(ResizePolicyType.FillToParent, DimensionType.AllDimensions);
         }
 
-        internal Layer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Layer.Upcast(cPtr), cMemoryOwn)
+        internal Layer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -355,7 +355,7 @@ namespace Tizen.NUI
         /// </summary>
         /// <returns>The child count of the layer.</returns>
         /// <since_tizen> 4 </since_tizen>
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
         public override uint GetChildCount()
         {
             return Convert.ToUInt32(Children.Count);
index 4679a33..103c8a0 100755 (executable)
@@ -39,7 +39,7 @@ namespace Tizen.NUI
 
         }
 
-        internal PropertyBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PropertyBuffer.Upcast(cPtr), cMemoryOwn)
+        internal PropertyBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 352257f..55d9b04 100755 (executable)
@@ -34,7 +34,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal PropertyCondition(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PropertyCondition.Upcast(cPtr), cMemoryOwn)
+        internal PropertyCondition(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 48eea3e..95db10f 100755 (executable)
@@ -50,7 +50,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal PropertyNotification(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PropertyNotification.Upcast(cPtr), cMemoryOwn)
+        internal PropertyNotification(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index b681815..502b2c3 100755 (executable)
@@ -170,7 +170,7 @@ namespace Tizen.NUI
             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
         }
 
-        internal StyleManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.StyleManager.Upcast(cPtr), cMemoryOwn)
+        internal StyleManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index cc68574..0ccc6e1 100755 (executable)
@@ -45,7 +45,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal TypeInfo(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.TypeInfo.Upcast(cPtr), cMemoryOwn)
+        internal TypeInfo(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 92bd67d..f5715bb 100755 (executable)
@@ -27,7 +27,7 @@ namespace Tizen.NUI
     public class TypeRegistry : BaseHandle
     {
 
-        internal TypeRegistry(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.TypeRegistry.Upcast(cPtr), cMemoryOwn)
+        internal TypeRegistry(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 59937cd..8c96847 100755 (executable)
@@ -78,6 +78,8 @@ namespace Tizen.NUI
     {
 
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use Type")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         public readonly ScriptableType type;
 
         /// <since_tizen> 3 </since_tizen>
index 0e13e1e..500f05a 100755 (executable)
@@ -27,7 +27,7 @@ namespace Tizen.NUI
     {
         internal ViewWrapperImpl viewWrapperImpl;
 
-        internal ViewWrapper(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ViewWrapper.Upcast(cPtr), cMemoryOwn, null)
+        internal ViewWrapper(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn, null)
         {
         }
 
@@ -37,7 +37,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal ViewWrapper(string typeName, ViewWrapperImpl implementation, ViewStyle viewStyle) : base(Interop.ViewWrapper.Upcast(Interop.ViewWrapper.New(typeName, ViewWrapperImpl.getCPtr(implementation))), true, viewStyle)
+        internal ViewWrapper(string typeName, ViewWrapperImpl implementation, ViewStyle viewStyle) : base(Interop.ViewWrapper.New(typeName, ViewWrapperImpl.getCPtr(implementation)), true, viewStyle)
         {
             viewWrapperImpl = implementation;
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
index 4df417a..94cd27b 100755 (executable)
@@ -37,7 +37,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Gesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Gesture.Upcast(cPtr), cMemoryOwn)
+        internal Gesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index d45606c..0a4b1de 100755 (executable)
@@ -51,7 +51,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal GestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.GestureDetector.Upcast(cPtr), cMemoryOwn)
+        internal GestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 919bd05..ae21f32 100755 (executable)
@@ -52,7 +52,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Hover(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Hover.Upcast(cPtr), cMemoryOwn)
+        internal Hover(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 829a082..26183ec 100755 (executable)
@@ -37,7 +37,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal LongPressGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.LongPressGesture.Upcast(cPtr), cMemoryOwn)
+        internal LongPressGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 632b1fb..74ab701 100755 (executable)
@@ -77,7 +77,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal LongPressGestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.LongPressGestureDetector.Upcast(cPtr), cMemoryOwn)
+        internal LongPressGestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 8304f50..42b820b 100755 (executable)
@@ -50,7 +50,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal PanGestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PanGestureDetector.Upcast(cPtr), cMemoryOwn)
+        internal PanGestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 33ee686..bfc5345 100755 (executable)
@@ -27,7 +27,7 @@ namespace Tizen.NUI
     public class PinchGesture : Gesture
     {
 
-        internal PinchGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PinchGesture.Upcast(cPtr), cMemoryOwn)
+        internal PinchGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index b922fe5..7863cc2 100755 (executable)
@@ -28,7 +28,7 @@ namespace Tizen.NUI
     public class RotationGesture : Gesture
     {
 
-        internal RotationGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.RotationGesture.Upcast(cPtr), cMemoryOwn)
+        internal RotationGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index e2822c9..e2b4747 100755 (executable)
@@ -35,7 +35,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal TapGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.TapGesture.Upcast(cPtr), cMemoryOwn)
+        internal TapGesture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 9971fbd..0701419 100755 (executable)
@@ -52,7 +52,7 @@ namespace Tizen.NUI
 
         }
 
-        internal TapGestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.TapGestureDetector.Upcast(cPtr), cMemoryOwn)
+        internal TapGestureDetector(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 88d9992..ad66db2 100755 (executable)
@@ -53,7 +53,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Wheel(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Wheel.Upcast(cPtr), cMemoryOwn)
+        internal Wheel(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index d038075..4681237 100755 (executable)
@@ -34,7 +34,7 @@ namespace Tizen.NUI
         }
 
         private IntPtr Handle;
-        internal NativeImageSource(IntPtr cPtr, bool cMemoryOwn) : base(Interop.NativeImageSource.Upcast(Interop.NativeImageSource.New(cPtr)), cMemoryOwn)
+        internal NativeImageSource(IntPtr cPtr, bool cMemoryOwn) : base(Interop.NativeImageSource.New(cPtr), cMemoryOwn)
         {
             Handle = cPtr;
         }
index d1b4562..3ecf424 100755 (executable)
@@ -56,7 +56,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal PixelBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PixelBuffer.Upcast(cPtr), cMemoryOwn)
+        internal PixelBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 2c1cde1..a1c5949 100755 (executable)
@@ -55,7 +55,7 @@ namespace Tizen.NUI
 
         }
 
-        internal PixelData(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PixelData.Upcast(cPtr), cMemoryOwn)
+        internal PixelData(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 7f68106..11474c6 100755 (executable)
@@ -107,7 +107,7 @@ namespace Tizen.NUI
 
         }
 
-        internal AutofillContainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.AutofillContainer.Upcast(cPtr), cMemoryOwn)
+        internal AutofillContainer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index aa237f9..754bdd6 100755 (executable)
@@ -48,7 +48,7 @@ namespace Tizen.NUI
         private EventHandler<FocusedViewActivatedEventArgs> _focusedViewEnterKeyEventHandler2;
         private FocusedViewEnterKeyEventCallback2 _focusedViewEnterKeyEventCallback2;
 
-        internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.FocusManager.Upcast(cPtr), cMemoryOwn)
+        internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 3ab02ba..2851bd5 100755 (executable)
@@ -48,7 +48,7 @@ namespace Tizen.NUI
 
         }
 
-        internal InputMethodContext(IntPtr cPtr, bool cMemoryOwn) : base(Interop.InputMethodContext.Upcast(cPtr), cMemoryOwn)
+        internal InputMethodContext(IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index e929986..e074d9a 100755 (executable)
@@ -51,7 +51,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Key(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Key.Upcast(cPtr), cMemoryOwn)
+        internal Key(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 319db75..515f3a4 100755 (executable)
@@ -35,7 +35,7 @@ namespace Tizen.NUI
 
         }
 
-        internal Geometry(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Geometry.Upcast(cPtr), cMemoryOwn)
+        internal Geometry(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 8c5446d..33342c8 100755 (executable)
@@ -668,7 +668,7 @@ namespace Tizen.NUI
             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
         }
 
-        internal Renderer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Renderer.Upcast(cPtr), cMemoryOwn)
+        internal Renderer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 3e3819b..496ece3 100755 (executable)
@@ -76,7 +76,7 @@ namespace Tizen.NUI
             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
         }
 
-        internal Sampler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Sampler.Upcast(cPtr), cMemoryOwn)
+        internal Sampler(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index e970b57..64ba5df 100755 (executable)
@@ -77,7 +77,7 @@ namespace Tizen.NUI
             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
         }
 
-        internal Shader(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Shader.Upcast(cPtr), cMemoryOwn)
+        internal Shader(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 9a10b20..00f6928 100755 (executable)
@@ -52,7 +52,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Texture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Texture.Upcast(cPtr), cMemoryOwn)
+        internal Texture(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 09276f7..ef5a1ef 100755 (executable)
@@ -36,7 +36,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal TextureSet(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.TextureSet.Upcast(cPtr), cMemoryOwn)
+        internal TextureSet(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 91a15bb..9081275 100755 (executable)
@@ -40,7 +40,7 @@ namespace Tizen.NUI
                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal VertexBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.VertexBuffer.Upcast(cPtr), cMemoryOwn)
+        internal VertexBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -1,26 +1,45 @@
 using System;
+using System.ComponentModel;
 using System.Collections.Generic;
 
 namespace Tizen.NUI.Binding
 {
-    internal class DataTemplate : ElementTemplate
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class DataTemplate : ElementTemplate
     {
+        /// <summary>
+        /// Base constructor.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public DataTemplate()
         {
         }
 
+        /// <summary>
+        /// Base constructor with specific Type.
+        /// </summary>
+        /// <param name="Type">The Type of content.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public DataTemplate(Type type) : base(type)
         {
         }
 
+        /// <summary>
+        /// Base constructor with loadTemplate function.
+        /// </summary>
+        /// <param name="loadTemplate">The function of loading templated object.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public DataTemplate(Func<object> loadTemplate) : base(loadTemplate)
         {
         }
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public IDictionary<BindableProperty, BindingBase> Bindings { get; } = new Dictionary<BindableProperty, BindingBase>();
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public IDictionary<BindableProperty, object> Values { get; } = new Dictionary<BindableProperty, object>();
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public void SetBinding(BindableProperty property, BindingBase binding)
         {
             if (property == null)
@@ -32,6 +51,7 @@ namespace Tizen.NUI.Binding
             Bindings[property] = binding;
         }
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public void SetValue(BindableProperty property, object value)
         {
             if (property == null)
@@ -3,8 +3,9 @@
 namespace Tizen.NUI.Binding
 {
     [EditorBrowsable(EditorBrowsableState.Never)]
-    internal static class DataTemplateExtensions
+    public static class DataTemplateExtensions
     {
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public static DataTemplate SelectDataTemplate(this DataTemplate self, object item, BindableObject container)
         {
             var selector = self as DataTemplateSelector;
@@ -14,6 +15,7 @@ namespace Tizen.NUI.Binding
             return selector.SelectTemplate(item, container);
         }
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public static object CreateContent(this DataTemplate self, object item, BindableObject container)
         {
             return self.SelectDataTemplate(item, container).CreateContent();
@@ -1,12 +1,15 @@
 using System;
+using System.ComponentModel;
 using System.Collections.Generic;
 
 namespace Tizen.NUI.Binding
 {
-    internal abstract class DataTemplateSelector : DataTemplate
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public abstract class DataTemplateSelector : DataTemplate
     {
         Dictionary<Type, DataTemplate> _dataTemplates = new Dictionary<Type, DataTemplate>();
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public DataTemplate SelectTemplate(object item, BindableObject container)
         {
             DataTemplate dataTemplate = null;
@@ -23,6 +26,7 @@ namespace Tizen.NUI.Binding
             return dataTemplate;
         }
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
         protected abstract DataTemplate OnSelectTemplate(object item, BindableObject container);
     }
 }
@@ -9,7 +9,7 @@ namespace Tizen.NUI.Binding
     /// Base class for DataTemplate and ControlTemplate classes.
     /// </summary>
     [EditorBrowsable(EditorBrowsableState.Never)]
-    internal class ElementTemplate : IElement, IDataTemplate
+    public class ElementTemplate : IElement, IDataTemplate
     {
         List<Action<object, ResourcesChangedEventArgs>> _changeHandlers;
         Element _parent;
@@ -80,6 +80,7 @@ namespace Tizen.NUI.Binding
         /// Used by the XAML infrastructure to load data templates and set up the content of the resulting UI.
         /// </summary>
         /// <returns></returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public object CreateContent()
         {
             if (LoadTemplate == null)
diff --git a/src/Tizen.NUI/src/public/Template/IDataTemplate.cs b/src/Tizen.NUI/src/public/Template/IDataTemplate.cs
new file mode 100755 (executable)
index 0000000..99ba11f
--- /dev/null
@@ -0,0 +1,11 @@
+using System;
+using System.ComponentModel;
+
+namespace Tizen.NUI.Binding
+{
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public interface IDataTemplate
+    {
+        Func<object> LoadTemplate { get; set; }
+    }
+}
index a88b8bf..36f69fa 100755 (executable)
@@ -458,7 +458,7 @@ namespace Tizen.NUI.UIComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Button(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Button.Upcast(cPtr), cMemoryOwn)
+        internal Button(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 68f4b5d..3cbe292 100755 (executable)
@@ -47,7 +47,7 @@ namespace Tizen.NUI.UIComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal CheckBoxButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CheckBoxButton.Upcast(cPtr), cMemoryOwn)
+        internal CheckBoxButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 23a60c2..87a2e25 100755 (executable)
@@ -54,7 +54,7 @@ namespace Tizen.NUI.UIComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Popup(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Popup.Upcast(cPtr), cMemoryOwn)
+        internal Popup(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 7cca30a..7981b74 100755 (executable)
@@ -210,7 +210,7 @@ namespace Tizen.NUI.UIComponents
 
         }
 
-        internal ProgressBar(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ProgressBar.Upcast(cPtr), cMemoryOwn)
+        internal ProgressBar(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 4de16a1..b6540c6 100755 (executable)
@@ -58,7 +58,7 @@ namespace Tizen.NUI.UIComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal PushButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.PushButton.Upcast(cPtr), cMemoryOwn)
+        internal PushButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index bad80fe..4ca6fcc 100755 (executable)
@@ -65,7 +65,7 @@ namespace Tizen.NUI.UIComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal RadioButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.RadioButton.Upcast(cPtr), cMemoryOwn)
+        internal RadioButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 8af6225..08ba35a 100755 (executable)
@@ -264,7 +264,7 @@ namespace Tizen.NUI.UIComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal ScrollBar(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ScrollBar.Upcast(cPtr), cMemoryOwn)
+        internal ScrollBar(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index b47031d..39b2a1e 100755 (executable)
@@ -42,7 +42,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal ScrollView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ScrollView.Upcast(cPtr), cMemoryOwn)
+        internal ScrollView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 414c283..312269e 100755 (executable)
@@ -322,7 +322,7 @@ namespace Tizen.NUI.UIComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Slider(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Slider.Upcast(cPtr), cMemoryOwn)
+        internal Slider(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index c7c63e8..0bffca6 100755 (executable)
@@ -101,7 +101,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal ToggleButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.ToggleButton.Upcast(cPtr), cMemoryOwn)
+        internal ToggleButton(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 6f5c9ba..5ecbc98 100755 (executable)
@@ -60,7 +60,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Capture(IntPtr cPtr, bool cMemoryOwn) : base(Interop.Capture.Upcast(cPtr), cMemoryOwn)
+        internal Capture(IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 2a0e33a..18aa376 100755 (executable)
@@ -51,7 +51,7 @@ namespace Tizen.NUI
             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
         }
 
-        internal CubeTransitionEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CubeTransitionEffect.Upcast(cPtr), cMemoryOwn)
+        internal CubeTransitionEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -335,7 +335,7 @@ namespace Tizen.NUI
         }
 
 
-        internal CubeTransitionWaveEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CubeTransitionWaveEffect.Upcast(cPtr), cMemoryOwn)
+        internal CubeTransitionWaveEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -363,7 +363,7 @@ namespace Tizen.NUI
         }
 
 
-        internal CubeTransitionCrossEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CubeTransitionCrossEffect.Upcast(cPtr), cMemoryOwn)
+        internal CubeTransitionCrossEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
@@ -391,7 +391,7 @@ namespace Tizen.NUI
         }
 
 
-        internal CubeTransitionFoldEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.CubeTransitionWaveEffect.Upcast(cPtr), cMemoryOwn)
+        internal CubeTransitionFoldEffect(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index 1e2d90b..9f010f1 100755 (executable)
@@ -27,7 +27,7 @@ namespace Tizen.NUI
 
         private static readonly FontClient instance = FontClient.Get();
 
-        internal FontClient(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.FontClient.Upcast(cPtr), cMemoryOwn)
+        internal FontClient(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index df48769..9f977bb 100755 (executable)
@@ -58,7 +58,7 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        internal Timer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Timer.Upcast(cPtr), cMemoryOwn)
+        internal Timer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
 
             _timerTickCallbackDelegate = OnTick;
index b2752a1..10e8f1e 100755 (executable)
@@ -44,7 +44,7 @@ namespace Tizen.NUI
         {
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
-        internal VisualBase(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.VisualBase.Upcast(cPtr), cMemoryOwn)
+        internal VisualBase(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index ee05346..a4531a5 100755 (executable)
@@ -33,7 +33,7 @@ namespace Tizen.NUI
         /// </summary>
         private static VisualFactory instance;
 
-        internal VisualFactory(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.VisualFactory.Upcast(cPtr), cMemoryOwn)
+        internal VisualFactory(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index bccc9f5..6f03ecf 100755 (executable)
@@ -31,12 +31,16 @@ namespace Tizen.NUI
         /// outputVisualMap.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use OutputVisualMap")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected PropertyMap _outputVisualMap = null;
 
         /// <summary>
         /// The shader of the visual.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use Shader")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected PropertyMap _shader = null;
         //private PropertyMap _transform = null;
 
@@ -44,24 +48,32 @@ namespace Tizen.NUI
         /// The premultipliedAlpha of the visual.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use PremultipliedAlpha")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected bool? _premultipliedAlpha = null;
 
         /// <summary>
         /// The mixColor of the Visual.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use MixColor")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected Color _mixColor = null;
 
         /// <summary>
         /// The opacity of the visual.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use Opacity")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected float? _opacity = null;
 
         /// <summary>
         /// The FittingMode of the visual.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Please use VisualFittingMode")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected VisualFittingModeType? _visualFittingMode = null;
 
         /// <summary>
@@ -74,6 +86,8 @@ namespace Tizen.NUI
         /// The map for visual.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated in API9, Will be removed in API11, Plese not use _comonlyUsedMap")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Pending>")]
         protected PropertyMap _commonlyUsedMap = null;
 
         private Vector2 visualSize = null;
index 223cf83..a25101f 100755 (executable)
@@ -50,7 +50,7 @@ namespace Tizen.NUI
             (WidgetApplication.Instance as WidgetApplication)?.AddWidgetInstance(this);
         }
 
-        internal Widget(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Widget.Upcast(cPtr), cMemoryOwn)
+        internal Widget(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index d881aa1..5d8398d 100755 (executable)
@@ -51,7 +51,7 @@ namespace Tizen.NUI
 
         }
 
-        internal WidgetView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.WidgetView.Upcast(cPtr), cMemoryOwn)
+        internal WidgetView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
         internal WidgetView(WidgetView handle) : this(Interop.WidgetView.NewWidgetView(WidgetView.getCPtr(handle)), true)
old mode 100644 (file)
new mode 100755 (executable)
index 0347263..885956a
@@ -44,7 +44,7 @@ namespace Tizen.NUI
         {
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
-        internal WidgetViewManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.WidgetViewManager.Upcast(cPtr), cMemoryOwn)
+        internal WidgetViewManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
         }
 
index f460c5c..9b7e79b 100755 (executable)
@@ -34,7 +34,7 @@ namespace Tizen.NUI
     [EditorBrowsable(EditorBrowsableState.Never)]
     public partial class GLWindow : BaseHandle
     {
-        internal GLWindow(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.GLWindow.GlWindowUpcast(cPtr), cMemoryOwn)
+        internal GLWindow(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
 
         }
index 113a327..459a5a8 100755 (executable)
@@ -46,7 +46,7 @@ namespace Tizen.NUI
             return isSupported;
         }
 
-        internal Window(global::System.IntPtr cPtr, bool cMemoryOwn) : base(Interop.Window.Upcast(cPtr), cMemoryOwn)
+        internal Window(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
         {
             if (Interop.Stage.IsInstalled())
             {
index 33bc2dd..6d0acdb 100755 (executable)
@@ -44,7 +44,7 @@ namespace Tizen.NUI.Binding
 
         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
         [EditorBrowsable(EditorBrowsableState.Never)]
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use GetValue() instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use GetValue() instead!")]
         public object Value
         {
             get { return ((BindingCondition)Condition).Value; }
index 0473df7..5c4b54d 100755 (executable)
@@ -51,7 +51,7 @@ namespace Tizen.NUI.Binding
         /// <since_tizen> 6 </since_tizen>
         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
         [EditorBrowsable(EditorBrowsableState.Never)]
-        // [Obsolete("Deprecated in API9, will be removed in API11. Please use GetValue() instead!")]
+        [Obsolete("Deprecated in API9, will be removed in API11. Please use GetValue() instead!")]
         public object Value
         {
             get { return ((XamlPropertyCondition)Condition).Value; }
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/CollectionViewGridSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/CollectionViewGridSample.cs
new file mode 100755 (executable)
index 0000000..36b2992
--- /dev/null
@@ -0,0 +1,113 @@
+using System.Collections.Generic;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Samples
+{
+    public class CollectionViewGridSample : IExample
+    {
+        CollectionView colView;
+        int itemCount = 500;
+        int selectedCount;
+        ItemSelectionMode selMode;
+
+        public void Activate()
+        {
+            Window window = NUIApplication.GetDefaultWindow();
+
+            var myViewModelSource = new GalleryViewModel(itemCount);
+            selMode = ItemSelectionMode.MultipleSelections;
+            DefaultTitleItem myTitle = new DefaultTitleItem();
+            myTitle.Text = "Grid Sample Count["+itemCount+"] Selected["+selectedCount+"]";
+            //Set Width Specification as MatchParent to fit the Item width with parent View.
+            myTitle.WidthSpecification = LayoutParamPolicies.MatchParent;
+
+            colView = new CollectionView()
+            {
+                ItemsSource = myViewModelSource,
+                ItemsLayouter = new GridLayouter(),
+                ItemTemplate = new DataTemplate(() =>
+                {
+                    DefaultGridItem item = new DefaultGridItem();
+                    item.WidthSpecification = 180;
+                    item.HeightSpecification = 240;
+                    //Decorate Label
+                    item.Caption.SetBinding(TextLabel.TextProperty, "ViewLabel");
+                    item.Caption.HorizontalAlignment = HorizontalAlignment.Center;
+                    //Decorate Image
+                    item.Image.SetBinding(ImageView.ResourceUrlProperty, "ImageUrl");
+                    item.Image.WidthSpecification = 170;
+                    item.Image.HeightSpecification = 170;
+                    //Decorate Badge checkbox.
+                    //[NOTE] This is sample of CheckBox usage in CollectionView.
+                    // Checkbox change their selection by IsSelectedProperty bindings with
+                    // SelectionChanged event with MulitpleSelections ItemSelectionMode of CollectionView.
+                    item.Badge = new CheckBox();
+                    //FIXME : SetBinding in RadioButton crashed as Sensitive Property is disposed.
+                    //item.Badge.SetBinding(CheckBox.IsSelectedProperty, "Selected");
+                    item.Badge.WidthSpecification = 30;
+                    item.Badge.HeightSpecification = 30;
+
+                    return item;
+                }),
+                Header = myTitle,
+                ScrollingDirection = ScrollableBase.Direction.Vertical,
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                               SelectionMode = selMode
+            };
+            colView.SelectionChanged += SelectionEvt;
+
+            window.Add(colView);
+        }
+
+        public void SelectionEvt(object sender, SelectionChangedEventArgs ev)
+        {
+            List<object> oldSel = new List<object>(ev.PreviousSelection);
+            List<object> newSel = new List<object>(ev.CurrentSelection);
+
+            foreach (object item in oldSel)
+            {
+                if (item != null && item is Gallery)
+                {
+                    Gallery galItem = (Gallery)item;
+                    if (!(newSel.Contains(item)))
+                    {
+                        galItem.Selected = false;
+                        Tizen.Log.Debug("Unselected: {0}", galItem.ViewLabel);
+                        selectedCount--;
+                    }
+                }
+                else continue;
+            }
+            foreach (object item in newSel)
+            {
+                if (item != null && item is Gallery)
+                {
+                    Gallery galItem = (Gallery)item;
+                    if (!(oldSel.Contains(item)))
+                    {
+                        galItem.Selected = true;
+                        Tizen.Log.Debug("Selected: {0}", galItem.ViewLabel);
+                        selectedCount++;
+                    }
+                }
+                else continue;
+            }
+            if (colView.Header != null && colView.Header is DefaultTitleItem)
+            {
+                DefaultTitleItem title = (DefaultTitleItem)colView.Header;
+                title.Text = "Grid Sample Count["+itemCount+"] Selected["+selectedCount+"]";
+            }
+        }
+
+        public void Deactivate()
+        {
+            if (colView != null)
+            {
+                colView.Dispose();
+            }
+        }
+    }
+}
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/CollectionViewLinearSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/CollectionViewLinearSample.cs
new file mode 100755 (executable)
index 0000000..693cf1e
--- /dev/null
@@ -0,0 +1,112 @@
+using System.Collections.Generic;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Binding;
+using System.ComponentModel;
+using System;
+
+namespace Tizen.NUI.Samples
+{
+    public class CollectionViewLinearSample : IExample
+    {
+        CollectionView colView;
+        int itemCount = 500;
+        string selectedItem;
+        ItemSelectionMode selMode;
+
+        public void Activate()
+        {
+            Window window = NUIApplication.GetDefaultWindow();
+
+            var myViewModelSource = new GalleryViewModel(itemCount);
+            selMode = ItemSelectionMode.SingleSelection;
+            DefaultTitleItem myTitle = new DefaultTitleItem();
+            myTitle.Text = "Linear Sample Count["+itemCount+"]";
+            //Set Width Specification as MatchParent to fit the Item width with parent View.
+            myTitle.WidthSpecification = LayoutParamPolicies.MatchParent;
+
+            colView = new CollectionView()
+            {
+                ItemsSource = myViewModelSource,
+                ItemsLayouter = new LinearLayouter(),
+                ItemTemplate = new DataTemplate(() =>
+                {
+                    var rand = new Random();
+                    RecyclerViewItem item = new RecyclerViewItem();
+                    item.WidthSpecification = LayoutParamPolicies.MatchParent;
+                    item.HeightSpecification = 100;
+                    item.BackgroundColor = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble(), 1);
+                    /*
+                    DefaultLinearItem item = new DefaultLinearItem();
+                    //Set Width Specification as MatchParent to fit the Item width with parent View.
+                    item.WidthSpecification = LayoutParamPolicies.MatchParent;
+                    //Decorate Label
+                    item.Label.SetBinding(TextLabel.TextProperty, "ViewLabel");
+                    item.Label.HorizontalAlignment = HorizontalAlignment.Begin;
+                    //Decorate Icon
+                    item.Icon.SetBinding(ImageView.ResourceUrlProperty, "ImageUrl");
+                    item.Icon.WidthSpecification = 80;
+                    item.Icon.HeightSpecification = 80;
+                    //Decorate Extra RadioButton.
+                    //[NOTE] This is sample of RadioButton usage in CollectionView.
+                    // RadioButton change their selection by IsSelectedProperty bindings with
+                    // SelectionChanged event with SingleSelection ItemSelectionMode of CollectionView.
+                    // be aware of there are no RadioButtonGroup. 
+                    item.Extra = new RadioButton();
+                    //FIXME : SetBinding in RadioButton crashed as Sensitive Property is disposed.
+                    //item.Extra.SetBinding(RadioButton.IsSelectedProperty, "Selected");
+                    item.Extra.WidthSpecification = 80;
+                    item.Extra.HeightSpecification = 80;
+                    */
+
+                    return item;
+                }),
+                Header = myTitle,
+                ScrollingDirection = ScrollableBase.Direction.Vertical,
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                               SelectionMode = selMode
+            };
+            colView.SelectionChanged += SelectionEvt;
+
+            window.Add(colView);
+
+        }
+
+        public void SelectionEvt(object sender, SelectionChangedEventArgs ev)
+        {
+            //Tizen.Log.Debug("NUI", "LSH :: SelectionEvt called");
+
+            //SingleSelection Only have 1 or nil object in the list.
+            foreach (object item in ev.PreviousSelection)
+            {
+                if (item == null) break;
+                Gallery unselItem = (Gallery)item;
+
+                unselItem.Selected = false;
+                selectedItem = null;
+                //Tizen.Log.Debug("NUI", "LSH :: Unselected: {0}", unselItem.ViewLabel);
+            }
+            foreach (object item in ev.CurrentSelection)
+            {
+                if (item == null) break;
+                Gallery selItem = (Gallery)item;
+                selItem.Selected = true;
+                selectedItem = selItem.Name;
+                //Tizen.Log.Debug("NUI", "LSH :: Selected: {0}", selItem.ViewLabel);
+            }
+            if (colView.Header != null && colView.Header is DefaultTitleItem)
+            {
+                DefaultTitleItem title = (DefaultTitleItem)colView.Header;
+                title.Text = "Linear Sample Count[" + itemCount + (selectedItem != null ? "] Selected [" + selectedItem + "]" : "]");
+            }
+        }
+        public void Deactivate()
+        {
+            if (colView != null)
+            {
+                colView.Dispose();
+            }
+        }
+    }
+}
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Gallery.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Gallery.cs
new file mode 100644 (file)
index 0000000..4a08d75
--- /dev/null
@@ -0,0 +1,208 @@
+using System;
+using System.ComponentModel;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Binding;
+
+
+
+class Gallery : INotifyPropertyChanged
+{
+    string sourceDir = Tizen.NUI.Samples.CommonResource.GetDaliResourcePath()+"ItemViewDemo/gallery/gallery-medium-";
+    private int index;
+    private string name;
+    private bool selected;
+
+    public event PropertyChangedEventHandler PropertyChanged;
+
+    private void OnPropertyyChanged(string propertyName)
+    {
+
+        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+    }
+
+    public Gallery(int galleryIndex, string galleryName)
+    {
+        index = galleryIndex;
+        name = galleryName;
+    }
+
+    public string Name {
+        get
+        {
+            return name;
+        }
+        set
+        {
+            name = value;
+            OnPropertyyChanged("Name");
+            OnPropertyyChanged("ViewLabel");
+        }
+    }
+    public string ViewLabel
+    {
+        get
+        {
+            return "[" + index + "] : " + name;
+        }
+    }
+
+    public string ImageUrl
+    {
+        get
+        {
+            return sourceDir+(index%20)+".jpg";
+        }
+    }
+
+    public bool Selected {
+        get
+        {
+            return selected;
+        }
+        set
+        {
+            selected = value;
+            OnPropertyyChanged("Selected");
+        }
+    }
+}
+
+class Album : ObservableCollection<Gallery>
+{
+    private int index;
+    private string name;
+    private DateTime date;
+
+    public Album(int albumIndex, string albumName, DateTime albumDate)
+    {
+        index = albumIndex;
+        name = albumName;
+        date = albumDate;
+    }
+
+    public string Title
+    {
+        get
+        {
+            return "[" + index + "] " + name;
+        }
+    }
+
+    public string Date
+    {
+        get
+        {
+            return date.ToLongDateString();
+        }
+    }
+}
+
+class GalleryViewModel : ObservableCollection<Gallery>
+{
+    string[] namePool = {
+        "Cat",
+        "Boy",
+        "Arm muscle",
+        "Girl",
+        "House",
+        "Cafe",
+        "Statue",
+        "Sea",
+        "hosepipe",
+        "Police",
+        "Rainbow",
+        "Icicle",
+        "Tower with the Moon",
+        "Giraffe",
+        "Camel",
+        "Zebra",
+        "Red Light",
+        "Banana",
+        "Lion",
+        "Espresso",
+    };
+    public GalleryViewModel(int count)
+    {
+        CreateData(this, count);
+    }
+
+    public ObservableCollection<Gallery> CreateData(ObservableCollection<Gallery> result , int count)
+    {
+        for (int i = 0; i < count; i++)
+        {
+            result.Add(new Gallery(i, namePool[i%20]));
+        }
+        return result;
+    }
+}
+
+class AlbumViewModel : ObservableCollection<Album>
+{
+    string[] namePool = {
+        "Cat",
+        "Boy",
+        "Arm muscle",
+        "Girl",
+        "House",
+        "Cafe",
+        "Statue",
+        "Sea",
+        "hosepipe",
+        "Police",
+        "Rainbow",
+        "Icicle",
+        "Tower with the Moon",
+        "Giraffe",
+        "Camel",
+        "Zebra",
+        "Red Light",
+        "Banana",
+        "Lion",
+        "Espresso",
+    };
+
+    (string name, DateTime date)[] titlePool = {
+        ("House Move", new DateTime(2021, 2, 26)),
+        ("Covid 19", new DateTime(2020, 1, 20)),
+        ("Porto Trip", new DateTime(2019, 11, 23)),
+        ("Granada Trip", new DateTime(2019, 11, 20)),
+        ("Barcelona Trip", new DateTime(2019, 11, 17)),
+        ("Developer's Day", new DateTime(2019, 11, 16)),
+        ("Tokyo Trip", new DateTime(2019, 7, 5)),
+        ("Otaru Trip", new DateTime(2019, 3, 2)),
+        ("Sapporo Trip", new DateTime(2019, 2, 28)),
+        ("Hakodate Trip", new DateTime(2019, 2, 26)),
+        ("Friend's Wedding", new DateTime(2018, 11, 23)),
+        ("Grandpa Birthday", new DateTime(2018, 9, 14)),
+        ("Family Jeju Trip", new DateTime(2018, 7, 15)),
+        ("HongKong Trip", new DateTime(2018, 3, 30)),
+        ("Mom's Birthday", new DateTime(2017, 12, 21)),
+        ("Buy new Car", new DateTime(2017, 10, 18)),
+        ("Graduation", new DateTime(2017, 6, 30)),
+    };
+
+
+    public AlbumViewModel()
+    {
+        CreateData(this);
+    }
+
+    public ObservableCollection<Album> CreateData(ObservableCollection<Album> result)
+    {
+        for (int i = 0; i < titlePool.Length; i++)
+        {
+            (string name, DateTime date) = titlePool[i];
+            Album cur = new Album(i, name, date);
+            for (int j = 0; j < 20; j++)
+            {
+                cur.Add(new Gallery(j, namePool[j]));
+            }
+            result.Add(cur);
+        }
+        return result;
+    }
+
+}
\ No newline at end of file
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Group/CollectionViewGridGroupSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Group/CollectionViewGridGroupSample.cs
new file mode 100644 (file)
index 0000000..5aa0b9c
--- /dev/null
@@ -0,0 +1,128 @@
+using System;
+using System.ComponentModel;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Samples
+{
+    public class CollectionViewGridGroupSample : IExample
+    {
+        CollectionView colView;
+        int selectedCount;
+        ItemSelectionMode selMode;
+        ObservableCollection<Album> groupSource;
+
+        public void Activate()
+        {
+            Window window = NUIApplication.GetDefaultWindow();
+
+            groupSource = new AlbumViewModel();
+            selMode = ItemSelectionMode.MultipleSelections;
+            DefaultTitleItem myTitle = new DefaultTitleItem();
+            myTitle.Text = "Grid Sample Count["+ groupSource.Count+"] Selected["+selectedCount+"]";
+            //Set Width Specification as MatchParent to fit the Item width with parent View.
+            myTitle.WidthSpecification = LayoutParamPolicies.MatchParent;
+
+            colView = new CollectionView()
+            {
+                ItemsSource = groupSource,
+                ItemsLayouter = new GridLayouter(),
+                ItemTemplate = new DataTemplate(() =>
+                {
+                    DefaultGridItem item = new DefaultGridItem();
+                    item.WidthSpecification = 180;
+                    item.HeightSpecification = 240;
+                    //Decorate Label
+                    item.Caption.SetBinding(TextLabel.TextProperty, "ViewLabel");
+                    item.Caption.HorizontalAlignment = HorizontalAlignment.Center;
+                    //Decorate Image
+                    item.Image.SetBinding(ImageView.ResourceUrlProperty, "ImageUrl");
+                    item.Image.WidthSpecification = 170;
+                    item.Image.HeightSpecification = 170;
+                    //Decorate Badge checkbox.
+                    //[NOTE] This is sample of CheckBox usage in CollectionView.
+                    // Checkbox change their selection by IsSelectedProperty bindings with
+                    // SelectionChanged event with MulitpleSelections ItemSelectionMode of CollectionView.
+                    item.Badge = new CheckBox();
+                    //FIXME : SetBinding in RadioButton crashed as Sensitive Property is disposed.
+                    //item.Badge.SetBinding(CheckBox.IsSelectedProperty, "Selected");
+                    item.Badge.WidthSpecification = 30;
+                    item.Badge.HeightSpecification = 30;
+
+                    return item;
+                }),
+                GroupHeaderTemplate = new DataTemplate(() =>
+                {
+                    DefaultTitleItem group = new DefaultTitleItem();
+                    //Set Width Specification as MatchParent to fit the Item width with parent View.
+                    group.WidthSpecification = LayoutParamPolicies.MatchParent;
+
+                    group.Label.SetBinding(TextLabel.TextProperty, "Date");
+                    group.Label.HorizontalAlignment = HorizontalAlignment.Begin;
+
+                    return group;
+                }),
+                Header = myTitle,
+                IsGrouped = true,
+                ScrollingDirection = ScrollableBase.Direction.Vertical,
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                               SelectionMode = selMode
+            };
+            colView.SelectionChanged += SelectionEvt;
+
+            window.Add(colView);
+        }
+
+        public void SelectionEvt(object sender, SelectionChangedEventArgs ev)
+        {
+            List<object> oldSel = new List<object>(ev.PreviousSelection);
+            List<object> newSel = new List<object>(ev.CurrentSelection);
+
+            foreach (object item in oldSel)
+            {
+                if (item != null && item is Gallery)
+                {
+                    Gallery galItem = (Gallery)item;
+                    if (!(newSel.Contains(item)))
+                    {
+                        galItem.Selected = false;
+                        Tizen.Log.Debug("Unselected: {0}", galItem.ViewLabel);
+                        selectedCount--;
+                    }
+                }
+                else continue;
+            }
+            foreach (object item in newSel)
+            {
+                if (item != null && item is Gallery)
+                {
+                    Gallery galItem = (Gallery)item;
+                    if (!(oldSel.Contains(item)))
+                    {
+                        galItem.Selected = true;
+                        Tizen.Log.Debug("Selected: {0}", galItem.ViewLabel);
+                        selectedCount++;
+                    }
+                }
+                else continue;
+            }
+            if (colView.Header != null && colView.Header is DefaultTitleItem)
+            {
+                DefaultTitleItem title = (DefaultTitleItem)colView.Header;
+                title.Text = "Grid Sample Count["+ groupSource.Count + "] Selected["+selectedCount+"]";
+            }
+        }
+
+        public void Deactivate()
+        {
+            if (colView != null)
+            {
+                colView.Dispose();
+            }
+        }
+    }
+}
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Group/CollectionViewLinearGroupSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/CollectionViewDemo/Group/CollectionViewLinearGroupSample.cs
new file mode 100644 (file)
index 0000000..f8a759b
--- /dev/null
@@ -0,0 +1,131 @@
+using System;
+using System.ComponentModel;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Samples
+{
+    public class CollectionViewLinearGroupSample : IExample
+    {
+        CollectionView colView;
+        string selectedItem;
+        ItemSelectionMode selMode;
+        ObservableCollection<Album> groupSource;
+
+        public void Activate()
+        {
+            Window window = NUIApplication.GetDefaultWindow();
+
+            groupSource = new AlbumViewModel();
+            selMode = ItemSelectionMode.SingleSelection;
+            DefaultTitleItem myTitle = new DefaultTitleItem();
+            //To Bind the Count property changes, need to create custom property for count.
+            myTitle.Text = "Linear Sample Group["+ groupSource.Count+"]";
+            //Set Width Specification as MatchParent to fit the Item width with parent View.
+            myTitle.WidthSpecification = LayoutParamPolicies.MatchParent;
+
+            colView = new CollectionView()
+            {
+                ItemsSource = groupSource,
+                ItemsLayouter = new LinearLayouter(),
+                ItemTemplate = new DataTemplate(() =>
+                {
+                    var rand = new Random();
+                    RecyclerViewItem item = new RecyclerViewItem();
+                    item.WidthSpecification = LayoutParamPolicies.MatchParent;
+                    item.HeightSpecification = 100;
+                    item.BackgroundColor = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble(), 1);
+                    /*
+                    DefaultLinearItem item = new DefaultLinearItem();
+                    //Set Width Specification as MatchParent to fit the Item width with parent View.
+                    item.WidthSpecification = LayoutParamPolicies.MatchParent;
+                    //Decorate Label
+                    item.Label.SetBinding(TextLabel.TextProperty, "ViewLabel");
+                    item.Label.HorizontalAlignment = HorizontalAlignment.Begin;
+                    //Decorate Icon
+                    item.Icon.SetBinding(ImageView.ResourceUrlProperty, "ImageUrl");
+                    item.Icon.WidthSpecification = 80;
+                    item.Icon.HeightSpecification = 80;
+                    //Decorate Extra RadioButton.
+                    //[NOTE] This is sample of RadioButton usage in CollectionView.
+                    // RadioButton change their selection by IsSelectedProperty bindings with
+                    // SelectionChanged event with SingleSelection ItemSelectionMode of CollectionView.
+                    // be aware of there are no RadioButtonGroup. 
+                    item.Extra = new RadioButton();
+                    //FIXME : SetBinding in RadioButton crashed as Sensitive Property is disposed.
+                    //item.Extra.SetBinding(RadioButton.IsSelectedProperty, "Selected");
+                    item.Extra.WidthSpecification = 80;
+                    item.Extra.HeightSpecification = 80;
+                    */
+                    return item;
+                }),
+                GroupHeaderTemplate = new DataTemplate(() =>
+                {
+                    var rand = new Random();
+                    RecyclerViewItem item = new RecyclerViewItem();
+                    item.WidthSpecification = LayoutParamPolicies.MatchParent;
+                    item.HeightSpecification = 50;
+                    item.BackgroundColor = new Color(0, 0, 0, 1);
+                    /*
+                    DefaultTitleItem group = new DefaultTitleItem();
+                    //Set Width Specification as MatchParent to fit the Item width with parent View.
+                    group.WidthSpecification = LayoutParamPolicies.MatchParent;
+
+                    group.Label.SetBinding(TextLabel.TextProperty, "Date");
+                    group.Label.HorizontalAlignment = HorizontalAlignment.Begin;
+                    */
+                    return item;
+                }),
+                Header = myTitle,
+                IsGrouped = true,
+                ScrollingDirection = ScrollableBase.Direction.Vertical,
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                               SelectionMode = selMode
+            };
+            colView.SelectionChanged += SelectionEvt;
+
+            window.Add(colView);
+
+        }
+
+        public void SelectionEvt(object sender, SelectionChangedEventArgs ev)
+        {
+            //Tizen.Log.Debug("NUI", "LSH :: SelectionEvt called");
+
+            //SingleSelection Only have 1 or nil object in the list.
+            foreach (object item in ev.PreviousSelection)
+            {
+                if (item == null) break;
+                Gallery unselItem = (Gallery)item;
+
+                unselItem.Selected = false;
+                selectedItem = null;
+                //Tizen.Log.Debug("NUI", "LSH :: Unselected: {0}", unselItem.ViewLabel);
+            }
+            foreach (object item in ev.CurrentSelection)
+            {
+                if (item == null) break;
+                Gallery selItem = (Gallery)item;
+                selItem.Selected = true;
+                selectedItem = selItem.Name;
+                //Tizen.Log.Debug("NUI", "LSH :: Selected: {0}", selItem.ViewLabel);
+            }
+            if (colView.Header != null && colView.Header is DefaultTitleItem)
+            {
+                DefaultTitleItem title = (DefaultTitleItem)colView.Header;
+                title.Text = "Linear Sample Count[" + groupSource + (selectedItem != null ? "] Selected [" + selectedItem + "]" : "]");
+            }
+        }
+        public void Deactivate()
+        {
+            if (colView != null)
+            {
+                colView.Dispose();
+            }
+        }
+    }
+}
index 8bf5b0e..39a4478 100755 (executable)
@@ -24,6 +24,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.System.Information",
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\..\src\Tizen\Tizen.csproj", "{2CF2BA0A-198E-4B8F-B5C4-2645AFBA85FA}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.System.Feedback", "..\..\src\Tizen.System.Feedback\Tizen.System.Feedback.csproj", "{999E72B5-7822-4187-973A-08800270716A}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
@@ -97,6 +99,12 @@ Global
                {2CF2BA0A-198E-4B8F-B5C4-2645AFBA85FA}.NUI|Any CPU.Build.0 = Debug|Any CPU
                {2CF2BA0A-198E-4B8F-B5C4-2645AFBA85FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
                {2CF2BA0A-198E-4B8F-B5C4-2645AFBA85FA}.Release|Any CPU.Build.0 = Release|Any CPU
+               {999E72B5-7822-4187-973A-08800270716A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {999E72B5-7822-4187-973A-08800270716A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {999E72B5-7822-4187-973A-08800270716A}.NUI|Any CPU.ActiveCfg = Release|Any CPU
+               {999E72B5-7822-4187-973A-08800270716A}.NUI|Any CPU.Build.0 = Release|Any CPU
+               {999E72B5-7822-4187-973A-08800270716A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {999E72B5-7822-4187-973A-08800270716A}.Release|Any CPU.Build.0 = Release|Any CPU
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
diff --git a/test/Tizen.NUI.Tests/Tizen.NUI.TCT/NuiSample.snk b/test/Tizen.NUI.Tests/Tizen.NUI.TCT/NuiSample.snk
new file mode 100755 (executable)
index 0000000..d21014f
Binary files /dev/null and b/test/Tizen.NUI.Tests/Tizen.NUI.TCT/NuiSample.snk differ
index f98e2e1..f982259 100755 (executable)
@@ -40,12 +40,18 @@ namespace Tizen.NUI.Devel.Tests
         float textSize = 30.0f;
         Window window;
         Layer layer;
+        public static int mainPid;
+        public static int mainTid;
+
         protected override void OnCreate()
         {
             base.OnCreate();
 
             tlog.Debug(tag, "OnCreate() START!");
 
+            mainPid = Process.GetCurrentProcess().Id;
+            mainTid = Thread.CurrentThread.ManagedThreadId;
+
             window = NUIApplication.GetDefaultWindow();
             window.BackgroundColor = Color.Green;
 
diff --git a/test/Tizen.NUI.Tests/Tizen.NUI.TCT/Properties/Resources.Designer.cs b/test/Tizen.NUI.Tests/Tizen.NUI.TCT/Properties/Resources.Designer.cs
deleted file mode 100755 (executable)
index 1851441..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.42000
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Tizen.NUI.Devel.Tests.Properties {
-    using System;
-
-
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-
-        private static global::System.Resources.ResourceManager resourceMan;
-
-        private static global::System.Globalization.CultureInfo resourceCulture;
-
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tizen.NUI.Devel.Tests.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-    }
-}
diff --git a/test/Tizen.NUI.Tests/Tizen.NUI.TCT/Properties/Resources.resx b/test/Tizen.NUI.Tests/Tizen.NUI.TCT/Properties/Resources.resx
deleted file mode 100755 (executable)
index 16d0353..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!--
-    Microsoft ResX Schema
-
-    Version 2.0
-
-    The primary goals of this format is to allow a simple XML format
-    that is mostly human readable. The generation and parsing of the
-    various data types are done through the TypeConverter classes
-    associated with the data types.
-
-    Example:
-
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-
-    There are any number of "resheader" rows that contain simple
-    name/value pairs.
-
-    Each data row contains a name, and value. The row also contains a
-    type or mimetype. Type corresponds to a .NET class that support
-    text/value conversion through the TypeConverter architecture.
-    Classes that don't support this are serialized and stored with the
-    mimetype set.
-
-    The mimetype is used for serialized objects, and tells the
-    ResXResourceReader how to depersist the object. This is currently not
-    extensible. For a given mimetype the value must be set accordingly:
-
-    Note - application/x-microsoft.net.object.binary.base64 is the format
-    that the ResXResourceWriter will generate, however the reader can
-    read any of the formats listed below.
-
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <data name="String1" xml:space="preserve">
-    <value />
-    <comment>test</comment>
-  </data>
-</root>
\ No newline at end of file
index 5022260..f1c2a5c 100755 (executable)
@@ -9,10 +9,14 @@
   <!-- Property Group for Tizen Project -->
   <PropertyGroup>
     <TizenCreateTpkOnBuild>true</TizenCreateTpkOnBuild>
+    <AssemblyName>Tizen.NUI.Devel.Tests</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>NuiSample.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
 
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugType>portable</DebugType>
+    <DefineConstants>TRACE;DEBUG;EXAMPLE_OFF</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>None</DebugType>
@@ -35,8 +39,5 @@
     <ProjectReference Include="..\nunit.framework\nunit.framework.csproj" />
     <ProjectReference Include="..\nunitlite\nunitlite.csproj" />
   </ItemGroup>
-  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
-    <Exec Command="sdb root on&#xD;&#xA;sdb shell &quot;mount -o remount,rw /&quot;&#xD;&#xA;sdb shell &quot;rm /usr/share/dotnet.tizen/framework/*.ni.dll&quot;&#xD;&#xA;sdb push $(TargetDir)Tizen.NUI.dll $(TargetDir)Tizen.NUI.pdb /usr/share/dotnet.tizen/framework/&#xD;&#xA;sdb shell &quot;chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.dll&quot;&#xD;&#xA;sdb shell &quot;chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.pdb&quot;&#xD;&#xA;sdb push $(TargetDir)Tizen.NUI.Components.dll $(TargetDir)Tizen.NUI.Components.pdb /usr/share/dotnet.tizen/framework/&#xD;&#xA;sdb shell &quot;chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.Components.dll&quot;&#xD;&#xA;sdb shell &quot;chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.Components.pdb&quot;&#xD;&#xA;sdb shell sync&#xD;&#xA;" />
-  </Target>
 
 </Project>
@@ -1,6 +1,3 @@
-#define EXAMPLE
-#undef EXAMPLE
-
 using NUnit.Framework;
 using NUnit.Framework.TUnit;
 using System;
@@ -29,7 +26,9 @@ namespace Tizen.NUI.Devel.Tests
             Tizen.Log.Info(TAG, "Destroy() is called!");
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("Test Button empty constructor. Check it has been triggered")]
         [Property("SPEC", "Tizen.NUI.Components.Button.Button C")]
@@ -45,7 +44,9 @@ namespace Tizen.NUI.Devel.Tests
             Assert.IsInstanceOf<Components.Button>(button, "Should be an instance of Button!");
         }
 
-        //[Test]
+#if (EXAMPLE)
+        [Test]
+#endif
         [Category("P2")]
         [Description("Check exception when constructing a Button with nonexistent style.")]
         [Property("SPEC", "Tizen.NUI.Components.Button.Button C")]
@@ -67,7 +68,9 @@ namespace Tizen.NUI.Devel.Tests
             }
         }
 
-        //[Test]
+#if (EXAMPLE)
+        [Test]
+#endif
         [Category("P1")]
         [Description("Test Button constructor using style. Check it has been triggered")]
         [Property("SPEC", "Tizen.NUI.Components.Button.Button C")]
@@ -24,7 +24,9 @@ namespace Tizen.NUI.Devel.Tests
         {
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("LottieAnimationView constructor test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.LottieAnimationView C")]
@@ -52,7 +54,9 @@ namespace Tizen.NUI.Devel.Tests
             lottie3.Dispose();
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("URL test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.URL A")]
@@ -75,7 +79,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("PlayState test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.PlayState A")]
@@ -121,7 +127,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("TotalFrame test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.TotalFrame A")]
@@ -154,7 +162,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("CurrentFrame test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.CurrentFrame A")]
@@ -183,7 +193,9 @@ namespace Tizen.NUI.Devel.Tests
 
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("LoopingMode test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.LoopingMode A")]
@@ -219,7 +231,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("LoopCount test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.LoopCount A")]
@@ -253,7 +267,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("StopBehavior test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.StopBehavior A")]
@@ -294,7 +310,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("RedrawInScalingDown test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.RedrawInScalingDown A")]
@@ -331,7 +349,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("SetMinMaxFrame test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.SetMinMaxFrame M")]
@@ -385,7 +405,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("Play test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Play M")]
@@ -418,7 +440,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("Pause test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Pause M")]
@@ -454,7 +478,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("Stop test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Stop M")]
@@ -488,7 +514,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("GetContentInfo test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.GetContentInfo M")]
@@ -526,7 +554,9 @@ namespace Tizen.NUI.Devel.Tests
             await Task.Delay(500);
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("Finished test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Finished E")]
@@ -582,7 +612,9 @@ namespace Tizen.NUI.Devel.Tests
             finishedCheck = true;
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("RedrawInScalingDown animation test")]
         [Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.RedrawInScalingDown A")]
@@ -24,7 +24,9 @@ namespace Tizen.NUI.Devel.Tests
         {
         }
 
+#if (EXAMPLE)
         [Test]
+#endif
         [Category("P1")]
         [Description("view memory leak test")]
         [Property("SPEC", "local test")]
diff --git a/test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/internal/Accessibility/TSAccessibilityActionSignal.cs b/test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/internal/Accessibility/TSAccessibilityActionSignal.cs
new file mode 100755 (executable)
index 0000000..53e7845
--- /dev/null
@@ -0,0 +1,147 @@
+
+using global::System;
+using NUnit.Framework;
+using NUnit.Framework.TUnit;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+
+namespace Tizen.NUI.Devel.Tests
+{
+    using tlog = Tizen.Log;
+
+    [TestFixture]
+    [Description("internal/Accessibility/AccessibilityActionSignal")]
+    public class InternalAccessibilityActionSignalTest
+    {
+        private const string tag = "NUITEST";
+        private delegate bool dummyCallback(IntPtr accessibilityManager);
+        private bool OnDummyCallback(IntPtr data)
+        {
+            return false;
+        }
+
+        [SetUp]
+        public void Init()
+        {
+            tlog.Info(tag, "Init() is called!");
+        }
+
+        [TearDown]
+        public void Destroy()
+        {
+            tlog.Info(tag, "Destroy() is called!");
+        }
+
+        [Test]
+        [Description("AccessibilityActionSignal constructor")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityActionSignalConstructor()
+        {
+            tlog.Debug(tag, $"AccessibilityActionSignalConstructor START");
+
+            var testingTarget = new AccessibilityActionSignal();
+
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityActionSignal>(testingTarget, "should be an instance of testing target class!");
+
+            testingTarget.Dispose();
+            tlog.Debug(tag, $"AccessibilityActionSignalConstructor END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityActionSignal Empty")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityActionSignalEmpty()
+        {
+            tlog.Debug(tag, $"AccessibilityActionSignalEmpty START");
+
+            var testingTarget = new AccessibilityActionSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityActionSignal>(testingTarget, "should be an instance of testing target class!");
+
+            var result = testingTarget.Empty();
+            Assert.IsTrue(result);
+
+            testingTarget.Dispose();
+            tlog.Debug(tag, $"AccessibilityActionSignalEmpty END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityActionSignal GetConnectionCount")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityActionSignalGetConnectionCount()
+        {
+            tlog.Debug(tag, $"AccessibilityActionSignal_GetConnectionCount START");
+
+            var testingTarget = new AccessibilityActionSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityActionSignal>(testingTarget, "should be an instance of testing target class!");
+
+            var result = testingTarget.GetConnectionCount();
+            Assert.IsTrue(result == 0, "result should be 0");
+
+            testingTarget.Dispose();
+            tlog.Debug(tag, $"AccessibilityActionSignalGetConnectionCount END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityActionSignal Connection")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityActionSignalConnection()
+        {
+            tlog.Debug(tag, $"AccessibilityActionSignalConnection START");
+
+            var testingTarget = new AccessibilityActionSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityActionSignal>(testingTarget, "should be an instance of testing target class!");
+
+            dummyCallback callback = OnDummyCallback;
+            testingTarget.Connect(callback);
+            testingTarget.Disconnect(callback);
+            testingTarget.Dispose();
+
+            tlog.Debug(tag, $"AccessibilityActionSignalConnection END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityActionSignal Disconnection")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityActionSignalDisconnection()
+        {
+            tlog.Debug(tag, $"AccessibilityActionSignalDisconnection START");
+
+            var testingTarget = new AccessibilityActionSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityActionSignal>(testingTarget, "should be an instance of testing target class!");
+
+            dummyCallback callback = OnDummyCallback;
+            testingTarget.Connect(callback);
+            testingTarget.Disconnect(callback);
+            testingTarget.Dispose();
+
+            tlog.Debug(tag, $"AccessibilityActionSignalDisconnection END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityActionSignal Emit")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityActionSignalEmit()
+        {
+            tlog.Debug(tag, $"AccessibilityActionSignalEmit START");
+            var currentPid = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+            var currentTid = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+
+            tlog.Debug(tag, $"thread check! main pid={App.mainPid}, current pid={currentPid}, main tid={App.mainTid}, current tid={currentTid}");
+
+            var testingTarget = new AccessibilityActionSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityActionSignal>(testingTarget, "should be an instance of testing target class!");
+
+            testingTarget.Emit(Tizen.NUI.Accessibility.AccessibilityManager.Instance);
+            testingTarget.Dispose();
+
+            tlog.Debug(tag, $"AccessibilityActionSignalEmit END (OK)");
+        }
+
+    }
+}
diff --git a/test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/internal/Accessibility/TSAccessibilityFocusOvershotSignal.cs b/test/Tizen.NUI.Tests/Tizen.NUI.TCT/testcase/internal/Accessibility/TSAccessibilityFocusOvershotSignal.cs
new file mode 100755 (executable)
index 0000000..98afa2b
--- /dev/null
@@ -0,0 +1,150 @@
+
+using global::System;
+using NUnit.Framework;
+using NUnit.Framework.TUnit;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+
+namespace Tizen.NUI.Devel.Tests
+{
+    using tlog = Tizen.Log;
+
+    [TestFixture]
+    [Description("internal/Accessibility/AccessibilityFocusOvershotSignal")]
+    public class InternalAccessibilityFocusOvershotSignalTests
+    {
+        private const string tag = "NUITEST";
+        private delegate bool dummyCallback(IntPtr accessibilityManager);
+        private bool OnDummyCallback(IntPtr data)
+        {
+            return false;
+        }
+
+        [SetUp]
+        public void Init()
+        {
+            tlog.Info(tag, "Init() is called!");
+        }
+
+        [TearDown]
+        public void Destroy()
+        {
+            tlog.Info(tag, "Destroy() is called!");
+        }
+
+        [Test]
+        [Description("AccessibilityFocusOvershotSignal constructor")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityFocusOvershotSignalConstructor()
+        {
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalConstructor START");
+
+            var testingTarget = new AccessibilityFocusOvershotSignal();
+
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityFocusOvershotSignal>(testingTarget, "should be an instance of testing target class!");
+
+            testingTarget.Dispose();
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalConstructor END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityFocusOvershotSignal Empty")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityFocusOvershotSignalEmpty()
+        {
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalEmpty START");
+
+            var testingTarget = new AccessibilityFocusOvershotSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityFocusOvershotSignal>(testingTarget, "should be an instance of testing target class!");
+
+            var result = testingTarget.Empty();
+            Assert.IsTrue(result);
+
+            testingTarget.Dispose();
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalEmpty END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityFocusOvershotSignal GetConnectionCount")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityFocusOvershotSignalGetConnectionCount()
+        {
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalGetConnectionCount START");
+
+            var testingTarget = new AccessibilityFocusOvershotSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityFocusOvershotSignal>(testingTarget, "should be an instance of testing target class!");
+
+            var result = testingTarget.GetConnectionCount();
+            Assert.IsTrue(result == 0, "result should be 0");
+
+            testingTarget.Dispose();
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalGetConnectionCount END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityFocusOvershotSignal Connection")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityFocusOvershotSignalConnection()
+        {
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalConnection START");
+
+            var testingTarget = new AccessibilityFocusOvershotSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityFocusOvershotSignal>(testingTarget, "should be an instance of testing target class!");
+
+            dummyCallback callback = OnDummyCallback;
+            testingTarget.Connect(callback);
+            testingTarget.Disconnect(callback);
+            testingTarget.Dispose();
+
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalConnection END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityFocusOvershotSignal Disconnection")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityFocusOvershotSignalDisconnection()
+        {
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalDisconnection START");
+
+            var testingTarget = new AccessibilityFocusOvershotSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityFocusOvershotSignal>(testingTarget, "should be an instance of testing target class!");
+
+            dummyCallback callback = OnDummyCallback;
+            testingTarget.Connect(callback);
+            testingTarget.Disconnect(callback);
+            testingTarget.Dispose();
+
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalDisconnection END (OK)");
+        }
+
+        [Test]
+        [Description("AccessibilityFocusOvershotSignal Emit")]
+        [Property("AUTHOR", "dongsug.song@samsung.com")]
+        public void AccessibilityFocusOvershotSignalEmit()
+        {
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalEmit START");
+            var currentPid = global::System.Diagnostics.Process.GetCurrentProcess().Id;
+            var currentTid = global::System.Threading.Thread.CurrentThread.ManagedThreadId;
+
+            tlog.Debug(tag, $"thread check! main pid={App.mainPid}, current pid={currentPid}, main tid={App.mainTid}, current tid={currentTid}");
+
+            var testingTarget = new AccessibilityFocusOvershotSignal();
+            Assert.IsNotNull(testingTarget, "should be not null");
+            Assert.IsInstanceOf<AccessibilityFocusOvershotSignal>(testingTarget, "should be an instance of testing target class!");
+
+            View dummy = new View();
+            testingTarget.Emit(dummy, Accessibility.AccessibilityManager.FocusOvershotDirection.Previous);
+            
+            testingTarget.Dispose();
+            dummy.Dispose();
+
+            tlog.Debug(tag, $"AccessibilityFocusOvershotSignalEmit END (OK)");
+        }
+
+    }
+}
index 086f74e..8d32572 100755 (executable)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest package="Tizen.NUI.Devel.Tests" version="1.0.0" api-version="8" xmlns="http://tizen.org/ns/packages">
+<manifest package="Tizen.NUI.Devel.Tests" version="1.0.0" api-version="9" xmlns="http://tizen.org/ns/packages">
     <profile name="common" />
     <ui-application appid="Tizen.NUI.Devel.Tests" exec="Tizen.NUI.Devel.Tests.dll" multiple="false" taskmanage="true" splash-screen-display="true" type="dotnet" launch_mode="single">
         <icon>nui-csharp.png</icon>