# 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
NUGET_VERSION=9.0.0.99999
# RPM Version Suffix
-RPM_VERSION_SUFFIX=nui22011
+RPM_VERSION_SUFFIX=nui22012
static Control()
{
- ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+ ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
}
/// <summary>
--- /dev/null
+/* 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;
+ }
+
+ }
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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();
+ }
+ }
+}
--- /dev/null
+/* 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();
+ }
+ }
+}
--- /dev/null
+/* 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();
+ }
+ }
+}
--- /dev/null
+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);
+ }
+ }
+}
--- /dev/null
+/* 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;
+ }
+ }
+}
--- /dev/null
+/* 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
+ }
+}
--- /dev/null
+/* 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,
+ }
+}
--- /dev/null
+/* 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");
+ }
+ }
+}
--- /dev/null
+/* 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);
+
+ }
+}
--- /dev/null
+/* 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));
+ }
+ }
+}
--- /dev/null
+/* 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();
+ }
+ }
+}
--- /dev/null
+/* 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);
+ }
+ }
+}
--- /dev/null
+/* 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;
+ }
+ }
+}
--- /dev/null
+/* 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;
+ }
+ }
+}
--- /dev/null
+/* 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;
+ }
+ }
+}
--- /dev/null
+/* 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
+ }
+ }
+}
--- /dev/null
+/* 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();
+ }
+ }
+}
--- /dev/null
+/* 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>();
+ }
+ }
+}
-/* 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);
}
}
/// 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;
}
}
}
--- /dev/null
+/* 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)));
+ }
+ }
+}
--- /dev/null
+/* 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();
+ }
+ }
+}
{
if (scrollBar)
{
- scrollBar.Unparent();
+ base.Remove(scrollBar);
}
scrollBar = value;
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>
/// <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
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/>
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)
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)
{
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);
[EditorBrowsable(EditorBrowsableState.Never)]
public override void ApplyStyle(ViewStyle viewStyle)
{
- base.ApplyStyle(viewStyle);
-
if (viewStyle is ScrollbarStyle scrollbarStyle)
{
// Apply essential look.
if (scrollbarStyle.WidthResizePolicy == null) scrollbarStyle.WidthResizePolicy = ResizePolicyType.FillToParent;
if (scrollbarStyle.HeightResizePolicy == null) scrollbarStyle.HeightResizePolicy = ResizePolicyType.FillToParent;
}
+
+ base.ApplyStyle(viewStyle);
}
/// <inheritdoc/>
return;
}
- trackVisual.Size = calculator.CalculateTrackSize(thickness, containerSize, TrackPadding);
+ trackVisual.Size = calculator.CalculateTrackSize(thickness, containerSize, EnsurePadding(TrackPadding));
trackVisual.UpdateVisual(true);
}
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);
}
}
+ 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
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
public override Visual.AlignType CalculatorTrackAlign()
{
- return Visual.AlignType.BottomCenter;
+ return Visual.AlignType.BottomBegin;
}
public override Visual.AlignType CalculatorThumbAlign()
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)
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);
}
}
public override Visual.AlignType CalculatorTrackAlign()
{
- return Visual.AlignType.CenterEnd;
+ return Visual.AlignType.TopEnd;
}
public override Visual.AlignType CalculatorThumbAlign()
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)
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);
}
}
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
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
// 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;
{
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()
{
bgTrackImage.Add(slidedTrackImage);
}
+ if (null != warningTrackImage)
+ {
+ bgTrackImage.Add(warningTrackImage);
+ }
+ if (null != thumbImage)
+ {
+ bgTrackImage.Add(thumbImage);
+ thumbImage.RaiseToTop();
+ }
bgTrackImage.TouchEvent += OnTouchEventForBgTrack;
}
PivotPoint = NUI.PivotPoint.Center,
PositionUsesPivotPoint = true
};
- if (slidedTrackImage != null)
+ if (bgTrackImage != null)
{
- slidedTrackImage.Add(thumbImage);
+ bgTrackImage.Add(thumbImage);
}
+ thumbImage.RaiseToTop();
thumbImage.TouchEvent += OnTouchEventForThumb;
}
private ImageView CreateValueIndicator()
{
- if (null == valueIndicatorImage)
+ if (valueIndicatorImage == null)
{
valueIndicatorImage = new ImageView()
{
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;
}
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;
}
}
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)
{
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()
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;
/// <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) =>
{
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) =>
{
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) =>
{
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) =>
{
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) =>
{
RelayoutBaseComponent(false);
UpdateBgTrackSize();
UpdateBgTrackPosition();
+ UpdateWarningTrackSize();
UpdateValue();
}
}
if (null != thumbImage)
{
thumbImage.Size = value;
+ thumbSize = value;
sliderStyle.Thumb.Size = value;
}
}
/// <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
if (null != thumbImage)
{
thumbImage.ResourceUrl = value;
+ thumbImageUrl = value;
sliderStyle.Thumb.ResourceUrl = value;
}
}
/// <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>
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;
}
}
}
if (null != thumbImage)
{
thumbImage.Color = value;
+ thumbColor = value;
sliderStyle.Thumb.Color = value;
}
}
}
/// <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>
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;
+ }
+ }
}
}
CreateValueIndicator().ApplyStyle(sliderStyle.ValueIndicatorImage);
}
+ if (null != sliderStyle?.WarningTrack)
+ {
+ CreateWarningTrack().ApplyStyle(sliderStyle.WarningTrack);
+ }
+
+ if (null != sliderStyle?.WarningProgress)
+ {
+ CreateWarningSlidedTrack().ApplyStyle(sliderStyle.WarningProgress);
+ }
+
EnableControlStatePropagation = true;
}
thumbImage.TouchEvent -= OnTouchEventForThumb;
Utility.Dispose(thumbImage);
}
+ Utility.Dispose(warningSlidedTrackImage);
+ Utility.Dispose(warningTrackImage);
Utility.Dispose(slidedTrackImage);
if (null != bgTrackImage)
{
UpdateComponentByIndicatorTypeChanged();
UpdateBgTrackSize();
UpdateBgTrackPosition();
+ UpdateWarningTrackSize();
UpdateLowIndicatorSize();
UpdateValue();
}
if (!isFocused && !isPressed)
{
ControlState = ControlState.Normal;
+ thumbImage.ResourceUrl = thumbImageUrlSelector?.Normal;
+
if (stateChangedHandler != null)
{
StateChangedArgs args = new StateChangedArgs();
else if (isPressed)
{
ControlState = ControlState.Pressed;
+ thumbImage.ResourceUrl = thumbImageUrlSelector?.Pressed;
if (stateChangedHandler != null)
{
else if (!isPressed && isFocused)
{
ControlState = ControlState.Focused;
+ thumbImage.ResourceUrl = thumbImageUrlSelector?.Focused;
if (stateChangedHandler != null)
{
{
static ControlStyle()
{
- ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+ ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
}
/// <summary>
--- /dev/null
+/*
+ * 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);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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)
+ {
+ //
+ }
+ */
+ }
+ }
+}
/// <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) =>
{
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) =>
{
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) =>
{
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) =>
{
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>
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);
// 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),
["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);
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;
}
}
["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);
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;
}
}
</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
{
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)
static CircularPagination()
{
- ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+ ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
}
/// <summary>
static CircularProgress()
{
- ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+ ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
}
/// <summary>
/// </summary>
static CircularScrollbar()
{
- ThemeManager.AddPackageTheme(new DefaultThemeCreator());
+ ThemeManager.AddPackageTheme(DefaultThemeCreator.Instance);
}
#endregion Constructors
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.
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.
*
*/
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.
--- /dev/null
+/* 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;
+ }
+ }
+}
</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" />
}
- 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);
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
* limitations under the License.
*
*/
+using System;
using System.ComponentModel;
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;
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)
{
}
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)
{
}
[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
{
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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);
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)
{
}
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)
{
}
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)
{
}
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)
{
}
[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);
[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);
[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);
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)
{
}
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)
{
}
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);
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);
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);
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);
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)
{
}
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)
{
}
});
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);
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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));
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) =>
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;
});
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;
});
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)
}
/// <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)
}
/// <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>
}
/// <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>
}
/// <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>
}
/// <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)]
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)
{
}
+++ /dev/null
-using System;
-using System.ComponentModel;
-
-namespace Tizen.NUI.Binding.Internals
-{
- internal interface IDataTemplate
- {
- Func<object> LoadTemplate { get; set; }
- }
-}
{
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)
{
}
}
- 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)
{
}
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;
}
- 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)
{
}
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)
{
}
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)
{
}
using Tizen.Applications.CoreBackend;
using Tizen.NUI.Binding;
using Tizen.NUI.Xaml;
+using Tizen.Applications.ThemeManager;
+using System.Collections.Generic;
namespace Tizen.NUI
{
internal static NUIApplication me;
private static bool isPreLoad = false;
+ private readonly ThemeLoader themeLoader = new ThemeLoader();
/// <summary>
/// The default constructor.
{
Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
me = this;
+ themeLoader.ThemeChanged += TizenThemeChanged;
}
/// <summary>
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;
{
Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
me = this;
+ themeLoader.ThemeChanged += TizenThemeChanged;
}
/// <summary>
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;
{
Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
me = this;
+ themeLoader.ThemeChanged += TizenThemeChanged;
}
/// <summary>
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;
if (windowPosition != null) { _windowPosition2D = windowPosition; }
Registry.Instance.SavedApplicationThread = Thread.CurrentThread;
me = this;
+ themeLoader.ThemeChanged += TizenThemeChanged;
}
/// <summary>
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.
/*
- * 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.
[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>
[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>
{
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.
base.Dispose(type);
- tlog.Fatal(tag, $"]VAV END]");
+ tlog.Fatal(tag, $"]AnimatedVectorImageView END]");
}
#endregion Constructor, Distructor, Dispose
/// <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;
}
}
{
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>
{
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");
}
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>
{
set
{
- tlog.Fatal(tag, $"[VAV START[ [{GetId()}] RepeatMode SET");
+ tlog.Fatal(tag, $"[AnimatedVectorImageView START[ [{GetId()}] RepeatMode SET");
repeatMode = value;
switch (repeatMode)
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)]
[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>
{
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>
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);
}
[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);
break;
case minMaxSetTypes.SetByMinAndMaxFrameMethod:
- base.SetMinMaxFrame(minFrame, mMaxFrame);
- base.CurrentFrame = minFrame;
+ base.SetMinMaxFrame(minimumFrame, maximumFrame);
+ base.CurrentFrame = minimumFrame;
break;
case minMaxSetTypes.SetByMarker:
base.Play();
AnimationState = AnimationStates.Playing;
- tlog.Fatal(tag, $" [{GetId()}] isMinMaxSet={isMinMaxSet}) ]VAV END]");
+ tlog.Fatal(tag, $" [{GetId()}] isMinMaxFrameSet={isMinMaxFrameSet}) ]AnimatedVectorImageView END]");
}
/// <summary>
[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");
}
base.Pause();
AnimationState = AnimationStates.Paused;
- tlog.Fatal(tag, $" [{GetId()}] ]VAV END]");
+ tlog.Fatal(tag, $" [{GetId()}] ]AnimatedVectorImageView END]");
}
/// <summary>
[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");
}
return;
}
- if (internalEndAction != endAction)
+ if (innerEndAction != endAction)
{
- internalEndAction = endAction;
+ innerEndAction = endAction;
switch (endAction)
{
case EndActions.Cancel:
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:
break;
}
}
- tlog.Fatal(tag, $" [{GetId()}] ]VAV END]");
+ tlog.Fatal(tag, $" [{GetId()}] ]AnimatedVectorImageView END]");
}
#endregion Method
/// <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
/// <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)]
}
/// <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)]
}
#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,
/// <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);
/// <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);
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)
{
}
}
}
- 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)
{
}
}
- 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)
{
{
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;
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)
{
}
/*
- * 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.
/// <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"/>.
}
/// <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>
/// <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));
}
}
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)
{
}
/// </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));
/// </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);
}
}
- 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)
{
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)
{
}
}
- 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)
{
}
}
- 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)
{
}
}
- 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)
{
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)
{
}
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())
{
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.");
}
/// </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);
/// </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);
/// </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);
/// <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);
/// <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);
/// </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));
/// 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;
/// <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);
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)
{
}
/// </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);
}
- 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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
{
/// <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>
{
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)
{
}
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();
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
}
- 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)
{
}
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)
{
}
}
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;
}
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)
{
}
}
- 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)
{
}
}
- 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)
{
}
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)
{
}
}
- internal InputMethodContext(IntPtr cPtr, bool cMemoryOwn) : base(Interop.InputMethodContext.Upcast(cPtr), cMemoryOwn)
+ internal InputMethodContext(IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
{
}
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)
{
}
}
- 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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
Bindings[property] = binding;
}
+ [EditorBrowsable(EditorBrowsableState.Never)]
public void SetValue(BindableProperty property, object value)
{
if (property == null)
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;
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();
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;
return dataTemplate;
}
+ [EditorBrowsable(EditorBrowsableState.Never)]
protected abstract DataTemplate OnSelectTemplate(object item, BindableObject container);
}
}
/// 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;
/// 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)
--- /dev/null
+using System;
+using System.ComponentModel;
+
+namespace Tizen.NUI.Binding
+{
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public interface IDataTemplate
+ {
+ Func<object> LoadTemplate { get; set; }
+ }
+}
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)
{
}
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)
{
}
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)
{
}
}
- 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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
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)
{
}
}
- 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)
{
}
}
- 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)
{
}
}
- 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)
{
}
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)
{
}
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;
{
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)
{
}
/// </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)
{
}
/// 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;
/// 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>
/// 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;
(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)
{
}
}
- 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)
{
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)
{
}
[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)
{
}
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())
{
/// 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; }
/// <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; }
--- /dev/null
+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();
+ }
+ }
+ }
+}
--- /dev/null
+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();
+ }
+ }
+ }
+}
--- /dev/null
+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
--- /dev/null
+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();
+ }
+ }
+ }
+}
--- /dev/null
+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();
+ }
+ }
+ }
+}
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
{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
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;
+++ /dev/null
-//------------------------------------------------------------------------------
-// <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;
- }
- }
- }
-}
+++ /dev/null
-<?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
<!-- 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>
<ProjectReference Include="..\nunit.framework\nunit.framework.csproj" />
<ProjectReference Include="..\nunitlite\nunitlite.csproj" />
</ItemGroup>
- <Target Name="PostBuild" AfterTargets="PostBuildEvent">
- <Exec Command="sdb root on
sdb shell "mount -o remount,rw /"
sdb shell "rm /usr/share/dotnet.tizen/framework/*.ni.dll"
sdb push $(TargetDir)Tizen.NUI.dll $(TargetDir)Tizen.NUI.pdb /usr/share/dotnet.tizen/framework/
sdb shell "chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.dll"
sdb shell "chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.pdb"
sdb push $(TargetDir)Tizen.NUI.Components.dll $(TargetDir)Tizen.NUI.Components.pdb /usr/share/dotnet.tizen/framework/
sdb shell "chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.Components.dll"
sdb shell "chsmack -a '_' /usr/share/dotnet.tizen/framework/Tizen.NUI.Components.pdb"
sdb shell sync
" />
- </Target>
</Project>
-#define EXAMPLE
-#undef EXAMPLE
-
using NUnit.Framework;
using NUnit.Framework.TUnit;
using System;
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")]
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")]
}
}
- //[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")]
{
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("LottieAnimationView constructor test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.LottieAnimationView C")]
lottie3.Dispose();
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("URL test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.URL A")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("PlayState test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.PlayState A")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("TotalFrame test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.TotalFrame A")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("CurrentFrame test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.CurrentFrame A")]
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("LoopingMode test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.LoopingMode A")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("LoopCount test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.LoopCount A")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("StopBehavior test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.StopBehavior A")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("RedrawInScalingDown test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.RedrawInScalingDown A")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("SetMinMaxFrame test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.SetMinMaxFrame M")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("Play test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Play M")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("Pause test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Pause M")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("Stop test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Stop M")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("GetContentInfo test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.GetContentInfo M")]
await Task.Delay(500);
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("Finished test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.Finished E")]
finishedCheck = true;
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("RedrawInScalingDown animation test")]
[Property("SPEC", "Tizen.NUI.BaseComponents.LottieAnimationView.RedrawInScalingDown A")]
{
}
+#if (EXAMPLE)
[Test]
+#endif
[Category("P1")]
[Description("view memory leak test")]
[Property("SPEC", "local test")]
--- /dev/null
+
+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)");
+ }
+
+ }
+}
--- /dev/null
+
+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)");
+ }
+
+ }
+}
<?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>