3cf18b17ab6ec63eb44c31ddf94505bf4a8a635a
[platform/core/csapi/xsf.git] / src / XSF / Tizen.Wearable.CircularUI.Forms.Renderer / CircleStepperRenderer.cs
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using ESpinner = ElmSharp.Wearable.CircleSpinner;
19 using ESize = ElmSharp.Size;
20 using Xamarin.Forms;
21 using Xamarin.Forms.Platform.Tizen;
22 using XForms = Xamarin.Forms.Forms;
23
24 [assembly: ExportRenderer(typeof(Tizen.Wearable.CircularUI.Forms.CircleStepper), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.CircleStepperRenderer))]
25
26
27 namespace Tizen.Wearable.CircularUI.Forms.Renderer
28 {
29         public class CircleStepperRenderer : ViewRenderer<CircleStepper, ESpinner>
30         {
31                 public CircleStepperRenderer()
32                 {
33 #pragma warning disable CS0618 // MarkerColorProperty and MarkerLineWidthProperty are obsolete
34                         RegisterPropertyHandler(CircleStepper.MarkerColorProperty, UpdateMarkerColor);
35                         RegisterPropertyHandler(CircleStepper.MarkerLineWidthProperty, UpdateMarkerLineWidth);
36 #pragma warning restore CS0618 // MarkerColorProperty and MarkerLineWidthProperty are obsolete
37                         RegisterPropertyHandler(CircleStepper.LabelFormatProperty, UpdateLabelFormat);
38                         RegisterPropertyHandler(CircleStepper.TitleProperty, UpdateTitle);
39                         RegisterPropertyHandler(Stepper.MinimumProperty, UpdateMinimum);
40                         RegisterPropertyHandler(Stepper.MaximumProperty, UpdateMaximum);
41                         RegisterPropertyHandler(Stepper.ValueProperty, UpdateValue);
42                         RegisterPropertyHandler(Stepper.IncrementProperty, UpdateIncrement);
43                 }
44
45                 protected override void OnElementChanged(ElementChangedEventArgs<CircleStepper> e)
46                 {
47                         if (Control == null)
48                         {
49                                 var surface = this.GetSurface();
50                                 if (null != surface)
51                                 {
52                                         var spinner = new ESpinner(XForms.NativeParent, surface);
53                                         spinner.Style = "circle";
54
55                                         SetNativeControl(spinner);
56                                         Control.ValueChanged += OnValueChanged;
57                                 }
58                                 else
59                                 {
60                                         throw new CirclePageNotFoundException();
61                                 }
62                         }
63
64                         base.OnElementChanged(e);
65                 }
66
67                 private void OnValueChanged(object sender, EventArgs e)
68                 {
69                         double newValue = Control.Value;
70                         ((IElementController)Element).SetValueFromRenderer(Stepper.ValueProperty, newValue);
71
72                         if (Element.LabelFormat == null)
73                         {
74                                 // Determines how many decimal places are there in current Stepper's value.
75                                 // The 15 pound characters below correspond to the maximum precision of Double type.
76                                 var decimalValue = Decimal.Parse(newValue.ToString("0.###############"));
77
78                                 // GetBits() method returns an array of four 32-bit integer values.
79                                 // The third (0-indexing) element of an array contains the following information:
80                                 //     bits 00-15: unused, required to be 0
81                                 //     bits 16-23: an exponent between 0 and 28 indicating the power of 10 to divide the integer number passed as a parameter.
82                                 //                 Conversely this is the number of decimal digits in the number as well.
83                                 //     bits 24-30: unused, required to be 0
84                                 //     bit     31: indicates the sign. 0 means positive number, 1 is for negative numbers.
85                                 //
86                                 // The precision information needs to be extracted from bits 16-23 of third element of an array
87                                 // returned by GetBits() call. Right-shifting by 16 bits followed by zeroing anything else results
88                                 // in a nice conversion of this data to integer variable.
89                                 var precision = (Decimal.GetBits(decimalValue)[3] >> 16) & 0x000000FF;
90
91                                 // Sets Stepper's inner label decimal format to use exactly as many decimal places as needed:
92                                 Control.LabelFormat = string.Format("%.{0}f", precision);
93                         }
94                 }
95
96                 protected override void Dispose(bool disposing)
97                 {
98                         if (disposing)
99                         {
100                                 if (Control != null)
101                                 {
102                                         Control.ValueChanged -= OnValueChanged;
103                                 }
104                         }
105                         base.Dispose(disposing);
106                 }
107
108                 protected override Size MinimumSize()
109                 {
110                         // This width and height are values taken from SPINNER_LAYOUT_CONTENT_AREA_SIZE of elm-theme-tizen-wearable module
111                         return new ESize(360, 110).ToDP();
112                 }
113
114                 protected override ESize Measure(int availableWidth, int availableHeight)
115                 {
116                         return new ESize(360, 110);
117                 }
118
119                 void UpdateMarkerColor()
120                 {
121 #pragma warning disable CS0618 // MarkerColor is obsolete
122                         if (null != Control && null != Element && Element.MarkerColor != Color.Default)
123                         {
124                                 Control.MarkerColor = Element.MarkerColor.ToNative();
125                         }
126 #pragma warning restore CS0618 // MarkerColor is obsolete
127                 }
128
129                 void UpdateMarkerLineWidth()
130                 {
131                         if (null != Control && null != Element)
132                         {
133 #pragma warning disable CS0618 // MarkerLineWidth is obsolete
134                                 Control.MarkerLineWidth = Element.MarkerLineWidth;
135 #pragma warning restore CS0618 // MarkerLineWidth is obsolete
136                         }
137                 }
138
139                 void UpdateLabelFormat()
140                 {
141                         if (null != Control && null != Element)
142                         {
143                                 Control.LabelFormat = Element.LabelFormat;
144                         }
145                 }
146
147                 void UpdateTitle()
148                 {
149                         if (null != Control && null != Element)
150                         {
151                                 Control.SetPartText("elm.text", Element.Title);
152                         }
153                 }
154
155                 void UpdateValue()
156                 {
157                         if (null != Control && null != Element)
158                         {
159                                 Control.Value = Element.Value;
160                         }
161                 }
162
163                 void UpdateMaximum()
164                 {
165                         if (null != Control && null != Element)
166                         {
167                                 Control.Maximum = Element.Maximum;
168                         }
169                 }
170
171                 void UpdateMinimum()
172                 {
173                         if (null != Control && null != Element)
174                         {
175                                 Control.Minimum = Element.Minimum;
176                         }
177                 }
178
179                 void UpdateIncrement()
180                 {
181                         if (null != Control && null != Element)
182                         {
183                                 Control.Step = Element.Increment;
184                         }
185                 }
186         }
187 }