[NUI] Modify NUI.Components private variable (#2764)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / RecyclerView / Item / DefaultTitleItem.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     /// DefaultTitleItem is one kind of common component, a DefaultTitleItem clearly describes what action will occur when the user selects it.
25     /// DefaultTitleItem may contain text or an icon.
26     /// </summary>
27     [EditorBrowsable(EditorBrowsableState.Never)]
28     public class DefaultTitleItem : RecyclerViewItem
29     {
30         private TextLabel itemLabel;
31         private View itemIcon;
32         private View itemSeperator;
33         private bool layoutChanged;
34         private Size prevSize;
35         private DefaultTitleItemStyle ItemStyle => ViewStyle as DefaultTitleItemStyle;
36
37         static DefaultTitleItem() { }
38
39         /// <summary>
40         /// Creates a new instance of DefaultTitleItem.
41         /// </summary>
42         [EditorBrowsable(EditorBrowsableState.Never)]
43         public DefaultTitleItem() : base()
44         {
45             Initialize();
46         }
47
48         /// <summary>
49         /// Creates a new instance of a DefaultTitleItem with style.
50         /// </summary>
51         /// <param name="style">Create DefaultTitleItem by style defined in UX.</param>
52         [EditorBrowsable(EditorBrowsableState.Never)]
53         public DefaultTitleItem(string style) : base(style)
54         {
55             Initialize();
56         }
57
58         /// <summary>
59         /// Creates a new instance of a DefaultTitleItem with style.
60         /// </summary>
61         /// <param name="itemStyle">Create DefaultTitleItem by style customized by user.</param>
62         [EditorBrowsable(EditorBrowsableState.Never)]
63         public DefaultTitleItem(DefaultTitleItemStyle itemStyle) : base(itemStyle)
64         {
65             Initialize();
66         }
67
68         /// <summary>
69         /// Icon part of DefaultTitleItem.
70         /// </summary>
71         [EditorBrowsable(EditorBrowsableState.Never)]
72         public View Icon
73         {
74             get
75             {
76                 if (itemIcon == null)
77                 {
78                     itemIcon = CreateIcon(ItemStyle?.Icon);
79                     if (itemIcon != null)
80                     {
81                         layoutChanged = true;
82                         Add(itemIcon);
83                         itemIcon.Relayout += OnIconRelayout;
84                     }
85                 }
86                 return itemIcon;
87             }
88             set
89             {
90                 itemIcon = value;
91             }
92         }
93
94         /* open when imageView using Uri not string.
95         /// <summary>
96         /// Icon image's resource url. Only activatable for icon as ImageView.
97         /// </summary>
98         [EditorBrowsable(EditorBrowsableState.Never)]
99         public string IconUrl
100         {
101             get
102             {
103                 return (Icon as ImageView)?.ResourceUrl;
104             }
105             set
106             {
107                 if (itemIcon != null && !(itemIcon is ImageView))
108                 {
109                     // Tizen.Log.Error("IconUrl only can set Icon is ImageView");
110                     return;
111                 }
112                 (Icon as ImageView).ResourceUrl = value; 
113             }
114         }
115         */
116
117         /// <summary>
118         /// DefaultTitleItem's text part of DefaultTitleItem
119         /// </summary>
120         [EditorBrowsable(EditorBrowsableState.Never)]
121         public TextLabel Label
122         {
123             get
124             {
125                 if (itemLabel == null)
126                 {
127                     itemLabel = CreateLabel(ItemStyle?.Label);
128                     if (itemLabel != null)
129                     {
130                         layoutChanged = true;
131                         Add(itemLabel);
132                     }
133                 }
134                 return itemLabel;
135             }
136             internal set
137             {
138                 itemLabel = value;
139                 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemLabel.Text);
140             }
141         }
142
143         /// <summary>
144         /// The text of DefaultTitleItem.
145         /// </summary>
146         [EditorBrowsable(EditorBrowsableState.Never)]
147         public string Text
148         {
149             get
150             {
151                 return Label.Text;
152             }
153             set
154             {
155                 Label.Text = value;
156             }
157         }
158
159         /// <summary>
160         /// Seperator divider of DefaultTitleItem. it will place at the end of item.
161         /// </summary>
162         [EditorBrowsable(EditorBrowsableState.Never)]
163         public View Seperator
164         {
165             get
166             {
167                 if (itemSeperator == null)
168                 {
169                     itemSeperator = new View(ItemStyle?.Seperator)
170                     {
171                         //need to consider horizontal/vertical!
172                         WidthSpecification = LayoutParamPolicies.MatchParent,
173                         HeightSpecification = 2,
174                         ExcludeLayouting = true
175                     };
176                     layoutChanged = true;
177                     Add(itemSeperator);
178                 }
179                 return itemSeperator;
180             }
181         }
182
183         /// <summary>
184         /// Apply style to DefaultTitleItemStyle.
185         /// </summary>
186         /// <param name="viewStyle">The style to apply.</param>
187         [EditorBrowsable(EditorBrowsableState.Never)]
188         public override void ApplyStyle(ViewStyle viewStyle)
189         {
190
191             base.ApplyStyle(viewStyle);
192             if (viewStyle != null && viewStyle is DefaultTitleItemStyle defaultStyle)
193             {
194                 if (itemLabel != null)
195                     itemLabel.ApplyStyle(defaultStyle.Label);
196                 if (itemIcon != null)
197                     itemIcon.ApplyStyle(defaultStyle.Icon);
198                 if (itemSeperator != null)
199                     itemSeperator.ApplyStyle(defaultStyle.Seperator);
200             }
201         }
202
203         /// <inheritdoc />
204         [EditorBrowsable(EditorBrowsableState.Never)]
205         public override void OnRelayout(Vector2 size, RelayoutContainer container)
206         {
207             base.OnRelayout(size, container);
208
209             if (prevSize != Size)
210             {
211                 prevSize = Size;
212                 if (itemSeperator)
213                 {
214                     var margin = itemSeperator.Margin;
215                     itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
216                     itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
217                     itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom - itemSeperator.SizeHeight);
218                 }
219             }
220         }
221
222         /// <summary>
223         /// Creates Item's text part.
224         /// </summary>
225         /// <return>The created Item's text part.</return>
226         [EditorBrowsable(EditorBrowsableState.Never)]
227         protected virtual TextLabel CreateLabel(TextLabelStyle style)
228         {
229             return new TextLabel(style)
230             {
231                 HorizontalAlignment = HorizontalAlignment.Begin,
232                 VerticalAlignment = VerticalAlignment.Center
233             };
234         }
235
236         /// <summary>
237         /// Creates Item's icon part.
238         /// </summary>
239         /// <return>The created Item's icon part.</return>
240         [EditorBrowsable(EditorBrowsableState.Never)]
241         protected virtual ImageView CreateIcon(ViewStyle style)
242         {
243             return new ImageView(style);
244         }
245
246         /// <inheritdoc/>
247         [EditorBrowsable(EditorBrowsableState.Never)]
248         protected override void MeasureChild()
249         {
250             if (itemLabel)
251             {
252                 var pad = Padding;
253                 var margin = itemLabel.Margin;
254                 itemLabel.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
255             }
256         }
257
258         /// <inheritdoc/>
259         [EditorBrowsable(EditorBrowsableState.Never)]
260         protected override void LayoutChild()
261         {
262             if (!layoutChanged) return;
263             if (itemLabel == null) return;
264
265             layoutChanged = false;
266
267             if (itemIcon != null)
268             {
269                 RelativeLayout.SetLeftTarget(itemIcon, this);
270                 RelativeLayout.SetLeftRelativeOffset(itemIcon, 1.0F);
271                 RelativeLayout.SetRightTarget(itemIcon, this);
272                 RelativeLayout.SetRightRelativeOffset(itemIcon, 1.0F);
273                 RelativeLayout.SetTopTarget(itemIcon, this);
274                 RelativeLayout.SetTopRelativeOffset(itemIcon, 0.0F);
275                 RelativeLayout.SetBottomTarget(itemIcon, this);
276                 RelativeLayout.SetBottomRelativeOffset(itemIcon, 1.0F);
277                 RelativeLayout.SetVerticalAlignment(itemIcon, RelativeLayout.Alignment.Center);
278                 RelativeLayout.SetHorizontalAlignment(itemIcon, RelativeLayout.Alignment.End);
279             }
280
281             RelativeLayout.SetLeftTarget(itemLabel, this);
282             RelativeLayout.SetLeftRelativeOffset(itemLabel, 0.0F);
283             if (itemIcon)
284             {
285                 RelativeLayout.SetRightTarget(itemLabel, itemIcon);
286                 RelativeLayout.SetRightRelativeOffset(itemLabel, 0.0F);
287             }
288             else
289             {
290                 RelativeLayout.SetRightTarget(itemLabel, this);
291                 RelativeLayout.SetRightRelativeOffset(itemLabel, 1.0F);
292             }
293
294             RelativeLayout.SetTopTarget(itemLabel, this);
295             RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
296             RelativeLayout.SetBottomTarget(itemLabel, this);
297             RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
298             RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Center);
299             RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
300             RelativeLayout.SetFillHorizontal(itemLabel, true);
301
302             if (prevSize != Size)
303             {
304                 prevSize = Size;
305                 if (itemSeperator)
306                 {
307                     var margin = itemSeperator.Margin;
308                     itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
309                     itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
310                     itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom - itemSeperator.SizeHeight);
311                 }
312             }
313         }
314
315         /// <summary>
316         /// Dispose Item and all children on it.
317         /// </summary>
318         /// <param name="type">Dispose type.</param>
319         [EditorBrowsable(EditorBrowsableState.Never)]
320         protected override void Dispose(DisposeTypes type)
321         {
322             if (disposed)
323             {
324                 return;
325             }
326
327             if (type == DisposeTypes.Explicit)
328             {
329                 //Extension : Extension?.OnDispose(this);
330
331                 if (itemIcon != null)
332                 {
333                     Utility.Dispose(itemIcon);
334                 }
335                 if (itemLabel != null)
336                 {
337                     Utility.Dispose(itemLabel);
338                 }
339                 if (itemSeperator != null)
340                 {
341                     Utility.Dispose(itemSeperator);
342                 }
343             }
344
345             base.Dispose(type);
346         }
347
348         /// <summary>
349         /// Get DefaultTitleItem style.
350         /// </summary>
351         /// <returns>The default DefaultTitleItem style.</returns>
352         [EditorBrowsable(EditorBrowsableState.Never)]
353         protected override ViewStyle CreateViewStyle()
354         {
355             return new DefaultTitleItemStyle();
356         }
357
358         private void Initialize()
359         {
360             base.OnInitialize();
361             Layout = new RelativeLayout();
362             var seperator = Seperator;
363             layoutChanged = true;
364             LayoutDirectionChanged += OnLayoutDirectionChanged;
365         }
366
367         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
368         {
369             MeasureChild();
370             LayoutChild();
371         }
372
373         private void OnIconRelayout(object sender, EventArgs e)
374         {
375             MeasureChild();
376             LayoutChild();
377         }
378
379         private void OnExtraRelayout(object sender, EventArgs e)
380         {
381             MeasureChild();
382             LayoutChild();
383         }
384     }
385 }