/* Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.ComponentModel;
using Tizen.NUI.BaseComponents;
using Tizen.NUI.Accessibility;
namespace Tizen.NUI.Components
{
///
/// DefaultGridItem is one kind of common component, a DefaultGridItem clearly describes what action will occur when the user selects it.
/// DefaultGridItem may contain text or an icon.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public partial class DefaultGridItem : RecyclerViewItem
{
private TextLabel itemLabel;
private ImageView itemImage;
private View itemBadge;
private LabelOrientation labelOrientation;
private bool layoutChanged;
private DefaultGridItemStyle ItemStyle => ViewStyle as DefaultGridItemStyle;
static DefaultGridItem() { }
///
/// Creates a new instance of DefaultGridItem.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public DefaultGridItem() : base()
{
}
///
/// Creates a new instance of DefaultGridItem with style
///
/// Create DefaultGridItem by special style defined in UX.
[EditorBrowsable(EditorBrowsableState.Never)]
public DefaultGridItem(string style) : base(style)
{
}
///
/// Creates a new instance of DefaultGridItem with style
///
/// Create DefaultGridItem by style customized by user.
[EditorBrowsable(EditorBrowsableState.Never)]
public DefaultGridItem(DefaultGridItemStyle itemStyle) : base(itemStyle)
{
}
///
/// Label orientation.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public enum LabelOrientation
{
///
/// Outside of image bottom edge.
///
[EditorBrowsable(EditorBrowsableState.Never)]
OutsideBottom,
///
/// Outside of image top edge.
///
[EditorBrowsable(EditorBrowsableState.Never)]
OutsideTop,
///
/// inside of image bottom edge.
///
[EditorBrowsable(EditorBrowsableState.Never)]
InsideBottom,
///
/// inside of image top edge.
///
[EditorBrowsable(EditorBrowsableState.Never)]
InsideTop,
}
///
/// DefaultGridItem's icon part.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public ImageView Image
{
get
{
if (itemImage == null)
{
itemImage = CreateImage(ItemStyle.Image);
if (itemImage != null)
{
Add(itemImage);
itemImage.Relayout += OnImageRelayout;
layoutChanged = true;
}
}
return itemImage;
}
internal set
{
if (itemImage != null) Remove(itemImage);
itemImage = value;
if (itemImage != null)
{
//FIXME: User applied image's style can be overwritten!
if (ItemStyle != null) itemImage.ApplyStyle(ItemStyle.Image);
Add(itemImage);
itemImage.Relayout += OnImageRelayout;
}
layoutChanged = true;
}
}
///
/// DefaultGridItem's badge object. will be placed in right-top edge.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public View Badge
{
get
{
return GetValue(BadgeProperty) as View;
}
set
{
SetValue(BadgeProperty, value);
NotifyPropertyChanged();
}
}
private View InternalBadge
{
get
{
return itemBadge;
}
set
{
if (itemBadge != null) Remove(itemBadge);
itemBadge = value;
if (itemBadge != null)
{
//FIXME: User applied badge's style can be overwritten!
if (ItemStyle != null) itemBadge.ApplyStyle(ItemStyle.Badge);
Add(itemBadge);
}
layoutChanged = true;
}
}
///
/// Image resource url in DefaultGridItem.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public string ResourceUrl
{
get => GetValue(ResourceUrlProperty) as string;
set
{
SetValue(ResourceUrlProperty, value);
NotifyPropertyChanged();
}
}
internal string InternalResourceUrl
{
get
{
return Image.ResourceUrl;
}
set
{
Image.ResourceUrl = value;
}
}
///
/// DefaultGridItem's text part.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public TextLabel Label
{
get
{
if (itemLabel == null)
{
itemLabel = CreateLabel(ItemStyle.Label);
if (itemLabel != null)
{
Add(itemLabel);
layoutChanged = true;
}
}
return itemLabel;
}
internal set
{
itemLabel = value;
layoutChanged = true;
}
}
///
/// The text of DefaultGridItem.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public string Text
{
get
{
return GetValue(TextProperty) as string;
}
set
{
SetValue(TextProperty, value);
NotifyPropertyChanged();
}
}
private string InternalText
{
get
{
return Label.Text;
}
set
{
Label.Text = value;
}
}
///
/// Label relative orientation with image in DefaultGridItem.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public LabelOrientation LabelOrientationType
{
get
{
return (Tizen.NUI.Components.DefaultGridItem.LabelOrientation)GetValue(LabelOrientationTypeProperty);
}
set
{
SetValue(LabelOrientationTypeProperty, value);
NotifyPropertyChanged();
}
}
private Tizen.NUI.Components.DefaultGridItem.LabelOrientation InternalLabelOrientationType
{
get
{
return labelOrientation;
}
set
{
labelOrientation = value;
layoutChanged = true;
}
}
///
/// Apply style to DefaultLinearItemStyle.
///
/// The style to apply.
[EditorBrowsable(EditorBrowsableState.Never)]
public override void ApplyStyle(ViewStyle viewStyle)
{
base.ApplyStyle(viewStyle);
if (viewStyle != null && viewStyle is DefaultGridItemStyle defaultStyle)
{
if (itemLabel != null)
itemLabel.ApplyStyle(defaultStyle.Label);
if (itemImage != null)
itemImage.ApplyStyle(defaultStyle.Image);
if (itemBadge != null)
itemBadge.ApplyStyle(defaultStyle.Badge);
}
}
///
/// Creates Item's text part.
///
/// The created Item's text part.
[EditorBrowsable(EditorBrowsableState.Never)]
protected virtual TextLabel CreateLabel(TextLabelStyle textStyle)
{
return new TextLabel(textStyle)
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
}
///
/// Creates Item's icon part.
///
/// The created Item's icon part.
[EditorBrowsable(EditorBrowsableState.Never)]
protected virtual ImageView CreateImage(ImageViewStyle imageStyle)
{
return new ImageView(imageStyle);
}
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void MeasureChild()
{
//nothing to do.
if (itemLabel)
{
var pad = Padding;
var margin = itemLabel.Margin;
itemLabel.SizeWidth = SizeWidth - pad.Start - pad.End - margin.Start - margin.End;
}
}
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void LayoutChild()
{
if (!layoutChanged) return;
if (itemImage == null) return;
layoutChanged = false;
RelativeLayout.SetLeftTarget(itemImage, this);
RelativeLayout.SetLeftRelativeOffset(itemImage, 0.0F);
RelativeLayout.SetRightTarget(itemImage, this);
RelativeLayout.SetRightRelativeOffset(itemImage, 1.0F);
RelativeLayout.SetHorizontalAlignment(itemImage, RelativeLayout.Alignment.Center);
RelativeLayout.SetFillHorizontal(itemImage, true);
RelativeLayout.SetFillVertical(itemImage, true);
if (itemLabel != null)
{
itemLabel.RaiseAbove(itemImage);
RelativeLayout.SetLeftTarget(itemLabel, itemImage);
RelativeLayout.SetLeftRelativeOffset(itemLabel, 0.0F);
RelativeLayout.SetRightTarget(itemLabel, itemImage);
RelativeLayout.SetRightRelativeOffset(itemLabel, 1.0F);
RelativeLayout.SetHorizontalAlignment(itemLabel, RelativeLayout.Alignment.Center);
RelativeLayout.SetFillHorizontal(itemLabel, true);
}
else
{
RelativeLayout.SetTopTarget(itemImage, this);
RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
RelativeLayout.SetBottomTarget(itemImage, this);
RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
}
if (itemBadge)
{
itemBadge.RaiseAbove(itemImage);
RelativeLayout.SetLeftTarget(itemBadge, itemImage);
RelativeLayout.SetLeftRelativeOffset(itemBadge, 1.0F);
RelativeLayout.SetRightTarget(itemBadge, itemImage);
RelativeLayout.SetRightRelativeOffset(itemBadge, 1.0F);
RelativeLayout.SetHorizontalAlignment(itemBadge, RelativeLayout.Alignment.End);
}
switch (labelOrientation)
{
case LabelOrientation.OutsideBottom:
if (itemLabel != null)
{
RelativeLayout.SetTopTarget(itemLabel, this);
RelativeLayout.SetTopRelativeOffset(itemLabel, 1.0F);
RelativeLayout.SetBottomTarget(itemLabel, this);
RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.End);
RelativeLayout.SetTopTarget(itemImage, this);
RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
RelativeLayout.SetBottomTarget(itemImage, itemLabel);
RelativeLayout.SetBottomRelativeOffset(itemImage, 0.0F);
RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
}
if (itemBadge)
{
RelativeLayout.SetTopTarget(itemBadge, itemImage);
RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
RelativeLayout.SetBottomTarget(itemBadge, itemImage);
RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
}
break;
case LabelOrientation.OutsideTop:
if (itemLabel != null)
{
RelativeLayout.SetTopTarget(itemLabel, this);
RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
RelativeLayout.SetBottomTarget(itemLabel, this);
RelativeLayout.SetBottomRelativeOffset(itemLabel, 0.0F);
RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Start);
RelativeLayout.SetTopTarget(itemImage, itemLabel);
RelativeLayout.SetTopRelativeOffset(itemImage, 1.0F);
RelativeLayout.SetBottomTarget(itemImage, this);
RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
}
if (itemBadge)
{
RelativeLayout.SetTopTarget(itemBadge, itemImage);
RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
RelativeLayout.SetBottomTarget(itemBadge, itemImage);
RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
}
break;
case LabelOrientation.InsideBottom:
if (itemLabel != null)
{
RelativeLayout.SetTopTarget(itemLabel, this);
RelativeLayout.SetTopRelativeOffset(itemLabel, 1.0F);
RelativeLayout.SetBottomTarget(itemLabel, this);
RelativeLayout.SetBottomRelativeOffset(itemLabel, 1.0F);
RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.End);
Console.WriteLine("Item Label Inside Bottom!");
RelativeLayout.SetTopTarget(itemImage, this);
RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
RelativeLayout.SetBottomTarget(itemImage, this);
RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
}
if (itemBadge)
{
RelativeLayout.SetTopTarget(itemBadge, itemImage);
RelativeLayout.SetTopRelativeOffset(itemBadge, 0.0F);
RelativeLayout.SetBottomTarget(itemBadge, itemImage);
RelativeLayout.SetBottomRelativeOffset(itemBadge, 0.0F);
RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.Start);
}
break;
case LabelOrientation.InsideTop:
if (itemLabel != null)
{
RelativeLayout.SetTopTarget(itemLabel, this);
RelativeLayout.SetTopRelativeOffset(itemLabel, 0.0F);
RelativeLayout.SetBottomTarget(itemLabel, this);
RelativeLayout.SetBottomRelativeOffset(itemLabel, 0.0F);
RelativeLayout.SetVerticalAlignment(itemLabel, RelativeLayout.Alignment.Start);
RelativeLayout.SetTopTarget(itemImage, this);
RelativeLayout.SetTopRelativeOffset(itemImage, 0.0F);
RelativeLayout.SetBottomTarget(itemImage, this);
RelativeLayout.SetBottomRelativeOffset(itemImage, 1.0F);
RelativeLayout.SetVerticalAlignment(itemImage, RelativeLayout.Alignment.Center);
}
if (itemBadge)
{
RelativeLayout.SetTopTarget(itemBadge, itemImage);
RelativeLayout.SetTopRelativeOffset(itemBadge, 1.0F);
RelativeLayout.SetBottomTarget(itemBadge, itemImage);
RelativeLayout.SetBottomRelativeOffset(itemBadge, 1.0F);
RelativeLayout.SetVerticalAlignment(itemBadge, RelativeLayout.Alignment.End);
}
break;
}
}
///
/// Gets accessibility name.
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected override string AccessibilityGetName()
{
return itemLabel.Text;
}
///
/// Initializes AT-SPI object.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public override void OnInitialize()
{
base.OnInitialize();
Layout = new RelativeLayout();
layoutChanged = true;
LayoutDirectionChanged += OnLayoutDirectionChanged;
EnableControlStatePropagation = true;
}
///
/// Dispose Item and all children on it.
///
/// Dispose type.
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void Dispose(DisposeTypes type)
{
if (disposed)
{
return;
}
if (type == DisposeTypes.Explicit)
{
//Extension : Extension?.OnDispose(this);
// Arugable to disposing user-created members.
/*
if (itemBadge != null)
{
Utility.Dispose(itemBadge);
}
*/
if (itemImage != null)
{
Utility.Dispose(itemImage);
itemImage = null;
}
if (itemLabel != null)
{
Utility.Dispose(itemLabel);
itemLabel = null;
}
}
base.Dispose(type);
}
private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
{
MeasureChild();
LayoutChild();
}
private void OnImageRelayout(object sender, EventArgs e)
{
MeasureChild();
LayoutChild();
}
}
}