Support new features of Tizen.CircularUI (#188)
[platform/core/csapi/xsf.git] / src / XSF / Tizen.Wearable.CircularUI.Forms.Renderer / TwoButtonPopupImplementation.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 Xamarin.Forms;
19 using Xamarin.Forms.Platform.Tizen;
20 using XForms = Xamarin.Forms.Forms;
21
22 [assembly: Dependency(typeof(Tizen.Wearable.CircularUI.Forms.Renderer.TwoButtonPopupImplementation))]
23
24 namespace Tizen.Wearable.CircularUI.Forms.Renderer
25 {
26         public class TwoButtonPopupImplementation : ITwoButtonPopup, IDisposable
27         {
28                 View _content;
29                 StackLayout _contentView;
30                 MenuItem _firstMenuItem;
31                 MenuItem _secondMenuItem;
32                 Color _firstButtonBgColor;
33                 Color _secondButtonBgColor;
34
35                 ElmSharp.Popup _popUp;
36                 ElmSharp.Layout _layout;
37                 ElmSharp.Button _firstButton;
38                 ElmSharp.Button _secondButton;
39                 ElmSharp.EvasObject _nativeContent;
40
41                 string _title;
42                 string _text;
43                 bool _isDisposed;
44
45                 public event EventHandler BackButtonPressed;
46
47                 public TwoButtonPopupImplementation()
48                 {
49                         _popUp = new ElmSharp.Popup(XForms.NativeParent);
50                         _popUp.Style = "circle";
51
52                         _layout = new ElmSharp.Layout(_popUp);
53                         _layout.SetTheme("layout", "popup", "content/circle/buttons2");
54                         _popUp.SetContent(_layout);
55
56                         _popUp.BackButtonPressed += BackButtonPressedHandler;
57                         _popUp.Dismissed += OnDismissed;
58
59                         _contentView = new StackLayout();
60                 }
61
62                 ~TwoButtonPopupImplementation()
63                 {
64                         Dispose(false);
65                 }
66
67                 public void Dispose()
68                 {
69                         Dispose(true);
70                         GC.SuppressFinalize(this);
71                 }
72
73                 protected virtual void Dispose(bool disposing)
74                 {
75                         if (_isDisposed)
76                                 return;
77
78                         if (disposing)
79                         {
80                                 if (_firstButton != null)
81                                 {
82                                         _firstButton.Unrealize();
83                                         _firstButton = null;
84                                 }
85
86                                 if (_secondButton != null)
87                                 {
88                                         _secondButton.Unrealize();
89                                         _secondButton = null;
90                                 }
91
92                                 if (_nativeContent != null)
93                                 {
94                                         _nativeContent.Unrealize();
95                                         _nativeContent = null;
96                                 }
97
98                                 if (_popUp != null)
99                                 {
100                                         _layout.Unrealize();
101                                         _layout = null;
102                                         _popUp.Unrealize();
103                                         _popUp = null;
104                                 }
105                         }
106
107                         _isDisposed = true;
108                 }
109
110                 void BackButtonPressedHandler(object sender, EventArgs e)
111                 {
112                         BackButtonPressed?.Invoke(this, EventArgs.Empty);
113                 }
114
115                 public View Content
116                 {
117                         get
118                         {
119                                 return _content;
120                         }
121                         set
122                         {
123                                 _content = value;
124                                 UpdateContent();
125                         }
126                 }
127
128                 public MenuItem FirstButton
129                 {
130                         get
131                         {
132                                 return _firstMenuItem;
133                         }
134                         set
135                         {
136                                 if (_firstMenuItem == value) return;
137                                 _firstMenuItem = value;
138
139                                 if (value is ColorMenuItem)
140                                 {
141                                         _firstButtonBgColor = ((ColorMenuItem)value).BackgroundColor;
142                                 }
143                                 else
144                                 {
145                                         _firstButtonBgColor = Color.Default;
146                                 }
147
148                                 UpdateFirstButton();
149                         }
150                 }
151
152                 public MenuItem SecondButton
153                 {
154                         get
155                         {
156                                 return _secondMenuItem;
157                         }
158                         set
159                         {
160                                 if (_secondMenuItem == value) return;
161                                 _secondMenuItem = value;
162
163                                 if (value is ColorMenuItem)
164                                 {
165                                         _secondButtonBgColor = ((ColorMenuItem)value).BackgroundColor;
166                                 }
167                                 else
168                                 {
169                                         _secondButtonBgColor = Color.Default;
170                                 }
171
172                                 UpdateSecondButton();
173                         }
174                 }
175
176                 public string Title
177                 {
178                         get
179                         {
180                                 return _title;
181                         }
182                         set
183                         {
184                                 if (_title == value) return;
185                                 _title = value;
186                                 UpdateTitle();
187                         }
188                 }
189
190                 public string Text
191                 {
192                         get
193                         {
194                                 return _text;
195                         }
196                         set
197                         {
198                                 if (_text == value) return;
199                                 _text = value;
200                                 UpdateText();
201                         }
202                 }
203
204                 void UpdateContent()
205                 {
206                         if (!XForms.IsInitialized)
207                         {
208                                 Log.Debug(FormsCircularUI.Tag, "Tizen Forms is not initialized");
209                                 return;
210                         }
211
212                         _contentView.Children.Clear();
213                         if (Content != null)
214                         {
215                                 _contentView.Children.Add(Content);
216
217                                 var renderer = Xamarin.Forms.Platform.Tizen.Platform.GetOrCreateRenderer(_contentView);
218                                 (renderer as LayoutRenderer)?.RegisterOnLayoutUpdated();
219                                 var sizeRequest = _contentView.Measure(XForms.NativeParent.Geometry.Width, XForms.NativeParent.Geometry.Height).Request.ToPixel();
220
221                                 _nativeContent = renderer.NativeView;
222                                 _nativeContent.MinimumHeight = sizeRequest.Height;
223
224                                 _layout.SetPartContent("elm.swallow.content", _nativeContent, true);
225                         }
226                         else
227                         {
228                                 _layout.SetPartContent("elm.swallow.content", null, true);
229                         }
230                 }
231
232                 void UpdateFirstButton()
233                 {
234                         _firstButton?.Hide();
235
236                         if (FirstButton != null)
237                         {
238                                 _firstButton = new ElmSharp.Button(_popUp)
239                                 {
240                                         WeightX = 1.0,
241                                         WeightY = 1.0,
242                                         Style = "popup/circle/left"
243                                 };
244
245                                 if (!string.IsNullOrEmpty(FirstButton.Text)) _firstButton.Text = FirstButton.Text;
246
247                                 if (!FirstButton.IconImageSource.IsNullOrEmpty())
248                                 {
249                                         var iconSource = FirstButton.IconImageSource as FileImageSource;
250                                         if (!iconSource.IsNullOrEmpty())
251                                         {
252                                                 var buttonImage = new ElmSharp.Image(_firstButton);
253                                                 buttonImage.LoadAsync(ResourcePath.GetPath(iconSource));
254                                                 buttonImage.Show();
255                                                 _firstButton.SetPartContent("elm.swallow.content", buttonImage);
256                                         }
257                                 }
258
259                                 _firstButton.Clicked += (s, e) =>
260                                 {
261                                         ((IMenuItemController)FirstButton).Activate();
262                                 };
263
264                                 if (_firstButtonBgColor != Color.Default)
265                                 {
266                                         Log.Debug(FormsCircularUI.Tag, $"TwoButtonPopup set first button background color:{_firstButtonBgColor.ToNative()}");
267                                         _firstButton.BackgroundColor = _firstButtonBgColor.ToNative();
268                                 }
269                         }
270                         else
271                         {
272                                 _firstButton = null;
273                         }
274
275                         _popUp.SetPartContent("button1", _firstButton);
276                 }
277
278                 void UpdateSecondButton()
279                 {
280                         _secondButton?.Hide();
281
282                         if (SecondButton != null)
283                         {
284                                 _secondButton = new ElmSharp.Button(_popUp)
285                                 {
286                                         WeightX = 1.0,
287                                         WeightY = 1.0,
288                                         Style = "popup/circle/right"
289                                 };
290
291                                 if (!string.IsNullOrEmpty(SecondButton.Text)) _secondButton.Text = SecondButton.Text;
292
293                                 if (!SecondButton.IconImageSource.IsNullOrEmpty())
294                                 {
295                                         var iconSource = SecondButton.IconImageSource as FileImageSource;
296                                         if (!iconSource.IsNullOrEmpty())
297                                         {
298                                                 var buttonImage = new ElmSharp.Image(_secondButton);
299                                                 buttonImage.LoadAsync(ResourcePath.GetPath(iconSource));
300                                                 buttonImage.Show();
301                                                 _secondButton.SetPartContent("elm.swallow.content", buttonImage);
302                                         }
303                                 }
304
305                                 _secondButton.Clicked += (s, e) =>
306                                 {
307                                         ((IMenuItemController)SecondButton).Activate();
308                                 };
309
310                                 if (_secondButtonBgColor != Color.Default)
311                                 {
312                                         Log.Debug(FormsCircularUI.Tag, $"TwoButtonPopup set second button background color:{_secondButtonBgColor.ToNative()}");
313                                         _secondButton.BackgroundColor = _secondButtonBgColor.ToNative();
314                                 }
315
316                                 _popUp.SetPartContent("button2", _secondButton);
317                         }
318                         else
319                         {
320                                 /* This is workaround fix for Left button occupied whole window when right button is null*/
321                                 _secondButton = new ElmSharp.Button(_popUp)
322                                 {
323                                         WeightX = 1.0,
324                                         WeightY = 1.0,
325                                         Style = "popup/circle/right"
326                                 };
327                                 _popUp.SetPartContent("button2", _secondButton);
328                                 _secondButton.Unrealize();
329                                 _secondButton = null;
330                         }
331                 }
332
333                 void UpdateTitle()
334                 {
335                         string title = _title?.Replace("&", "&")
336                                                                   .Replace("<", "&lt;")
337                                                                   .Replace(">", "&gt;")
338                                                                   .Replace(Environment.NewLine, "<br>");
339                         _layout.SetPartText("elm.text.title", title);
340                 }
341
342                 void UpdateText()
343                 {
344                         string text = _text?.Replace("&", "&amp;")
345                                                                 .Replace("<", "&lt;")
346                                                                 .Replace(">", "&gt;")
347                                                                 .Replace(Environment.NewLine, "<br>");
348                         _layout.SetPartText("elm.text", text);
349                 }
350
351                 public void Show()
352                 {
353                         if (!XForms.IsInitialized)
354                         {
355                                 throw new InvalidOperationException("When the Application's Platform is not initialized, it can not show the Dialog.");
356                         }
357
358                         if (_popUp != null)
359                         {
360                                 _popUp.Show();
361                         }
362                 }
363
364                 public void Dismiss()
365                 {
366                         if (_firstButton != null)
367                         {
368                                 _firstButton.Unrealize();
369                                 _firstButton = null;
370                                 _popUp.SetPartContent("button1", null);
371                         }
372
373                         if (_secondButton != null)
374                         {
375                                 _secondButton.Unrealize();
376                                 _secondButton = null;
377                                 _popUp.SetPartContent("button2", null);
378                         }
379
380                         if (_nativeContent != null)
381                         {
382                                 _nativeContent.Unrealize();
383                                 _nativeContent = null;
384                         }
385
386                         if (_popUp != null)
387                         {
388                                 _layout.Unrealize();
389                                 _layout = null;
390                                 _popUp.Unrealize();
391                                 _popUp = null;
392                         }
393                 }
394
395                 void OnDismissed(object sender, EventArgs e)
396                 {
397                         Log.Debug(FormsCircularUI.Tag, $"OnDismissed called");
398                         Dispose();
399                 }
400         }
401 }