499f1e900ed787691ed92cceedc62aaaaa5d97e3
[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         /* open when ImageView using Uri not string
168                 /// <summary>
169                 /// Image image's resource url in DefaultGridItem.
170                 /// </summary>
171                 [EditorBrowsable(EditorBrowsableState.Never)]
172                 public string ImageUrl
173                 {
174                     get
175                     {
176                         return Image.ResourceUrl;
177                     }
178                     set
179                     {
180                         Image.ResourceUrl = value;
181                     }
182                 }
183         */
184
185         /// <summary>
186         /// DefaultGridItem's text part.
187         /// </summary>
188         [EditorBrowsable(EditorBrowsableState.Never)]
189         public TextLabel Label
190         {
191             get
192             {
193                 if (itemLabel == null)
194                 {
195                     itemLabel = CreateLabel(ItemStyle.Label);
196                     if (itemLabel != null)
197                     {
198                         Add(itemLabel);
199                         layoutChanged = true;
200                     }
201                 }
202                 return itemLabel;
203             }
204             internal set
205             {
206                 itemLabel = value;
207                 layoutChanged = true;
208             }
209         }
210
211         /// <summary>
212         /// The text of DefaultGridItem.
213         /// </summary>
214         [EditorBrowsable(EditorBrowsableState.Never)]
215         public string Text
216         {
217             get
218             {
219                 return GetValue(TextProperty) as string;
220             }
221             set
222             {
223                 SetValue(TextProperty, value);
224                 NotifyPropertyChanged();
225             }
226         }
227         private string InternalText
228         {
229             get
230             {
231                 return Label.Text;
232             }
233             set
234             {
235                 Label.Text = value;
236             }
237         }
238
239         /// <summary>
240         /// Label relative orientation with image in DefaultGridItem.
241         /// </summary>
242         [EditorBrowsable(EditorBrowsableState.Never)]
243         public LabelOrientation LabelOrientationType
244         {
245             get
246             {
247                 return (Tizen.NUI.Components.DefaultGridItem.LabelOrientation)GetValue(LabelOrientationTypeProperty);
248             }
249             set
250             {
251                 SetValue(LabelOrientationTypeProperty, value);
252                 NotifyPropertyChanged();
253             }
254         }
255         private Tizen.NUI.Components.DefaultGridItem.LabelOrientation InternalLabelOrientationType
256         {
257             get
258             {
259                 return labelOrientation;
260             }
261             set
262             {
263                 labelOrientation = value;
264                 layoutChanged = true;
265             }
266         }
267
268         /// <summary>
269         /// Apply style to DefaultLinearItemStyle.
270         /// </summary>
271         /// <param name="viewStyle">The style to apply.</param>
272         [EditorBrowsable(EditorBrowsableState.Never)]
273         public override void ApplyStyle(ViewStyle viewStyle)
274         {
275
276             base.ApplyStyle(viewStyle);
277             if (viewStyle != null && viewStyle is DefaultGridItemStyle defaultStyle)
278             {
279                 if (itemLabel != null)
280                     itemLabel.ApplyStyle(defaultStyle.Label);
281                 if (itemImage != null)
282                     itemImage.ApplyStyle(defaultStyle.Image);
283                 if (itemBadge != null)
284                     itemBadge.ApplyStyle(defaultStyle.Badge);
285             }
286         }
287
288         /// <summary>
289         /// Creates Item's text part.
290         /// </summary>
291         /// <return>The created Item's text part.</return>
292         [EditorBrowsable(EditorBrowsableState.Never)]
293         protected virtual TextLabel CreateLabel(TextLabelStyle textStyle)
294         {
295             return new TextLabel(textStyle)
296             {
297                 HorizontalAlignment = HorizontalAlignment.Center,
298                 VerticalAlignment = VerticalAlignment.Center
299             };
300         }
301
302         /// <summary>
303         /// Creates Item's icon part.
304         /// </summary>
305         /// <return>The created Item's icon part.</return>
306         [EditorBrowsable(EditorBrowsableState.Never)]
307         protected virtual ImageView CreateImage(ImageViewStyle imageStyle)
308         {
309             return new ImageView(imageStyle);
310         }
311
312         /// <inheritdoc/>
313         [EditorBrowsable(EditorBrowsableState.Never)]
314         protected override void MeasureChild()
315         {
316             //nothing to do.
317             if (itemLabel)
318             {
319                 var pad = Padding;
320                 var margin = itemLabel.Margin;
321                 itemLabel.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
322             }
323         }
324
325         /// <inheritdoc/>
326         [EditorBrowsable(EditorBrowsableState.Never)]
327         protected override void LayoutChild()
328         {
329             if (!layoutChanged) return;
330             if (itemImage == null) return;
331
332             layoutChanged = false;
333
334             RelativeLayout.SetLeftTarget(itemImage, this);
335             RelativeLayout.SetLeftRelativeOffset(itemImage, 0.0F);
336             RelativeLayout.SetRightTarget(itemImage, this);
337             RelativeLayout.SetRightRelativeOffset(itemImage, 1.0F);
338             RelativeLayout.SetHorizontalAlignment(itemImage, RelativeLayout.Alignment.Center);
339
340             if (itemLabel != null)
341             {
342                 itemLabel.RaiseAbove(itemImage);
343                 RelativeLayout.SetLeftTarget(itemLabel, itemImage);
344                 RelativeLayout.SetLeftRelativeOffset(itemLabel, 0.0F);
345                 RelativeLayout.SetRightTarget(itemLabel, itemImage);
346                 RelativeLayout.SetRightRelativeOffset(itemLabel, 1.0F);
347                 RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
348                 RelativeLayout.SetFillHorizontal(itemLabel, true);
349             }
350             else
351             {
352                 RelativeLayout.SetTopTarget(itemImage, this);
353                 RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
354                 RelativeLayout.SetBottomTarget(itemImage, this);
355                 RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
356                 RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
357             }
358
359             if (itemBadge)
360             {
361                 itemBadge.RaiseAbove(itemImage);
362                 RelativeLayout.SetLeftTarget(itemBadge, itemImage);
363                 RelativeLayout.SetLeftRelativeOffset(itemBadge, 1.0F);
364                 RelativeLayout.SetRightTarget(itemBadge, itemImage);
365                 RelativeLayout.SetRightRelativeOffset(itemBadge, 1.0F);
366                 RelativeLayout.SetHorizontalAlignment(itemBadge, RelativeLayout.Alignment.End);
367             }
368
369             switch (labelOrientation)
370             {
371                 case LabelOrientation.OutsideBottom:
372                     if (itemLabel != null)
373                     {
374                         RelativeLayout.SetTopTarget(itemLabel, this);
375                         RelativeLayout.SetTopRelativeOffset(itemLabel, 1.0F);
376                         RelativeLayout.SetBottomTarget(itemLabel, this);
377                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
378                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.End);
379
380                         RelativeLayout.SetTopTarget(itemImage, this);
381                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
382                         RelativeLayout.SetBottomTarget(itemImage, itemLabel);
383                         RelativeLayout.SetBottomRelativeOffset(itemImage, 0.0F);
384                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
385                     }
386
387                     if (itemBadge)
388                     {
389                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
390                         RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
391                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
392                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
393                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
394                     }
395                     break;
396
397                 case LabelOrientation.OutsideTop:
398                     if (itemLabel != null)
399                     {
400                         RelativeLayout.SetTopTarget(itemLabel, this);
401                         RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
402                         RelativeLayout.SetBottomTarget(itemLabel, this);
403                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 0.0F);
404                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Start);
405
406                         RelativeLayout.SetTopTarget(itemImage, itemLabel);
407                         RelativeLayout.SetTopRelativeOffset(itemImage, 1.0F);
408                         RelativeLayout.SetBottomTarget(itemImage, this);
409                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
410                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
411                     }
412
413                     if (itemBadge)
414                     {
415                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
416                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
417                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
418                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
419                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
420                     }
421                     break;
422
423                 case LabelOrientation.InsideBottom:
424                     if (itemLabel != null)
425                     {
426                         RelativeLayout.SetTopTarget(itemLabel, this);
427                         RelativeLayout.SetTopRelativeOffset(itemLabel, 1.0F);
428                         RelativeLayout.SetBottomTarget(itemLabel, this);
429                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
430                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.End);
431
432                         Console.WriteLine("Item Label Inside Bottom!");
433
434                         RelativeLayout.SetTopTarget(itemImage, this);
435                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
436                         RelativeLayout.SetBottomTarget(itemImage, this);
437                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
438                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
439                     }
440
441                     if (itemBadge)
442                     {
443                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
444                         RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
445                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
446                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
447                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
448                     }
449                     break;
450
451                 case LabelOrientation.InsideTop:
452                     if (itemLabel != null)
453                     {
454                         RelativeLayout.SetTopTarget(itemLabel, this);
455                         RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
456                         RelativeLayout.SetBottomTarget(itemLabel, this);
457                         RelativeLayout.SetBottomRelativeOffset(itemLabel, 0.0F);
458                         RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Start);
459
460                         RelativeLayout.SetTopTarget(itemImage, this);
461                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
462                         RelativeLayout.SetBottomTarget(itemImage, this);
463                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
464                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
465                     }
466
467                     if (itemBadge)
468                     {
469                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
470                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
471                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
472                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
473                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
474                     }
475                     break;
476             }
477
478
479         }
480
481         /// <summary>
482         /// Gets accessibility name.
483         /// </summary>
484         [EditorBrowsable(EditorBrowsableState.Never)]
485         protected override string AccessibilityGetName()
486         {
487             return itemLabel.Text;
488         }
489
490         /// <summary>
491         /// Initializes AT-SPI object.
492         /// </summary>
493         [EditorBrowsable(EditorBrowsableState.Never)]
494         public override void OnInitialize()
495         {
496             base.OnInitialize();
497             Layout = new RelativeLayout();
498             layoutChanged = true;
499             LayoutDirectionChanged += OnLayoutDirectionChanged;
500             EnableControlStatePropagation = true;
501         }
502
503         /// <summary>
504         /// Dispose Item and all children on it.
505         /// </summary>
506         /// <param name="type">Dispose type.</param>
507         [EditorBrowsable(EditorBrowsableState.Never)]
508         protected override void Dispose(DisposeTypes type)
509         {
510             if (disposed)
511             {
512                 return;
513             }
514
515             if (type == DisposeTypes.Explicit)
516             {
517                 //Extension : Extension?.OnDispose(this);
518
519                 // Arugable to disposing user-created members.
520                 /*
521                 if (itemBadge != null)
522                 {
523                     Utility.Dispose(itemBadge);
524                 }
525                 */
526
527                 if (itemImage != null)
528                 {
529                     Utility.Dispose(itemImage);
530                     itemImage = null;
531                 }
532                 if (itemLabel != null)
533                 {
534                     Utility.Dispose(itemLabel);
535                     itemLabel = null;
536                 }
537
538             }
539
540             base.Dispose(type);
541         }
542
543         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
544         {
545             MeasureChild();
546             LayoutChild();
547         }
548         private void OnImageRelayout(object sender, EventArgs e)
549         {
550             MeasureChild();
551             LayoutChild();
552         }
553     }
554 }