1 /* Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 using System.ComponentModel;
18 using Tizen.NUI.BaseComponents;
19 using Tizen.NUI.Accessibility;
21 namespace Tizen.NUI.Components
24 /// DefaultLinearItem is one kind of common component, a DefaultLinearItem clearly describes what action will occur when the user selects it.
25 /// DefaultLinearItem may contain text or an icon.
27 [EditorBrowsable(EditorBrowsableState.Never)]
28 public partial class DefaultLinearItem : RecyclerViewItem
30 private View itemIcon;
31 private TextLabel itemLabel;
32 private TextLabel itemSubLabel;
33 private View itemExtra;
34 private View itemSeperator;
35 private bool layoutChanged;
36 private Size prevSize;
37 private DefaultLinearItemStyle ItemStyle => ViewStyle as DefaultLinearItemStyle;
39 static DefaultLinearItem() { }
42 /// Creates a new instance of DefaultLinearItem.
44 [EditorBrowsable(EditorBrowsableState.Never)]
45 public DefaultLinearItem() : base()
50 /// Creates a new instance of a DefaultLinearItem with style.
52 /// <param name="style">Create DefaultLinearItem by style defined in UX.</param>
53 [EditorBrowsable(EditorBrowsableState.Never)]
54 public DefaultLinearItem(string style) : base(style)
59 /// Creates a new instance of a DefaultLinearItem with style.
61 /// <param name="itemStyle">Create DefaultLinearItem by style customized by user.</param>
62 [EditorBrowsable(EditorBrowsableState.Never)]
63 public DefaultLinearItem(DefaultLinearItemStyle itemStyle) : base(itemStyle)
68 /// Icon part of DefaultLinearItem.
70 [EditorBrowsable(EditorBrowsableState.Never)]
75 return GetValue(IconProperty) as View;
79 SetValue(IconProperty, value);
80 NotifyPropertyChanged();
83 private View InternalIcon
89 itemIcon = CreateIcon(ItemStyle?.Icon);
94 itemIcon.Relayout += OnIconRelayout;
101 if (itemIcon != null) Remove(itemIcon);
103 if (itemIcon != null)
105 //FIXME: User applied icon's style can be overwritten!
106 if (ItemStyle != null) itemIcon.ApplyStyle(ItemStyle.Icon);
108 itemIcon.Relayout += OnIconRelayout;
110 layoutChanged = true;
114 /* open when imageView using Uri not string.
116 /// Icon image's resource url. Only activatable for icon as ImageView.
118 [EditorBrowsable(EditorBrowsableState.Never)]
119 public string IconUrl
123 return (Icon as ImageView)?.ResourceUrl;
127 if (itemIcon != null && !(itemIcon is ImageView))
129 // Tizen.Log.Error("IconUrl only can set Icon is ImageView");
132 (Icon as ImageView).ResourceUrl = value;
138 /// DefaultLinearItem's text part of DefaultLinearItem
140 [EditorBrowsable(EditorBrowsableState.Never)]
141 public TextLabel Label
145 if (itemLabel == null)
147 itemLabel = CreateLabel(ItemStyle?.Label);
148 if (itemLabel != null)
150 layoutChanged = true;
159 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemLabel.Text);
164 /// The text of DefaultLinearItem.
166 [EditorBrowsable(EditorBrowsableState.Never)]
171 return GetValue(TextProperty) as string;
175 SetValue(TextProperty, value);
176 NotifyPropertyChanged();
179 private string InternalText
192 /// DefaultLinearItem's secondary text part of DefaultLinearItem
194 [EditorBrowsable(EditorBrowsableState.Never)]
195 public TextLabel SubLabel
199 if (itemSubLabel == null)
201 itemSubLabel = CreateLabel(ItemStyle?.SubLabel);
202 if (itemLabel != null)
204 layoutChanged = true;
212 itemSubLabel = value;
213 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemSubLabel.Text);
218 /// The text of DefaultLinearItem.
220 [EditorBrowsable(EditorBrowsableState.Never)]
221 public string SubText
225 return GetValue(SubTextProperty) as string;
229 SetValue(SubTextProperty, value);
230 NotifyPropertyChanged();
233 private string InternalSubText
237 return SubLabel.Text;
241 SubLabel.Text = value;
246 /// Extra icon part of DefaultLinearItem. it will place next of label.
248 [EditorBrowsable(EditorBrowsableState.Never)]
253 return GetValue(ExtraProperty) as View;
257 SetValue(ExtraProperty, value);
258 NotifyPropertyChanged();
261 private View InternalExtra
265 if (itemExtra == null)
267 itemExtra = CreateIcon(ItemStyle?.Extra);
268 if (itemExtra != null)
270 layoutChanged = true;
272 itemExtra.Relayout += OnExtraRelayout;
279 if (itemExtra != null) Remove(itemExtra);
281 if (itemExtra != null)
283 //FIXME: User applied extra's style can be overwritten!
284 if (ItemStyle != null) itemExtra.ApplyStyle(ItemStyle.Extra);
287 layoutChanged = true;
292 /// Seperator divider of DefaultLinearItem. it will place at the end of item.
294 [EditorBrowsable(EditorBrowsableState.Never)]
295 public View Seperator
299 if (itemSeperator == null)
301 itemSeperator = new View(ItemStyle?.Seperator)
303 //need to consider horizontal/vertical!
304 WidthSpecification = LayoutParamPolicies.MatchParent,
305 HeightSpecification = 2,
306 ExcludeLayouting = true,
307 AccessibilityHidden = true
309 layoutChanged = true;
312 return itemSeperator;
317 /// Apply style to DefaultLinearItemStyle.
319 /// <param name="viewStyle">The style to apply.</param>
320 [EditorBrowsable(EditorBrowsableState.Never)]
321 public override void ApplyStyle(ViewStyle viewStyle)
323 base.ApplyStyle(viewStyle);
324 if (viewStyle != null && viewStyle is DefaultLinearItemStyle defaultStyle)
326 if (itemLabel != null)
327 itemLabel.ApplyStyle(defaultStyle.Label);
328 if (itemSubLabel != null)
329 itemSubLabel.ApplyStyle(defaultStyle.SubLabel);
330 if (itemIcon != null)
331 itemIcon.ApplyStyle(defaultStyle.Icon);
332 if (itemExtra != null)
333 itemExtra.ApplyStyle(defaultStyle.Extra);
334 if (itemSeperator != null)
336 itemSeperator.ApplyStyle(defaultStyle.Seperator);
337 //FIXME : currently padding and margin are not applied by ApplyStyle automatically as missing binding features.
338 itemSeperator.Margin = new Extents(defaultStyle.Seperator.Margin);
344 [EditorBrowsable(EditorBrowsableState.Never)]
345 public override void OnRelayout(Vector2 size, RelayoutContainer container)
347 base.OnRelayout(size, container);
349 if (prevSize != Size)
354 var margin = itemSeperator.Margin;
355 itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
356 itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
357 itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom - itemSeperator.SizeHeight);
363 /// Get accessibility name.
365 [EditorBrowsable(EditorBrowsableState.Never)]
366 protected override string AccessibilityGetName()
368 return Label.Text + ", " + SubLabel.Text;
372 /// Creates Item's text part.
374 /// <return>The created Item's text part.</return>
375 [EditorBrowsable(EditorBrowsableState.Never)]
376 protected virtual TextLabel CreateLabel(TextLabelStyle style)
378 return new TextLabel(style)
380 HorizontalAlignment = HorizontalAlignment.Begin,
381 VerticalAlignment = VerticalAlignment.Center,
382 AccessibilityHidden = true
387 /// Creates Item's icon part.
389 /// <return>The created Item's icon part.</return>
390 [EditorBrowsable(EditorBrowsableState.Never)]
391 protected virtual ImageView CreateIcon(ViewStyle style)
393 return new ImageView(style);
397 [EditorBrowsable(EditorBrowsableState.Never)]
398 protected override void MeasureChild()
400 //Do Measure in here if necessary.
404 [EditorBrowsable(EditorBrowsableState.Never)]
405 protected override void LayoutChild()
407 if (!layoutChanged) return;
408 if (itemLabel == null) return;
410 layoutChanged = false;
412 if (itemIcon != null)
414 RelativeLayout.SetLeftTarget(itemIcon, this);
415 RelativeLayout.SetLeftRelativeOffset(itemIcon, 0.0F);
416 RelativeLayout.SetRightTarget(itemIcon, this);
417 RelativeLayout.SetRightRelativeOffset(itemIcon, 0.0F);
418 RelativeLayout.SetTopTarget(itemIcon, this);
419 RelativeLayout.SetTopRelativeOffset(itemIcon, 0.0F);
420 RelativeLayout.SetBottomTarget(itemIcon, this);
421 RelativeLayout.SetBottomRelativeOffset(itemIcon, 1.0F);
422 RelativeLayout.SetVerticalAlignment(itemIcon, RelativeLayout.Alignment.Center);
423 RelativeLayout.SetHorizontalAlignment(itemIcon, RelativeLayout.Alignment.Start);
426 if (itemExtra != null)
428 RelativeLayout.SetLeftTarget(itemExtra, this);
429 RelativeLayout.SetLeftRelativeOffset(itemExtra, 1.0F);
430 RelativeLayout.SetRightTarget(itemExtra, this);
431 RelativeLayout.SetRightRelativeOffset(itemExtra, 1.0F);
432 RelativeLayout.SetTopTarget(itemExtra, this);
433 RelativeLayout.SetTopRelativeOffset(itemExtra, 0.0F);
434 RelativeLayout.SetBottomTarget(itemExtra, this);
435 RelativeLayout.SetBottomRelativeOffset(itemExtra, 1.0F);
436 RelativeLayout.SetVerticalAlignment(itemExtra, RelativeLayout.Alignment.Center);
437 RelativeLayout.SetHorizontalAlignment(itemExtra, RelativeLayout.Alignment.End);
440 if (itemSubLabel != null)
442 RelativeLayout.SetLeftTarget(itemSubLabel, ((itemIcon != null)? itemIcon : this));
443 RelativeLayout.SetLeftRelativeOffset(itemSubLabel, ( (itemIcon != null)? 1.0F : 0.0F));
444 RelativeLayout.SetRightTarget(itemSubLabel, ((itemExtra != null)? itemExtra : this));
445 RelativeLayout.SetRightRelativeOffset(itemSubLabel, ((itemExtra != null)? 0.0F : 1.0F));
446 RelativeLayout.SetTopTarget(itemSubLabel, this);
447 RelativeLayout.SetTopRelativeOffset(itemSubLabel, 1.0F);
448 RelativeLayout.SetBottomTarget(itemSubLabel, this);
449 RelativeLayout.SetBottomRelativeOffset(itemSubLabel, 1.0F);
450 RelativeLayout.SetVerticalAlignment(itemSubLabel, RelativeLayout.Alignment.End);
451 RelativeLayout.SetHorizontalAlignment(itemSubLabel, RelativeLayout.Alignment.Center);
452 RelativeLayout.SetFillHorizontal(itemSubLabel, true);
455 RelativeLayout.SetLeftTarget(itemLabel, ((itemIcon != null)? itemIcon : this));
456 RelativeLayout.SetLeftRelativeOffset(itemLabel, ((itemIcon != null)? 1.0F : 0.0F));
457 RelativeLayout.SetRightTarget(itemLabel, ((itemExtra != null)? itemExtra : this));
458 RelativeLayout.SetRightRelativeOffset(itemLabel, ((itemExtra != null)? 0.0F : 1.0F));
459 RelativeLayout.SetTopTarget(itemLabel, this);
460 RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
461 RelativeLayout.SetBottomTarget(itemLabel, ((itemSubLabel != null)? (View)itemSubLabel : this));
462 RelativeLayout.SetBottomRelativeOffset(itemLabel, ((itemSubLabel != null)? 0.0F : 1.0F));
463 RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Center);
464 RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
465 RelativeLayout.SetFillHorizontal(itemLabel, true);
467 if (prevSize != Size)
472 var margin = itemSeperator.Margin;
473 itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
474 itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
475 itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom - itemSeperator.SizeHeight);
481 /// Dispose Item and all children on it.
483 /// <param name="type">Dispose type.</param>
484 [EditorBrowsable(EditorBrowsableState.Never)]
485 protected override void Dispose(DisposeTypes type)
492 if (type == DisposeTypes.Explicit)
494 //Extension : Extension?.OnDispose(this);
496 // Arugable to disposing user-created members.
498 if (itemIcon != null)
500 Utility.Dispose(itemIcon);
502 if (itemExtra != null)
504 Utility.Dispose(itemExtra);
507 if (itemLabel != null)
509 Utility.Dispose(itemLabel);
512 if (itemSubLabel != null)
514 Utility.Dispose(itemSubLabel);
517 if (itemSeperator != null)
519 Utility.Dispose(itemSeperator);
520 itemSeperator = null;
528 /// Get DefaultLinearItem style.
530 /// <returns>The default DefaultLinearItem style.</returns>
531 [EditorBrowsable(EditorBrowsableState.Never)]
532 protected override ViewStyle CreateViewStyle()
534 return new DefaultLinearItemStyle();
538 /// Initializes AT-SPI object.
540 [EditorBrowsable(EditorBrowsableState.Never)]
541 public override void OnInitialize()
544 Layout = new RelativeLayout();
545 var seperator = Seperator;
546 layoutChanged = true;
547 LayoutDirectionChanged += OnLayoutDirectionChanged;
550 private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
556 private void OnIconRelayout(object sender, EventArgs e)
562 private void OnExtraRelayout(object sender, EventArgs e)