--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp.Wearable;
+using System;
+using Tizen.Wearable.CircularUI.Forms;
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Tizen;
+using ERotaryEventManager = ElmSharp.Wearable.RotaryEventManager;
+using AppSpecific = Xamarin.Forms.PlatformConfiguration.TizenSpecific.Application;
+
+[assembly: ExportRenderer(typeof(BezelInteractionPage), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.BezelInteractionPageRenderer))]
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class BezelInteractionPageRenderer : PageRenderer, IBezelInteractionController
+ {
+ IRotaryFocusable _currentRotaryFocusObject;
+
+ new IBezelInteractionRouter Element => base.Element as IBezelInteractionRouter;
+
+ public BezelInteractionPageRenderer()
+ {
+ RegisterPropertyHandler(BezelInteractionPage.RotaryFocusObjectProperty, UpdateRotaryFocusObject);
+ }
+
+ IRotaryFocusable IBezelInteractionController.RotaryFocusObject => _currentRotaryFocusObject;
+
+ void IBezelInteractionController.Activate()
+ {
+ ActivateRotaryWidget();
+ }
+
+ void IBezelInteractionController.Deactivate()
+ {
+ DeactivateRotaryWidget();
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
+ {
+ base.OnElementChanged(e);
+ e.NewElement.Appearing += OnPageAppearing;
+ e.NewElement.Disappearing += OnPageDisappearing;
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ base.Element.Appearing -= OnPageAppearing;
+ base.Element.Disappearing -= OnPageDisappearing;
+ }
+ base.Dispose(disposing);
+ }
+
+ protected override void OnElementReady()
+ {
+ base.OnElementReady();
+ // A Page created by with ContentTemplate of ShellContent, was appered before create a renderer
+ // So need to call ActivateRotaryWidget() if page already appeared
+ if (Element.Appeared)
+ {
+ ActivateRotaryWidget();
+ }
+ }
+
+ protected override void OnMoreOptionClosed()
+ {
+ DeactivateRotaryWidget();
+ }
+
+ protected override void OnMoreOptionOpened()
+ {
+ ActivateRotaryWidget();
+ }
+
+ void UpdateRotaryFocusObject(bool initialize)
+ {
+ if (initialize)
+ {
+ _currentRotaryFocusObject = Element.RotaryFocusObject;
+ }
+ else
+ {
+ DeactivateRotaryWidget();
+ _currentRotaryFocusObject = Element.RotaryFocusObject;
+ ActivateRotaryWidget();
+ }
+ }
+
+ void ActivateRotaryWidget()
+ {
+ if (!Element.Appeared)
+ return;
+
+ if (_currentRotaryFocusObject is IRotaryEventReceiver)
+ {
+ ERotaryEventManager.Rotated += OnRotaryEventChanged;
+ }
+ else
+ {
+ GetRotaryWidget(_currentRotaryFocusObject)?.Activate();
+ }
+ AppSpecific.SetActiveBezelInteractionElement(Application.Current, base.Element);
+ }
+
+ void DeactivateRotaryWidget()
+ {
+ if (_currentRotaryFocusObject is IRotaryEventReceiver)
+ {
+ ERotaryEventManager.Rotated -= OnRotaryEventChanged;
+ }
+ else if (_currentRotaryFocusObject is IRotaryFocusable)
+ {
+ GetRotaryWidget(_currentRotaryFocusObject)?.Deactivate();
+ }
+ if (AppSpecific.GetActiveBezelInteractionElement(Application.Current) == base.Element)
+ AppSpecific.SetActiveBezelInteractionElement(Application.Current, null);
+ }
+
+ void OnPageDisappearing(object sender, EventArgs e)
+ {
+ DeactivateRotaryWidget();
+ }
+
+ void OnPageAppearing(object sender, EventArgs e)
+ {
+ ActivateRotaryWidget();
+ }
+
+ void OnRotaryEventChanged(ElmSharp.Wearable.RotaryEventArgs e)
+ {
+ if (_currentRotaryFocusObject is IRotaryEventReceiver receiver)
+ {
+ receiver.Rotate(new RotaryEventArgs { IsClockwise = e.IsClockwise });
+ }
+ }
+
+ IRotaryActionWidget GetRotaryWidget(IRotaryFocusable focusable)
+ {
+ IRotaryActionWidget rotaryWidget = null;
+ if (focusable is BindableObject consumer)
+ {
+ if (consumer is CircleSurfaceItem circleSlider)
+ {
+ rotaryWidget = GetCircleWidget(circleSlider) as IRotaryActionWidget;
+ }
+ else
+ {
+ rotaryWidget = Platform.GetRenderer(consumer)?.NativeView as IRotaryActionWidget;
+ }
+ }
+ return rotaryWidget;
+ }
+
+ ICircleWidget GetCircleWidget(CircleSurfaceItem item)
+ {
+ if (item.Parent == null)
+ return null;
+ return (Platform.GetRenderer(item.Parent) as ICircleSurfaceItemRenderer)?.GetCircleWidget(item);
+ }
+ }
+
+ public static class BezelInteractionExtension
+ {
+ public static IBezelInteractionRouter FindBezelRouter(this Element element)
+ {
+ while (element != null)
+ {
+ if (element is IBezelInteractionRouter router)
+ {
+ return router;
+ }
+ element = element.Parent;
+ }
+ return null;
+ }
+
+ public static IBezelInteractionController FindBezelController(this Element element)
+ {
+ while (element != null)
+ {
+ if (element is IBezelInteractionRouter router)
+ {
+ return Platform.GetRenderer(element) as IBezelInteractionController;
+ }
+ element = element.Parent;
+ }
+ return null;
+ }
+
+ }
+
+}
\ No newline at end of file
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Tizen;
+using Xamarin.Forms.Platform.Tizen.Native;
+using Xamarin.Forms.Platform.Tizen.Native.Watch;
using XForms = Xamarin.Forms.Forms;
-using ECircleDateTimeSelector = ElmSharp.Wearable.CircleDateTimeSelector;
using EDateTimeFieldType = ElmSharp.DateTimeFieldType;
-[assembly: ExportRenderer(typeof(Tizen.Wearable.CircularUI.Forms.CircleDateTimeSelector), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleDateTimeSelectorRenderer))]
+[assembly: ExportRenderer(typeof(Tizen.Wearable.CircularUI.Forms.CircleDateTimeSelector), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleDateTimeSelectorRenderer))]
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- public class CircleDateTimeSelectorRenderer : ViewRenderer<CircleDateTimeSelector, ECircleDateTimeSelector>
+ public class CircleDateTimeSelectorRenderer : ViewRenderer<CircleDateTimeSelector, WatchDateTimePicker>
{
public CircleDateTimeSelectorRenderer()
{
var surface = this.GetSurface();
if (null != surface)
{
- SetNativeControl(new ECircleDateTimeSelector(XForms.NativeParent, surface));
+ SetNativeControl(new WatchDateTimePicker(XForms.NativeParent, surface));
Control.DateTimeChanged += OnDateTimeChanged;
}
else
return new ElmSharp.Size(300, 290);
}
- void UpdateMinimum()
+ protected override void UpdateRotaryInteraction(bool enable)
{
- if (null != Control && null != Element)
+ if (Element.FindBezelRouter() == null)
{
- Control.MinimumDateTime = Element.MinimumDate;
+ base.UpdateRotaryInteraction(enable);
}
}
+ void UpdateMinimum()
+ {
+ Control.MinimumDateTime = Element.MinimumDate;
+ }
+
void UpdateMaximum()
{
- if (null != Control && null != Element)
- {
Control.MaximumDateTime = Element.MaximumDate;
}
- }
void UpdateDateTime()
{
- if (null != Control && null != Element && Element.DateTime != Control.DateTime)
+ if (Element.DateTime != Control.DateTime)
{
Control.DateTime = Element.DateTime;
}
void UpdateValueType()
{
- if (null != Control && null != Element)
- {
- if (Element.ValueType == DateTimeType.Date)
- {
- Control.Style = "datepicker/circle";
- Control.Format = "%d/%b/%Y";
- }
- else if (Element.ValueType == DateTimeType.Time)
- {
- Control.Style = "timepicker/circle";
- Control.Format = "%d/%b/%Y%I:%M%p";
- }
- }
+ Control.Mode = Element.ValueType.ToNative();
}
void UpdateMarkerColor()
{
#pragma warning disable CS0618 // MarkerColor is obsolete
- if (null != Control && null != Element && Element.MarkerColor != Xamarin.Forms.Color.Default)
+ if (Element.MarkerColor != Xamarin.Forms.Color.Default)
{
Control.MarkerColor = Element.MarkerColor.ToNative();
}
void OnDateTimeChanged(object sender, EventArgs e)
{
- if (null != Control && null != Element)
- {
Element.DateTime = Control.DateTime;
}
- }
void UpdateFieldVisibilityOfYear()
{
- if (null != Control && null != Element)
- {
Control.SetFieldVisible(EDateTimeFieldType.Year, Element.IsVisibleOfYear);
}
- }
void UpdateFieldVisibilityOfMonth()
{
- if (null != Control && null != Element)
- {
Control.SetFieldVisible(EDateTimeFieldType.Month, Element.IsVisibleOfMonth);
}
- }
void UpdateFieldVisibilityOfDate()
{
- if (null != Control && null != Element)
- {
Control.SetFieldVisible(EDateTimeFieldType.Date, Element.IsVisibleOfDate);
}
- }
void UpdateFieldVisibilityOfHour()
{
- if (null != Control && null != Element)
- {
Control.SetFieldVisible(EDateTimeFieldType.Hour, Element.IsVisibleOfHour);
}
- }
void UpdateFieldVisibilityOfMinute()
{
- if (null != Control && null != Element)
+ Control.SetFieldVisible(EDateTimeFieldType.Minute, Element.IsVisibleOfMinute);
+ }
+
+ void UpdateFieldVisibilityOfAmPm()
{
- Control.SetFieldVisible(EDateTimeFieldType.Minute, Element.IsVisibleOfMinute);
+ Control.SetFieldVisible(EDateTimeFieldType.AmPm, Element.IsVisibleOfAmPm);
}
}
- void UpdateFieldVisibilityOfAmPm()
+ internal static class DateTimeTypeEntensions
+ {
+ internal static DateTimePickerMode ToNative(this DateTimeType type)
{
- if (null != Control && null != Element)
+ switch (type)
{
- Control.SetFieldVisible(EDateTimeFieldType.AmPm, Element.IsVisibleOfAmPm);
+ case DateTimeType.Date:
+ return DateTimePickerMode.Date;
+ case DateTimeType.Time:
+ return DateTimePickerMode.Time;
+ default:
+ throw new NotImplementedException($"DateTimeType {type} not supported");
}
}
}
using Xamarin.Forms;
using TLog = Tizen.Log;
using FormsCircularUI = Tizen.Wearable.CircularUI.Forms.Renderer.FormsCircularUI;
+using XForms = Xamarin.Forms.Forms;
[assembly: ExportRenderer(typeof(CircleImage), typeof(CircleImageRenderer))]
namespace Tizen.Wearable.CircularUI.Forms.Renderer
public class CircleImageRenderer : ViewRenderer<CircleImage, FormsNative.Image>
{
ElmSharp.EvasImage _circleImage;
- ElmSharp.EvasObject _nativeParent;
protected override void OnElementChanged(ElementChangedEventArgs<CircleImage> e)
{
if (Control == null)
{
- _nativeParent = Platform.GetRenderer(Element.Parent).NativeView;
- _circleImage = new ElmSharp.EvasImage(_nativeParent);
+ _circleImage = new ElmSharp.EvasImage(XForms.NativeParent);
_circleImage.IsFilled = true;
GetClipImage();
- var image = new FormsNative.Image(_nativeParent);
+ var image = new FormsNative.Image(XForms.NativeParent);
SetNativeControl(image);
Control.Resized += Control_Resized;
Control.Moved += Control_Moved;
void UpdateBackgroundColor()
{
- if (_nativeParent == null) return;
+ if (Control == null) return;
if (Element.BackgroundColor.ToNative() != ElmSharp.Color.Transparent
&& Element.BackgroundColor.ToNative() != ElmSharp.Color.Default)
{
- _nativeParent.Color = Element.BackgroundColor.ToNative();
+ Control.Color = Element.BackgroundColor.ToNative();
}
}
+++ /dev/null
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using ElmSharp.Wearable;
-using System;
-using System.Collections.Generic;
-using Xamarin.Forms;
-using ElmSharp;
-using System.Collections;
-using Xamarin.Forms.Platform.Tizen;
-using Xamarin.Forms.Internals;
-using System.ComponentModel;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- using GroupList = TemplatedItemsList<ItemsView<Cell>, Cell>;
-
- public class CircleListView : CircleGenList
- {
- const int HeaderMinimumHeight = 115;
- const int GroupHeaderMinimumHeight = 83;
-
- readonly Dictionary<Cell, GenListItem> _itemContexts = new Dictionary<Cell, GenListItem>();
-
- VisualElement _header;
- VisualElement _footer;
- int _rowHeight;
-
- public CircleListView(EvasObject parent, CircleSurface surface) : base(parent, surface)
- {
- }
-
- public VisualElement Header
- {
- get => _header;
- set
- {
- if (_header == value) return;
- _header = value;
- UpdateHeader();
- }
- }
- public VisualElement Footer
- {
- get => _footer;
- set
- {
- if (_footer == value) return;
- _footer = value;
- UpdateFooter();
- }
- }
-
- public int HeaderRowHeight
- {
- get => _rowHeight;
- set
- {
- if (_rowHeight == value) return;
- _rowHeight = value;
- }
- }
-
- public void ResetGroup(GroupList group)
- {
- GenListItem groupItem;
- if (_itemContexts.TryGetValue(group.HeaderContent, out groupItem))
- {
- groupItem.ClearSubitems();
- }
- }
-
- public void AddSource(IEnumerable source)
- {
- UpdateHeader();
- foreach (var data in source)
- {
- var groupList = data as GroupList;
- if (groupList != null)
- {
- AddGroup(groupList);
- foreach (var item in groupList)
- {
- AddItem(item as Cell, groupList);
- }
- }
- else
- {
- AddItem(data as Cell, null);
- }
- }
- UpdateFooter();
- }
- public void AddSource(IEnumerable source, Cell before)
- {
- foreach (var data in source)
- {
- var groupList = data as GroupList;
- if (groupList != null)
- {
- InsertGroup(groupList, before);
- foreach (var item in groupList)
- {
- AddItem(item as Cell, groupList);
- }
- }
- else
- {
- InsertItem(data as Cell, before, null);
- }
- }
- }
- public void AddSource(IEnumerable source, GroupList group, Cell before)
- {
- foreach (var data in source)
- {
- InsertItem(data as Cell, before, group);
- }
- }
- public void AddSource(IEnumerable source, GroupList group)
- {
- foreach (var data in source)
- {
- AddItem(data as Cell, group);
- }
- }
-
- public void RemoveSource(IEnumerable source)
- {
- foreach (var data in source)
- {
- if (data is GroupList)
- Remove(data as GroupList);
- else
- Remove(data as Cell);
- }
- }
-
- public void ApplyScrollTo(Cell cell, Xamarin.Forms.ScrollToPosition position, bool animated)
- {
- GenListItem item;
- if (_itemContexts.TryGetValue(cell, out item))
- {
- ScrollTo(item, position.ToNative(), animated);
- }
- }
-
- public void ApplySelectedItem(Cell cell)
- {
- GenListItem item;
- if (_itemContexts.TryGetValue(cell, out item))
- {
- item.IsSelected = true;
- }
- }
-
- public void AddItem(Cell cell, GroupList group)
- {
- CellRenderer renderer = ListViewCache.Get(cell);
- GenListItem groupItem = null;
- if (group != null)
- {
- _itemContexts.TryGetValue(group.HeaderContent, out groupItem);
- }
- GenListItem item;
- var lastCtx = LastItem?.Data as TypedItemContext;
- if (lastCtx != null && (lastCtx.Type == ItemType.Footer || lastCtx.Type == ItemType.BottomPadding))
- {
- item = InsertBefore(renderer.Class, new ListViewItemContext(cell, group), LastItem, GenListItemType.Normal, groupItem);
- }
- else
- {
- item = Append(renderer.Class, new ListViewItemContext(cell, group), GenListItemType.Normal, groupItem);
- }
- RegisterItem(cell, item);
- }
- public void InsertItem(Cell cell, Cell before, GroupList group)
- {
- CellRenderer renderer = ListViewCache.Get(cell);
- GenListItem groupItem = null;
- if (group != null)
- {
- _itemContexts.TryGetValue(group.HeaderContent, out groupItem);
- }
- _itemContexts.TryGetValue(before, out GenListItem beforeItem);
- var item = InsertBefore(renderer.Class, new ListViewItemContext(cell, group), beforeItem, GenListItemType.Normal, groupItem);
- RegisterItem(cell, item);
- }
- public void AddGroup(GroupList group)
- {
- CellRenderer renderer = ListViewCache.Get(group.HeaderContent, true);
- var lastCtx = LastItem?.Data as TypedItemContext;
- GenListItem item = null;
- if (lastCtx != null && (lastCtx.Type == ItemType.Footer || lastCtx.Type == ItemType.BottomPadding))
- {
- item = InsertBefore(renderer.Class, new ListViewItemContext(group), LastItem, GenListItemType.Group);
- }
- else
- {
- item = Append(renderer.Class, new ListViewItemContext(group), GenListItemType.Group);
- }
- RegisterItem(group.HeaderContent, item, true);
- }
- public void InsertGroup(GroupList group, Cell before)
- {
- CellRenderer renderer = ListViewCache.Get(group.HeaderContent, true);
- _itemContexts.TryGetValue(before, out GenListItem beforeItem);
- var item = InsertBefore(renderer.Class, new ListViewItemContext(group), beforeItem, GenListItemType.Group);
- RegisterItem(group.HeaderContent, item, true);
- }
- public void Remove(Cell cell)
- {
- GenListItem item;
- if (_itemContexts.TryGetValue(cell, out item))
- {
- item.Delete();
- }
- }
- public void Remove(GroupList group)
- {
- Remove(group.HeaderContent);
- foreach (var data in group)
- {
- Remove(data as Cell);
- }
- }
-
- public new void Clear()
- {
- base.Clear();
- }
-
- protected override void OnRealized()
- {
- base.OnRealized();
-
- ItemRealized += OnItemAppear;
- ItemUnrealized += OnItemDisappear;
- }
-
- void OnItemDisappear(object sender, GenListItemEventArgs e)
- {
- ListViewItemContext ctx = e?.Item?.Data as ListViewItemContext;
- if (ctx?.Cell != null)
- {
- ctx.Cell.SendDisappearing();
- var renderer = ListViewCache.Get(ctx.Cell);
- renderer.SendUnrealizedCell(ctx.Cell);
- }
- }
-
- void OnItemAppear(object sender, GenListItemEventArgs e)
- {
- ListViewItemContext ctx = e?.Item?.Data as ListViewItemContext;
- if (ctx?.Cell != null)
- {
- ctx.Cell.SendAppearing();
- }
- }
-
- void UpdateHeaderHeightForGroup(bool isPreviousOfGroup)
- {
- if (Header == null) return;
- if (isPreviousOfGroup)
- {
- Header.MinimumHeightRequest = GroupHeaderMinimumHeight; // correct visible height on the Group Header
- }
- else
- {
- if (Header.HeightRequest < 0 && HeaderRowHeight < 0)
- {
- Header.MinimumHeightRequest = HeaderMinimumHeight; // correct visible height on the None group header
- }
- else if(HeaderRowHeight > 0)
- {
- Header.MinimumHeightRequest = HeaderRowHeight;
- }
- }
- }
-
- void UpdateHeader()
- {
- GenItemClass cls = null;
- ItemType type = ItemType.TopPadding;
- var ctx = FirstItem?.Data as TypedItemContext;
-
- if (Header == null)
- {
- cls = ListViewCache.PaddingItemClass;
- }
- else
- {
- cls = Forms.CircleListView.GetCancelEffect(Header) ? ListViewCache.InformalItemClassWithoutFishEye : ListViewCache.InformalItemClass;
- type = ItemType.Header;
- }
-
- if (FirstItem == null)
- {
- Append(cls, new TypedItemContext(Header, type));
- }
- else
- {
- if (ctx == null || ctx.Type == ItemType.Footer || ctx.Type == ItemType.BottomPadding)
- {
- InsertBefore(cls, new TypedItemContext(Header, type), FirstItem);
- }
- else
- {
- FirstItem.UpdateItemClass(cls, new TypedItemContext(Header, type));
- }
- }
-
- if (Header != null && FirstItem?.Next != null)
- {
- var nextCtx = FirstItem.Next?.Data as ListViewItemContext;
- var isNextItemIsGroupHeader = nextCtx == null ? false : nextCtx.IsGroupItem;
-
- UpdateHeaderHeightForGroup(isNextItemIsGroupHeader);
- }
- }
-
- void UpdateFooter()
- {
- GenItemClass cls = null;
- ItemType type;
- var ctx = LastItem?.Data as TypedItemContext;
- if (Footer == null)
- {
- cls = ListViewCache.PaddingItemClass;
- type = ItemType.BottomPadding;
- }
- else
- {
- cls = Forms.CircleListView.GetCancelEffect(Footer) ? ListViewCache.InformalItemClassWithoutFishEye : ListViewCache.InformalItemClass;
- type = ItemType.Footer;
- }
-
- if (ctx == null || ctx.Type == ItemType.Header || ctx.Type == ItemType.TopPadding)
- {
- Append(cls, new TypedItemContext(Footer, type));
- }
- else
- {
- LastItem.UpdateItemClass(cls, new TypedItemContext(Footer, type));
- }
- }
-
- void RegisterItem(Cell cell, GenListItem item, bool IsGroup = false)
- {
- item.SelectionMode = IsGroup ? GenItemSelectionMode.None : GenItemSelectionMode.Always;
- item.IsEnabled = cell.IsEnabled;
- item.Deleted += ItemDeletedHandler;
- _itemContexts[cell] = item;
-
-
- if (Header != null && item == FirstItem.Next)
- {
- UpdateHeaderHeightForGroup(IsGroup);
- }
-
- if (!IsGroup)
- {
- cell.PropertyChanged += OnCellPropertyChanged;
- (cell as ICellController).ForceUpdateSizeRequested += OnForceUpdateSizeRequested;
- }
- }
- void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- var cell = sender as Cell;
- var renderer = ListViewCache.Get(cell);
- GenListItem item;
- if (_itemContexts.TryGetValue(cell, out item))
- {
- renderer.SendCellPropertyChanged(cell, item, e.PropertyName);
- }
- }
- void OnForceUpdateSizeRequested(object sender, EventArgs e)
- {
- var cell = sender as Cell;
- GenListItem item;
- if (_itemContexts.TryGetValue(cell, out item))
- {
- item.Update();
- }
- }
- void ItemDeletedHandler(object sender, EventArgs e)
- {
- var context = (sender as GenListItem)?.Data as ListViewItemContext;
- if (context != null)
- {
- Cell cell;
- if (!context.IsGroupItem)
- {
- cell = context.Cell;
- cell.PropertyChanged -= OnCellPropertyChanged;
- (cell as ICellController).ForceUpdateSizeRequested -= OnForceUpdateSizeRequested;
- }
- else
- {
- cell = context.Group.HeaderContent;
- }
- _itemContexts.Remove(cell);
- }
- }
- }
-
- enum ItemType
- {
- TopPadding,
- BottomPadding,
- Header,
- Footer
- }
-
- class TypedItemContext
- {
- public TypedItemContext(VisualElement element, ItemType type)
- {
- Element = element;
- Type = type;
- }
- public VisualElement Element { get; set; }
- public ItemType Type { get; set; }
- }
-
- public class ListViewItemContext : Xamarin.Forms.Platform.Tizen.Native.ListView.ItemContext
- {
- public ListViewItemContext(Cell cell, GroupList group, bool isGroup)
- {
- Cell = cell;
- Group = group;
- IsGroupItem = isGroup;
- }
- public ListViewItemContext(Cell cell, GroupList group) : this(cell, group, false)
- {
- }
-
- public ListViewItemContext(GroupList group) : this(group.HeaderContent, group, true)
- {
- }
-
- public GroupList Group { get; set; }
- }
-}
\ No newline at end of file
* limitations under the License.
*/
-using ElmSharp;
-using System.Collections;
-using System.Collections.Specialized;
using Xamarin.Forms;
-using Xamarin.Forms.Internals;
using Xamarin.Forms.Platform.Tizen;
using XForms = Xamarin.Forms.Forms;
-using CCircularListView = global::Tizen.Wearable.CircularUI.Forms.CircleListView;
-using System;
+using CircleListView = Tizen.Wearable.CircularUI.Forms.CircleListView;
-[assembly: ExportRenderer(typeof(Tizen.Wearable.CircularUI.Forms.CircleListView), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleListViewRenderer))]
+[assembly: ExportRenderer(typeof(CircleListView), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleListViewRenderer))]
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- using GroupList = TemplatedItemsList<ItemsView<Cell>, Cell>;
-
- public class CircleListViewRenderer : ViewRenderer<CCircularListView, CircleListView>
+ public class CircleListViewRenderer : ListViewRenderer
{
- int _selectedItemChanging;
+ new CircleListView Element => base.Element as CircleListView;
+ WatchListView _listView;
public CircleListViewRenderer()
{
- RegisterPropertyHandler(global::Tizen.Wearable.CircularUI.Forms.CircleListView.HasUnevenRowsProperty, UpdateHasUnevenRows);
- RegisterPropertyHandler(CCircularListView.RowHeightProperty, UpdateRowHeight);
- RegisterPropertyHandler(CCircularListView.SelectedItemProperty, UpdateSelectedItem);
- RegisterPropertyHandler(CCircularListView.ItemsSourceProperty, UpdateSource);
- RegisterPropertyHandler("HeaderElement", UpdateHeader);
- RegisterPropertyHandler("FooterElement", UpdateFooter);
- RegisterPropertyHandler(CCircularListView.BarColorProperty, UpdateBarColor);
- }
-
- protected override void OnElementChanged(ElementChangedEventArgs<CCircularListView> e)
- {
- if (Control == null)
- {
- var surface = this.GetSurface();
- SetNativeControl(NativeFactory.GetNativeControl(typeof(CircleListView), surface) as CircleListView);
- Control.ItemSelected += OnListViewItemSelected;
- }
-
- if (e.NewElement != null)
- {
- e.NewElement.ScrollToRequested += OnScrollToRequested;
- e.NewElement.TemplatedItems.GroupedCollectionChanged += OnGroupedCollectionChanged;
- e.NewElement.TemplatedItems.CollectionChanged += OnCollectionChanged;
- }
- if (e.OldElement != null)
- {
- e.OldElement.ScrollToRequested -= OnScrollToRequested;
- e.OldElement.TemplatedItems.GroupedCollectionChanged -= OnGroupedCollectionChanged;
- e.OldElement.TemplatedItems.CollectionChanged -= OnCollectionChanged;
- }
- base.OnElementChanged(e);
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (Element != null)
- {
- Element.ScrollToRequested -= OnScrollToRequested;
- Element.TemplatedItems.GroupedCollectionChanged -= OnGroupedCollectionChanged;
- Element.TemplatedItems.CollectionChanged -= OnCollectionChanged;
- }
- if (Control != null)
- {
- Control.ItemSelected -= OnListViewItemSelected;
- }
- }
- base.Dispose(disposing);
- }
-
- void UpdateFooter()
- {
- var footer = (Element as IListViewController)?.FooterElement as VisualElement;
- Control.Footer = footer;
+ RegisterPropertyHandler(CircleListView.BarColorProperty, UpdateBarColor);
}
- void UpdateHeader()
+ protected override Xamarin.Forms.Platform.Tizen.Native.ListView CreateNativeControl()
{
- var header = (Element as IListViewController)?.HeaderElement as VisualElement;
- Control.Header = header;
+ return _listView = new WatchListView(XForms.NativeParent, this.GetSurface());
}
void UpdateBarColor()
{
- var color = Element.BarColor;
- if (color != Xamarin.Forms.Color.Default)
- {
- Control.VerticalScrollBarColor = color.ToNative();
- }
- }
-
- void UpdateSource(bool init)
- {
- if (!init)
- Control.Clear();
- Control.AddSource(Element.TemplatedItems);
- UpdateSelectedItem();
- }
-
- void UpdateSelectedItem()
- {
- if (Element.SelectedItem == null)
- {
- if (Control.SelectedItem != null)
- Control.SelectedItem.IsSelected = false;
- }
- else
- {
- var results = Element.TemplatedItems.GetGroupAndIndexOfItem(Element.SelectedItem);
- if (results.Item1 != -1 && results.Item2 != -1)
- {
- var group = (Element.TemplatedItems as ITemplatedItemsList<Cell>).GetGroup(results.Item1);
- var cell = group[results.Item2];
-
- _selectedItemChanging++;
- Control.ApplySelectedItem(cell);
- _selectedItemChanging--;
- }
- }
- }
-
- void UpdateRowHeight(bool initialize)
- {
- Control.HeaderRowHeight = Element.RowHeight;
- if (!initialize)
- Control.UpdateRealizedItems();
- }
-
- void UpdateHasUnevenRows()
- {
- Control.Homogeneous = !Element.HasUnevenRows;
- Control.UpdateRealizedItems();
- }
-
- void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- if (e.NewStartingIndex + e.NewItems.Count < Element.TemplatedItems.Count)
- {
- Cell before = Element.TemplatedItems[e.NewStartingIndex + e.NewItems.Count];
- Control.AddSource(e.NewItems, before);
- }
- else
- {
- Control.AddSource(e.NewItems);
- }
- }
- else if (e.Action == NotifyCollectionChangedAction.Remove)
- {
- Control.RemoveSource(e.OldItems);
- }
- else if (e.Action == NotifyCollectionChangedAction.Reset)
- {
- UpdateSource(false);
- }
- }
-
- void OnGroupedCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- GroupList group = sender as GroupList;
- if (e.NewStartingIndex + e.NewItems.Count < Element.TemplatedItems.Count)
- {
- Cell before = Element.TemplatedItems[e.NewStartingIndex + e.NewItems.Count];
- Control.AddSource(e.NewItems, group, before);
- }
- else
- {
- Control.AddSource(e.NewItems, group);
- }
- }
- else if (e.Action == NotifyCollectionChangedAction.Remove)
- {
- Control.RemoveSource(e.OldItems);
- }
- else if (e.Action == NotifyCollectionChangedAction.Reset)
- {
- Control.ResetGroup(sender as GroupList);
- }
- }
-
- void OnScrollToRequested(object sender, ScrollToRequestedEventArgs e)
- {
- Cell cell;
- var args = e as ITemplatedItemsListScrollToRequestedEventArgs;
- if (Element.IsGroupingEnabled)
- {
- var results = Element.TemplatedItems.GetGroupAndIndexOfItem(args.Group, args.Item);
- if (results.Item1 == -1 || results.Item2 == -1)
- return;
-
- var group = (Element.TemplatedItems as ITemplatedItemsList<Cell>).GetGroup(results.Item1);
- cell = group[results.Item2];
- }
- else
- {
- int index = (Element.TemplatedItems as ITemplatedItemsList<Cell>).GetGlobalIndexOfItem(args.Item);
- cell = Element.TemplatedItems[index];
- }
-
- Control.ApplyScrollTo(cell, e.Position, e.ShouldAnimate);
- }
-
- void OnListViewItemSelected(object sender, GenListItemEventArgs e)
- {
- var context = e.Item?.Data as ListViewItemContext;
-
- if (context == null)
- {
- return;
- }
-
- if (_selectedItemChanging != 0 || context.IsGroupItem)
- {
- return;
- }
-
- if (Element.IsGroupingEnabled)
- {
- int groupIndex = (Element.TemplatedItems as IList).IndexOf(context.Group);
- int subIndex = context.Group.IndexOf(context.Cell);
- _selectedItemChanging++;
- Element.NotifyRowTapped(groupIndex, subIndex);
- _selectedItemChanging--;
- }
- else
+ if (!Element.BarColor.IsDefault)
{
- int index = Element.TemplatedItems.IndexOf(context.Cell);
- _selectedItemChanging++;
- Element.NotifyRowTapped(index);
- _selectedItemChanging--;
+ _listView.CircleGenList.VerticalScrollBarColor = Element.BarColor.ToNative();
}
}
}
* limitations under the License.
*/
+using ElmSharp;
+using ElmSharp.Wearable;
using System;
-using System.Collections.ObjectModel;
+using System.Collections.Generic;
using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Linq;
using Tizen.Wearable.CircularUI.Forms;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Tizen;
+using Xamarin.Forms.Platform.Tizen.Native;
+using ERotaryEventManager = ElmSharp.Wearable.RotaryEventManager;
+using NPage = Xamarin.Forms.Platform.Tizen.Native.Page;
using XForms = Xamarin.Forms.Forms;
-using XToolbarItem = Xamarin.Forms.ToolbarItem;
+using AppSpecific = Xamarin.Forms.PlatformConfiguration.TizenSpecific.Application;
[assembly: ExportRenderer(typeof(CirclePage), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CirclePageRenderer))]
+
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- public class CirclePageRenderer : VisualElementRenderer<CirclePage>
+ public class CirclePageRenderer : PageRenderer, IBezelInteractionController
{
- NativeCirclePage _circlePage = null;
+ ElmSharp.Button _actionButton;
+ ActionButtonItem _actionButtonItem;
+ ElmSharp.Layout _surfaceLayout;
+ CircleSurface _circleSurface;
+ Dictionary<ICircleSurfaceItem, ICircleWidget> _circleSurfaceItems;
+ IRotaryFocusable _currentRotaryFocusObject;
+ bool _isInitialized;
+
+ NPage Control => (NativeView as NPage);
+
+ new CirclePage Element => base.Element as CirclePage;
public CirclePageRenderer()
{
- RegisterPropertyHandler(Xamarin.Forms.Page.BackgroundImageSourceProperty, UpdateBackgroundImage);
RegisterPropertyHandler(CirclePage.ActionButtonProperty, UpdateActionButton);
RegisterPropertyHandler(CirclePage.RotaryFocusObjectProperty, UpdateRotaryFocusObject);
}
- public ElmSharp.Wearable.CircleSurface CircleSurface;
+ public CircleSurface CircleSurface => _circleSurface;
- public void UpdateRotaryFocusObject()
+ IRotaryFocusable IBezelInteractionController.RotaryFocusObject => _currentRotaryFocusObject;
+
+ void IBezelInteractionController.Activate()
{
- _circlePage.UpdateRotaryFocusObject(Element.RotaryFocusObject);
+ ActivateRotaryWidget();
}
- protected override void OnElementChanged(ElementChangedEventArgs<CirclePage> e)
+ void IBezelInteractionController.Deactivate()
{
- if (_circlePage == null)
- {
- _circlePage = NativeFactory.GetNativeControl(typeof(NativeCirclePage)) as NativeCirclePage;
- CircleSurface = _circlePage.Surface;
-
- if (Element.ToolbarItems.Count > 0)
- {
- Device.BeginInvokeOnMainThread(() =>
- {
- _circlePage.SetVisibleMoreOption(true);
+ DeactivateRotaryWidget();
+ }
- foreach (var item in Element.ToolbarItems)
- {
- _circlePage.AddToolbarItem(item);
- }
- });
- }
- SetNativeView(_circlePage);
+ public void UpdateRotaryFocusObject(bool initialize)
+ {
+ if (initialize)
+ {
+ _currentRotaryFocusObject = Element.RotaryFocusObject;
}
- if (e.NewElement != null)
+ else
{
- _circlePage.SetElement(e.NewElement);
-
- e.NewElement.CircleSurface = _circlePage.Surface;
- e.NewElement.Appearing += OnPageAppearing;
- e.NewElement.Disappearing += OnPageDisappearing;
- var toolbarItems = e.NewElement.ToolbarItems as ObservableCollection<XToolbarItem>;
- if (toolbarItems != null)
- toolbarItems.CollectionChanged += OnToolbarItemChanged;
- var circleSurfaceItems = e.NewElement.CircleSurfaceItems as ObservableCollection<ICircleSurfaceItem>;
- if (circleSurfaceItems != null)
- {
- circleSurfaceItems.CollectionChanged += OnCircleSurfaceItemsChanged;
+ DeactivateRotaryWidget();
+ _currentRotaryFocusObject = Element.RotaryFocusObject;
+ ActivateRotaryWidget();
+ }
+ }
- foreach (var item in circleSurfaceItems)
- {
- _circlePage.AddCircleSurfaceItem(item);
- }
- }
+ protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
+ {
+ // It will create NativeView and it will be Native.Page
+ base.OnElementChanged(e);
+ if (!_isInitialized)
+ {
+ _isInitialized = true;
+ InitializeComponent();
}
- if (e.OldElement != null)
+
+ if (e.NewElement is CirclePage newElement)
{
- e.OldElement.Appearing -= OnPageAppearing;
- e.OldElement.Disappearing -= OnPageDisappearing;
- var toolbarItems = e.NewElement.ToolbarItems as ObservableCollection<XToolbarItem>;
- if (toolbarItems != null)
- toolbarItems.CollectionChanged -= OnToolbarItemChanged;
- var circleSurfaceItems = e.NewElement.CircleSurfaceItems as ObservableCollection<ICircleSurfaceItem>;
- if (circleSurfaceItems != null)
- circleSurfaceItems.CollectionChanged -= OnCircleSurfaceItemsChanged;
+ newElement.Appearing += OnPageAppearing;
+ newElement.Disappearing += OnPageDisappearing;
+ newElement.CircleSurface = CircleSurface;
+ foreach (var item in newElement.CircleSurfaceItems)
+ {
+ AddCircleSurfaceItem(item);
+ }
+ if (newElement.CircleSurfaceItems is INotifyCollectionChanged collectionChanged)
+ {
+ collectionChanged.CollectionChanged += OnCircleSurfaceItemsChanged;
+ }
}
- base.OnElementChanged(e);
}
protected override void OnElementReady()
}
}
- protected override void UpdateBackgroundColor(bool initialize)
+
+ protected override void OnMoreOptionClosed()
{
- if (initialize && Element.BackgroundColor.IsDefault)
- return;
+ DeactivateRotaryWidget();
+ }
+
- _circlePage.UpdateBackgroundColor(Element.BackgroundColor);
+ protected override void OnMoreOptionOpened()
+ {
+ ActivateRotaryWidget();
}
- protected void UpdateBackgroundImage(bool initialize)
+ protected override void Dispose(bool disposing)
{
- if (initialize && Element.BackgroundImageSource.IsNullOrEmpty())
- return;
+ if (disposing)
+ {
+ if (Element != null)
+ {
+ Element.Appearing -= OnPageAppearing;
+ Element.Disappearing -= OnPageDisappearing;
+ Element.CircleSurface = null;
+ if (_actionButtonItem != null)
+ {
+ _actionButtonItem.PropertyChanged -= OnActionButtonItemChanged;
+ }
+ if (Element.CircleSurfaceItems is INotifyCollectionChanged collectionChanged)
+ {
+ collectionChanged.CollectionChanged -= OnCircleSurfaceItemsChanged;
+ }
+ }
+ }
+ base.Dispose(disposing);
+ }
- _circlePage.UpdateBackgroundImage(Element.BackgroundImageSource);
+ void InitializeComponent()
+ {
+ Control.LayoutUpdated += OnLayoutUpdated;
+ _surfaceLayout = new ElmSharp.Layout(XForms.NativeParent);
+ _circleSurface = new CircleSurface(_surfaceLayout);
+ Control.Children.Add(_surfaceLayout);
+ _surfaceLayout.Show();
+ _circleSurfaceItems = new Dictionary<ICircleSurfaceItem, ICircleWidget>();
}
- protected override void Dispose(bool disposing)
+ void InitializeActionButton()
{
- if (Element != null)
+ _actionButton = new ElmSharp.Button(XForms.NativeParent)
{
- Element.Appearing -= OnPageAppearing;
- Element.Disappearing -= OnPageDisappearing;
+ Style = "bottom"
+ };
+ _actionButton.Clicked += OnActionButtonClicked;
+ Control.Children.Add(_actionButton);
+ }
- var toolbarItems = Element.ToolbarItems as ObservableCollection<XToolbarItem>;
- if (toolbarItems != null)
- toolbarItems.CollectionChanged -= OnToolbarItemChanged;
+ void DeinitializeActionButton()
+ {
+ _actionButton.Clicked -= OnActionButtonClicked;
+ Control.Children.Remove(_actionButton);
+ _actionButton.Unrealize();
+ _actionButton = null;
+ }
- var circleSurfaceItems = Element.CircleSurfaceItems as ObservableCollection<ICircleSurfaceItem>;
- if (circleSurfaceItems != null)
- circleSurfaceItems.CollectionChanged -= OnCircleSurfaceItemsChanged;
+ void UpdateActionButton(bool init)
+ {
+ if (_actionButtonItem != null)
+ {
+ _actionButtonItem.PropertyChanged -= OnActionButtonItemChanged;
+ _actionButtonItem = null;
}
- if (_circlePage != null)
+ if (Element.ActionButton != null)
+ {
+ if (_actionButton == null)
+ {
+ InitializeActionButton();
+ }
+
+ UpdateActionButtonVisible(Element.ActionButton.IsVisible);
+ UpdateActionButtonText(Element.ActionButton.Text);
+ UpdateActionButtonIcon(Element.ActionButton.IconImageSource);
+ _actionButton.IsEnabled = Element.ActionButton.IsEnable;
+ _actionButton.BackgroundColor = Element.ActionButton.BackgroundColor.ToNative();
+
+ _actionButtonItem = Element.ActionButton;
+ _actionButtonItem.PropertyChanged += OnActionButtonItemChanged;
+ }
+ else
{
- _circlePage.Dispose(disposing);
+ if (_actionButton != null)
+ {
+ DeinitializeActionButton();
+ }
}
+ if (!init)
+ {
+ Device.BeginInvokeOnMainThread(() => OnLayout());
+ }
+ }
- base.Dispose(disposing);
+ void UpdateActionButtonVisible(bool visible)
+ {
+ if (_actionButton == null)
+ {
+ return;
+ }
+ if (visible) _actionButton.Show();
+ else _actionButton.Hide();
}
- void UpdateActionButton(bool initialize)
+ void UpdateActionButtonText(string text)
{
- _circlePage.UpdateActionButton(Element.ActionButton);
+ _actionButton.Text = text?.Replace("&", "&")
+ .Replace("<", "<")
+ .Replace(">", ">")
+ .Replace(Environment.NewLine, "<br>") ?? string.Empty;
}
- void OnToolbarItemChanged(object sender, NotifyCollectionChangedEventArgs e)
+ void UpdateActionButtonIcon(ImageSource source)
{
- _circlePage.SetVisibleMoreOption(Element.ToolbarItems.Count > 0);
- if (e.Action == NotifyCollectionChangedAction.Add ||
- e.Action == NotifyCollectionChangedAction.Replace)
+ if (source is FileImageSource filesource)
{
- foreach (XToolbarItem item in e.NewItems) _circlePage.AddToolbarItem(item);
+ var path = ResourcePath.GetPath(filesource);
+ var buttonImage = new ElmSharp.Image(_actionButton);
+ buttonImage.Load(path);
+ buttonImage.Show();
+ _actionButton.SetPartContent("elm.swallow.content", buttonImage);
}
- if (e.Action == NotifyCollectionChangedAction.Remove ||
- e.Action == NotifyCollectionChangedAction.Replace)
+ else
{
- foreach (XToolbarItem item in e.OldItems) _circlePage.RemoveToolbarITem(item);
+ _actionButton.SetPartContent("elm.swallow.content", null);
}
}
void OnPageDisappearing(object sender, EventArgs e)
{
- _circlePage.DeactivateRotaryWidget();
+ DeactivateRotaryWidget();
}
void OnPageAppearing(object sender, EventArgs e)
{
- _circlePage.ActivateRotaryWidget();
+ ActivateRotaryWidget();
+ }
+
+ void OnLayoutUpdated(object sender, LayoutEventArgs e)
+ {
+ OnLayout();
+ }
+
+ void OnLayout()
+ {
+ // Page layout was updated on base class
+ // It only update ActionButton
+
+ var content = (Element as IElementController).LogicalChildren.FirstOrDefault();
+ if (content == null)
+ return;
+
+ var topmostView = Platform.GetRenderer(content)?.NativeView;
+
+ var bound = Control.Geometry;
+
+ if (_actionButton != null)
+ {
+ var btnRect = _actionButton.Geometry;
+ var btnW = Math.Max(_actionButton.MinimumWidth, btnRect.Width);
+ var btnH = Math.Max(_actionButton.MinimumHeight, btnRect.Height);
+ var btnX = bound.X + (bound.Width - btnW) / 2;
+ var btnY = bound.Y + bound.Height - btnH;
+ _actionButton.Geometry = new Rect(btnX, btnY, btnW, btnH);
+ _actionButton.StackAbove(topmostView);
+ topmostView = _actionButton;
+ }
+
+ _surfaceLayout.Geometry = bound;
+ _surfaceLayout.StackAbove(topmostView);
+ }
+
+ void OnActionButtonClicked(object sender, EventArgs e)
+ {
+ if (Element.ActionButton != null)
+ {
+ ((IMenuItemController)Element.ActionButton).Activate();
+ }
+ }
+
+ void OnActionButtonItemChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (_actionButton == null)
+ {
+ return;
+ }
+ if (e.PropertyName == MenuItem.TextProperty.PropertyName)
+ {
+ UpdateActionButtonText(Element.ActionButton.Text);
+ }
+ else if (e.PropertyName == ActionButtonItem.IsEnableProperty.PropertyName)
+ {
+ _actionButton.IsEnabled = Element.ActionButton.IsEnable;
+ }
+ else if (e.PropertyName == ActionButtonItem.IsVisibleProperty.PropertyName)
+ {
+ UpdateActionButtonVisible(Element.ActionButton.IsVisible);
+ }
+ else if (e.PropertyName == ActionButtonItem.BackgroundColorProperty.PropertyName)
+ {
+ _actionButton.BackgroundColor = Element.ActionButton.BackgroundColor.ToNative();
+ }
+ else if (e.PropertyName == MenuItem.IconImageSourceProperty.PropertyName)
+ {
+ UpdateActionButtonIcon(Element.ActionButton.IconImageSource);
+ }
}
void OnCircleSurfaceItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
e.Action == NotifyCollectionChangedAction.Replace)
{
foreach (ICircleSurfaceItem item in e.NewItems)
- _circlePage.AddCircleSurfaceItem(item);
+ AddCircleSurfaceItem(item);
}
if (e.Action == NotifyCollectionChangedAction.Remove ||
e.Action == NotifyCollectionChangedAction.Replace)
{
foreach (ICircleSurfaceItem item in e.OldItems)
- _circlePage.RemoveCircleSurfaceItem(item);
+ RemoveCircleSurfaceItem(item);
+ }
+ }
+
+ void OnRotaryEventChanged(ElmSharp.Wearable.RotaryEventArgs e)
+ {
+ if (_currentRotaryFocusObject is IRotaryEventReceiver receiver)
+ {
+ receiver.Rotate(new RotaryEventArgs { IsClockwise = e.IsClockwise });
+ }
+ }
+
+ void AddCircleSurfaceItem(ICircleSurfaceItem item)
+ {
+ if (item is CircleProgressBarSurfaceItem progressbar)
+ {
+ _circleSurfaceItems[item] = new CircleProgressBarSurfaceItemImplements(progressbar, _surfaceLayout, CircleSurface);
+ }
+ else if (item is CircleSliderSurfaceItem slider)
+ {
+ _circleSurfaceItems[item] = new CircleSliderSurfaceItemImplements(slider, _surfaceLayout, CircleSurface);
+ }
+ }
+
+ void RemoveCircleSurfaceItem(ICircleSurfaceItem item)
+ {
+ if (_circleSurfaceItems.TryGetValue(item, out var widget))
+ {
+ (widget as EvasObject)?.Unrealize();
+ _circleSurfaceItems.Remove(item);
+ }
+ }
+
+ void ActivateRotaryWidget()
+ {
+ if (!Element.Appeared)
+ return;
+
+ if (_currentRotaryFocusObject is IRotaryEventReceiver)
+ {
+ ERotaryEventManager.Rotated += OnRotaryEventChanged;
+ }
+ else
+ {
+ GetRotaryWidget(_currentRotaryFocusObject)?.Activate();
+ }
+ AppSpecific.SetActiveBezelInteractionElement(Application.Current, base.Element);
+ }
+
+ void DeactivateRotaryWidget()
+ {
+ if (_currentRotaryFocusObject is IRotaryEventReceiver)
+ {
+ ERotaryEventManager.Rotated -= OnRotaryEventChanged;
+ }
+ else if (_currentRotaryFocusObject is IRotaryFocusable)
+ {
+ GetRotaryWidget(_currentRotaryFocusObject)?.Deactivate();
+ }
+ if (AppSpecific.GetActiveBezelInteractionElement(Application.Current) == base.Element)
+ AppSpecific.SetActiveBezelInteractionElement(Application.Current, null);
+ }
+
+ IRotaryActionWidget GetRotaryWidget(IRotaryFocusable focusable)
+ {
+ IRotaryActionWidget rotaryWidget = null;
+ if (focusable is BindableObject consumer)
+ {
+ if (consumer is ICircleSurfaceItem circleSurfaceItem)
+ {
+ rotaryWidget = GetCircleWidget(circleSurfaceItem) as IRotaryActionWidget;
+ }
+ else
+ {
+ rotaryWidget = Platform.GetRenderer(consumer)?.NativeView as IRotaryActionWidget;
+ }
+ }
+ return rotaryWidget;
+ }
+
+ ICircleWidget GetCircleWidget(ICircleSurfaceItem item)
+ {
+ if (_circleSurfaceItems.TryGetValue(item, out ICircleWidget widget))
+ {
+ return widget;
}
+ return null;
}
}
}
\ No newline at end of file
* limitations under the License.
*/
-using System;
-using System.ComponentModel;
-using System.Threading.Tasks;
-using ElmSharp;
-using ElmSharp.Wearable;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Tizen;
-using Xamarin.Forms.Platform.Tizen.Native;
-using ERect = ElmSharp.Rect;
using XForms = Xamarin.Forms.Forms;
+using WatchScroller = Xamarin.Forms.Platform.Tizen.Native.Watch.WatchScroller;
[assembly: ExportRenderer(typeof(Tizen.Wearable.CircularUI.Forms.CircleScrollView), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleScrollViewRenderer))]
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- public class CircleScrollViewRenderer : ViewRenderer<CircleScrollView, ElmSharp.Wearable.CircleScroller>
+ public class CircleScrollViewRenderer : ScrollViewRenderer
{
- Xamarin.Forms.Platform.Tizen.Native.Box _scrollCanvas;
- ElmSharp.SmartEvent _scrollAnimationStart, _scrollAnimationStop;
- bool _isAnimation;
- TaskCompletionSource<bool> _animationTaskComplateSource;
+ public CircleScrollView CircleElement => Element as CircleScrollView;
+ WatchScroller _scroller;
public CircleScrollViewRenderer()
{
RegisterPropertyHandler(CircleScrollView.BarColorProperty, UpdateBarColor);
- RegisterPropertyHandler("Content", OnContent);
}
- public override ERect GetNativeContentGeometry()
- {
- return _scrollCanvas.Geometry;
- }
-
- protected override void OnElementChanged(ElementChangedEventArgs<CircleScrollView> e)
- {
- if (Control == null)
- {
- var surface = this.GetSurface();
- SetNativeControl(NativeFactory.GetNativeControl(typeof(CircleScroller), surface) as CircleScroller);
- InitControl();
- Control.Scrolled += OnScrolled;
- _scrollCanvas = new Xamarin.Forms.Platform.Tizen.Native.Box(Control);
- _scrollCanvas.LayoutUpdated += OnContentLayoutUpdated;
- Control.SetContent(_scrollCanvas);
- }
- if (e.OldElement != null)
- {
- (e.OldElement as IScrollViewController).ScrollToRequested -= OnScrollRequestedAsync;
- }
- if (e.NewElement != null)
- {
- (e.NewElement as IScrollViewController).ScrollToRequested += OnScrollRequestedAsync;
- }
-
- UpdateAll();
-
- base.OnElementChanged(e);
- }
-
- protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (ScrollView.OrientationProperty.PropertyName == e.PropertyName)
- {
- UpdateOrientation();
- }
- else if (ScrollView.ContentSizeProperty.PropertyName == e.PropertyName)
- {
- UpdateContentSize();
- }
- else if (ScrollView.VerticalScrollBarVisibilityProperty.PropertyName == e.PropertyName)
- {
- UpdateVerticalScrollBarVisibility();
- }
- else if (ScrollView.HorizontalScrollBarVisibilityProperty.PropertyName == e.PropertyName)
- {
- UpdateHorizontalScrollBarVisibility();
- }
-
- base.OnElementPropertyChanged(sender, e);
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
+ protected override Xamarin.Forms.Platform.Tizen.Native.Scroller CreateNativeControl()
{
- if (null != Element)
- {
- (Element as IScrollViewController).ScrollToRequested -= OnScrollRequestedAsync;
- }
- if (Control != null)
- {
- Control.Scrolled -= OnScrolled;
- }
- if (_scrollCanvas != null)
- {
- _scrollCanvas.LayoutUpdated -= OnContentLayoutUpdated;
- }
- _scrollAnimationStart?.Dispose();
- _scrollAnimationStop?.Dispose();
- }
- base.Dispose(disposing);
- }
-
- void UpdateAll()
- {
- UpdateOrientation();
- UpdateVerticalScrollBarVisibility();
- UpdateHorizontalScrollBarVisibility();
- }
-
- void UpdateVerticalScrollBarVisibility()
- {
- var orientation = Element.Orientation;
- if (orientation == ScrollOrientation.Vertical || orientation == ScrollOrientation.Both)
- Control.VerticalScrollBarVisiblePolicy = ScrollBarVisibilityToTizen(Element.VerticalScrollBarVisibility);
- }
-
- void UpdateHorizontalScrollBarVisibility()
- {
- var orientation = Element.Orientation;
- if (orientation == ScrollOrientation.Horizontal || orientation == ScrollOrientation.Both)
- Control.HorizontalScrollBarVisiblePolicy = ScrollBarVisibilityToTizen(Element.HorizontalScrollBarVisibility);
+ return _scroller = new WatchScroller(XForms.NativeParent, this.GetSurface());
}
void UpdateBarColor()
{
- var color = Element.BarColor;
- if (color != Xamarin.Forms.Color.Default)
- {
- Control.VerticalScrollBarColor = color.ToNative();
- Control.HorizontalScrollBarColor = color.ToNative();
- }
- }
-
- ScrollBarVisiblePolicy ScrollBarVisibilityToTizen(ScrollBarVisibility visibility)
- {
- switch (visibility)
- {
- case ScrollBarVisibility.Always:
- return ScrollBarVisiblePolicy.Visible;
- case ScrollBarVisibility.Never:
- return ScrollBarVisiblePolicy.Invisible;
- default:
- return ScrollBarVisiblePolicy.Auto;
- }
- }
-
- async void OnScrollRequestedAsync(object sender, ScrollToRequestedEventArgs e)
- {
- var x = e.ScrollX;
- var y = e.ScrollY;
- if (e.Mode == ScrollToMode.Element)
- {
- var itemPosition = (Element as IScrollViewController).GetScrollPositionForElement(e.Element as VisualElement, e.Position);
- x = itemPosition.X;
- y = itemPosition.Y;
- }
- var region = new Xamarin.Forms.Rectangle(x, y, Element.Width, Element.Height).ToPixel();
- await ScrollToAsync(region, e.ShouldAnimate).ConfigureAwait(false);
- Element.SendScrollFinished();
- }
-
- void OnScrolled(object sender, EventArgs e)
- {
- var region = Control.CurrentRegion.ToDP();
- ((IScrollViewController)Element).SetScrolledPosition(region.X, region.Y);
- }
-
- void OnContent()
- {
- _scrollCanvas.UnPackAll();
- if (Element.Content != null)
- {
- _scrollCanvas.PackEnd(Platform.GetOrCreateRenderer(Element.Content).NativeView);
- UpdateContentSize();
- }
- }
-
- void UpdateContentSize()
- {
- _scrollCanvas.MinimumWidth = XForms.ConvertToScaledPixel(Element.ContentSize.Width + Element.Padding.HorizontalThickness);
- _scrollCanvas.MinimumHeight = XForms.ConvertToScaledPixel(Element.ContentSize.Height + Element.Padding.VerticalThickness);
-
- Device.BeginInvokeOnMainThread(() =>
- {
- if (Control != null)
- {
- OnScrolled(Control, EventArgs.Empty);
- }
- });
- }
-
- void OnContentLayoutUpdated(object sender, LayoutEventArgs e)
- {
- UpdateContentSize();
- }
-
- void UpdateOrientation()
- {
- switch (Element.Orientation)
- {
- case ScrollOrientation.Horizontal:
- Control.ScrollBlock = ElmSharp.ScrollBlock.Vertical;
- Control.HorizontalScrollBarVisiblePolicy = ElmSharp.ScrollBarVisiblePolicy.Auto;
- Control.VerticalScrollBarVisiblePolicy = ElmSharp.ScrollBarVisiblePolicy.Invisible;
- break;
- case ScrollOrientation.Vertical:
- Control.ScrollBlock = ElmSharp.ScrollBlock.Horizontal;
- Control.HorizontalScrollBarVisiblePolicy = ElmSharp.ScrollBarVisiblePolicy.Invisible;
- Control.VerticalScrollBarVisiblePolicy = ElmSharp.ScrollBarVisiblePolicy.Auto;
- break;
- case ScrollOrientation.Both:
- Control.ScrollBlock = ElmSharp.ScrollBlock.None;
- Control.HorizontalScrollBarVisiblePolicy = ElmSharp.ScrollBarVisiblePolicy.Auto;
- Control.VerticalScrollBarVisiblePolicy = ElmSharp.ScrollBarVisiblePolicy.Auto;
- break;
- default:
- throw new InvalidOperationException("Not supported orientation.");
- }
- }
-
- void InitControl()
- {
- _scrollAnimationStart = new ElmSharp.SmartEvent(Control, Control.RealHandle, "scroll,anim,start");
- _scrollAnimationStop = new ElmSharp.SmartEvent(Control, Control.RealHandle, "scroll,anim,stop");
- _scrollAnimationStart.On += (s, e) => _isAnimation = true;
- _scrollAnimationStop.On += (s, e) =>
- {
- if (_animationTaskComplateSource != null)
- {
- _animationTaskComplateSource.TrySetResult(true);
- }
- _isAnimation = false;
- };
- }
-
- Task ScrollToAsync(Rect region, bool shouldAnimate)
- {
- CheckTaskCompletionSource();
- Control.ScrollTo(region, shouldAnimate);
- return shouldAnimate && _isAnimation ? _animationTaskComplateSource.Task : Task.CompletedTask;
- }
-
- void CheckTaskCompletionSource()
- {
- if (_animationTaskComplateSource != null)
+ var color = CircleElement.BarColor;
+ if (!color.IsDefault)
{
- if (_animationTaskComplateSource.Task.Status == TaskStatus.Running)
- {
- _animationTaskComplateSource.TrySetCanceled();
- }
+ _scroller.CircleScroller.VerticalScrollBarColor = color.ToNative();
+ _scroller.CircleScroller.HorizontalScrollBarColor = color.ToNative();
}
- _animationTaskComplateSource = new TaskCompletionSource<bool>();
}
}
}
\ No newline at end of file
*/
using System;
-using ESpinner = ElmSharp.Wearable.CircleSpinner;
-using ESize = ElmSharp.Size;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Tizen;
+using Xamarin.Forms.Platform.Tizen.Native.Watch;
+using ESize = ElmSharp.Size;
using XForms = Xamarin.Forms.Forms;
[assembly: ExportRenderer(typeof(Tizen.Wearable.CircularUI.Forms.CircleStepper), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleStepperRenderer))]
-
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- public class CircleStepperRenderer : ViewRenderer<CircleStepper, ESpinner>
+ public class CircleStepperRenderer : StepperRenderer
{
public CircleStepperRenderer()
{
#pragma warning restore CS0618 // MarkerColorProperty and MarkerLineWidthProperty are obsolete
RegisterPropertyHandler(CircleStepper.LabelFormatProperty, UpdateLabelFormat);
RegisterPropertyHandler(CircleStepper.TitleProperty, UpdateTitle);
- RegisterPropertyHandler(Stepper.MinimumProperty, UpdateMinimum);
- RegisterPropertyHandler(Stepper.MaximumProperty, UpdateMaximum);
- RegisterPropertyHandler(Stepper.ValueProperty, UpdateValue);
- RegisterPropertyHandler(Stepper.IncrementProperty, UpdateIncrement);
RegisterPropertyHandler(CircleStepper.IsWrapEnabledProperty, UpdateWrapEnabled);
}
- protected override void OnElementChanged(ElementChangedEventArgs<CircleStepper> e)
- {
- if (Control == null)
- {
- var surface = this.GetSurface();
- if (null != surface)
- {
- var spinner = new ESpinner(XForms.NativeParent, surface);
- spinner.Style = "circle";
+ protected new WatchSpinner Control => base.Control as WatchSpinner;
- SetNativeControl(spinner);
- Control.ValueChanged += OnValueChanged;
- }
- else
- {
- throw new CirclePageNotFoundException();
- }
- }
+ protected new CircleStepper Element => base.Element as CircleStepper;
- base.OnElementChanged(e);
+ protected override ElmSharp.Spinner CreateNativeControl()
+ {
+ return new WatchSpinner(XForms.NativeParent, this.GetSurface());
}
- private void OnValueChanged(object sender, EventArgs e)
- {
- double newValue = Control.Value;
- ((IElementController)Element).SetValueFromRenderer(Stepper.ValueProperty, newValue);
+ protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
+ {
+ base.OnElementChanged(e);
- if (Element.LabelFormat == null)
- {
- // Determines how many decimal places are there in current Stepper's value.
- // The 15 pound characters below correspond to the maximum precision of Double type.
- var decimalValue = Decimal.Parse(newValue.ToString("0.###############"));
-
- // GetBits() method returns an array of four 32-bit integer values.
- // The third (0-indexing) element of an array contains the following information:
- // bits 00-15: unused, required to be 0
- // bits 16-23: an exponent between 0 and 28 indicating the power of 10 to divide the integer number passed as a parameter.
- // Conversely this is the number of decimal digits in the number as well.
- // bits 24-30: unused, required to be 0
- // bit 31: indicates the sign. 0 means positive number, 1 is for negative numbers.
- //
- // The precision information needs to be extracted from bits 16-23 of third element of an array
- // returned by GetBits() call. Right-shifting by 16 bits followed by zeroing anything else results
- // in a nice conversion of this data to integer variable.
- var precision = (Decimal.GetBits(decimalValue)[3] >> 16) & 0x000000FF;
-
- // Sets Stepper's inner label decimal format to use exactly as many decimal places as needed:
- Control.LabelFormat = string.Format("%.{0}f", precision);
- }
+ Control.WheelAppeared += OnListShow;
+ Control.WheelDisappeared += OnListHide;
}
protected override void Dispose(bool disposing)
return new ESize(360, 110);
}
+ void OnListShow(object sender, EventArgs args)
+ {
+ Element.SendWheelAppeared();
+ }
+
+ void OnListHide(object sender, EventArgs args)
+ {
+ Element.SendWheelDisappeared();
+ }
+
void UpdateMarkerColor()
{
#pragma warning disable CS0618 // MarkerColor is obsolete
- if (null != Control && null != Element && Element.MarkerColor != Color.Default)
+ if (Element.MarkerColor != Color.Default)
{
Control.MarkerColor = Element.MarkerColor.ToNative();
}
void UpdateMarkerLineWidth()
{
- if (null != Control && null != Element)
- {
#pragma warning disable CS0618 // MarkerLineWidth is obsolete
Control.MarkerLineWidth = Element.MarkerLineWidth;
#pragma warning restore CS0618 // MarkerLineWidth is obsolete
}
- }
void UpdateLabelFormat()
{
- if (null != Control && null != Element)
- {
Control.LabelFormat = Element.LabelFormat;
}
- }
void UpdateTitle()
{
- if (null != Control && null != Element)
- {
Control.SetPartText("elm.text", Element.Title);
}
- }
-
- void UpdateValue()
- {
- if (null != Control && null != Element)
- {
- Control.Value = Element.Value;
- }
- }
-
- void UpdateMaximum()
- {
- if (null != Control && null != Element)
- {
- Control.Maximum = Element.Maximum;
- }
- }
-
- void UpdateMinimum()
- {
- if (null != Control && null != Element)
- {
- Control.Minimum = Element.Minimum;
- }
- }
void UpdateIncrement()
{
- if (null != Control && null != Element)
- {
Control.Step = Element.Increment;
}
- }
void UpdateWrapEnabled()
{
- if (null != Control && null != Element)
- {
Control.IsWrapEnabled = Element.IsWrapEnabled;
}
}
- }
-}
\ No newline at end of file
+ }
\ No newline at end of file
[assembly: ExportRenderer(typeof(CircleSurfaceView), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleSurfaceViewRenderer))]
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- public class CircleSurfaceViewRenderer : ViewRenderer<CircleSurfaceView, Box>
+ public class CircleSurfaceViewRenderer : ViewRenderer<CircleSurfaceView, Box>, ICircleSurfaceItemRenderer
{
-
Dictionary<ICircleSurfaceItem, ICircleWidget> _circleSurfaceItems;
ELayout _surfaceLayout;
CircleSurface _circleSurface;
+ ICircleWidget ICircleSurfaceItemRenderer.GetCircleWidget(ICircleSurfaceItem item)
+ {
+ if (_circleSurfaceItems.TryGetValue(item, out ICircleWidget widget))
+ {
+ return widget;
+ }
+ return null;
+ }
+
protected override void OnElementChanged(ElementChangedEventArgs<CircleSurfaceView> e)
{
if (Control == null)
using System.Diagnostics;
using Tizen.Applications;
using Tizen.Wearable.CircularUI.Forms.Renderer;
+using Tizen.Wearable.CircularUI.Forms.Renderer.Shell;
namespace Tizen.Wearable.CircularUI.Forms
{
{
if (IsInitialized) return;
IsInitialized = true;
+ CircularShellRendererFactory.Setup();
}
public static void Init(string apiKey)
{ typeof(CircleScrollView), () => new CircleScrollViewRenderer() },
{ typeof(CircleStepper), () => new CircleStepperRenderer() },
{ typeof(CircleSurfaceView), () => new CircleSurfaceViewRenderer() },
- { typeof(CircularShell), () => new ShellRenderer() },
+ { typeof(CircularShell), () => new CircularShellRenderer() },
{ typeof(ContentButton), () => new ContentButtonRenderer() },
{ typeof(GoogleMapView), () => new GoogleMapViewRenderer() },
{ typeof(IndexPage), () => new IndexPageRenderer() },
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Xamarin.Forms;
+using XStructuredItemsViewRenderer = Xamarin.Forms.Platform.Tizen.StructuredItemsViewRenderer;
+using CStructuredItemsViewRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.StructuredItemsViewRenderer;
+
+using XCarouselViewRenderer = Xamarin.Forms.Platform.Tizen.CarouselViewRenderer;
+using CCarouselViewRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.CarouselViewRenderer;
+
+
+[assembly: ExportRenderer(typeof(StructuredItemsView), typeof(CStructuredItemsViewRenderer))]
+[assembly: ExportRenderer(typeof(CarouselView), typeof(CCarouselViewRenderer))]
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class StructuredItemsViewRenderer : XStructuredItemsViewRenderer
+ {
+ protected override void UpdateRotaryInteraction(bool enable)
+ {
+ if (Element.FindBezelRouter() == null)
+ {
+ base.UpdateRotaryInteraction(enable);
+ }
+ }
+ }
+
+ public class CarouselViewRenderer : XCarouselViewRenderer
+ {
+ protected override void UpdateRotaryInteraction(bool enable)
+ {
+ if (Element.FindBezelRouter() == null)
+ {
+ base.UpdateRotaryInteraction(enable);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using Xamarin.Forms;
+
+using XDatePickerRenderer = Xamarin.Forms.Platform.Tizen.DatePickerRenderer;
+using CDatePickerRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.DatePickerRenderer;
+using System;
+
+[assembly: ExportRenderer(typeof(DatePicker), typeof(CDatePickerRenderer))]
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class DatePickerRenderer : XDatePickerRenderer
+ {
+ protected override void OnPickerOpened(object sender, EventArgs args)
+ {
+ Element.FindBezelController()?.Deactivate();
+ base.OnPickerOpened(sender, args);
+ }
+
+ protected override void OnPickerClosed(object sender, EventArgs args)
+ {
+ base.OnPickerClosed(sender, args);
+ Element.FindBezelController()?.Activate();
+ }
+ }
+}
\ No newline at end of file
*/
using System;
-using SCObjectModel = System.Collections.ObjectModel;
+using OModel = System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Text;
using Tizen.Wearable.CircularUI.Forms;
if (e.OldElement != null)
{
- ((SCObjectModel.ObservableCollection<Marker>)e.OldElement.Markers).CollectionChanged -= OnCollectionChanged;
+ ((OModel.ObservableCollection<Marker>)e.OldElement.Markers).CollectionChanged -= OnCollectionChanged;
e.OldElement.LoadMapRequested -= OnLoadMapRequested;
}
if (e.NewElement != null)
{
- ((SCObjectModel.ObservableCollection<Marker>)e.NewElement.Markers).CollectionChanged += OnCollectionChanged;
+ ((OModel.ObservableCollection<Marker>)e.NewElement.Markers).CollectionChanged += OnCollectionChanged;
e.NewElement.LoadMapRequested += OnLoadMapRequested;
LoadMap();
}
}
if (Element != null)
{
- ((SCObjectModel.ObservableCollection<Marker>)Element.Markers).CollectionChanged -= OnCollectionChanged;
+ ((OModel.ObservableCollection<Marker>)Element.Markers).CollectionChanged -= OnCollectionChanged;
Element.LoadMapRequested -= OnLoadMapRequested;
}
}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public interface IBezelInteractionController
+ {
+ IRotaryFocusable RotaryFocusObject { get; }
+
+ void Activate();
+ void Deactivate();
+ }
+}
\ No newline at end of file
--- /dev/null
+using ElmSharp.Wearable;
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ interface ICircleSurfaceItemRenderer
+ {
+ ICircleWidget GetCircleWidget(ICircleSurfaceItem item);
+ }
+}
\ No newline at end of file
(nativeView as ElmSharp.Widget)?.AllowFocus(true);
index++;
}
- _innerContainer.MinimumWidth = Element.Children.Count * bound.Width;
- if (_scroller.HorizontalPageIndex != _pageIndex)
+ var widthRequest = Element.Children.Count * bound.Width;
+ _innerContainer.MinimumWidth = widthRequest;
+ if (_innerContainer.Geometry.Width == widthRequest && _scroller.HorizontalPageIndex != _pageIndex)
{
_scroller.ScrollTo(_pageIndex, 0, false);
}
}
_pageIndex = Element.Children.IndexOf(Element.CurrentPage);
_isUpdateCarousel = true;
+ Element.UpdateFocusTreePolicy();
_scroller.ScrollTo(_pageIndex, 0, false);
- Element.UpdateFocusTreePolicy();
_isUpdateCarousel = false;
}
_bottomButton.Clicked += (s, e) =>
{
- ((IMenuItemController)BottomButton).Activate();
+ (BottomButton as IMenuItemController)?.Activate();
};
if (_buttonBgColor != Color.Default)
}
else
{
- _bottomButton.Unrealize();
+ _bottomButton?.Unrealize();
_bottomButton = null;
}
using System;
using ElmSharp;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
+using OModel = System.Collections.ObjectModel;
using System.Collections.Specialized;
-using TNative = Xamarin.Forms.Platform.Tizen.Native;
+using Xamarin.Forms.Platform.Tizen.Native;
namespace Tizen.Wearable.CircularUI.Forms
{
- public class LayoutCanvas : ElmSharp.Layout, TNative.IContainable<EvasObject>
+ public class LayoutCanvas : ElmSharp.Layout, IContainable<EvasObject>
{
/// <summary>
/// The list of Views.
/// </summary>
- readonly ObservableCollection<EvasObject> _children = new ObservableCollection<EvasObject>();
+ readonly OModel.ObservableCollection<EvasObject> _children = new OModel.ObservableCollection<EvasObject>();
Xamarin.Forms.Platform.Tizen.Native.Box _box;
};
}
- public event EventHandler<TNative.LayoutEventArgs> LayoutUpdated
+ public event EventHandler<LayoutEventArgs> LayoutUpdated
{
add { _box.LayoutUpdated += value; }
remove { _box.LayoutUpdated -= value; }
+++ /dev/null
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ElmSharp;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.Tizen;
-using XForms = Xamarin.Forms.Forms;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public static class ListViewCache
- {
- static readonly Dictionary<Type, CellRenderer> _cellRendererCache = new Dictionary<Type, CellRenderer>();
- static GenItemClass _informalItemClass;
- static GenItemClass _informalItemClassWithoutFishEye;
- static GenItemClass _paddingItemClass;
- static GroupTextCellRenderer _groupCache;
-
- public static CellRenderer Get(Cell cell, bool IsGroupHeader)
- {
- if (IsGroupHeader)
- {
- if (_groupCache == null)
- {
- _groupCache = new GroupTextCellRenderer();
- }
- return _groupCache;
- }
-
- Type type = cell.GetType();
- CellRenderer renderer;
- if (_cellRendererCache.TryGetValue(type, out renderer))
- {
- return renderer;
- }
- else
- {
- renderer = XForms.GetHandler<CellRenderer>(type);
- if (renderer == null)
- {
- throw new ArgumentNullException("Unsupported cell type");
- }
- return _cellRendererCache[type] = renderer;
- }
- }
- public static CellRenderer Get(Cell cell) => Get(cell, false);
-
- public static GenItemClass InformalItemClass => _informalItemClass ?? (_informalItemClass = new HeaderOrFooterItemClass());
- public static GenItemClass PaddingItemClass => _paddingItemClass ?? (_paddingItemClass = new PaddingItemClass());
- public static GenItemClass InformalItemClassWithoutFishEye => _informalItemClassWithoutFishEye ?? (_informalItemClassWithoutFishEye = new HeaderOrFooterItemClass(false));
- }
-
- public class HeaderOrFooterItemClass : GenItemClass
- {
- static int ToPx(double dp)
- {
- return (int)Math.Round(dp * Device.Info.ScalingFactor);
- }
- public HeaderOrFooterItemClass(bool fishEye) : base(fishEye ? "full" : "full_off")
- {
- GetContentHandler = OnGetContent;
- }
-
- public HeaderOrFooterItemClass() : this(true)
- {
- }
-
- protected EvasObject OnGetContent(object data, string part)
- {
- var ctx = data as TypedItemContext;
- if (ctx != null)
- {
- var element = ctx.Element;
- var renderer = Platform.GetOrCreateRenderer(element);
- if (element.MinimumHeightRequest == -1)
- {
- var request = element.Measure(double.PositiveInfinity, double.PositiveInfinity);
- renderer.NativeView.MinimumHeight = ToPx(request.Request.Height);
- }
- else
- {
- renderer.NativeView.MinimumHeight = ToPx(element.MinimumHeightRequest);
- }
- (renderer as LayoutRenderer)?.RegisterOnLayoutUpdated();
- return renderer.NativeView;
- }
- return null;
- }
- }
-
- public class PaddingItemClass : GenItemClass
- {
- public PaddingItemClass() : base("padding")
- {
- }
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Xamarin.Forms;
+using XListViewRenderer = Xamarin.Forms.Platform.Tizen.ListViewRenderer;
+using CListViewRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.ListViewRenderer;
+
+[assembly: ExportRenderer(typeof(ListView), typeof(CListViewRenderer))]
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class ListViewRenderer : XListViewRenderer
+ {
+ protected override void UpdateRotaryInteraction(bool enable)
+ {
+ if (Element.FindBezelRouter() == null)
+ {
+ base.UpdateRotaryInteraction(enable);
+ }
+ }
+ }
+}
\ No newline at end of file
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- public class NativeCirclePage : ObservableBox
+ class NativeCirclePage : ObservableBox
{
ElmSharp.Rectangle _bgColorObject;
ElmSharp.EvasImage _bgImageObject;
public void ActivateRotaryWidget()
{
+ CirclePage cp = _element as CirclePage;
+ if (!cp.Appeared)
+ return;
+
if (_currentRotaryFocusObject is IRotaryEventReceiver)
{
ERotaryEventManager.Rotated += OnRotaryEventChanged;
page.Hide();
circlePages.Add(page);
- var listview = new CircleListView(window, page.Surface);
- listview.Hide();
- circleListviews.Add(page.Surface, listview);
+ //var listview = new CircleListView(window, page.Surface);
+ //listview.Hide();
+ //circleListviews.Add(page.Surface, listview);
var scroller = new CircleScroller(window, page.Surface);
scroller.Hide();
}
else if (type == typeof(CircleListView))
{
- if (circleListviews.ContainsKey(surface))
- {
- var listview = circleListviews[surface];
- if (listview != null)
- {
- circleListviews.Remove(surface);
- return listview;
- }
- }
- return new CircleListView(XForms.NativeParent, surface);
+ //if (circleListviews.ContainsKey(surface))
+ //{
+ // var listview = circleListviews[surface];
+ // if (listview != null)
+ // {
+ // circleListviews.Remove(surface);
+ // return listview;
+ // }
+ //}
+ //return new CircleListView(XForms.NativeParent, surface);
}
else if (type == typeof(CircleScroller))
{
}
circlePages.Clear();
- foreach (var item in circleListviews)
- {
- item.Value.Unrealize();
- }
- circleListviews.Clear();
+ //foreach (var item in circleListviews)
+ //{
+ // item.Value.Unrealize();
+ //}
+ //circleListviews.Clear();
foreach (var item in circleScrollers)
{
using System.Collections.Generic;
using System.Collections.Specialized;
using ElmSharp;
-using Tizen.Wearable.CircularUI.Forms;
-using Xamarin.Forms;
using Xamarin.Forms.Platform.Tizen.Native;
-[assembly: ExportRenderer(typeof(CirclePage), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CirclePageRenderer))]
-
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- public class ObservableBox : ElmSharp.Box, IContainable<EvasObject>
+ class ObservableBox : ElmSharp.Box, IContainable<EvasObject>
{
ReObservableCollection<EvasObject> _children;
public ObservableBox(EvasObject parent) : base(parent)
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Tizen;
+using Xamarin.Forms.Platform.Tizen.Native.Watch;
+using XPageRenderer = Xamarin.Forms.Platform.Tizen.PageRenderer;
+using CPageRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.PageRenderer;
+
+[assembly: ExportRenderer(typeof(Page), typeof(CPageRenderer))]
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class PageRenderer : XPageRenderer
+ {
+ protected override FormsMoreOptionItem CreateMoreOptionItem(ToolbarItem item)
+ {
+ var moreOptionItem = base.CreateMoreOptionItem(item);
+ if (item is CircleToolbarItem circleToolbarItem)
+ {
+ moreOptionItem.SubText = circleToolbarItem.SubText;
+ }
+ return moreOptionItem;
+ }
+ }
+}
\ No newline at end of file
{
CreatePopup();
}
+
_editor.IsPassword = Control.IsPassword;
if (Control is IEntry ie)
{
using XForms = Xamarin.Forms.Forms;
[assembly: ExportRenderer(typeof(Radio), typeof(RadioRenderer))]
+
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
+
public class RadioRenderer : ViewRenderer<Radio, ERadio>
{
static Lazy<RadioGroupManager> s_GroupManager = new Lazy<RadioGroupManager>();
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Xamarin.Forms;
+using XScrollViewRenderer = Xamarin.Forms.Platform.Tizen.ScrollViewRenderer;
+using CScrollViewRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.ScrollViewRenderer;
+
+[assembly: ExportRenderer(typeof(ScrollView), typeof(CScrollViewRenderer))]
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class ScrollViewRenderer : XScrollViewRenderer
+ {
+ protected override void UpdateRotaryInteraction(bool enable)
+ {
+ if (Element.FindBezelRouter() == null)
+ {
+ base.UpdateRotaryInteraction(enable);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using ElmSharp;
+using System;
+using System.Linq;
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Tizen;
+using XShell = Xamarin.Forms.Shell;
+using NavigationDrawer = Xamarin.Forms.Platform.Tizen.Watch.NavigationDrawer;
+using NavigationView = Xamarin.Forms.Platform.Tizen.Watch.NavigationView;
+
+[assembly: ExportRenderer(typeof(XShell), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircularShellRenderer))]
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class CircularShellRenderer : Xamarin.Forms.Platform.Tizen.Watch.ShellRenderer
+ {
+
+ NavigationDrawer _drawer;
+ NavigationView _navigationView;
+
+ public CircularShellRenderer()
+ {
+ RegisterPropertyHandler(CircularShell.FlyoutIconBackgroundColorProperty, UpdateFlyoutIconBackgroundColor);
+ RegisterPropertyHandler(CircularShell.FlyoutForegroundColorProperty, UpdateFlyoutForegroundColor);
+ }
+
+ protected override NavigationDrawer CreateNavigationDrawer(EvasObject parent)
+ {
+ return _drawer = base.CreateNavigationDrawer(parent);
+ }
+
+ protected override NavigationView CreateNavigationView(EvasObject parent)
+ {
+ return _navigationView = base.CreateNavigationView(parent);
+ }
+
+ protected override void OnNavigationDrawerToggled(object sender, EventArgs e)
+ {
+ base.OnNavigationDrawerToggled(sender, e);
+ if (!Element.FlyoutIsPresented)
+ {
+ var currentPage = GetCurrentPage(Element);
+
+ if (currentPage != null)
+ {
+ var renderer = Platform.GetOrCreateRenderer(currentPage);
+ (renderer as IBezelInteractionController)?.Activate();
+ }
+ }
+ }
+
+ void UpdateFlyoutIconBackgroundColor()
+ {
+ _drawer.HandlerBackgroundColor = CircularShell.GetFlyoutIconBackgroundColor(Element).ToNative();
+ }
+
+ void UpdateFlyoutForegroundColor(bool init)
+ {
+ if (init && CircularShell.GetFlyoutForegroundColor(Element).IsDefault)
+ return;
+
+ if (_navigationView != null)
+ {
+ _navigationView.ForegroundColor = CircularShell.GetFlyoutForegroundColor(Element).ToNative();
+ }
+ }
+
+ static Page GetCurrentPage(XShell shell)
+ {
+ var stack = (shell.CurrentItem.CurrentItem as ShellSection)?.Stack;
+ var currentPage = stack?.LastOrDefault<Page>();
+
+ if (currentPage == null)
+ {
+ currentPage = (shell.CurrentItem.CurrentItem.CurrentItem as IShellContentController)?.Page;
+ }
+ return currentPage;
+ }
+ }
+}
--- /dev/null
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Tizen.Watch;
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer.Shell
+{
+ class CircularShellRendererFactory : ShellRendererFactory
+ {
+ public static void Setup()
+ {
+ Default = new CircularShellRendererFactory();
+ }
+
+ public override IShellItemRenderer CreateItemRenderer(ShellSection item)
+ {
+ if (item.Items.Count == 1)
+ {
+ return CreateItemRenderer(item.CurrentItem);
+ }
+ return new CircularShellSectionItemsRenderer(item);
+ }
+ }
+}
--- /dev/null
+using System.Linq;
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Tizen;
+using Xamarin.Forms.Platform.Tizen.Watch;
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer.Shell
+{
+ public class CircularShellSectionItemsRenderer : ShellSectionItemsRenderer
+ {
+ public CircularShellSectionItemsRenderer(ShellSection section) : base(section)
+ {
+ }
+
+ protected override bool OnRotated(bool isClockwise)
+ {
+ var currentPage = GetCurrentPage(ShellSection);
+ if (currentPage is IBezelInteractionRouter)
+ {
+ var renderer = Platform.GetOrCreateRenderer(currentPage);
+ if (renderer is IBezelInteractionController bezelController)
+ {
+ bezelController.Activate();
+ return false;
+ }
+ }
+ return base.OnRotated(isClockwise);
+ }
+
+ Page GetCurrentPage(ShellSection section)
+ {
+ return section?.Stack?.LastOrDefault<Page>() ?? (section?.CurrentItem as IShellContentController)?.Page;
+ }
+ }
+}
+++ /dev/null
-using System;
-using ElmSharp;
-using Xamarin.Forms;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public interface IShellItemRenderer : IDisposable
- {
- BaseShellItem Item { get; }
- EvasObject NativeView { get; }
- }
-}
\ No newline at end of file
+++ /dev/null
-using ElmSharp;
-using ElmSharp.Wearable;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.Tizen;
-using EColor = ElmSharp.Color;
-using EImage = ElmSharp.Image;
-using ELayout = ElmSharp.Layout;
-using EWidget = ElmSharp.Widget;
-using EButton = ElmSharp.Button;
-using ERotaryEventManager = ElmSharp.Wearable.RotaryEventManager;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public class NavigationDrawer : ELayout, IAnimatable
- {
- static readonly int TouchWidth = 50;
- static readonly int IconSize = 40;
- static readonly string DefaultIcon = "Tizen.Wearable.CircularUI.Forms.Renderer.res.wc_visual_cue.png";
-
- Box _mainLayout;
- Box _contentGestureBox;
- Box _contentBox;
- Box _drawerBox;
- Box _drawerContentBox;
- Box _drawerIconBox;
-
- EvasObject _content;
- EvasObject _drawerContent;
-
- EImage _drawerIcon;
- EButton _touchArea;
-
- GestureLayer _gestureOnContent;
- GestureLayer _gestureOnDrawer;
-
- ImageSource _drawerIconSource;
-
- bool _isOpen;
- bool _isDefaultIcon;
-
- CancellationTokenSource _fadeInCancelTokenSource = null;
-
- bool HasDrawer => _drawerBox != null;
-
- public NavigationDrawer(EvasObject parent) : base(parent)
- {
- Initialize();
- }
-
- public int HandlerHeight { get; set; } = 40;
-
- public bool IsOpen
- {
- get
- {
- return _isOpen;
- }
- set
- {
- if (_isOpen != value)
- {
- if (value)
- {
- Open();
- }
- else
- {
- Close();
- }
- }
- }
- }
-
- EColor _handlerBackgroundColor = EColor.Transparent;
- public EColor HandlerBackgroundColor
- {
- get => _handlerBackgroundColor;
- set
- {
- _handlerBackgroundColor = value;
- UpdateHandlerBackgroundColor();
- }
- }
-
- public event EventHandler Toggled;
-
- public void SetMainContent(EvasObject content)
- {
- if (content == null)
- {
- UnsetMainContent();
- return;
- }
-
- _content = content;
- _content.Show();
- _contentBox.PackEnd(_content);
- _content.Geometry = _contentBox.Geometry;
- }
-
- public void SetDrawerContent(EvasObject content)
- {
- InitializeDrawerBox();
-
- if (content == null)
- {
- UnsetDrawerContent();
- return;
- }
-
- _drawerContent = content;
- _drawerContent.Show();
- _drawerContentBox.PackEnd(_drawerContent);
-
- _drawerContentBox.Show();
- _drawerIconBox.Show();
-
- if (_drawerContent is NavigationView nv)
- {
- nv.Dragged += (s, e) =>
- {
- if (e.State == DraggedState.EdgeTop)
- {
- Close();
- }
- };
- }
- }
-
- public void UpdateDrawerIcon(ImageSource source)
- {
- _drawerIconSource = source;
- if (HasDrawer)
- {
- SetDrawerIcon(_drawerIconSource);
- }
- }
-
- public async void Open(uint length = 300)
- {
- if (!HasDrawer)
- return;
-
- var toMove = _drawerBox.Geometry;
- toMove.Y = 0;
-
- await RunMoveAnimation(_drawerBox, toMove, length);
-
- if (!_isOpen)
- {
- _isOpen = true;
- Toggled?.Invoke(this, EventArgs.Empty);
- }
- OnLayout();
- OnDrawerLayout();
- FlipIcon();
- }
-
- public async void Close(uint length = 300)
- {
- if (!HasDrawer)
- return;
-
- var toMove = _drawerBox.Geometry;
- toMove.Y = Geometry.Height - HandlerHeight;
-
- await RunMoveAnimation(_drawerBox, toMove, length);
-
- if (_isOpen)
- {
- _isOpen = false;
- Toggled?.Invoke(this, EventArgs.Empty);
- }
- OnLayout();
- OnDrawerLayout();
- ResetIcon();
- StartHighlightAnimation(_drawerIcon);
- }
-
- void IAnimatable.BatchBegin()
- {
- }
-
- void IAnimatable.BatchCommit()
- {
- }
-
- protected override IntPtr CreateHandle(EvasObject parent)
- {
- _mainLayout = new Box(parent);
- return _mainLayout.Handle;
- }
-
- void Initialize()
- {
- _mainLayout.SetLayoutCallback(OnLayout);
-
- _contentGestureBox = new Box(_mainLayout);
- _contentGestureBox.Show();
- _mainLayout.PackEnd(_contentGestureBox);
-
- _contentBox = new Box(_mainLayout);
- _contentBox.SetLayoutCallback(OnContentLayout);
- _contentBox.Show();
- _mainLayout.PackEnd(_contentBox);
- }
-
- void InitializeDrawerBox()
- {
- if (_drawerBox != null)
- return;
-
- _drawerBox = new Box(_mainLayout);
- _drawerBox.SetLayoutCallback(OnDrawerLayout);
- _drawerBox.Show();
- _mainLayout.PackEnd(_drawerBox);
-
- _drawerContentBox = new Box(_drawerBox);
- _drawerBox.PackEnd(_drawerContentBox);
-
- _drawerIconBox = new Box(_drawerBox)
- {
- BackgroundColor = _handlerBackgroundColor
- };
- _drawerBox.PackEnd(_drawerIconBox);
-
- _drawerIcon = new EImage(_drawerIconBox)
- {
- AlignmentY = 0.5,
- AlignmentX = 0.5,
- MinimumHeight = IconSize,
- MinimumWidth = IconSize,
- };
- _drawerIcon.Show();
- _drawerIconBox.PackEnd(_drawerIcon);
- SetDrawerIcon(_drawerIconSource);
-
- _touchArea = new EButton(_drawerBox)
- {
- Color = EColor.Transparent,
- BackgroundColor = EColor.Transparent,
- };
- _touchArea.SetPartColor("effect", EColor.Transparent);
- _touchArea.Show();
- _touchArea.RepeatEvents = true;
- _touchArea.Clicked += OnIconClicked;
-
- _drawerBox.PackEnd(_touchArea);
-
- _gestureOnContent = new GestureLayer(_contentGestureBox);
- _gestureOnContent.SetMomentumCallback(GestureLayer.GestureState.Start, OnContentDragStarted);
- _gestureOnContent.SetMomentumCallback(GestureLayer.GestureState.End, OnContentDragEnded);
- _gestureOnContent.SetMomentumCallback(GestureLayer.GestureState.Abort, OnContentDragEnded);
- _gestureOnContent.Attach(_contentGestureBox);
- _contentBox.RepeatEvents = true;
-
- _gestureOnDrawer = new GestureLayer(_drawerIconBox);
- _gestureOnDrawer.SetMomentumCallback(GestureLayer.GestureState.Move, OnDrawerDragged);
- _gestureOnDrawer.SetMomentumCallback(GestureLayer.GestureState.End, OnDrawerDragEnded);
- _gestureOnDrawer.SetMomentumCallback(GestureLayer.GestureState.Abort, OnDrawerDragEnded);
- _gestureOnDrawer.Attach(_drawerIconBox);
-
- ERotaryEventManager.Rotated += OnRotateEventReceived;
- }
-
- void SetDrawerIcon(ImageSource source)
- {
- if (source == null)
- {
- _drawerIcon.LoadFromImageSourceAsync(ImageSource.FromResource(DefaultIcon, GetType().Assembly));
- _isDefaultIcon = true;
- }
- else
- {
- _isDefaultIcon = false;
- if (source is FileImageSource fsource)
- {
- _drawerIcon.Load(fsource.ToAbsPath());
- }
- else
- {
- _drawerIcon.LoadFromImageSourceAsync(source);
- }
- }
- }
-
- void UpdateHandlerBackgroundColor()
- {
- if (_drawerIconBox != null)
- {
- _drawerIconBox.BackgroundColor = _handlerBackgroundColor;
- }
- }
-
- void OnIconClicked(object sender, EventArgs e)
- {
- if (IsOpen)
- Close();
- else
- Open();
- }
-
- async Task<bool> ShowAsync(EWidget target, Easing easing = null, uint length = 300, CancellationToken cancelltaionToken = default(CancellationToken))
- {
- var tcs = new TaskCompletionSource<bool>();
-
- await Task.Delay(1000);
-
- if (cancelltaionToken.IsCancellationRequested)
- {
- cancelltaionToken.ThrowIfCancellationRequested();
- }
-
- target.Show();
- var opacity = target.Opacity;
-
- if (opacity == 255 || opacity == -1)
- return true;
-
- new Animation((progress) =>
- {
- target.Opacity = opacity + (int)((255 - opacity) * progress);
-
- }).Commit(this, "FadeIn", length: length, finished: (p, e) =>
- {
- target.Opacity = 255;
- tcs.SetResult(true);
- StartHighlightAnimation(_drawerIcon);
- });
-
- return await tcs.Task;
- }
-
- void OnLayout()
- {
- var bound = Geometry;
- _contentGestureBox.Geometry = bound;
- _contentBox.Geometry = bound;
- if (_drawerBox != null)
- {
- bound.Y = _isOpen ? 0 : (bound.Height - HandlerHeight);
- _drawerBox.Geometry = bound;
- }
- }
-
- void OnContentLayout()
- {
- if (_content != null)
- {
- _content.Geometry = _contentBox.Geometry;
- }
- }
-
- void OnDrawerLayout()
- {
- this.AbortAnimation("HighlightAnimation");
-
- var bound = _drawerBox.Geometry;
-
- var currentY = bound.Y;
- var ratio = currentY / (double)(Geometry.Height - HandlerHeight);
-
- var contentBound = bound;
- contentBound.Y += (int)(HandlerHeight * ratio);
- _drawerContentBox.Geometry = contentBound;
-
- var drawerHandleBound = bound;
- drawerHandleBound.Height = HandlerHeight;
- _drawerIconBox.Geometry = drawerHandleBound;
-
- var drawerTouchBound = drawerHandleBound;
- drawerTouchBound.Width = TouchWidth;
- drawerTouchBound.X = drawerHandleBound.X + (drawerHandleBound.Width - TouchWidth) / 2;
- _touchArea.Geometry = drawerTouchBound;
- }
-
- async Task<bool> HideAsync(EWidget target, Easing easing = null, uint length = 300)
- {
- var tcs = new TaskCompletionSource<bool>();
-
- var opacity = target.Opacity;
- if (opacity == -1)
- opacity = 255;
-
- new Animation((progress) =>
- {
- target.Opacity = opacity - (int)(progress * opacity);
-
- }).Commit(this, "FadeOut", length: length, finished: (p, e) =>
- {
- target.Opacity = 0;
- target.Hide();
- tcs.SetResult(true);
- });
-
- return await tcs.Task;
- }
-
- void StartHighlightAnimation(EWidget target)
- {
- if (!_isDefaultIcon || this.AnimationIsRunning("HighlightAnimation"))
- return;
-
- int count = 2;
- var bound = target.Geometry;
- var y = bound.Y;
- var dy = bound.Y - bound.Height / 3;
-
- var anim = new Animation();
-
- var transfAnim = new Animation((f) =>
- {
- bound.Y = (int)f;
- var map = new EvasMap(4);
- map.PopulatePoints(bound, 0);
- target.IsMapEnabled = true;
- target.EvasMap = map;
- }, y, dy);
-
- var opacityAnim = new Animation(f => target.Opacity = (int)f, 255, 40);
-
- anim.Add(0, 1, opacityAnim);
- anim.Add(0, 1, transfAnim);
-
- anim.Commit(this, "HighlightAnimation", 16, 800, finished: (f, b) =>
- {
- target.Opacity = 255;
- target.IsMapEnabled = false;
- }, repeat:() => --count > 0);
- }
-
- async void OnRotateEventReceived(EventArgs args)
- {
- _fadeInCancelTokenSource?.Cancel();
- _fadeInCancelTokenSource = new CancellationTokenSource();
-
- if (!_isOpen)
- {
- var token = _fadeInCancelTokenSource.Token;
- await HideAsync(_drawerBox);
- _ = ShowAsync(_drawerBox, cancelltaionToken: token);
- }
- }
-
- void OnContentDragStarted(GestureLayer.MomentumData moment)
- {
- _fadeInCancelTokenSource?.Cancel();
- _fadeInCancelTokenSource = null;
-
- if (!_isOpen)
- {
- _ = HideAsync(_drawerBox);
- }
- }
-
- void OnContentDragEnded(GestureLayer.MomentumData moment)
- {
- _fadeInCancelTokenSource = new CancellationTokenSource();
- _ = ShowAsync(_drawerBox, cancelltaionToken: _fadeInCancelTokenSource.Token);
- }
-
- void OnDrawerDragged(GestureLayer.MomentumData moment)
- {
- var toMove = _drawerBox.Geometry;
- toMove.Y = (moment.Y2 < 0) ? 0 : moment.Y2;
- _drawerBox.Geometry = toMove;
- OnDrawerLayout();
- }
-
- void OnDrawerDragEnded(GestureLayer.MomentumData moment)
- {
- if (_drawerBox.Geometry.Y < (_mainLayout.Geometry.Height / 2))
- {
- Open();
- }
- else
- {
- Close();
- }
- }
-
- void FlipIcon()
- {
- if (_isDefaultIcon)
- {
- _drawerIcon.Orientation = ImageOrientation.FlipVertical;
- }
- }
-
- void ResetIcon()
- {
- _drawerIcon.Orientation = ImageOrientation.None;
- }
-
- Task RunMoveAnimation(EvasObject target, Rect dest, uint length, Easing easing = null)
- {
- var tcs = new TaskCompletionSource<bool>();
-
- var dx = target.Geometry.X - dest.X;
- var dy = target.Geometry.Y - dest.Y;
-
- new Animation((progress) =>
- {
- var toMove = dest;
- toMove.X += (int)(dx * (1 - progress));
- toMove.Y += (int)(dy * (1 - progress));
- target.Geometry = toMove;
- OnDrawerLayout();
- }).Commit(this, "Move", length: length, finished: (s, e) =>
- {
- target.Geometry = dest;
- tcs.SetResult(true);
- });
- return tcs.Task;
- }
-
- void UnsetMainContent()
- {
- if (_content != null)
- {
- _contentBox.UnPack(_content);
- _content.Hide();
- _content = null;
- }
- }
-
- void UnsetDrawerContent()
- {
- if (_drawerContent != null)
- {
- _drawerContentBox.UnPack(_drawerContent);
- _drawerContent.Hide();
- _drawerContent = null;
-
- _drawerContentBox.Hide();
- _drawerIconBox.Hide();
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using ElmSharp;
-using ElmSharp.Wearable;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.Tizen;
-using EColor = ElmSharp.Color;
-using ELayout = ElmSharp.Layout;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public class NavigationView : ELayout
- {
- readonly int _dafaultIconSize = 60;
-
- class Item : INotifyPropertyChanged
- {
- Element _source;
- public Element Source
- {
- get
- {
- return _source;
- }
- set
- {
- if (_source != null)
- {
- _source.PropertyChanged -= OnElementPropertyChanged;
- }
- _source = value;
- _source.PropertyChanged += OnElementPropertyChanged;
- UpdateContent();
- }
- }
-
- public string Text { get; set; }
- public string Icon { get; set; }
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- void UpdateContent()
- {
- if (Source is BaseShellItem shellItem)
- {
- Text = shellItem.Title;
- Icon = (shellItem.Icon as FileImageSource)?.ToAbsPath();
- }
- else if (Source is MenuItem menuItem)
- {
- Text = menuItem.Text;
- Icon = (menuItem.IconImageSource as FileImageSource)?.ToAbsPath();
- }
- else
- {
- Text = null;
- Icon = null;
- }
- SendPropertyChanged();
- }
-
- void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- UpdateContent();
- }
-
- void SendPropertyChanged([CallerMemberName] string propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
- Box _outterBox;
- ELayout _surfaceLayout;
- CircleSurface _surface;
- CircleGenList _naviMenu;
-
- GenItemClass _defaultClass;
- SmartEvent _draggedUpCallback;
- SmartEvent _draggedDownCallback;
-
- GenListItem _header;
- GenListItem _footer;
-
- List<List<Element>> _itemCache;
- List<GenListItem> _items = new List<GenListItem>();
-
- public NavigationView(EvasObject parent) : base(parent)
- {
- InitializeComponent();
- }
-
- public event EventHandler<SelectedItemChangedEventArgs> ItemSelected;
-
- public event EventHandler<DraggedEventArgs> Dragged;
-
-
- EColor _backgroundColor = EColor.Black;
- public override EColor BackgroundColor
- {
- get => _backgroundColor;
- set
- {
- _backgroundColor = value.IsDefault ? EColor.Black : value;
- UpdateBackgroundColor();
- }
- }
-
- EColor _foregroundColor = EColor.Default;
- public EColor ForegroundColor
- {
- get => _foregroundColor;
- set
- {
- _foregroundColor = value;
- UpdateForegroundColor();
- }
- }
-
-
- public void Build(List<List<Element>> items)
- {
- // Only update when items was changed
- if (!IsUpdated(items))
- {
- return;
- }
- _itemCache = items;
-
- ClearItemPropertyChangedHandler();
- _naviMenu.Clear();
- _items.Clear();
- // header
- _header = _naviMenu.Append(_defaultClass, new Item { Text = "" });
-
- // TODO. need to improve, need to support group
- foreach (var group in items)
- {
- foreach (var item in group)
- {
- var data = new Item
- {
- Source = item
- };
- if (item is BaseShellItem shellItem)
- {
- data.Text = shellItem.Title;
- data.Icon = (shellItem.Icon as FileImageSource)?.ToAbsPath();
- }
- else if (item is MenuItem menuItem)
- {
- data.Text = menuItem.Text;
- data.Icon = (menuItem.IconImageSource as FileImageSource)?.ToAbsPath();
- }
- var genitem = _naviMenu.Append(_defaultClass, data, GenListItemType.Normal);
- genitem.SetPartColor("bg", _backgroundColor);
- _items.Add(genitem);
- data.PropertyChanged += OnItemPropertyChanged;
- }
- }
- _footer = _naviMenu.Append(_defaultClass, new Item { Text = "" });
- }
-
- public void Activate()
- {
- (_naviMenu as IRotaryActionWidget)?.Activate();
- }
- public void Deactivate()
- {
- (_naviMenu as IRotaryActionWidget)?.Deactivate();
- }
-
- protected override IntPtr CreateHandle(EvasObject parent)
- {
- _outterBox = new Box(parent);
- return _outterBox.Handle;
- }
-
- void InitializeComponent()
- {
- _outterBox.SetLayoutCallback(OnLayout);
-
- _surfaceLayout = new ELayout(this);
- _surfaceLayout.Show();
- _surface = new CircleSurface(_surfaceLayout);
-
- _naviMenu = new CircleGenList(this, _surface)
- {
- Homogeneous = true,
- BackgroundColor = _backgroundColor
- };
- _naviMenu.Show();
-
- _draggedUpCallback = new SmartEvent(_naviMenu, "drag,start,up");
- _draggedUpCallback.On += (s, e) =>
- {
- if (_footer.TrackObject.IsVisible)
- {
- Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.EdgeBottom));
- }
- else
- {
- Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.Up));
- }
- };
-
- _draggedDownCallback = new SmartEvent(_naviMenu, "drag,start,down");
- _draggedDownCallback.On += (s, e) =>
- {
- if (_header.TrackObject.IsVisible)
- {
- Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.EdgeTop));
- }
- else
- {
- Dragged?.Invoke(this, new DraggedEventArgs(DraggedState.Down));
- }
- };
-
- _outterBox.PackEnd(_naviMenu);
- _outterBox.PackEnd(_surfaceLayout);
-
- _surfaceLayout.StackAbove(_naviMenu);
-
- _defaultClass = new GenItemClass("1icon_1text")
- {
- GetTextHandler = (obj, part) =>
- {
- if (part == "elm.text")
- {
- var text = (obj as Item).Text;
- if (_foregroundColor != EColor.Default)
- return $"<span color='{_foregroundColor.ToHex()}'>{text}</span>";
- else
- return text;
- }
- return null;
- },
- GetContentHandler = (obj, part) =>
- {
- if (part == "elm.swallow.icon" && obj is Item menuItem && !string.IsNullOrEmpty(menuItem.Icon))
- {
- var icon = new ElmSharp.Image(Xamarin.Forms.Forms.NativeParent)
- {
- AlignmentX = -1,
- AlignmentY = -1,
- WeightX = 1.0,
- WeightY = 1.0,
- MinimumWidth = _dafaultIconSize,
- MinimumHeight = _dafaultIconSize,
- };
- icon.Show();
- icon.Load(menuItem.Icon);
- return icon;
- }
- return null;
- }
- };
-
- _naviMenu.ItemSelected += OnItemSelected;
-
- }
-
- void OnItemSelected(object sender, GenListItemEventArgs e)
- {
- ItemSelected?.Invoke(this, new SelectedItemChangedEventArgs((e.Item.Data as Item).Source, -1));
- }
-
- void OnLayout()
- {
- _surfaceLayout.Geometry = Geometry;
- _naviMenu.Geometry = Geometry;
- }
-
- void UpdateBackgroundColor()
- {
- _naviMenu.BackgroundColor = _backgroundColor;
- foreach (var item in _items)
- {
- item.SetPartColor("bg", _backgroundColor);
- }
- }
-
- void UpdateForegroundColor()
- {
- foreach (var item in _items)
- {
- item.Update();
- }
- }
-
- bool IsUpdated(List<List<Element>> items)
- {
- if (_itemCache == null)
- return true;
-
- if (_itemCache.Count != items.Count)
- return true;
-
- for (int i = 0; i < items.Count; i++)
- {
- if (_itemCache[i].Count != items[i].Count)
- return true;
-
- for (int j = 0; j < items[i].Count; j++)
- {
- if (_itemCache[i][j] != items[i][j])
- return true;
- }
- }
- return false;
- }
-
- void ClearItemPropertyChangedHandler()
- {
- foreach (var item in _items)
- {
- (item.Data as Item).PropertyChanged -= OnItemPropertyChanged;
- }
- }
-
- void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- var item = _items.Where((d) => d.Data == sender).FirstOrDefault();
- item?.Update();
- }
-
- }
- public enum DraggedState
- {
- EdgeTop,
- Up,
- Down,
- EdgeBottom,
- }
-
- public class DraggedEventArgs
- {
- public DraggedState State { get; private set; }
-
- public DraggedEventArgs(DraggedState state)
- {
- State = state;
- }
- }
-
- static class FileImageSourceEX
- {
- public static string ToAbsPath(this FileImageSource source)
- {
- return ResourcePath.GetPath(source.File);
- }
- }
-
- static class ColorEX
- {
- public static string ToHex(this EColor c)
- {
- return string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", c.R, c.G, c.B, c.A);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using ElmSharp;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.Tizen;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public class ShellContentRenderer : IShellItemRenderer
- {
- public ShellContentRenderer(ShellContent content)
- {
- ShellContent = content;
- NativeView = GetNativeView(content);
- }
-
- public ShellContent ShellContent { get; protected set; }
-
- public BaseShellItem Item => ShellContent;
-
- public EvasObject NativeView { get; protected set; }
-
- public void Dispose()
- {
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- NativeView?.Unrealize();
- }
- }
-
- static EvasObject GetNativeView(ShellContent content)
- {
- var page = (content as IShellContentController).GetOrCreateContent();
- return Platform.GetOrCreateRenderer(page).NativeView;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using ElmSharp;
-using System.Collections.Generic;
-using System.ComponentModel;
-using Xamarin.Forms;
-using XForms = Xamarin.Forms.Forms;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public class ShellItemRenderer : IShellItemRenderer
- {
- Box _mainLayout;
- EvasObject _currentItem;
- Dictionary<BaseShellItem, IShellItemRenderer> _rendererCache = new Dictionary<BaseShellItem, IShellItemRenderer>();
-
- public ShellItemRenderer(ShellItem item)
- {
- ShellItem = item;
- ShellItem.PropertyChanged += OnItemPropertyChanged;
- InitializeComponent();
- UpdateCurrentItem();
- }
-
- public ShellItem ShellItem { get; protected set; }
-
- public BaseShellItem Item => ShellItem;
-
- public EvasObject NativeView => _mainLayout;
-
- public void Dispose()
- {
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- ResetCurrentItem();
- ShellItem.PropertyChanged -= OnItemPropertyChanged;
- }
- }
-
- void InitializeComponent()
- {
- _mainLayout = new Box(XForms.NativeParent);
- _mainLayout.SetLayoutCallback(OnLayout);
- }
-
- void UpdateCurrentItem()
- {
- ResetCurrentItem();
- var currentItem = ShellItem.CurrentItem;
- if (currentItem != null)
- {
- if (!_rendererCache.TryGetValue(currentItem, out IShellItemRenderer renderer))
- {
- renderer = ShellRendererFactory.Default.CreateShellNavigationRenderer(currentItem);
- _rendererCache[currentItem] = renderer;
- }
- SetCurrentItem(renderer.NativeView);
- }
- }
-
- void SetCurrentItem(EvasObject item)
- {
- _currentItem = item;
- _currentItem.Show();
- _mainLayout.PackEnd(_currentItem);
- }
-
- void ResetCurrentItem()
- {
- if (_currentItem != null)
- {
- _mainLayout.UnPack(_currentItem);
- _currentItem.Hide();
- _currentItem = null;
- }
- }
-
- void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(ShellItem.CurrentItem))
- {
- UpdateCurrentItem();
- }
- }
-
- void OnLayout()
- {
- if (_currentItem != null)
- {
- _currentItem.Geometry = _mainLayout.Geometry;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using ElmSharp;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.Tizen;
-using XForms = Xamarin.Forms.Forms;
-using XShell = Xamarin.Forms.Shell;
-using Tizen.Wearable.CircularUI.Forms;
-
-[assembly: ExportRenderer(typeof(CircularShell), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.ShellRenderer))]
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public class ShellRenderer : VisualElementRenderer<XShell>
- {
- NavigationDrawer _drawer;
- NavigationView _navigationView;
-
- Dictionary<BaseShellItem, IShellItemRenderer> _rendererCache = new Dictionary<BaseShellItem, IShellItemRenderer>();
-
- public ShellRenderer()
- {
- RegisterPropertyHandler(XShell.CurrentItemProperty, UpdateCurrentItem);
- RegisterPropertyHandler(XShell.FlyoutIsPresentedProperty, UpdateFlyoutIsPresented);
- RegisterPropertyHandler(XShell.FlyoutBehaviorProperty, UpdateFlyoutBehavior);
- RegisterPropertyHandler(XShell.FlyoutIconProperty, UpdateFlyoutIcon);
- RegisterPropertyHandler(XShell.FlyoutBackgroundColorProperty, UpdateFlyoutBackgroundColor);
- RegisterPropertyHandler(CircularShell.FlyoutIconBackgroundColorProperty, UpdateFlyoutIconBackgroundColor);
- RegisterPropertyHandler(CircularShell.FlyoutForegroundColorProperty, UpdateFlyoutForegroundColor);
- }
-
- protected override void OnElementChanged(ElementChangedEventArgs<XShell> e)
- {
- InitializeComponent();
- base.OnElementChanged(e);
- }
-
- protected override void OnElementReady()
- {
- base.OnElementReady();
- UpdateFlyoutMenu();
- (Element as IShellController).StructureChanged += OnNavigationStructureChanged;
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- foreach (var renderer in _rendererCache.Values)
- {
- renderer.Dispose();
- }
- (Element as IShellController).StructureChanged -= OnNavigationStructureChanged;
- }
- base.Dispose(disposing);
- }
-
- void InitializeComponent()
- {
- if (_drawer == null)
- {
- _drawer = new NavigationDrawer(XForms.NativeParent);
- _drawer.IsOpen = Element.FlyoutIsPresented;
- _drawer.Toggled += OnNavigationDrawerToggled;
- SetNativeView(_drawer);
- }
- }
-
- void OnNavigationStructureChanged(object sender, EventArgs e)
- {
- UpdateFlyoutMenu();
- }
-
- void UpdateFlyoutMenu()
- {
- if (Element.FlyoutBehavior == FlyoutBehavior.Disabled)
- return;
-
- var flyoutItems = (Element as IShellController).GenerateFlyoutGrouping();
- int itemCount = 0;
- foreach (var item in flyoutItems)
- {
- itemCount += item.Count;
- }
-
- if (itemCount > 1)
- {
- InitializeNavigationDrawer();
- _navigationView.Build(flyoutItems);
- }
- else
- {
- DeinitializeNavigationView();
- }
- }
-
- void InitializeNavigationDrawer()
- {
- if (_navigationView != null)
- {
- return;
- }
-
- _navigationView = new NavigationView(XForms.NativeParent)
- {
- AlignmentX = -1,
- AlignmentY = -1,
- WeightX = 1,
- WeightY = 1,
- };
- _navigationView.Show();
- _navigationView.ItemSelected += OnMenuItemSelected;
-
- _drawer.SetDrawerContent(_navigationView);
- }
-
- void OnNavigationDrawerToggled(object sender, EventArgs e)
- {
- if (_drawer.IsOpen)
- {
- _navigationView.Activate();
- }
- else
- {
- _navigationView.Deactivate();
-
- var stack = (Element.CurrentItem.CurrentItem as ShellSection)?.Stack;
- var currentPage = stack?.LastOrDefault<Page>();
-
- if (currentPage == null)
- {
- currentPage = (Element.CurrentItem.CurrentItem.CurrentItem as IShellContentController)?.Page;
- }
-
- if (currentPage != null)
- {
- var renderer = Platform.GetOrCreateRenderer(currentPage);
- (renderer as CirclePageRenderer)?.UpdateRotaryFocusObject();
- }
- }
-
- Element.SetValueFromRenderer(XShell.FlyoutIsPresentedProperty, _drawer.IsOpen);
- }
-
- void DeinitializeNavigationView()
- {
- if (_navigationView == null)
- return;
- _drawer.SetDrawerContent(null);
- _navigationView.Unrealize();
- _navigationView = null;
- }
-
- void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
- {
- ((IShellController)Element).OnFlyoutItemSelected(e.SelectedItem as Element);
- }
-
- void UpdateCurrentItem()
- {
- ResetCurrentItem();
- if (Element.CurrentItem != null)
- {
- if (!_rendererCache.TryGetValue(Element.CurrentItem, out IShellItemRenderer renderer))
- {
- renderer = ShellRendererFactory.Default.CreateItemRenderer(Element.CurrentItem);
- _rendererCache[Element.CurrentItem] = renderer;
- }
- SetCurrentItem(renderer.NativeView);
- }
- }
-
- void UpdateFlyoutBehavior(bool init)
- {
- if (init)
- return;
-
- if (Element.FlyoutBehavior == FlyoutBehavior.Disabled)
- {
- DeinitializeNavigationView();
- }
- else if (Element.FlyoutBehavior == FlyoutBehavior.Flyout)
- {
- UpdateFlyoutMenu();
- }
- else if (Element.FlyoutBehavior == FlyoutBehavior.Locked)
- {
- // Locked behavior is not supported on circularshell
- }
- }
-
- void UpdateFlyoutIcon(bool init)
- {
- if (init && Element.FlyoutIcon == null)
- return;
-
- _drawer.UpdateDrawerIcon(Element.FlyoutIcon);
- }
-
- void UpdateFlyoutBackgroundColor(bool init)
- {
- if (init && Element.FlyoutBackgroundColor.IsDefault)
- return;
-
- if (_navigationView != null)
- {
- _navigationView.BackgroundColor = Element.FlyoutBackgroundColor.ToNative();
- }
- }
-
- void UpdateFlyoutForegroundColor(bool init)
- {
- if (init && CircularShell.GetFlyoutForegroundColor(Element).IsDefault)
- return;
-
- if (_navigationView != null)
- {
- _navigationView.ForegroundColor = CircularShell.GetFlyoutForegroundColor(Element).ToNative();
- }
- }
-
- void UpdateFlyoutIconBackgroundColor()
- {
- _drawer.HandlerBackgroundColor = CircularShell.GetFlyoutIconBackgroundColor(Element).ToNative();
- }
-
- void UpdateFlyoutIsPresented()
- {
- _drawer.IsOpen = Element.FlyoutIsPresented;
- }
-
- void SetCurrentItem(EvasObject item)
- {
- _drawer.SetMainContent(item);
- }
-
- void ResetCurrentItem()
- {
- _drawer.SetMainContent(null);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using Xamarin.Forms;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public class ShellRendererFactory
- {
- static ShellRendererFactory _instance;
- public static ShellRendererFactory Default
- {
- get
- {
- if (_instance == null)
- {
- _instance = new ShellRendererFactory();
- }
- return _instance;
- }
- set
- {
- _instance = value;
- }
-
- }
-
- public virtual IShellItemRenderer CreateItemRenderer(ShellItem item)
- {
- if (item.Items.Count == 1)
- {
- return CreateShellNavigationRenderer(item.CurrentItem);
- }
- return new ShellItemRenderer(item);
- }
-
- public virtual IShellItemRenderer CreateShellNavigationRenderer(ShellSection item)
- {
- return new ShellSectionNavigationRenderer(item);
- }
-
- public virtual IShellItemRenderer CreateItemRenderer(ShellSection item)
- {
- if (item.Items.Count == 1)
- {
- return CreateItemRenderer(item.CurrentItem);
- }
- return new ShellSectionItemsRenderer(item);
- }
-
- public virtual IShellItemRenderer CreateItemRenderer(ShellContent item)
- {
- return new ShellContentRenderer(item);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using ElmSharp;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.ComponentModel;
-using Xamarin.Forms;
-using XForms = Xamarin.Forms.Forms;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- public class ShellSectionItemsRenderer : IShellItemRenderer
- {
- const int ItemMaxCount = 20;
- const int OddMiddleItem = 10;
- const int EvenMiddleItem = 11;
-
- Box _mainLayout;
- Index _indexIndicator;
- Scroller _scroller;
- Box _innerContainer;
- List<ItemHolder> _items = new List<ItemHolder>();
-
- int _currentIndex = -1;
- Rect _lastLayoutBound;
- int _updateByCode;
-
-
- public ShellSectionItemsRenderer(ShellSection shellSection)
- {
- ShellSection = shellSection;
- ShellSection.PropertyChanged += OnSectionPropertyChanged;
- (ShellSection.Items as INotifyCollectionChanged).CollectionChanged += OnItemsChanged;
- InitializeComponent();
- UpdateItems();
- }
-
- public ShellSection ShellSection { get; protected set; }
-
- public BaseShellItem Item => ShellSection;
-
- public EvasObject NativeView => _mainLayout;
-
- public void Dispose()
- {
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- _mainLayout?.Unrealize();
- (ShellSection.Items as INotifyCollectionChanged).CollectionChanged -= OnItemsChanged;
- ShellSection.PropertyChanged -= OnSectionPropertyChanged;
- }
- }
-
- void InitializeComponent()
- {
- _mainLayout = new Box(XForms.NativeParent)
- {
- AlignmentX = -1,
- AlignmentY = -1,
- WeightX = 1,
- WeightY = 1,
- };
- _mainLayout.Show();
- _mainLayout.SetLayoutCallback(OnLayout);
-
- _indexIndicator = new Index(_mainLayout)
- {
- IsHorizontal = true,
- AutoHide = false,
- Style = IndexStyle.Circle,
- };
- _indexIndicator.Show();
-
- _scroller = new Scroller(_mainLayout);
- _scroller.PageScrolled += OnPageScrolled;
- _scroller.DragStart += OnDragStarted;
-
- // Disables the visibility of the scrollbar in both directions:
- _scroller.HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible;
- _scroller.VerticalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible;
- // Sets the limit of scroll to one page maximum:
- _scroller.HorizontalPageScrollLimit = 1;
- _scroller.SetPageSize(1.0, 1.0);
- _scroller.SetAlignment(-1, -1);
- _scroller.SetWeight(1.0, 1.0);
- _scroller.Show();
-
- _innerContainer = new Box(_mainLayout);
- _innerContainer.SetLayoutCallback(OnInnerLayoutUpdate);
- _innerContainer.SetAlignment(-1, -1);
- _innerContainer.SetWeight(1.0, 1.0);
- _innerContainer.Show();
- _scroller.SetContent(_innerContainer);
-
- _mainLayout.PackEnd(_indexIndicator);
- _mainLayout.PackEnd(_scroller);
- _indexIndicator.StackAbove(_scroller);
- }
-
- void OnDragStarted(object sender, EventArgs e)
- {
- if (_currentIndex - 1 >= 0 && !_items[_currentIndex - 1].IsRealized)
- {
- RealizeItem(_items[_currentIndex - 1]);
- }
- if (_currentIndex + 1 < _items.Count && !_items[_currentIndex + 1].IsRealized)
- {
- RealizeItem(_items[_currentIndex + 1]);
- }
- }
-
- void UpdateItems()
- {
- _items.Clear();
- _indexIndicator.Clear();
- _innerContainer.UnPackAll();
- _lastLayoutBound = default(Rect);
-
- foreach (var item in ShellSection.Items)
- {
- var indexItem = _indexIndicator.Append(null);
- indexItem.Style = GetItemStyle(ShellSection.Items.Count, _items.Count);
- _items.Add(new ItemHolder
- {
- IsRealized = false,
- IndexItem = indexItem,
- Item = item
- });
- }
- _indexIndicator.Update(0);
- UpdateCurrentPage(ShellSection.Items.IndexOf(ShellSection.CurrentItem));
- }
-
- void RealizeItem(ItemHolder item)
- {
- var renderer = ShellRendererFactory.Default.CreateItemRenderer(item.Item);
- renderer.NativeView.Show();
- item.NativeView = renderer.NativeView;
- item.IsRealized = true;
- _innerContainer.PackEnd(item.NativeView);
- item.NativeView.StackBelow(_indexIndicator);
- item.NativeView.Geometry = item.Bound;
- }
-
- void UpdateCurrentPage(int index)
- {
- if (_currentIndex == index)
- return;
-
- _currentIndex = index;
- UpdateCurrentIndexIndicator();
- if (!_items[index].IsRealized)
- {
- RealizeItem(_items[index]);
- }
- UpdateFocusPolicy();
- }
-
- void UpdateFocusPolicy()
- {
- foreach (var item in _items)
- {
- if (item.IsRealized)
- {
- if (item.NativeView is ElmSharp.Widget widget)
- {
- widget.AllowTreeFocus = (_items[_currentIndex] == item);
- }
- }
- }
- }
-
- void UpdateCurrentIndexIndicator()
- {
- if (_currentIndex >= 0 && _currentIndex < _items.Count)
- {
- _items[_currentIndex].IndexItem.Select(true);
- }
- }
- void OnItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- UpdateItems();
- }
-
- void OnPageScrolled(object sender, EventArgs e)
- {
- if (_updateByCode > 0)
- {
- return;
- }
-
- if (_currentIndex < 0 || ShellSection.Items.Count <= _currentIndex)
- {
- return;
- }
-
- UpdateCurrentPage(_scroller.HorizontalPageIndex);
- var currentItem = ShellSection.Items[_currentIndex];
- ShellSection.SetValueFromRenderer(ShellSection.CurrentItemProperty, currentItem);
- }
-
- void OnSectionPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(ShellSection.CurrentItem))
- {
- var newIndex = ShellSection.Items.IndexOf(ShellSection.CurrentItem);
- if (_currentIndex != newIndex)
- {
- UpdateCurrentPage(newIndex);
- _updateByCode++;
- _scroller.ScrollTo(newIndex, 0, false);
- _updateByCode--;
- }
- }
- }
-
- void OnLayout()
- {
- _indexIndicator.Geometry = _mainLayout.Geometry;
- _scroller.Geometry = _mainLayout.Geometry;
- }
-
- void OnInnerLayoutUpdate()
- {
- if (_lastLayoutBound == _innerContainer.Geometry)
- {
- return;
- }
- _lastLayoutBound = _innerContainer.Geometry;
-
- var layoutBound = _innerContainer.Geometry.Size;
- int baseX = _innerContainer.Geometry.X;
-
- Rect bound = _scroller.Geometry;
- int index = 0;
- foreach (var item in _items)
- {
- bound.X = baseX + index * bound.Width;
- item.Bound = bound;
- if (item.IsRealized)
- {
- item.NativeView.Geometry = bound;
- }
- index++;
- }
- _innerContainer.MinimumWidth = _items.Count * bound.Width;
-
- if (_items.Count > _currentIndex && _currentIndex >= 0)
- {
- _updateByCode++;
- _scroller.ScrollTo(_currentIndex, 0, false);
- _updateByCode--;
- }
- }
-
- static string GetItemStyle(int itemCount, int offset)
- {
- string returnValue = string.Empty;
- int startItem;
- int styleNumber;
-
- if (itemCount % 2 == 0) //Item count is even.
- {
- startItem = EvenMiddleItem - itemCount / 2;
- styleNumber = startItem + offset;
- returnValue = "item/even_" + styleNumber;
- }
- else //Item count is odd.
- {
- startItem = OddMiddleItem - itemCount / 2;
- styleNumber = startItem + offset;
- returnValue = "item/odd_" + styleNumber;
- }
- return returnValue;
- }
-
- class ItemHolder
- {
- public bool IsRealized { get; set; }
- public Rect Bound { get; set; }
- public EvasObject NativeView { get; set; }
- public IndexItem IndexItem { get; set; }
- public ShellContent Item { get; set; }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using ElmSharp;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Xamarin.Forms;
-using Xamarin.Forms.Internals;
-using Xamarin.Forms.Platform.Tizen;
-using XForms = Xamarin.Forms.Forms;
-
-namespace Tizen.Wearable.CircularUI.Forms.Renderer
-{
- class SimpleViewStack : Box
- {
- EvasObject _lastTop;
-
- public SimpleViewStack(EvasObject parent) : base(parent)
- {
- InternalStack = new List<EvasObject>();
- SetLayoutCallback(OnLayout);
- }
-
- List<EvasObject> InternalStack { get; set; }
-
- public IReadOnlyList<EvasObject> Stack => InternalStack;
-
- public void Push(EvasObject view)
- {
- InternalStack.Add(view);
- PackEnd(view);
- UpdateTopView();
- }
-
- public void Pop()
- {
- if (_lastTop != null)
- {
- var tobeRemoved = _lastTop;
- InternalStack.Remove(tobeRemoved);
- UnPack(tobeRemoved);
- UpdateTopView();
-
- // if Pop was called by removed page,
- // Unrealize cause deletation of NativeCallback, it could be a cause of crash
- Device.BeginInvokeOnMainThread(() =>
- {
- tobeRemoved.Unrealize();
- });
- }
- }
-
- public void PopToRoot()
- {
- while (InternalStack.Count > 1)
- {
- Pop();
- }
- }
-
- public void Insert(EvasObject before, EvasObject view)
- {
- view.Hide();
- var idx = InternalStack.IndexOf(before);
- InternalStack.Insert(idx, view);
- PackEnd(view);
- UpdateTopView();
- }
-
- public void Remove(EvasObject view)
- {
- InternalStack.Remove(view);
- UnPack(view);
- UpdateTopView();
- Device.BeginInvokeOnMainThread(() =>
- {
- view?.Unrealize();
- });
- }
-
- void UpdateTopView()
- {
- if (_lastTop != InternalStack.LastOrDefault())
- {
- _lastTop?.Hide();
- _lastTop = InternalStack.LastOrDefault();
- _lastTop.Show();
- }
- }
-
- void OnLayout()
- {
- foreach (var view in Stack)
- {
- view.Geometry = Geometry;
- }
- }
-
- }
-
- public class ShellSectionNavigationRenderer : IShellItemRenderer
- {
- SimpleViewStack _viewStack;
- IShellItemRenderer _rootPageRenderer;
-
- public ShellSectionNavigationRenderer(ShellSection item)
- {
- ShellSection = item;
- (ShellSection as IShellSectionController).NavigationRequested += OnNavigationRequested;
- InitializeComponent();
- }
-
- public ShellSection ShellSection { get; protected set; }
-
- public BaseShellItem Item => ShellSection;
-
- public EvasObject NativeView => _viewStack;
-
- public void Dispose()
- {
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- _rootPageRenderer?.Dispose();
- _viewStack?.Unrealize();
- (ShellSection as IShellSectionController).NavigationRequested -= OnNavigationRequested;
- }
- }
-
- void InitializeComponent()
- {
- _viewStack = new SimpleViewStack(XForms.NativeParent);
- _viewStack.Show();
-
- _rootPageRenderer = ShellRendererFactory.Default.CreateItemRenderer(ShellSection);
- _viewStack.Push(_rootPageRenderer.NativeView);
- }
-
- void OnInsertRequest(NavigationRequestedEventArgs request)
- {
- var before = Platform.GetRenderer(request.BeforePage)?.NativeView ?? null;
- if (before == null)
- {
- request.Task = Task.FromException<bool>(new ArgumentException("Can't found page on stack", nameof(request.BeforePage)));
- return;
- }
- var renderer = Platform.GetOrCreateRenderer(request.Page);
- _viewStack.Insert(before, renderer.NativeView);
- request.Task = Task.FromResult(true);
- }
-
- void OnPushRequest(NavigationRequestedEventArgs request)
- {
- var renderer = Platform.GetOrCreateRenderer(request.Page);
- _viewStack.Push(renderer.NativeView);
- request.Task = Task.FromResult(true);
- }
-
- void OnPopRequest(NavigationRequestedEventArgs request)
- {
- _viewStack.Pop();
- request.Task = Task.FromResult(true);
- }
-
- void OnPopToRootRequest(NavigationRequestedEventArgs request)
- {
- _viewStack.PopToRoot();
- request.Task = Task.FromResult(true);
- }
-
- void OnRemoveRequest(NavigationRequestedEventArgs request)
- {
- var renderer = Platform.GetRenderer(request.Page);
- if (renderer == null)
- {
- request.Task = Task.FromException<bool>(new ArgumentException("Can't found page on stack", nameof(request.Page)));
- return;
- }
- _viewStack.Remove(renderer.NativeView);
- request.Task = Task.FromResult(true);
- }
-
- void OnNavigationRequested(object sender, NavigationRequestedEventArgs e)
- {
- switch (e.RequestType)
- {
- case NavigationRequestType.Insert:
- OnInsertRequest(e);
- break;
- case NavigationRequestType.Push:
- OnPushRequest(e);
- break;
- case NavigationRequestType.Pop:
- OnPopRequest(e);
- break;
- case NavigationRequestType.PopToRoot:
- OnPopToRootRequest(e);
- break;
- case NavigationRequestType.Remove:
- OnRemoveRequest(e);
- break;
- }
- }
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Xamarin.Forms;
+using XStepperRenderer = Xamarin.Forms.Platform.Tizen.StepperRenderer;
+using CStepperRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.StepperRenderer;
+
+[assembly: ExportRenderer(typeof(Stepper), typeof(CStepperRenderer))]
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class StepperRenderer : XStepperRenderer
+ {
+ protected override void UpdateRotaryInteraction(bool enable)
+ {
+ if (Element.FindBezelRouter() == null)
+ {
+ base.UpdateRotaryInteraction(enable);
+ }
+ }
+ }
+}
\ No newline at end of file
namespace Tizen.Wearable.CircularUI.Forms.Renderer
{
- internal static class ThemeLoader
- {
- const string CircularUITheme = "/usr/share/elm-sharp/tizen-circular-ui-theme.edj";
+ internal static class ThemeLoader
+ {
+ const string CircularUITheme = "/usr/share/elm-sharp/tizen-circular-ui-theme.edj";
public static string AppResourcePath { get; private set; }
}
}
- public static void AddThemeOverlay(string themeFilePath)
- {
- if (!IsInitialized)
- {
- Log.Error(Circular.Tag, $"ThemeLoader is not initialized properly");
- return;
- }
- Elementary.AddThemeOverlay(themeFilePath);
- }
- }
+ public static void AddThemeOverlay(string themeFilePath)
+ {
+ if (!IsInitialized)
+ {
+ Log.Error(Circular.Tag, $"ThemeLoader is not initialized properly");
+ return;
+ }
+ Elementary.AddThemeOverlay(themeFilePath);
+ }
+ }
}
\ No newline at end of file
--- /dev/null
+using Xamarin.Forms;
+
+using XTimePickerRenderer = Xamarin.Forms.Platform.Tizen.TimePickerRenderer;
+using CTimePickerRenderer = Tizen.Wearable.CircularUI.Forms.Renderer.TimePickerRenderer;
+using System;
+
+[assembly: ExportRenderer(typeof(TimePicker), typeof(CTimePickerRenderer))]
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class TimePickerRenderer : XTimePickerRenderer
+ {
+ protected override void OnPickerOpened(object sender, EventArgs args)
+ {
+ Element.FindBezelController()?.Deactivate();
+ base.OnPickerOpened(sender, args);
+ }
+
+ protected override void OnPickerClosed(object sender, EventArgs args)
+ {
+ base.OnPickerClosed(sender, args);
+ Element.FindBezelController()?.Activate();
+ }
+ }
+}
\ No newline at end of file
_firstButton.Clicked += (s, e) =>
{
- ((IMenuItemController)FirstButton).Activate();
+ (FirstButton as IMenuItemController)?.Activate();
};
if (_firstButtonBgColor != Color.Default)
_secondButton.Clicked += (s, e) =>
{
- ((IMenuItemController)SecondButton).Activate();
+ (SecondButton as IMenuItemController)?.Activate();
};
if (_secondButtonBgColor != Color.Default)
--- /dev/null
+using ElmSharp;
+using ElmSharp.Wearable;
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Tizen;
+using XForms = Xamarin.Forms.Forms;
+using CForms = Tizen.Wearable.CircularUI.Forms;
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+ public class WatchListView : Xamarin.Forms.Platform.Tizen.Native.Watch.WatchListView
+ {
+ GenItemClass _cancelEffectTemplete;
+
+ public WatchListView(EvasObject parent, CircleSurface surface) : base(parent, surface)
+ {
+ }
+
+ public override void SetHeader(VisualElement header)
+ {
+ base.SetHeader(header);
+ if (HasHeader() && CForms.CircleListView.GetCancelEffect(header))
+ {
+ FirstItem.UpdateItemClass(GetCancelEffectTemplete(), header);
+ }
+ }
+
+ public override void SetFooter(VisualElement footer)
+ {
+ base.SetFooter(footer);
+ if (HasFooter() && CForms.CircleListView.GetCancelEffect(footer))
+ {
+ LastItem.UpdateItemClass(GetCancelEffectTemplete(), footer);
+ }
+ }
+
+ GenItemClass GetCancelEffectTemplete()
+ {
+ if (_cancelEffectTemplete != null)
+ return _cancelEffectTemplete;
+ _cancelEffectTemplete = new GenItemClass("full_off")
+ {
+ GetContentHandler = (data, part) =>
+ {
+ VisualElement element = data as VisualElement;
+ var renderer = Platform.GetOrCreateRenderer(element);
+
+ if (element.MinimumHeightRequest == -1)
+ {
+ SizeRequest request = element.Measure(double.PositiveInfinity, double.PositiveInfinity);
+ renderer.NativeView.MinimumHeight = XForms.ConvertToScaledPixel(request.Request.Height);
+ }
+ else
+ {
+ renderer.NativeView.MinimumHeight = XForms.ConvertToScaledPixel(element.MinimumHeightRequest);
+ }
+ (renderer as LayoutRenderer)?.RegisterOnLayoutUpdated();
+
+ return renderer.NativeView;
+ }
+ };
+
+ return _cancelEffectTemplete;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.ComponentModel;
+using Xamarin.Forms;
+
+namespace Tizen.Wearable.CircularUI.Forms
+{
+ /// <summary>
+ /// The BezelInteractionPage is a ContentPage, which allows you to interact with Bezel rotation
+ /// </summary>
+ public class BezelInteractionPage : ContentPage, IBezelInteractionRouter
+ {
+ /// <summary>
+ /// BindableProperty. Identifies the RotaryFocusObject bindable property Key.
+ /// </summary>
+ public static readonly BindableProperty RotaryFocusObjectProperty = BindableProperty.Create(nameof(RotaryFocusObject), typeof(IRotaryFocusable), typeof(BezelInteractionPage), null);
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool Appeared { get; set; }
+
+ /// <summary>
+ /// Gets or sets object of RotaryFocusObject to receive bezel action(take a rotary event) from the current page.
+ /// </summary>
+ public IRotaryFocusable RotaryFocusObject
+ {
+ get => (IRotaryFocusable)GetValue(RotaryFocusObjectProperty);
+ set => SetValue(RotaryFocusObjectProperty, value);
+ }
+
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ Appeared = true;
+ }
+
+ protected override void OnDisappearing()
+ {
+ base.OnDisappearing();
+ Appeared = false;
+ }
+ }
+}
\ No newline at end of file
/// }
/// </code>
/// </example>
+ [Obsolete("Check is obsolete as of version 1.5.0. Please use Xamarin.Forms.Switch instead.")]
public class Check : Switch
{
/// <summary>
* limitations under the License.
*/
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
/// It has an ActionButton, and can use the MenuItem type as text, icon, command, and so on.
/// </summary>
/// <since_tizen> 4 </since_tizen>
- public class CirclePage : ContentPage, ICircleSurfaceProvider
+ [Obsolete("CirclePage is obsolete as of version 1.5.0. Please use Xamarin.Forms.ContentPage, CircleSurfaceView, and BezelInteracationPage instead.")]
+ public class CirclePage : ContentPage, ICircleSurfaceProvider, IBezelInteractionRouter
{
/// <summary>
/// BindableProperty. Identifies the ActionButton bindable property.
* limitations under the License.
*/
+using System;
using Xamarin.Forms;
namespace Tizen.Wearable.CircularUI.Forms
/// BindableProperty. Identifies the Header, Footer cancel the Fish Eye Effect or not.
/// </summary>
/// <since_tizen> 4 </since_tizen>
- public static readonly BindableProperty BarColorProperty = BindableProperty.CreateAttached("BarColor", typeof(Color), typeof(CircleScrollView), Color.Default);
+ public static readonly BindableProperty BarColorProperty = BindableProperty.CreateAttached("BarColor", typeof(Color), typeof(CircleScrollView), Color.Default);
/// <summary>
/// Gets or sets a scroll bar color value.
*/
using System;
+using System.ComponentModel;
using Xamarin.Forms;
namespace Tizen.Wearable.CircularUI.Forms
/// </summary>
/// <since_tizen> 4 </since_tizen>
public ICircleSurfaceProvider CircleSurfaceProvider { get; set; }
+
+ /// <summary>
+ /// Occurs when the circle stepper's wheel is appeared.
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public event EventHandler WheelAppeared;
+
+ /// <summary>
+ /// Occurs when the circle stepper's wheel is disappeared.
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public event EventHandler WheelDisappeared;
+
+ /// <summary>
+ /// Internal use only, initializes a new instance of the EmbeddingControls.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void SendWheelAppeared()
+ {
+ WheelAppeared?.Invoke(this, EventArgs.Empty);
+ }
+
+ /// <summary>
+ /// Internal use only, initializes a new instance of the EmbeddingControls.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void SendWheelDisappeared()
+ {
+ WheelDisappeared?.Invoke(this, EventArgs.Empty);
+ }
}
}
\ No newline at end of file
void OnCircleObjectItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
- if (args.Action != NotifyCollectionChangedAction.Add)
- return;
- foreach (Element item in args.NewItems)
- item.Parent = this;
+ if (args.Action == NotifyCollectionChangedAction.Add)
+ {
+ foreach (Element item in args.NewItems)
+ item.Parent = this;
+ }
+ else if (args.Action == NotifyCollectionChangedAction.Remove)
+ {
+ foreach (Element item in args.OldItems)
+ item.Parent = null;
+ }
}
}
}
\ No newline at end of file
TargetView = view;
view.SetValue(ContextPopupEffectBehaviorProperty, this);
- global::System.Diagnostics.Debug.WriteLine($"TargetView = {TargetView}");
+ Console.WriteLine($"TargetView = {TargetView}");
var effect = Effect.Resolve("CircleUI.ContextPopupEffectBehavior");
if (effect != null)
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Wearable.CircularUI.Forms
+{
+ public interface IBezelInteractionRouter
+ {
+ IRotaryFocusable RotaryFocusObject { get; }
+ bool Appeared { get; }
+ }
+}
\ No newline at end of file
* limitations under the License.
*/
+using System;
using Xamarin.Forms;
namespace Tizen.Wearable.CircularUI.Forms
/// When Page is added/removed at Multipage. circular index is added/removed automatically at the top of window.
/// </summary>
/// <since_tizen> 4 </since_tizen>
+ [Obsolete("IndexPage is obsolete as of version 1.5.0. Please use Xamarin.Forms.CarouselView and Xamarin.Forms.IndicatorView instead.")]
public class IndexPage : MultiPage<ContentPage>
{
protected override ContentPage CreateDefault(object item)
using Xamarin.Forms;
using Xamarin.Forms.Internals;
using Xamarin.Forms.PlatformConfiguration.TizenSpecific;
-using Xamarin.Forms.Platform.Tizen.Native;
namespace Tizen.Wearable.CircularUI.Forms
{
}
}
}
-
protected override void LayoutChildren(double x, double y, double width, double height)
{
_controller?.Layout(new Rectangle(x, y, width, height));
/// };
/// </code>
/// </example>
+ [Obsolete("Radio is obsolete as of version 1.5.0. Please use Xamarin.Forms.RadioButton instead.")]
public class Radio : View
{
/// <summary>
StackLayout ExpanderLayout { get; }
ContentView ContentHolder { get; set; }
-
+
double ContentHeightRequest
{
get
{
if (DesignMode.IsDesignModeEnabled)
{
- return;
+ return;
}
if (Device.Flags == null || !Device.Flags.Contains(flagName))
{
WeakReference<BindableObject> _weakTarget;
BindableProperty _targetProperty;
-
+
public OnAppTheme()
{
Application.Current.RequestedThemeChanged += ThemeChanged;
Control.Step = Element.Increment;
}
}
-}
+}
\ No newline at end of file