Support new features of CircularUI based on 1.5.0 branch (#225)
author유리나/Common Platform Lab(SR)/Staff Engineer/삼성전자 <rina6350.you@samsung.com>
Thu, 14 May 2020 12:37:12 +0000 (08:37 -0400)
committer윤정현/Common Platform Lab(SR)/Staff Engineer/삼성전자 <jh0506.yun@samsung.com>
Thu, 14 May 2020 12:37:12 +0000 (21:37 +0900)
* Fix SVACE issues (#274)

* Fix SVACE issues

* Add guard for null exceptions

* Make PageRenderer even better (#279)

* Add WheelAppeared and WheelDisappeared events in CircleStepper (#282)

* Fix IndexPage CurrentPage issue (#285)

* Fix rotary event activation issue (#286)

* Fix rotary event issue

* Add TC

* Add BezelInteractionPage (#298)

* Add BezelInteractionPage

* Apply code review

* Deprecate the legacy APIs

* Refactoring CircularShell Renderer

* Update bezel interaction behavior (#299)

* Refactoring CircularShell Renderer

* Update bezel interaction behavior

* Update OnMoreOptionOpened/Closed

* Update CircleScrollViewRenderer (#300)

* Update CircleScrollViewRenderer

* Obsolete BarColor property in CircleScrollView

* Update the CircleScrollViewRenderer (#301)

* Update CircleStepperRenderer and CircleDateTimeSelectorRenderer (#296)

* Update ActiveBezelInteractionElement on Activate bezel interaction (#302)

* Update CircleListViewRenderer (#303)

* Update CircleListViewRenderer

* Apply Review comment

* Remove unused ListViewCache

* Update Bezel Intercation behavior on closing dialog (#304)

* Merge 1.5.0 branch of CircularUI

* Update Renderer to use disable rotary event on IBezelInteractionRoutor (#305)

* Fix ExportRenderer (#306)

* Meets alignment for all cs files

62 files changed:
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/BezelInteractionPageRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleDateTimeSelectorRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleImageRenderer.cs [changed mode: 0755->0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleListView.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleListViewRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CirclePageRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleScrollViewRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleStepperRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleSurfaceViewRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircularUI.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircularUIForms.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CollectionViewRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/DatePickerRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/GoogleMapViewRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/IBezelInteractionController.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ICircleSurfaceItemRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/IndexPageRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/InformationPopupImplementation.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/LayoutCanvas.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ListViewCache.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ListViewRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/NativeCirclePage.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/NativeFactory.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ObservableBox.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/PageRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/PopupEntryRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/RadioRenderer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ScrollViewRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellRendererFactory.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellSectionItemsRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/IShellItemRenderer.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/NavigationDrawer.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/NavigationView.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellContentRenderer.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellItemRenderer.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellRenderer.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellRendererFactory.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellSectionItemsRenderer.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellSectionNavigationRenderer.cs [deleted file]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/StepperRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ThemeLoader.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/TimePickerRenderer.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/TizenCircleSurfaceEffect.cs [changed mode: 0755->0644]
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/TwoButtonPopupImplementation.cs
src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/WatchListView.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms/BezelInteractionPage.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms/Check.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/CirclePage.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/CircleScrollView.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/CircleStepper.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/CircleSurfaceView.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/ContextPopupEffectBehavior.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/IBezelInteractionRouter.cs [new file with mode: 0644]
src/XSF/Tizen.Wearable.CircularUI.Forms/IndexPage.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/MediaPlayer.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/MediaView.cs
src/XSF/Tizen.Wearable.CircularUI.Forms/Radio.cs
src/XSF/Xamarin.Forms.Core/Expander.cs
src/XSF/Xamarin.Forms.Core/ExperimentalFlags.cs
src/XSF/Xamarin.Forms.Core/OnAppTheme.cs
src/XSF/Xamarin.Forms.Platform.Tizen/Renderers/StepperRenderer.cs

diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/BezelInteractionPageRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/BezelInteractionPageRenderer.cs
new file mode 100644 (file)
index 0000000..88f03a1
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * 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
index 461ae10..c28a5ff 100644 (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()
                {
@@ -53,7 +54,7 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                                var surface = this.GetSurface();
                                if (null != surface)
                                {
-                                       SetNativeControl(new ECircleDateTimeSelector(XForms.NativeParent, surface));
+                                       SetNativeControl(new WatchDateTimePicker(XForms.NativeParent, surface));
                                        Control.DateTimeChanged += OnDateTimeChanged;
                                }
                                else
@@ -74,25 +75,27 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        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;
                        }
@@ -100,25 +103,13 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                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();
                        }
@@ -127,57 +118,52 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                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");
                        }
                }
        }
old mode 100755 (executable)
new mode 100644 (file)
index aed0ebf..440bcfe
@@ -23,6 +23,7 @@ using Tizen.Wearable.CircularUI.Forms.Renderer;
 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
@@ -30,18 +31,16 @@ 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;
@@ -141,12 +140,12 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                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();
                        }
                }
 
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleListView.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CircleListView.cs
deleted file mode 100644 (file)
index fb06f79..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * 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
index d6ef93c..91bb806 100644 (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();
                        }
                }
        }
index a49e7aa..9aa1ab7 100644 (file)
  * 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()
@@ -111,74 +119,217 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        }
                }
 
-               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("&", "&amp;")
+                       .Replace("<", "&lt;")
+                       .Replace(">", "&gt;")
+                       .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)
@@ -187,14 +338,99 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                                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
index c11130f..c9b39d2 100644 (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
index 866f812..29dad77 100644 (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()
                {
@@ -36,62 +35,24 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 #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)
@@ -117,10 +78,20 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        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();
                        }
@@ -129,68 +100,29 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                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
index e53e60e..41d388a 100644 (file)
@@ -28,13 +28,21 @@ using ELayout = ElmSharp.Layout;
 [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)
index f40c4c9..9ab8d3b 100644 (file)
@@ -17,6 +17,7 @@ using System;
 using System.Diagnostics;
 using Tizen.Applications;
 using Tizen.Wearable.CircularUI.Forms.Renderer;
+using Tizen.Wearable.CircularUI.Forms.Renderer.Shell;
 
 namespace Tizen.Wearable.CircularUI.Forms
 {
@@ -48,6 +49,7 @@ namespace Tizen.Wearable.CircularUI.Forms
                {
                        if (IsInitialized) return;
                        IsInitialized = true;
+       CircularShellRendererFactory.Setup();
                }
 
                public static void Init(string apiKey)
index fb6dcf3..ad638a3 100644 (file)
@@ -26,7 +26,7 @@ namespace Tizen.Wearable.CircularUI.Forms
                        { 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() },
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CollectionViewRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/CollectionViewRenderer.cs
new file mode 100644 (file)
index 0000000..1fa945f
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/DatePickerRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/DatePickerRenderer.cs
new file mode 100644 (file)
index 0000000..fa21ebe
--- /dev/null
@@ -0,0 +1,25 @@
+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
index 29c7023..f8788c0 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 using System;
-using SCObjectModel = System.Collections.ObjectModel;
+using OModel = System.Collections.ObjectModel;
 using System.Collections.Specialized;
 using System.Text;
 using Tizen.Wearable.CircularUI.Forms;
@@ -59,13 +59,13 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                        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();
                        }
@@ -85,7 +85,7 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                                }
                                if (Element != null)
                                {
-                                       ((SCObjectModel.ObservableCollection<Marker>)Element.Markers).CollectionChanged -= OnCollectionChanged;
+       ((OModel.ObservableCollection<Marker>)Element.Markers).CollectionChanged -= OnCollectionChanged;
                                        Element.LoadMapRequested -= OnLoadMapRequested;
                                }
                        }
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/IBezelInteractionController.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/IBezelInteractionController.cs
new file mode 100644 (file)
index 0000000..043a067
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ICircleSurfaceItemRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ICircleSurfaceItemRenderer.cs
new file mode 100644 (file)
index 0000000..9b617da
--- /dev/null
@@ -0,0 +1,9 @@
+using ElmSharp.Wearable;
+
+namespace Tizen.Wearable.CircularUI.Forms.Renderer
+{
+       interface ICircleSurfaceItemRenderer
+       {
+               ICircleWidget GetCircleWidget(ICircleSurfaceItem item);
+       }
+}
\ No newline at end of file
index 9985603..a41dc3c 100644 (file)
@@ -148,9 +148,10 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                                (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);
                        }
@@ -242,8 +243,8 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        }
                        _pageIndex = Element.Children.IndexOf(Element.CurrentPage);
                        _isUpdateCarousel = true;
+       Element.UpdateFocusTreePolicy();
                        _scroller.ScrollTo(_pageIndex, 0, false);
-                       Element.UpdateFocusTreePolicy();
                        _isUpdateCarousel = false;
                }
 
index df0a943..cbea260 100644 (file)
@@ -255,7 +255,7 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                                _bottomButton.Clicked += (s, e) =>
                                {
-                                       ((IMenuItemController)BottomButton).Activate();
+                                       (BottomButton as IMenuItemController)?.Activate();
                                };
 
                                if (_buttonBgColor != Color.Default)
@@ -266,7 +266,7 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        }
                        else
                        {
-                               _bottomButton.Unrealize();
+                               _bottomButton?.Unrealize();
                                _bottomButton = null;
                        }
 
index f1e6119..9e71b65 100644 (file)
 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;
 
 
@@ -72,7 +72,7 @@ namespace Tizen.Wearable.CircularUI.Forms
                        };
                }
 
-               public event EventHandler<TNative.LayoutEventArgs> LayoutUpdated
+               public event EventHandler<LayoutEventArgs> LayoutUpdated
                {
                        add { _box.LayoutUpdated += value; }
                        remove { _box.LayoutUpdated -= value; }
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ListViewCache.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ListViewCache.cs
deleted file mode 100644 (file)
index bb64770..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ListViewRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ListViewRenderer.cs
new file mode 100644 (file)
index 0000000..c30e78c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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
index ef0bc84..deddd0a 100644 (file)
@@ -28,7 +28,7 @@ using ERotaryEventManager = ElmSharp.Wearable.RotaryEventManager;
 
 namespace Tizen.Wearable.CircularUI.Forms.Renderer
 {
-       public class NativeCirclePage : ObservableBox
+       class NativeCirclePage : ObservableBox
        {
                ElmSharp.Rectangle _bgColorObject;
                ElmSharp.EvasImage _bgImageObject;
@@ -154,6 +154,10 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                public void ActivateRotaryWidget()
                {
+                       CirclePage cp = _element as CirclePage;
+                       if (!cp.Appeared)
+                               return;
+
                        if (_currentRotaryFocusObject is IRotaryEventReceiver)
                        {
                                ERotaryEventManager.Rotated += OnRotaryEventChanged;
index 301e0b7..cb30e7d 100644 (file)
@@ -21,9 +21,9 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                                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();
@@ -45,16 +45,16 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        }
                        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))
                        {
@@ -80,11 +80,11 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        }
                        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)
                        {
index 265f955..0c28ba0 100644 (file)
 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)
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/PageRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/PageRenderer.cs
new file mode 100644 (file)
index 0000000..c2bc4fb
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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
index 6e4b6cf..20e24fd 100644 (file)
@@ -183,6 +183,7 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        {
                                CreatePopup();
                        }
+
                        _editor.IsPassword = Control.IsPassword;
                        if (Control is IEntry ie)
                        {
index de8112a..b27e89a 100644 (file)
@@ -25,8 +25,10 @@ using ERadio = ElmSharp.Radio;
 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>();
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ScrollViewRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/ScrollViewRenderer.cs
new file mode 100644 (file)
index 0000000..cfa2f32
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellRenderer.cs
new file mode 100644 (file)
index 0000000..14cc4f9
--- /dev/null
@@ -0,0 +1,78 @@
+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;
+        }
+    }
+}
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellRendererFactory.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellRendererFactory.cs
new file mode 100644 (file)
index 0000000..5294de1
--- /dev/null
@@ -0,0 +1,22 @@
+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);
+        }
+    }
+}
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellSectionItemsRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/CircularShellSectionItemsRenderer.cs
new file mode 100644 (file)
index 0000000..0ba03f5
--- /dev/null
@@ -0,0 +1,34 @@
+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;
+        }
+    }
+}
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/IShellItemRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/IShellItemRenderer.cs
deleted file mode 100644 (file)
index aeffc75..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/NavigationDrawer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/NavigationDrawer.cs
deleted file mode 100644 (file)
index 342021d..0000000
+++ /dev/null
@@ -1,543 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/NavigationView.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/NavigationView.cs
deleted file mode 100644 (file)
index bd07f3c..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellContentRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellContentRenderer.cs
deleted file mode 100644 (file)
index 47c0673..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellItemRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellItemRenderer.cs
deleted file mode 100644 (file)
index 908851a..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellRenderer.cs
deleted file mode 100644 (file)
index 525e369..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellRendererFactory.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellRendererFactory.cs
deleted file mode 100644 (file)
index 5895d44..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellSectionItemsRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellSectionItemsRenderer.cs
deleted file mode 100644 (file)
index 3e72aca..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellSectionNavigationRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/Shell/ShellSectionNavigationRenderer.cs
deleted file mode 100644 (file)
index ca5d705..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/StepperRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/StepperRenderer.cs
new file mode 100644 (file)
index 0000000..d201e22
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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
index 6b5e569..8e4ecc2 100644 (file)
@@ -19,9 +19,9 @@ using Circular = Tizen.Wearable.CircularUI.Forms.FormsCircularUI;
 
 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; }
 
@@ -37,14 +37,14 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
                        }
                }
 
-        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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/TimePickerRenderer.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/TimePickerRenderer.cs
new file mode 100644 (file)
index 0000000..3680aa6
--- /dev/null
@@ -0,0 +1,25 @@
+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
index f5141a2..d69e90d 100644 (file)
@@ -259,7 +259,7 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                                _firstButton.Clicked += (s, e) =>
                                {
-                                       ((IMenuItemController)FirstButton).Activate();
+       (FirstButton as IMenuItemController)?.Activate();
                                };
 
                                if (_firstButtonBgColor != Color.Default)
@@ -305,7 +305,7 @@ namespace Tizen.Wearable.CircularUI.Forms.Renderer
 
                                _secondButton.Clicked += (s, e) =>
                                {
-                                       ((IMenuItemController)SecondButton).Activate();
+       (SecondButton as IMenuItemController)?.Activate();
                                };
 
                                if (_secondButtonBgColor != Color.Default)
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/WatchListView.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms.Renderer/WatchListView.cs
new file mode 100644 (file)
index 0000000..007261a
--- /dev/null
@@ -0,0 +1,65 @@
+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
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms/BezelInteractionPage.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms/BezelInteractionPage.cs
new file mode 100644 (file)
index 0000000..3d923b4
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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
index 90b5008..5fcf978 100644 (file)
@@ -38,6 +38,7 @@ namespace Tizen.Wearable.CircularUI.Forms
        /// }
        /// </code>
        /// </example>
+       [Obsolete("Check is obsolete as of version 1.5.0. Please use Xamarin.Forms.Switch instead.")]
        public class Check : Switch
        {
                /// <summary>
index 85beff4..f4df755 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Collections.Specialized;
@@ -27,7 +28,8 @@ namespace Tizen.Wearable.CircularUI.Forms
        /// 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.
index a71c37b..f7dde6e 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+using System;
 using Xamarin.Forms;
 
 namespace Tizen.Wearable.CircularUI.Forms
@@ -29,7 +30,7 @@ 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.
index 1e0cf39..b2a34f9 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.ComponentModel;
 using Xamarin.Forms;
 
 namespace Tizen.Wearable.CircularUI.Forms
@@ -112,5 +113,35 @@ 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
index 4bf63db..3d32b84 100644 (file)
@@ -46,10 +46,16 @@ namespace Tizen.Wearable.CircularUI.Forms
 
                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
index d9c196a..ee2d3a7 100644 (file)
@@ -162,7 +162,7 @@ namespace Tizen.Wearable.CircularUI.Forms
                        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)
diff --git a/src/XSF/Tizen.Wearable.CircularUI.Forms/IBezelInteractionRouter.cs b/src/XSF/Tizen.Wearable.CircularUI.Forms/IBezelInteractionRouter.cs
new file mode 100644 (file)
index 0000000..a183297
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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
index 1f19fed..3f93200 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+using System;
 using Xamarin.Forms;
 
 namespace Tizen.Wearable.CircularUI.Forms
@@ -23,6 +24,7 @@ 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)
index 0206336..e66c350 100644 (file)
@@ -23,7 +23,6 @@ using System.Threading.Tasks;
 using Xamarin.Forms;
 using Xamarin.Forms.Internals;
 using Xamarin.Forms.PlatformConfiguration.TizenSpecific;
-using Xamarin.Forms.Platform.Tizen.Native;
 
 namespace Tizen.Wearable.CircularUI.Forms
 {
index a69c8a2..e517b61 100644 (file)
@@ -70,7 +70,6 @@ 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));
index ab1ff25..3b9f05c 100644 (file)
@@ -50,6 +50,7 @@ namespace Tizen.Wearable.CircularUI.Forms
        /// };
        /// </code>
        /// </example>
+       [Obsolete("Radio is obsolete as of version 1.5.0. Please use Xamarin.Forms.RadioButton instead.")]
        public class Radio : View
        {
                /// <summary>
index 67f5a9b..b331631 100644 (file)
@@ -76,7 +76,7 @@ namespace Xamarin.Forms
                StackLayout ExpanderLayout { get; }
 
                ContentView ContentHolder { get; set; }
-               
+
                double ContentHeightRequest
                {
                        get
index e4c1fe8..62887c2 100644 (file)
@@ -29,7 +29,7 @@ namespace Xamarin.Forms
                {
                        if (DesignMode.IsDesignModeEnabled)
                        {
-                               return; 
+                               return;
                        }
 
                        if (Device.Flags == null || !Device.Flags.Contains(flagName))
index 49c3c04..b8b7b67 100644 (file)
@@ -6,7 +6,7 @@ namespace Xamarin.Forms
        {
                WeakReference<BindableObject> _weakTarget;
                BindableProperty _targetProperty;
-               
+
                public OnAppTheme()
                {
                        Application.Current.RequestedThemeChanged += ThemeChanged;
index beb5b02..f54eb1e 100644 (file)
@@ -98,4 +98,4 @@ namespace Xamarin.Forms.Platform.Tizen
                        Control.Step = Element.Increment;
                }
        }
-}
+}
\ No newline at end of file