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;
153 itemLabel.AppendAccessibilityRelation(this, AccessibilityRelationType.ControlledBy);
154 this.AppendAccessibilityRelation(itemLabel, AccessibilityRelationType.LabelledBy);
161 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemLabel.Text);
166 /// The text of DefaultLinearItem.
168 [EditorBrowsable(EditorBrowsableState.Never)]
173 return GetValue(TextProperty) as string;
177 SetValue(TextProperty, value);
178 NotifyPropertyChanged();
181 private string InternalText
194 /// DefaultLinearItem's secondary text part of DefaultLinearItem
196 [EditorBrowsable(EditorBrowsableState.Never)]
197 public TextLabel SubLabel
201 if (itemSubLabel == null)
203 itemSubLabel = CreateLabel(ItemStyle?.SubLabel);
204 if (itemLabel != null)
206 layoutChanged = true;
214 itemSubLabel = value;
215 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, itemSubLabel.Text);
220 /// The text of DefaultLinearItem.
222 [EditorBrowsable(EditorBrowsableState.Never)]
223 public string SubText
227 return GetValue(SubTextProperty) as string;
231 SetValue(SubTextProperty, value);
232 NotifyPropertyChanged();
235 private string InternalSubText
239 return SubLabel.Text;
243 SubLabel.Text = value;
248 /// Extra icon part of DefaultLinearItem. it will place next of label.
250 [EditorBrowsable(EditorBrowsableState.Never)]
255 return GetValue(ExtraProperty) as View;
259 SetValue(ExtraProperty, value);
260 NotifyPropertyChanged();
263 private View InternalExtra
267 if (itemExtra == null)
269 itemExtra = CreateIcon(ItemStyle?.Extra);
270 if (itemExtra != null)
272 layoutChanged = true;
274 itemExtra.Relayout += OnExtraRelayout;
281 if (itemExtra != null) Remove(itemExtra);
283 if (itemExtra != null)
285 //FIXME: User applied extra's style can be overwritten!
286 if (ItemStyle != null) itemExtra.ApplyStyle(ItemStyle.Extra);
289 layoutChanged = true;
294 /// Seperator divider of DefaultLinearItem. it will place at the end of item.
296 [EditorBrowsable(EditorBrowsableState.Never)]
297 public View Seperator
301 if (itemSeperator == null)
303 itemSeperator = new View(ItemStyle?.Seperator)
305 //need to consider horizontal/vertical!
306 WidthSpecification = LayoutParamPolicies.MatchParent,
307 HeightSpecification = 2,
308 ExcludeLayouting = true
310 layoutChanged = true;
313 return itemSeperator;
318 /// Apply style to DefaultLinearItemStyle.
320 /// <param name="viewStyle">The style to apply.</param>
321 [EditorBrowsable(EditorBrowsableState.Never)]
322 public override void ApplyStyle(ViewStyle viewStyle)
324 base.ApplyStyle(viewStyle);
325 if (viewStyle != null && viewStyle is DefaultLinearItemStyle defaultStyle)
327 if (itemLabel != null)
328 itemLabel.ApplyStyle(defaultStyle.Label);
329 if (itemSubLabel != null)
330 itemSubLabel.ApplyStyle(defaultStyle.SubLabel);
331 if (itemIcon != null)
332 itemIcon.ApplyStyle(defaultStyle.Icon);
333 if (itemExtra != null)
334 itemExtra.ApplyStyle(defaultStyle.Extra);
335 if (itemSeperator != null)
337 itemSeperator.ApplyStyle(defaultStyle.Seperator);
338 //FIXME : currently padding and margin are not applied by ApplyStyle automatically as missing binding features.
339 itemSeperator.Margin = new Extents(defaultStyle.Seperator.Margin);
345 [EditorBrowsable(EditorBrowsableState.Never)]
346 public override void OnRelayout(Vector2 size, RelayoutContainer container)
348 base.OnRelayout(size, container);
350 if (prevSize != Size)
355 var margin = itemSeperator.Margin;
356 itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
357 itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
358 itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom - itemSeperator.SizeHeight);
364 /// Creates Item's text part.
366 /// <return>The created Item's text part.</return>
367 [EditorBrowsable(EditorBrowsableState.Never)]
368 protected virtual TextLabel CreateLabel(TextLabelStyle style)
370 return new TextLabel(style)
372 HorizontalAlignment = HorizontalAlignment.Begin,
373 VerticalAlignment = VerticalAlignment.Center
378 /// Creates Item's icon part.
380 /// <return>The created Item's icon part.</return>
381 [EditorBrowsable(EditorBrowsableState.Never)]
382 protected virtual ImageView CreateIcon(ViewStyle style)
384 return new ImageView(style);
388 [EditorBrowsable(EditorBrowsableState.Never)]
389 protected override void MeasureChild()
391 //Do Measure in here if necessary.
395 [EditorBrowsable(EditorBrowsableState.Never)]
396 protected override void LayoutChild()
398 if (!layoutChanged) return;
399 if (itemLabel == null) return;
401 layoutChanged = false;
403 if (itemIcon != null)
405 RelativeLayout.SetLeftTarget(itemIcon, this);
406 RelativeLayout.SetLeftRelativeOffset(itemIcon, 0.0F);
407 RelativeLayout.SetRightTarget(itemIcon, this);
408 RelativeLayout.SetRightRelativeOffset(itemIcon, 0.0F);
409 RelativeLayout.SetTopTarget(itemIcon, this);
410 RelativeLayout.SetTopRelativeOffset(itemIcon, 0.0F);
411 RelativeLayout.SetBottomTarget(itemIcon, this);
412 RelativeLayout.SetBottomRelativeOffset(itemIcon, 1.0F);
413 RelativeLayout.SetVerticalAlignment(itemIcon, RelativeLayout.Alignment.Center);
414 RelativeLayout.SetHorizontalAlignment(itemIcon, RelativeLayout.Alignment.Start);
417 if (itemExtra != null)
419 RelativeLayout.SetLeftTarget(itemExtra, this);
420 RelativeLayout.SetLeftRelativeOffset(itemExtra, 1.0F);
421 RelativeLayout.SetRightTarget(itemExtra, this);
422 RelativeLayout.SetRightRelativeOffset(itemExtra, 1.0F);
423 RelativeLayout.SetTopTarget(itemExtra, this);
424 RelativeLayout.SetTopRelativeOffset(itemExtra, 0.0F);
425 RelativeLayout.SetBottomTarget(itemExtra, this);
426 RelativeLayout.SetBottomRelativeOffset(itemExtra, 1.0F);
427 RelativeLayout.SetVerticalAlignment(itemExtra, RelativeLayout.Alignment.Center);
428 RelativeLayout.SetHorizontalAlignment(itemExtra, RelativeLayout.Alignment.End);
431 if (itemSubLabel != null)
433 RelativeLayout.SetLeftTarget(itemSubLabel, ((itemIcon != null)? itemIcon : this));
434 RelativeLayout.SetLeftRelativeOffset(itemSubLabel, ( (itemIcon != null)? 1.0F : 0.0F));
435 RelativeLayout.SetRightTarget(itemSubLabel, ((itemExtra != null)? itemExtra : this));
436 RelativeLayout.SetRightRelativeOffset(itemSubLabel, ((itemExtra != null)? 0.0F : 1.0F));
437 RelativeLayout.SetTopTarget(itemSubLabel, this);
438 RelativeLayout.SetTopRelativeOffset(itemSubLabel, 1.0F);
439 RelativeLayout.SetBottomTarget(itemSubLabel, this);
440 RelativeLayout.SetBottomRelativeOffset(itemSubLabel, 1.0F);
441 RelativeLayout.SetVerticalAlignment(itemSubLabel, RelativeLayout.Alignment.End);
442 RelativeLayout.SetHorizontalAlignment(itemSubLabel, RelativeLayout.Alignment.Center);
443 RelativeLayout.SetFillHorizontal(itemSubLabel, true);
446 RelativeLayout.SetLeftTarget(itemLabel, ((itemIcon != null)? itemIcon : this));
447 RelativeLayout.SetLeftRelativeOffset(itemLabel, ((itemIcon != null)? 1.0F : 0.0F));
448 RelativeLayout.SetRightTarget(itemLabel, ((itemExtra != null)? itemExtra : this));
449 RelativeLayout.SetRightRelativeOffset(itemLabel, ((itemExtra != null)? 0.0F : 1.0F));
450 RelativeLayout.SetTopTarget(itemLabel, this);
451 RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
452 RelativeLayout.SetBottomTarget(itemLabel, ((itemSubLabel != null)? (View)itemSubLabel : this));
453 RelativeLayout.SetBottomRelativeOffset(itemLabel, ((itemSubLabel != null)? 0.0F : 1.0F));
454 RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Center);
455 RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
456 RelativeLayout.SetFillHorizontal(itemLabel, true);
458 if (prevSize != Size)
463 var margin = itemSeperator.Margin;
464 itemSeperator.SizeWidth = SizeWidth - margin.Start - margin.End;
465 itemSeperator.SizeHeight = itemSeperator.HeightSpecification;
466 itemSeperator.Position = new Position(margin.Start, SizeHeight - margin.Bottom - itemSeperator.SizeHeight);
472 /// Dispose Item and all children on it.
474 /// <param name="type">Dispose type.</param>
475 [EditorBrowsable(EditorBrowsableState.Never)]
476 protected override void Dispose(DisposeTypes type)
483 if (type == DisposeTypes.Explicit)
485 //Extension : Extension?.OnDispose(this);
487 // Arugable to disposing user-created members.
489 if (itemIcon != null)
491 Utility.Dispose(itemIcon);
493 if (itemExtra != null)
495 Utility.Dispose(itemExtra);
498 if (itemLabel != null)
500 Utility.Dispose(itemLabel);
503 if (itemSubLabel != null)
505 Utility.Dispose(itemSubLabel);
508 if (itemSeperator != null)
510 Utility.Dispose(itemSeperator);
511 itemSeperator = null;
519 /// Get DefaultLinearItem style.
521 /// <returns>The default DefaultLinearItem style.</returns>
522 [EditorBrowsable(EditorBrowsableState.Never)]
523 protected override ViewStyle CreateViewStyle()
525 return new DefaultLinearItemStyle();
529 /// Initializes AT-SPI object.
531 [EditorBrowsable(EditorBrowsableState.Never)]
532 public override void OnInitialize()
535 Layout = new RelativeLayout();
536 var seperator = Seperator;
537 layoutChanged = true;
538 LayoutDirectionChanged += OnLayoutDirectionChanged;
541 private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
547 private void OnIconRelayout(object sender, EventArgs e)
553 private void OnExtraRelayout(object sender, EventArgs e)