Support new features of Tizen.CircularUI (#188)
[platform/core/csapi/xsf.git] / src / XSF / Xamarin.Forms.Platform.Tizen / Shell / ShellNavBar.cs
1 using System;
2 using System.Reflection;
3 using ElmSharp;
4 using Xamarin.Forms.Platform.Tizen.Native;
5 using EColor = ElmSharp.Color;
6 using EButton = ElmSharp.Button;
7 using EImage = ElmSharp.Image;
8
9 namespace Xamarin.Forms.Platform.Tizen
10 {
11         public class ShellNavBar : Native.Box
12         {
13                 EImage _menu = null;
14                 EButton _menuButton = null;
15                 Native.Label _title = null;
16                 Native.SearchBar _nativeSearchHandler = null;
17                 EvasObject _nativeTitleView = null;
18
19                 SearchHandler _searchHandler = null;
20                 View _titleView = null;
21                 Page _page = null;
22
23                 IFlyoutController _flyoutController = null;
24
25                 EColor _backgroudColor = ShellRenderer.DefaultBackgroundColor.ToNative();
26                 EColor _foregroudColor = ShellRenderer.DefaultForegroundColor.ToNative();
27
28                 // The source of icon resources is https://materialdesignicons.com/
29                 const string _menuIcon = "XSF.Resources.menu.png";
30                 const string _backIcon = "XSF.Resources.arrow_left.png";
31
32                 bool _hasBackButton = false;
33
34                 public ShellNavBar(IFlyoutController flyoutController) : base(Forms.NativeParent)
35                 {
36                         _flyoutController = flyoutController;
37
38                         _menuButton = new EButton(Forms.NativeParent);
39                         _menuButton.Clicked += OnMenuClicked;
40                         _menu = new EImage(Forms.NativeParent);
41                         UpdateMenuIcon();
42                         _menu.Show();
43                         _menuButton.Show();
44
45                         _menuButton.SetPartContent("icon", _menu);
46
47                         _title = new Native.Label(Forms.NativeParent)
48                         {
49                                 FontSize = Device.Idiom == TargetIdiom.TV ? 60 : 23,
50                                 VerticalTextAlignment = Native.TextAlignment.Center,
51                                 TextColor = _backgroudColor,
52                                 FontAttributes = FontAttributes.Bold,
53                         };
54                         _title.Show();
55
56                         BackgroundColor = _backgroudColor;
57                         _menuButton.BackgroundColor = _backgroudColor;
58                         PackEnd(_menuButton);
59                         PackEnd(_title);
60                         LayoutUpdated += OnLayoutUpdated;
61                 }
62
63                 public bool HasBackButton
64                 {
65                         get
66                         {
67                                 return _hasBackButton;
68                         }
69                         set
70                         {
71                                 _hasBackButton = value;
72                                 UpdateMenuIcon();
73                         }
74                 }
75
76                 public SearchHandler SearchHandler
77                 {
78                         get
79                         {
80                                 return _searchHandler;
81                         }
82                         set
83                         {
84                                 _searchHandler = value;
85                                 UpdateSearchHandler(_searchHandler);
86                                 UpdateChildren();
87                         }
88                 }
89
90                 public View TitleView
91                 {
92                         get
93                         {
94                                 return _titleView;
95                         }
96                         set
97                         {
98                                 _titleView = value;
99                                 UpdateTitleView(_titleView);
100                                 UpdateChildren();
101                         }
102                 }
103
104                 public string Title
105                 {
106                         get
107                         {
108                                 return _title?.Text;
109                         }
110                         set
111                         {
112                                 if (string.IsNullOrEmpty(value))
113                                 {
114                                         _title?.Hide();
115                                 }
116                                 else
117                                 {
118                                         _title.Text = value;
119                                 }
120                         }
121                 }
122
123                 public override EColor BackgroundColor
124                 {
125                         get
126                         {
127                                 return _backgroudColor;
128                         }
129                         set
130                         {
131                                 _backgroudColor = value;
132                                 _menuButton.BackgroundColor = _backgroudColor;
133                                 base.BackgroundColor = _backgroudColor;
134                         }
135                 }
136
137                 public EColor ForegroundColor
138                 {
139                         get
140                         {
141                                 return _foregroudColor;
142                         }
143                         set
144                         {
145                                 _foregroudColor = value;
146                                 _menuButton.Color = value;
147                         }
148                 }
149
150                 public EColor TitleColor
151                 {
152                         get
153                         {
154                                 return _title.TextColor;
155                         }
156                         set
157                         {
158                                 _title.TextColor = value;
159                         }
160                 }
161
162                 internal Page CurrentPage
163                 {
164                         get
165                         {
166                                 return _page;
167                         }
168                         set
169                         {
170                                 _page = value;
171                         }
172                 }
173
174                 void UpdateMenuIcon()
175                 {
176                         string file = _hasBackButton ? _backIcon : _menuIcon;
177                         var path = Assembly.GetExecutingAssembly().GetManifestResourceStream(file);
178                         _menu.Load(path);
179                 }
180
181                 void OnMenuClicked(object sender, EventArgs e)
182                 {
183                         var backButtonHandler = Shell.GetBackButtonBehavior(_page);
184                         if (backButtonHandler?.Command != null)
185                         {
186                                 backButtonHandler.Command.Execute(backButtonHandler.CommandParameter);
187                         }
188                         else if (_hasBackButton)
189                         {
190                                 Shell.Current.CurrentItem.Navigation.PopAsync();
191                         }
192                         else
193                         {
194                                 _flyoutController.Open();
195                         }
196                 }
197
198                 void UpdateTitleView(View titleView)
199                 {
200                         _nativeTitleView?.Unrealize();
201                         _nativeTitleView = null;
202
203                         if (titleView != null)
204                         {
205                                 var renderer = Platform.GetOrCreateRenderer(titleView);
206                                 (renderer as LayoutRenderer)?.RegisterOnLayoutUpdated();
207                                 _nativeTitleView = renderer.NativeView;
208                                 PackEnd(_nativeTitleView);
209                         }
210                 }
211
212                 void UpdateSearchHandler(SearchHandler handler)
213                 {
214                         _nativeSearchHandler?.Unrealize();
215                         _nativeSearchHandler = null;
216
217                         if (handler != null)
218                         {
219                                 _nativeSearchHandler = new Native.SearchBar(Forms.NativeParent);
220                                 _nativeSearchHandler.IsSingleLine = true;
221                                 _nativeSearchHandler.BackgroundColor = ElmSharp.Color.White;
222                                 _nativeSearchHandler.Placeholder = handler.Placeholder;
223                                 _nativeSearchHandler.Show();
224                                 PackEnd(_nativeSearchHandler);
225                         }
226                 }
227
228                 Native.Image GetSearchHandlerIcon(ImageSource source)
229                 {
230                         Native.Image _icon = new Native.Image(Forms.NativeParent);
231                         if (source != null)
232                         {
233                                 var task = _icon.LoadFromImageSourceAsync(source);
234                         }
235                         return _icon;
236                 }
237
238                 void UpdateChildren()
239                 {
240                         if (_searchHandler != null)
241                         {
242                                 _nativeSearchHandler.Show();
243                                 _title?.Hide();
244                                 _nativeTitleView?.Hide();
245                         }
246                         else if (_titleView != null)
247                         {
248                                 _nativeTitleView.Show();
249                                 _title?.Hide();
250                                 _nativeSearchHandler?.Hide();
251                         }
252                         else
253                         {
254                                 _title.Show();
255                                 _nativeTitleView?.Hide();
256                                 _nativeSearchHandler?.Hide();
257                         }
258                         UpdatPageLayout();
259                 }
260
261                 void OnLayoutUpdated(object sender, LayoutEventArgs e)
262                 {
263                         int menuSize = 50;
264                         int menuMargin = 20;
265                         int titleLeftMargin = 40;
266                         int titleViewTopMargin = 40;
267
268                         _menuButton.Move(e.Geometry.X + menuMargin, e.Geometry.Y + (e.Geometry.Height - menuSize) / 2);
269                         _menuButton.Resize(menuSize, menuSize);
270
271                         if (_searchHandler != null)
272                         {
273                                 _nativeSearchHandler.Move(e.Geometry.X + (menuSize + menuMargin * 2) + titleLeftMargin, e.Geometry.Y + (titleViewTopMargin / 2));
274                                 _nativeSearchHandler.Resize(e.Geometry.Width - (menuSize + menuMargin * 2) - titleLeftMargin - (titleViewTopMargin / 2), e.Geometry.Height - titleViewTopMargin);
275                         }
276                         else if (_titleView != null)
277                         {
278                                 _nativeTitleView.Move(e.Geometry.X + (menuSize + menuMargin * 2) + titleLeftMargin, e.Geometry.Y + (titleViewTopMargin / 2));
279                                 _nativeTitleView.Resize(e.Geometry.Width - (menuSize + menuMargin * 2) - titleLeftMargin - (titleViewTopMargin / 2), e.Geometry.Height - titleViewTopMargin);
280                         }
281                         else
282                         {
283                                 _title.Move(e.Geometry.X + (menuSize + menuMargin * 2) + titleLeftMargin, e.Geometry.Y);
284                                 _title.Resize(e.Geometry.Width - (menuSize + menuMargin) - titleLeftMargin, e.Geometry.Height);
285                         }
286                 }
287
288                 void UpdatPageLayout()
289                 {
290                         OnLayoutUpdated(this, new LayoutEventArgs() { Geometry = Geometry });
291                 }
292         }
293 }