[NUI] Theme change do not overwrite user set properties. (#2731)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / RecyclerView / Item / DefaultGridItem.cs
1 /* Copyright (c) 2021 Samsung Electronics Co., Ltd.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  */
16 using System;
17 using System.ComponentModel;
18 using Tizen.NUI.BaseComponents;
19 using Tizen.NUI.Binding;
20 using Tizen.NUI.Components.Extension;
21 using Tizen.NUI.Accessibility;
22
23 namespace Tizen.NUI.Components
24 {
25     /// <summary>
26     /// DefaultGridItem is one kind of common component, a DefaultGridItem clearly describes what action will occur when the user selects it.
27     /// DefaultGridItem may contain text or an icon.
28     /// </summary>
29     [EditorBrowsable(EditorBrowsableState.Never)]
30     public class DefaultGridItem : RecyclerViewItem
31     {
32         private TextLabel itemCaption;
33         private ImageView itemImage;
34         private View itemBadge;
35         private CaptionOrientation captionOrientation;
36         private bool layoutChanged;
37
38         private DefaultGridItemStyle ItemStyle => ViewStyle as DefaultGridItemStyle;
39
40         static DefaultGridItem() { }
41
42         /// <summary>
43         /// Creates a new instance of DefaultGridItem.
44         /// </summary>
45         [EditorBrowsable(EditorBrowsableState.Never)]
46         public DefaultGridItem() : base()
47         {
48             Initialize();
49         }
50
51         /// <summary>
52         /// Creates a new instance of DefaultGridItem with style
53         /// </summary>
54         /// <param name="style=">Create DefaultGridItem by special style defined in UX.</param>
55         [EditorBrowsable(EditorBrowsableState.Never)]
56         public DefaultGridItem(string style) : base(style)
57         {
58             Initialize();
59         }
60
61         /// <summary>
62         /// Creates a new instance of DefaultGridItem with style
63         /// </summary>
64         /// <param name="itemStyle=">Create DefaultGridItem by style customized by user.</param>
65         [EditorBrowsable(EditorBrowsableState.Never)]
66         public DefaultGridItem(DefaultGridItemStyle itemStyle) : base(itemStyle)
67         {
68             Initialize();
69         }
70
71         /// <summary>
72         /// Caption orientation.
73         /// </summary>
74         [EditorBrowsable(EditorBrowsableState.Never)]
75         public enum CaptionOrientation
76         {
77             /// <summary>
78             /// Outside of image bottom edge.
79             /// </summary>
80             [EditorBrowsable(EditorBrowsableState.Never)]
81             OutsideBottom,
82             /// <summary>
83             /// Outside of image top edge.
84             /// </summary>
85             [EditorBrowsable(EditorBrowsableState.Never)]
86             OutsideTop,
87             /// <summary>
88             /// inside of image bottom edge.
89             /// </summary>
90             [EditorBrowsable(EditorBrowsableState.Never)]
91             InsideBottom,
92             /// <summary>
93             /// inside of image top edge.
94             /// </summary>
95             [EditorBrowsable(EditorBrowsableState.Never)]
96             InsideTop,
97         }
98
99         /// <summary>
100         /// DefaultGridItem's icon part.
101         /// </summary>
102         [EditorBrowsable(EditorBrowsableState.Never)]
103         public ImageView Image
104         {
105             get
106             {
107                 if (itemImage == null)
108                 {
109                     itemImage = CreateImage(ItemStyle.Image);
110                     if (itemImage != null)
111                     {
112                         Add(itemImage);
113                         itemImage.Relayout += OnImageRelayout;
114                         layoutChanged = true;
115                     }
116                 }
117                 return itemImage;
118             }
119             internal set
120             {
121                 itemImage = value;
122                 layoutChanged = true;
123             }
124         }
125
126
127         /// <summary>
128         /// DefaultGridItem's badge object. will be placed in right-top edge.
129         /// </summary>
130         [EditorBrowsable(EditorBrowsableState.Never)]
131         public View Badge
132         {
133             get
134             {
135                 return itemBadge;
136
137             }
138             set
139             {
140                 if (value == null)
141                 {
142                     Remove(itemBadge);
143                 }
144                 itemBadge = value;
145                 if (itemBadge != null)
146                 {
147                     itemBadge.ApplyStyle(ItemStyle.Badge);
148                     Add(itemBadge);
149                 }
150                 layoutChanged = true;
151             }
152         }
153
154         /* open when ImageView using Uri not string
155                 /// <summary>
156                 /// Image image's resource url in DefaultGridItem.
157                 /// </summary>
158                 [EditorBrowsable(EditorBrowsableState.Never)]
159                 public string ImageUrl
160                 {
161                     get
162                     {
163                         return Image.ResourceUrl;
164                     }
165                     set
166                     {
167                         Image.ResourceUrl = value;
168                     }
169                 }
170         */
171
172         /// <summary>
173         /// DefaultGridItem's text part.
174         /// </summary>
175         [EditorBrowsable(EditorBrowsableState.Never)]
176         public TextLabel Caption
177         {
178             get
179             {
180                 if (itemCaption == null)
181                 {
182                     itemCaption = CreateLabel(ItemStyle.Caption);
183                     if (itemCaption != null)
184                     {
185                         Add(itemCaption);
186                         layoutChanged = true;
187                     }
188                 }
189                 return itemCaption;
190             }
191             internal set
192             {
193                 itemCaption = value;
194                 layoutChanged = true;
195                 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemCaption.Text);
196             }
197         }
198
199         /// <summary>
200         /// The text of DefaultGridItem.
201         /// </summary>
202         [EditorBrowsable(EditorBrowsableState.Never)]
203         public string Text
204         {
205             get
206             {
207                 return Caption.Text;
208             }
209             set
210             {
211                 Caption.Text = value;
212             }
213         }
214
215         /// <summary>
216         /// Caption relative orientation with image in DefaultGridItem.
217         /// </summary>
218         [EditorBrowsable(EditorBrowsableState.Never)]
219         public CaptionOrientation CaptionRelativeOrientation
220         {
221             get
222             {
223                 return captionOrientation;
224             }
225             set
226             {
227                 captionOrientation = value;
228                 layoutChanged = true;
229             }
230         }
231
232         /// <summary>
233         /// Apply style to DefaultLinearItemStyle.
234         /// </summary>
235         /// <param name="viewStyle">The style to apply.</param>
236         [EditorBrowsable(EditorBrowsableState.Never)]
237         public override void ApplyStyle(ViewStyle viewStyle)
238         {
239
240             base.ApplyStyle(viewStyle);
241             if (viewStyle != null && viewStyle is DefaultGridItemStyle defaultStyle)
242             {
243                 if (itemCaption != null)
244                     itemCaption.ApplyStyle(defaultStyle.Caption);
245                 if (itemImage != null)
246                     itemImage.ApplyStyle(defaultStyle.Image);
247                 if (itemBadge != null)
248                     itemBadge.ApplyStyle(defaultStyle.Badge);
249             }
250         }
251
252         /// <summary>
253         /// Creates Item's text part.
254         /// </summary>
255         /// <return>The created Item's text part.</return>
256         [EditorBrowsable(EditorBrowsableState.Never)]
257         protected virtual TextLabel CreateLabel(TextLabelStyle textStyle)
258         {
259             return new TextLabel(textStyle)
260             {
261                 HorizontalAlignment = HorizontalAlignment.Center,
262                 VerticalAlignment = VerticalAlignment.Center
263             };
264         }
265
266         /// <summary>
267         /// Creates Item's icon part.
268         /// </summary>
269         /// <return>The created Item's icon part.</return>
270         [EditorBrowsable(EditorBrowsableState.Never)]
271         protected virtual ImageView CreateImage(ImageViewStyle imageStyle)
272         {
273             return new ImageView(imageStyle);
274         }
275
276         /// <inheritdoc/>
277         [EditorBrowsable(EditorBrowsableState.Never)]
278         protected override void MeasureChild()
279         {
280             //nothing to do.
281             if (itemCaption)
282             {
283                 var pad = Padding;
284                 var margin = itemCaption.Margin;
285                 itemCaption.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
286             }
287         }
288
289         /// <inheritdoc/>
290         [EditorBrowsable(EditorBrowsableState.Never)]
291         protected override void LayoutChild()
292         {
293             if (!layoutChanged) return;
294             if (itemImage == null) return;
295
296             layoutChanged = false;
297
298             RelativeLayout.SetLeftTarget(itemImage, this);
299             RelativeLayout.SetLeftRelativeOffset(itemImage, 0.0F);
300             RelativeLayout.SetRightTarget(itemImage, this);
301             RelativeLayout.SetRightRelativeOffset(itemImage, 1.0F);
302             RelativeLayout.SetHorizontalAlignment(itemImage, RelativeLayout.Alignment.Center);
303
304             if (itemCaption != null)
305             {
306                 itemCaption.RaiseAbove(itemImage);
307                 RelativeLayout.SetLeftTarget(itemCaption, itemImage);
308                 RelativeLayout.SetLeftRelativeOffset(itemCaption, 0.0F);
309                 RelativeLayout.SetRightTarget(itemCaption, itemImage);
310                 RelativeLayout.SetRightRelativeOffset(itemCaption, 1.0F);
311                 RelativeLayout.SetHorizontalAlignment(itemCaption, RelativeLayout.Alignment.Center);
312                 RelativeLayout.SetFillHorizontal(itemCaption, true);
313             }
314             else
315             {
316                 RelativeLayout.SetTopTarget(itemImage, this);
317                 RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
318                 RelativeLayout.SetBottomTarget(itemImage, this);
319                 RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
320                 RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
321             }
322
323             if (itemBadge)
324             {
325                 RelativeLayout.SetLeftTarget(itemBadge, itemImage);
326                 RelativeLayout.SetLeftRelativeOffset(itemBadge, 1.0F);
327                 RelativeLayout.SetRightTarget(itemBadge, itemImage);
328                 RelativeLayout.SetRightRelativeOffset(itemBadge, 1.0F);
329                 RelativeLayout.SetHorizontalAlignment(itemBadge, RelativeLayout.Alignment.End);
330             }
331
332             switch (captionOrientation)
333             {
334                 case CaptionOrientation.OutsideBottom:
335                     if (itemCaption != null)
336                     {
337                         RelativeLayout.SetTopTarget(itemCaption, this);
338                         RelativeLayout.SetTopRelativeOffset(itemCaption, 1.0F);
339                         RelativeLayout.SetBottomTarget(itemCaption, this);
340                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 1.0F);
341                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.End);
342
343                         RelativeLayout.SetTopTarget(itemImage, this);
344                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
345                         RelativeLayout.SetBottomTarget(itemImage, itemCaption);
346                         RelativeLayout.SetBottomRelativeOffset(itemImage, 0.0F);
347                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
348                     }
349
350                     if (itemBadge)
351                     {
352                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
353                         RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
354                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
355                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
356                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
357                     }
358                     break;
359
360                 case CaptionOrientation.OutsideTop:
361                     if (itemCaption != null)
362                     {
363                         RelativeLayout.SetTopTarget(itemCaption, this);
364                         RelativeLayout.SetTopRelativeOffset(itemCaption, 0.0F);
365                         RelativeLayout.SetBottomTarget(itemCaption, this);
366                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 0.0F);
367                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.Start);
368
369                         RelativeLayout.SetTopTarget(itemImage, itemCaption);
370                         RelativeLayout.SetTopRelativeOffset(itemImage, 1.0F);
371                         RelativeLayout.SetBottomTarget(itemImage, this);
372                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
373                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
374                     }
375
376                     if (itemBadge)
377                     {
378                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
379                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
380                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
381                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
382                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
383                     }
384                     break;
385
386                 case CaptionOrientation.InsideBottom:
387                     if (itemCaption != null)
388                     {
389                         RelativeLayout.SetTopTarget(itemCaption, this);
390                         RelativeLayout.SetTopRelativeOffset(itemCaption, 1.0F);
391                         RelativeLayout.SetBottomTarget(itemCaption, this);
392                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 1.0F);
393                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.End);
394
395                         RelativeLayout.SetTopTarget(itemImage, this);
396                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
397                         RelativeLayout.SetBottomTarget(itemImage, this);
398                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
399                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
400                     }
401
402                     if (itemBadge)
403                     {
404                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
405                         RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
406                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
407                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
408                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
409                     }
410                     break;
411
412                 case CaptionOrientation.InsideTop:
413                     if (itemCaption != null)
414                     {
415                         RelativeLayout.SetTopTarget(itemCaption, this);
416                         RelativeLayout.SetTopRelativeOffset(itemCaption, 0.0F);
417                         RelativeLayout.SetBottomTarget(itemCaption, this);
418                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 0.0F);
419                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.Start);
420
421                         RelativeLayout.SetTopTarget(itemImage, this);
422                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
423                         RelativeLayout.SetBottomTarget(itemImage, this);
424                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
425                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
426                     }
427
428                     if (itemBadge)
429                     {
430                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
431                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
432                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
433                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
434                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
435                     }
436                     break;
437             }
438
439
440         }
441
442         /// <inheritdoc/>
443         [EditorBrowsable(EditorBrowsableState.Never)]
444         private void Initialize()
445         {
446             Layout = new RelativeLayout();
447             layoutChanged = true;
448             LayoutDirectionChanged += OnLayoutDirectionChanged;
449         }
450
451         /// <summary>
452         /// Dispose Item and all children on it.
453         /// </summary>
454         /// <param name="type">Dispose type.</param>
455         [EditorBrowsable(EditorBrowsableState.Never)]
456         protected override void Dispose(DisposeTypes type)
457         {
458             if (disposed)
459             {
460                 return;
461             }
462
463             if (type == DisposeTypes.Explicit)
464             {
465                 //Extension : Extension?.OnDispose(this);
466
467                 if (itemImage != null)
468                 {
469                     Utility.Dispose(itemImage);
470                 }
471                 if (itemCaption != null)
472                 {
473                     Utility.Dispose(itemCaption);
474                 }
475                 if (itemBadge != null)
476                 {
477                     Utility.Dispose(itemBadge);
478                 }
479             }
480
481             base.Dispose(type);
482         }
483
484         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
485         {
486             MeasureChild();
487             LayoutChild();
488         }
489         private void OnImageRelayout(object sender, EventArgs e)
490         {
491             MeasureChild();
492             LayoutChild();
493         }
494     }
495 }