[NUI] Introduce CollectionView and related classes. (#2525)
[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         /// <summary>
41         /// Return a copied Style instance of DefaultLinearItem
42         /// </summary>
43         /// <remarks>
44         /// It returns copied Style instance and changing it does not effect to the DefaultLinearItem.
45         /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
46         /// </remarks>
47         [EditorBrowsable(EditorBrowsableState.Never)]
48         public new DefaultGridItemStyle Style
49         {
50             get
51             {
52                 var result = new DefaultGridItemStyle(ItemStyle);
53                 result.CopyPropertiesFromView(this);
54                 if (itemCaption) result.Caption.CopyPropertiesFromView(itemCaption);
55                 if (itemImage) result.Image.CopyPropertiesFromView(itemImage);
56                 if (itemBadge) result.Badge.CopyPropertiesFromView(itemBadge);
57
58                 return result;
59             }
60         }
61
62         static DefaultGridItem() {}
63
64         /// <summary>
65         /// Creates a new instance of DefaultGridItem.
66         /// </summary>
67         [EditorBrowsable(EditorBrowsableState.Never)]
68         public DefaultGridItem() : base()
69         {
70             Initialize();
71         }
72
73         /// <summary>
74         /// Creates a new instance of DefaultGridItem with style
75         /// </summary>
76         /// <param name="style=">Create DefaultGridItem by special style defined in UX.</param>
77         [EditorBrowsable(EditorBrowsableState.Never)]
78         public DefaultGridItem(string style) : base(style)
79         {
80             Initialize();
81         }
82
83         /// <summary>
84         /// Creates a new instance of DefaultGridItem with style
85         /// </summary>
86         /// <param name="itemStyle=">Create DefaultGridItem by style customized by user.</param>
87         [EditorBrowsable(EditorBrowsableState.Never)]
88         public DefaultGridItem(DefaultGridItemStyle itemStyle) : base(itemStyle)
89         {
90             Initialize();
91         }
92
93         /// <summary>
94         /// Caption orientation.
95         /// </summary>
96         [EditorBrowsable(EditorBrowsableState.Never)]
97         public enum CaptionOrientation
98         {
99             /// <summary>
100             /// Outside of image bottom edge.
101             /// </summary>
102             [EditorBrowsable(EditorBrowsableState.Never)]
103             OutsideBottom,
104             /// <summary>
105             /// Outside of image top edge.
106             /// </summary>
107             [EditorBrowsable(EditorBrowsableState.Never)]
108             OutsideTop,
109             /// <summary>
110             /// inside of image bottom edge.
111             /// </summary>
112             [EditorBrowsable(EditorBrowsableState.Never)]
113             InsideBottom,
114             /// <summary>
115             /// inside of image top edge.
116             /// </summary>
117             [EditorBrowsable(EditorBrowsableState.Never)]
118             InsideTop,
119         }
120
121         /// <summary>
122         /// DefaultGridItem's icon part.
123         /// </summary>
124         [EditorBrowsable(EditorBrowsableState.Never)]
125         public ImageView Image
126         {
127             get
128             {
129                 if ( itemImage == null)
130                 {
131                     itemImage = CreateImage(ItemStyle.Image);
132                     if (itemImage != null)
133                     {
134                         Add(itemImage);
135                         itemImage.Relayout += OnImageRelayout;
136                         layoutChanged = true;
137                     }
138                 }
139                 return itemImage;
140             }
141             internal set
142             {
143                 itemImage = value;
144                 layoutChanged = true;
145             }
146         }
147
148
149         /// <summary>
150         /// DefaultGridItem's badge object. will be placed in right-top edge.
151         /// </summary>
152         [EditorBrowsable(EditorBrowsableState.Never)]
153         public View Badge
154         {
155             get
156             {
157                 return itemBadge;
158
159             }
160             set
161             {
162                 if (value == null)
163                 {
164                     Remove(itemBadge);
165                 }
166                 itemBadge = value;
167                 if (itemBadge != null)
168                 {
169                     itemBadge.ApplyStyle(ItemStyle.Badge);
170                     Add(itemBadge);
171                 }
172                 layoutChanged = true;
173             }
174         }
175
176 /* open when ImageView using Uri not string
177         /// <summary>
178         /// Image image's resource url in DefaultGridItem.
179         /// </summary>
180         [EditorBrowsable(EditorBrowsableState.Never)]
181         public string ImageUrl
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 Caption
199         {
200             get
201             {
202                 if (itemCaption == null)
203                 {
204                     itemCaption = CreateLabel(ItemStyle.Caption);
205                     if (itemCaption != null)
206                     {
207                         Add(itemCaption);
208                         layoutChanged = true;
209                     }
210                 }
211                 return itemCaption;
212             }
213             internal set
214             {
215                 itemCaption = value;
216                 layoutChanged = true;
217                 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemCaption.Text);
218             }
219         }
220
221         /// <summary>
222         /// The text of DefaultGridItem.
223         /// </summary>
224         [EditorBrowsable(EditorBrowsableState.Never)]
225         public string Text
226         {
227             get
228             {
229                 return Caption.Text;
230             }
231             set
232             {
233                 Caption.Text = value;
234             }
235         }
236
237         /// <summary>
238         /// Caption relative orientation with image in DefaultGridItem.
239         /// </summary>
240         [EditorBrowsable(EditorBrowsableState.Never)]
241         public CaptionOrientation CaptionRelativeOrientation
242         {
243             get
244             {
245                 return captionOrientation;
246             }
247             set
248             {
249                 captionOrientation = value;
250                 layoutChanged = true;
251             }
252         }
253
254         /// <summary>
255         /// Apply style to DefaultLinearItemStyle.
256         /// </summary>
257         /// <param name="viewStyle">The style to apply.</param>
258         [EditorBrowsable(EditorBrowsableState.Never)]
259         public override void ApplyStyle(ViewStyle viewStyle)
260         {
261
262             base.ApplyStyle(viewStyle);
263             if (viewStyle != null && viewStyle is DefaultGridItemStyle defaultStyle)
264             {
265                 if (itemCaption != null)
266                     itemCaption.ApplyStyle(defaultStyle.Caption);
267                 if (itemImage != null)
268                     itemImage.ApplyStyle(defaultStyle.Image);
269                 if (itemBadge != null)
270                     itemBadge.ApplyStyle(defaultStyle.Badge);
271             }
272         }
273
274         /// <summary>
275         /// Creates Item's text part.
276         /// </summary>
277         /// <return>The created Item's text part.</return>
278         [EditorBrowsable(EditorBrowsableState.Never)]
279         protected virtual TextLabel CreateLabel(TextLabelStyle textStyle)
280         {
281             return new TextLabel(textStyle)
282             {
283                 HorizontalAlignment = HorizontalAlignment.Center,
284                 VerticalAlignment = VerticalAlignment.Center
285             };
286         }
287
288         /// <summary>
289         /// Creates Item's icon part.
290         /// </summary>
291         /// <return>The created Item's icon part.</return>
292         [EditorBrowsable(EditorBrowsableState.Never)]
293         protected virtual ImageView CreateImage(ImageViewStyle imageStyle)
294         {
295             return new ImageView(imageStyle);
296         }
297
298          /// <inheritdoc/>
299         [EditorBrowsable(EditorBrowsableState.Never)]
300         protected override void MeasureChild()
301         {
302             //nothing to do.
303             if (itemCaption)
304             {
305                 var pad = Padding;
306                 var margin = itemCaption.Margin;
307                 itemCaption.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
308             }
309         }
310
311         /// <inheritdoc/>
312         [EditorBrowsable(EditorBrowsableState.Never)]
313         protected override void LayoutChild()
314         {
315             if (!layoutChanged) return;
316             if (itemImage == null) return;
317
318             layoutChanged = false;
319
320             RelativeLayout.SetLeftTarget(itemImage, this);
321             RelativeLayout.SetLeftRelativeOffset(itemImage, 0.0F);
322             RelativeLayout.SetRightTarget(itemImage, this);
323             RelativeLayout.SetRightRelativeOffset(itemImage, 1.0F);
324             RelativeLayout.SetHorizontalAlignment(itemImage, RelativeLayout.Alignment.Center);
325
326             if (itemCaption != null)
327             {
328                 itemCaption.RaiseAbove(itemImage);
329                 RelativeLayout.SetLeftTarget(itemCaption, itemImage);
330                 RelativeLayout.SetLeftRelativeOffset(itemCaption, 0.0F);
331                 RelativeLayout.SetRightTarget(itemCaption, itemImage);
332                 RelativeLayout.SetRightRelativeOffset(itemCaption, 1.0F);
333                 RelativeLayout.SetHorizontalAlignment(itemCaption, RelativeLayout.Alignment.Center);
334                 RelativeLayout.SetFillHorizontal(itemCaption, true);
335             }
336             else
337             {
338                 RelativeLayout.SetTopTarget(itemImage, this);
339                 RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
340                 RelativeLayout.SetBottomTarget(itemImage, this);
341                 RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
342                 RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
343             }
344
345             if (itemBadge)
346             {
347                 RelativeLayout.SetLeftTarget(itemBadge, itemImage);
348                 RelativeLayout.SetLeftRelativeOffset(itemBadge, 1.0F);
349                 RelativeLayout.SetRightTarget(itemBadge, itemImage);
350                 RelativeLayout.SetRightRelativeOffset(itemBadge, 1.0F);
351                 RelativeLayout.SetHorizontalAlignment(itemBadge, RelativeLayout.Alignment.End);
352             }
353
354             switch (captionOrientation)
355             {
356                 case CaptionOrientation.OutsideBottom:
357                     if (itemCaption != null)
358                     {
359                         RelativeLayout.SetTopTarget(itemCaption, this);
360                         RelativeLayout.SetTopRelativeOffset(itemCaption, 1.0F);
361                         RelativeLayout.SetBottomTarget(itemCaption, this);
362                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 1.0F);
363                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.End);
364
365                         RelativeLayout.SetTopTarget(itemImage, this);
366                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
367                         RelativeLayout.SetBottomTarget(itemImage, itemCaption);
368                         RelativeLayout.SetBottomRelativeOffset(itemImage, 0.0F);
369                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
370                     }
371
372                     if (itemBadge)
373                     {
374                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
375                         RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
376                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
377                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
378                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
379                     }
380                     break;
381
382                 case CaptionOrientation.OutsideTop:
383                     if (itemCaption != null)
384                     {
385                         RelativeLayout.SetTopTarget(itemCaption, this);
386                         RelativeLayout.SetTopRelativeOffset(itemCaption, 0.0F);
387                         RelativeLayout.SetBottomTarget(itemCaption, this);
388                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 0.0F);
389                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.Start);
390
391                         RelativeLayout.SetTopTarget(itemImage, itemCaption);
392                         RelativeLayout.SetTopRelativeOffset(itemImage, 1.0F);
393                         RelativeLayout.SetBottomTarget(itemImage, this);
394                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
395                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
396                     }
397
398                     if (itemBadge)
399                     {
400                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
401                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
402                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
403                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
404                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
405                     }
406                     break;
407
408                 case CaptionOrientation.InsideBottom:
409                     if (itemCaption != null)
410                     {
411                         RelativeLayout.SetTopTarget(itemCaption, this);
412                         RelativeLayout.SetTopRelativeOffset(itemCaption, 1.0F);
413                         RelativeLayout.SetBottomTarget(itemCaption, this);
414                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 1.0F);
415                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.End);
416
417                         RelativeLayout.SetTopTarget(itemImage, this);
418                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.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, 0.0F);
428                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
429                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
430                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
431                     }
432                     break;
433
434                 case CaptionOrientation.InsideTop:
435                     if (itemCaption != null)
436                     {
437                         RelativeLayout.SetTopTarget(itemCaption, this);
438                         RelativeLayout.SetTopRelativeOffset(itemCaption, 0.0F);
439                         RelativeLayout.SetBottomTarget(itemCaption, this);
440                         RelativeLayout.SetBottomRelativeOffset(itemCaption, 0.0F);
441                         RelativeLayout.SetVerticalAlignment(itemCaption, RelativeLayout.Alignment.Start);
442
443                         RelativeLayout.SetTopTarget(itemImage, this);
444                         RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
445                         RelativeLayout.SetBottomTarget(itemImage, this);
446                         RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
447                         RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
448                     }
449
450                     if (itemBadge)
451                     {
452                         RelativeLayout.SetTopTarget(itemBadge, itemImage);
453                         RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
454                         RelativeLayout.SetBottomTarget(itemBadge, itemImage);
455                         RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
456                         RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
457                     }
458                     break;
459             }
460
461
462         }
463
464         /// <inheritdoc/>
465         [EditorBrowsable(EditorBrowsableState.Never)]
466         private void Initialize()
467         {
468             Layout = new RelativeLayout();
469             layoutChanged = true;
470             LayoutDirectionChanged += OnLayoutDirectionChanged;
471         }
472
473         /// <summary>
474         /// Dispose Item and all children on it.
475         /// </summary>
476         /// <param name="type">Dispose type.</param>
477         [EditorBrowsable(EditorBrowsableState.Never)]
478         protected override void Dispose(DisposeTypes type)
479         {
480             if (disposed)
481             {
482                 return;
483             }
484
485             if (type == DisposeTypes.Explicit)
486             {
487                 //Extension : Extension?.OnDispose(this);
488
489                 if (itemImage != null)
490                 {
491                     Utility.Dispose(itemImage);
492                 }
493                 if (itemCaption != null)
494                 {
495                     Utility.Dispose(itemCaption);
496                 }
497                 if (itemBadge != null)
498                 {
499                     Utility.Dispose(itemBadge);
500                 }
501             }
502
503             base.Dispose(type);
504         }
505
506         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
507         {
508             MeasureChild();
509             LayoutChild();
510         }
511         private void OnImageRelayout(object sender, EventArgs e)
512         {
513             MeasureChild();
514             LayoutChild();
515         }
516     }
517 }