72c922186c7b3704c364d5682406d978f35156d3
[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.Accessibility;
20
21 namespace Tizen.NUI.Components
22 {
23     /// <summary>
24     /// DefaultGridItem is one kind of common component, a DefaultGridItem clearly describes what action will occur when the user selects it.
25     /// DefaultGridItem may contain text or an icon.
26     /// </summary>
27     [EditorBrowsable(EditorBrowsableState.Never)]
28     public partial class DefaultGridItem : RecyclerViewItem
29     {
30         private TextLabel itemLabel;
31         private ImageView itemImage;
32         private View itemBadge;
33         private LabelOrientation labelOrientation;
34         private bool layoutChanged;
35
36         private DefaultGridItemStyle ItemStyle => ViewStyle as DefaultGridItemStyle;
37
38         static DefaultGridItem() { }
39
40         /// <summary>
41         /// Creates a new instance of DefaultGridItem.
42         /// </summary>
43         [EditorBrowsable(EditorBrowsableState.Never)]
44         public DefaultGridItem() : base()
45         {
46         }
47
48         /// <summary>
49         /// Creates a new instance of DefaultGridItem with style
50         /// </summary>
51         /// <param name="style=">Create DefaultGridItem by special style defined in UX.</param>
52         [EditorBrowsable(EditorBrowsableState.Never)]
53         public DefaultGridItem(string style) : base(style)
54         {
55         }
56
57         /// <summary>
58         /// Creates a new instance of DefaultGridItem with style
59         /// </summary>
60         /// <param name="itemStyle=">Create DefaultGridItem by style customized by user.</param>
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public DefaultGridItem(DefaultGridItemStyle itemStyle) : base(itemStyle)
63         {
64         }
65
66         /// <summary>
67         /// Label orientation.
68         /// </summary>
69         [EditorBrowsable(EditorBrowsableState.Never)]
70         public enum LabelOrientation
71         {
72             /// <summary>
73             /// Outside of image bottom edge.
74             /// </summary>
75             [EditorBrowsable(EditorBrowsableState.Never)]
76             OutsideBottom,
77             /// <summary>
78             /// Outside of image top edge.
79             /// </summary>
80             [EditorBrowsable(EditorBrowsableState.Never)]
81             OutsideTop,
82             /// <summary>
83             /// inside of image bottom edge.
84             /// </summary>
85             [EditorBrowsable(EditorBrowsableState.Never)]
86             InsideBottom,
87             /// <summary>
88             /// inside of image top edge.
89             /// </summary>
90             [EditorBrowsable(EditorBrowsableState.Never)]
91             InsideTop,
92         }
93
94         /// <summary>
95         /// DefaultGridItem's icon part.
96         /// </summary>
97         [EditorBrowsable(EditorBrowsableState.Never)]
98         public ImageView Image
99         {
100             get
101             {
102                 if (itemImage == null)
103                 {
104                     itemImage = CreateImage(ItemStyle.Image);
105                     if (itemImage != null)
106                     {
107                         Add(itemImage);
108                         itemImage.Relayout += OnImageRelayout;
109                         layoutChanged = true;
110                     }
111                 }
112                 return itemImage;
113             }
114             internal set
115             {
116                 if (itemImage != null) Remove(itemImage);
117                 itemImage = value;
118                 if (itemImage != null)
119                 {
120                     //FIXME: User applied image's style can be overwritten!
121                     if (ItemStyle != null) itemImage.ApplyStyle(ItemStyle.Image);
122                     Add(itemImage);
123                     itemImage.Relayout += OnImageRelayout;
124                 }
125                 layoutChanged = true;
126             }
127         }
128
129
130         /// <summary>
131         /// DefaultGridItem's badge object. will be placed in right-top edge.
132         /// </summary>
133         [EditorBrowsable(EditorBrowsableState.Never)]
134         public View Badge
135         {
136             get
137             {
138                 return GetValue(BadgeProperty) as View;
139             }
140             set
141             {
142                 SetValue(BadgeProperty, value);
143                 NotifyPropertyChanged();
144             }
145         }
146         private View InternalBadge
147         {
148             get
149             {
150                 return itemBadge;
151
152             }
153             set
154             {
155                 if (itemBadge != null) Remove(itemBadge);
156                 itemBadge = value;
157                 if (itemBadge != null)
158                 {
159                     //FIXME: User applied badge's style can be overwritten!
160                     if (ItemStyle != null) itemBadge.ApplyStyle(ItemStyle.Badge);
161                     Add(itemBadge);
162                 }
163                 layoutChanged = true;
164             }
165         }
166
167         /// <summary>
168         /// Image resource url in DefaultGridItem.
169         /// </summary>
170         [EditorBrowsable(EditorBrowsableState.Never)]
171         public string ResourceUrl
172         {
173             get => GetValue(ResourceUrlProperty) as string;
174             set
175             {
176                 SetValue(ResourceUrlProperty, value);
177                 NotifyPropertyChanged();
178             }
179         }
180
181         internal string InternalResourceUrl
182         {
183             get
184             {
185                 return Image.ResourceUrl;
186             }
187             set
188             {
189                 Image.ResourceUrl = value;
190             }
191         }
192
193
194         /// <summary>
195         /// DefaultGridItem's text part.
196         /// </summary>
197         [EditorBrowsable(EditorBrowsableState.Never)]
198         public TextLabel Label
199         {
200             get
201             {
202                 if (itemLabel == null)
203                 {
204                     itemLabel = CreateLabel(ItemStyle.Label);
205                     if (itemLabel != null)
206                     {
207                         Add(itemLabel);
208                         layoutChanged = true;
209                     }
210                 }
211                 return itemLabel;
212             }
213             internal set
214             {
215                 itemLabel = value;
216                 layoutChanged = true;
217             }
218         }
219
220         /// <summary>
221         /// The text of DefaultGridItem.
222         /// </summary>
223         [EditorBrowsable(EditorBrowsableState.Never)]
224         public string Text
225         {
226             get
227             {
228                 return GetValue(TextProperty) as string;
229             }
230             set
231             {
232                 SetValue(TextProperty, value);
233                 NotifyPropertyChanged();
234             }
235         }
236         private string InternalText
237         {
238             get
239             {
240                 return Label.Text;
241             }
242             set
243             {
244                 Label.Text = value;
245             }
246         }
247
248         /// <summary>
249         /// Label relative orientation with image in DefaultGridItem.
250         /// </summary>
251         [EditorBrowsable(EditorBrowsableState.Never)]
252         public LabelOrientation LabelOrientationType
253         {
254             get
255             {
256                 return (Tizen.NUI.Components.DefaultGridItem.LabelOrientation)GetValue(LabelOrientationTypeProperty);
257             }
258             set
259             {
260                 SetValue(LabelOrientationTypeProperty, value);
261                 NotifyPropertyChanged();
262             }
263         }
264         private Tizen.NUI.Components.DefaultGridItem.LabelOrientation InternalLabelOrientationType
265         {
266             get
267             {
268                 return labelOrientation;
269             }
270             set
271             {
272                 labelOrientation = value;
273                 layoutChanged = true;
274             }
275         }
276
277         /// <summary>
278         /// Apply style to DefaultLinearItemStyle.
279         /// </summary>
280         /// <param name="viewStyle">The style to apply.</param>
281         [EditorBrowsable(EditorBrowsableState.Never)]
282         public override void ApplyStyle(ViewStyle viewStyle)
283         {
284
285             base.ApplyStyle(viewStyle);
286             if (viewStyle != null && viewStyle is DefaultGridItemStyle defaultStyle)
287             {
288                 if (itemLabel != null)
289                     itemLabel.ApplyStyle(defaultStyle.Label);
290                 if (itemImage != null)
291                     itemImage.ApplyStyle(defaultStyle.Image);
292                 if (itemBadge != null)
293                     itemBadge.ApplyStyle(defaultStyle.Badge);
294             }
295         }
296
297         /// <summary>
298         /// Creates Item's text part.
299         /// </summary>
300         /// <return>The created Item's text part.</return>
301         [EditorBrowsable(EditorBrowsableState.Never)]
302         protected virtual TextLabel CreateLabel(TextLabelStyle textStyle)
303         {
304             return new TextLabel(textStyle)
305             {
306                 HorizontalAlignment = HorizontalAlignment.Center,
307                 VerticalAlignment = VerticalAlignment.Center
308             };
309         }
310
311         /// <summary>
312         /// Creates Item's icon part.
313         /// </summary>
314         /// <return>The created Item's icon part.</return>
315         [EditorBrowsable(EditorBrowsableState.Never)]
316         protected virtual ImageView CreateImage(ImageViewStyle imageStyle)
317         {
318             return new ImageView(imageStyle);
319         }
320
321         /// <inheritdoc/>
322         [EditorBrowsable(EditorBrowsableState.Never)]
323         protected override void MeasureChild()
324         {
325             //nothing to do.
326             if (itemLabel)
327             {
328                 var pad = Padding;
329                 var margin = itemLabel.Margin;
330                 itemLabel.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
331             }
332         }
333
334         /// <inheritdoc/>
335         [EditorBrowsable(EditorBrowsableState.Never)]
336         protected override void LayoutChild()
337         {
338             if (!layoutChanged) return;
339             if (itemImage == null) return;
340
341             layoutChanged = false;
342
343             RelativeLayout.SetLeftTarget(itemImage, this);
344             RelativeLayout.SetLeftRelativeOffset(itemImage, 0.0F);
345             RelativeLayout.SetRightTarget(itemImage, this);
346             RelativeLayout.SetRightRelativeOffset(itemImage, 1.0F);
347             RelativeLayout.SetHorizontalAlignment(itemImage, RelativeLayout.Alignment.Center);
348             RelativeLayout.SetFillHorizontal(itemImage, true);
349             RelativeLayout.SetFillVertical(itemImage, true);
350
351             if (itemLabel != null)
352             {
353                 itemLabel.RaiseAbove(itemImage);
354                 RelativeLayout.SetLeftTarget(itemLabel, itemImage);
355                 RelativeLayout.SetLeftRelativeOffset(itemLabel, 0.0F);
356                 RelativeLayout.SetRightTarget(itemLabel, itemImage);
357                 RelativeLayout.SetRightRelativeOffset(itemLabel, 1.0F);
358                 RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
359                 RelativeLayout.SetFillHorizontal(itemLabel, true);
360             }
361             else
362             {
363                 RelativeLayout.SetTopTarget(itemImage, this);
364                 RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
365                 RelativeLayout.SetBottomTarget(itemImage, this);
366                 RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
367                 RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
368             }
369
370             if (itemBadge)
371             {
372                 itemBadge.RaiseAbove(itemImage);
373                 RelativeLayout.SetLeftTarget(itemBadge, itemImage);
374                 RelativeLayout.SetLeftRelativeOffset(itemBadge, 1.0F);
375                 RelativeLayout.SetRightTarget(itemBadge, itemImage);
376                 RelativeLayout.SetRightRelativeOffset(itemBadge, 1.0F);
377                 RelativeLayout.SetHorizontalAlignment(itemBadge, RelativeLayout.Alignment.End);
378             }
379
380             switch (labelOrientation)
381             {
382                 case LabelOrientation.OutsideBottom:
383                     if (itemLabel != null)
384                     {
385                         RelativeLayout.SetTopTarget(itemLabel, this);
386                         RelativeLayout.SetTopRelativeOffset(itemLabel, 1.0F);
387                         RelativeLayout.SetBottomTarget(itemLabel, this);
388                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
389                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.End);
390
391                         RelativeLayout.SetTopTarget(itemImage, this);
392                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
393                         RelativeLayout.SetBottomTarget(itemImage, itemLabel);
394                         RelativeLayout.SetBottomRelativeOffset(itemImage, 0.0F);
395                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
396                     }
397
398                     if (itemBadge)
399                     {
400                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
401                         RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
402                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
403                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
404                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
405                     }
406                     break;
407
408                 case LabelOrientation.OutsideTop:
409                     if (itemLabel != null)
410                     {
411                         RelativeLayout.SetTopTarget(itemLabel, this);
412                         RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
413                         RelativeLayout.SetBottomTarget(itemLabel, this);
414                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 0.0F);
415                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Start);
416
417                         RelativeLayout.SetTopTarget(itemImage, itemLabel);
418                         RelativeLayout.SetTopRelativeOffset(itemImage, 1.0F);
419                         RelativeLayout.SetBottomTarget(itemImage, this);
420                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
421                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
422                     }
423
424                     if (itemBadge)
425                     {
426                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
427                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
428                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
429                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
430                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
431                     }
432                     break;
433
434                 case LabelOrientation.InsideBottom:
435                     if (itemLabel != null)
436                     {
437                         RelativeLayout.SetTopTarget(itemLabel, this);
438                         RelativeLayout.SetTopRelativeOffset(itemLabel, 1.0F);
439                         RelativeLayout.SetBottomTarget(itemLabel, this);
440                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
441                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.End);
442
443                         Console.WriteLine("Item Label Inside Bottom!");
444
445                         RelativeLayout.SetTopTarget(itemImage, this);
446                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
447                         RelativeLayout.SetBottomTarget(itemImage, this);
448                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
449                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
450                     }
451
452                     if (itemBadge)
453                     {
454                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
455                         RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
456                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
457                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
458                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
459                     }
460                     break;
461
462                 case LabelOrientation.InsideTop:
463                     if (itemLabel != null)
464                     {
465                         RelativeLayout.SetTopTarget(itemLabel, this);
466                         RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
467                         RelativeLayout.SetBottomTarget(itemLabel, this);
468                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 0.0F);
469                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Start);
470
471                         RelativeLayout.SetTopTarget(itemImage, this);
472                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
473                         RelativeLayout.SetBottomTarget(itemImage, this);
474                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
475                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
476                     }
477
478                     if (itemBadge)
479                     {
480                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
481                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
482                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
483                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
484                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
485                     }
486                     break;
487             }
488
489
490         }
491
492         /// <summary>
493         /// Gets accessibility name.
494         /// </summary>
495         [EditorBrowsable(EditorBrowsableState.Never)]
496         protected override string AccessibilityGetName()
497         {
498             return itemLabel.Text;
499         }
500
501         /// <summary>
502         /// Initializes AT-SPI object.
503         /// </summary>
504         [EditorBrowsable(EditorBrowsableState.Never)]
505         public override void OnInitialize()
506         {
507             base.OnInitialize();
508             Layout = new RelativeLayout();
509             layoutChanged = true;
510             LayoutDirectionChanged += OnLayoutDirectionChanged;
511             EnableControlStatePropagation = true;
512         }
513
514         /// <summary>
515         /// Dispose Item and all children on it.
516         /// </summary>
517         /// <param name="type">Dispose type.</param>
518         [EditorBrowsable(EditorBrowsableState.Never)]
519         protected override void Dispose(DisposeTypes type)
520         {
521             if (disposed)
522             {
523                 return;
524             }
525
526             if (type == DisposeTypes.Explicit)
527             {
528                 //Extension : Extension?.OnDispose(this);
529
530                 // Arugable to disposing user-created members.
531                 /*
532                 if (itemBadge != null)
533                 {
534                     Utility.Dispose(itemBadge);
535                 }
536                 */
537
538                 if (itemImage != null)
539                 {
540                     Utility.Dispose(itemImage);
541                     itemImage = null;
542                 }
543                 if (itemLabel != null)
544                 {
545                     Utility.Dispose(itemLabel);
546                     itemLabel = null;
547                 }
548
549             }
550
551             base.Dispose(type);
552         }
553
554         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
555         {
556             MeasureChild();
557             LayoutChild();
558         }
559         private void OnImageRelayout(object sender, EventArgs e)
560         {
561             MeasureChild();
562             LayoutChild();
563         }
564     }
565 }