/*
* Copyright(c) 2019 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.Collections.Generic;
using System.ComponentModel;
using Tizen.NUI.BaseComponents;
namespace Tizen.NUI.Components
{
///
/// The control component is base class of tv nui components. It's abstract class, so cann't instantiate and can only be inherited.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public abstract class Control : VisualView
{
///
/// Control style.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected string style;
///
/// Control attributes.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected Attributes attributes;
private TapGestureDetector tapGestureDetector = new TapGestureDetector();
private bool isFocused = false;
///
/// Construct an empty Control.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public Control() : base()
{
Initialize(null);
}
///
/// Construct with attributes
///
/// Create attributes customized by user
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public Control(Attributes attributes) : base()
{
Initialize(null);
this.attributes = attributes.Clone();
}
///
/// Construct with style
///
/// Style to be applied
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public Control(string style) : base()
{
Initialize(style);
}
///
/// Get/Set the control state.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public new ControlStates State
{
get;
set;
}
///
/// Whether focusable when touch
///
/// 6
internal bool StateFocusableOnTouchMode
{
get;
set;
}
internal bool IsFocused
{
get
{
return isFocused || HasFocus();
}
}
///
/// Apply attributes for View, Image or TextLabel.
///
/// View which will be applied attrs
/// Attributes for View, Image or TextLabel
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected void ApplyAttributes(View view, ViewAttributes attrs)
{
if (view == null || attrs == null)
{
return;
}
if (attrs.Position2D != null)
{
view.Position2D = attrs.Position2D;
}
if (attrs.Size2D != null)
{
view.Size2D = attrs.Size2D;
}
if (attrs.MinimumSize != null)
{
view.MinimumSize = attrs.MinimumSize;
}
if (attrs.BackgroundColor?.GetValue(State) != null)
{
view.BackgroundColor = attrs.BackgroundColor.GetValue(State);
}
if (attrs.PositionUsesPivotPoint != null)
{
view.PositionUsesPivotPoint = attrs.PositionUsesPivotPoint.Value;
}
if (attrs.ParentOrigin != null)
{
view.ParentOrigin = attrs.ParentOrigin;
}
if (attrs.PivotPoint != null)
{
view.PivotPoint = attrs.PivotPoint;
}
if (attrs.WidthResizePolicy!= null)
{
view.WidthResizePolicy = attrs.WidthResizePolicy.Value;
}
if (attrs.HeightResizePolicy != null)
{
view.HeightResizePolicy = attrs.HeightResizePolicy.Value;
}
if (attrs.SizeModeFactor != null)
{
view.SizeModeFactor = attrs.SizeModeFactor;
}
if (attrs.Opacity?.GetValue(State) != null)
{
view.Opacity = attrs.Opacity.GetValue(State).Value;
}
ImageView image = view as ImageView;
ImageAttributes imageAttrs = attrs as ImageAttributes;
if (image != null && imageAttrs != null)
{
if (imageAttrs.ResourceURL?.GetValue(State) != null)
{
image.ResourceUrl = imageAttrs.ResourceURL.GetValue(State);
}
if (imageAttrs.Border?.GetValue(State) != null)
{
image.Border = imageAttrs.Border.GetValue(State);
}
}
TextLabel text = view as TextLabel;
TextAttributes textAttrs = attrs as TextAttributes;
if (text != null && textAttrs != null)
{
if (textAttrs.Text?.GetValue(State) != null )
{
text.Text = textAttrs.Text.GetValue(State);
}
if (textAttrs.TranslatableText?.GetValue(State) != null)
{
text.TranslatableText = textAttrs.TranslatableText.GetValue(State);
}
if (textAttrs.MultiLine != null)
{
text.MultiLine = textAttrs.MultiLine.Value;
}
if (textAttrs.HorizontalAlignment != null)
{
text.HorizontalAlignment = textAttrs.HorizontalAlignment.Value;
}
if (textAttrs.VerticalAlignment != null)
{
text.VerticalAlignment = textAttrs.VerticalAlignment.Value;
}
if (textAttrs.EnableMarkup != null)
{
text.EnableMarkup = textAttrs.EnableMarkup.Value;
}
if (textAttrs.AutoScrollLoopCount != null)
{
text.AutoScrollLoopCount = textAttrs.AutoScrollLoopCount.Value;
}
if (textAttrs.AutoScrollSpeed != null)
{
text.AutoScrollSpeed = textAttrs.AutoScrollSpeed.Value;
}
if (textAttrs.AutoScrollGap != null)
{
text.AutoScrollGap = textAttrs.AutoScrollGap.Value;
}
if (textAttrs.AutoScrollLoopDelay != null)
{
text.AutoScrollLoopDelay = textAttrs.AutoScrollLoopDelay.Value;
}
if (textAttrs.AutoScrollStopMode != null)
{
text.AutoScrollStopMode = textAttrs.AutoScrollStopMode.Value;
}
if (textAttrs.LineSpacing != null)
{
text.LineSpacing = textAttrs.LineSpacing.Value;
}
if (textAttrs.TextColor?.GetValue(State) != null)
{
text.TextColor = textAttrs.TextColor.GetValue(State);
}
if (textAttrs.FontFamily != null)
{
text.FontFamily = textAttrs.FontFamily;
}
if (textAttrs.PointSize?.GetValue(State) != null)
{
text.PointSize = textAttrs.PointSize.GetValue(State).Value;
}
int thickness = 0;
if (textAttrs.OutstrokeThickness?.GetValue(State) != null)
{
thickness = textAttrs.OutstrokeThickness.GetValue(State).Value;
}
if (textAttrs.OutstrokeColor?.GetValue(State) != null)
{
Color outstrokeColor = textAttrs.OutstrokeColor.GetValue(State);
PropertyMap outlineMap = new PropertyMap();
outlineMap.Add("color", new PropertyValue(new Color(outstrokeColor.R, outstrokeColor.G, outstrokeColor.B, outstrokeColor.A)));
outlineMap.Add("width", new PropertyValue(thickness));
text.Outline = outlineMap;
}
else
{
text.Outline = new PropertyMap();
}
}
TextField textField = view as TextField;
TextFieldAttributes textFieldAttrs = attrs as TextFieldAttributes;
if (textField != null && textFieldAttrs != null)
{
if (textFieldAttrs.Text?.GetValue(State) != null)
{
textField.Text = textFieldAttrs.Text.GetValue(State);
}
if (textFieldAttrs.PlaceholderText?.GetValue(State) != null)
{
textField.PlaceholderText = textFieldAttrs.PlaceholderText.GetValue(State);
}
if (textFieldAttrs.TranslatablePlaceholderText?.GetValue(State) != null)
{
textField.TranslatablePlaceholderText = textFieldAttrs.TranslatablePlaceholderText.GetValue(State);
}
if (textFieldAttrs.HorizontalAlignment != null)
{
textField.HorizontalAlignment = textFieldAttrs.HorizontalAlignment.Value;
}
if (textFieldAttrs.VerticalAlignment != null)
{
textField.VerticalAlignment = textFieldAttrs.VerticalAlignment.Value;
}
if (textFieldAttrs.EnableMarkup != null)
{
textField.EnableMarkup = textFieldAttrs.EnableMarkup.Value;
}
if (textFieldAttrs.TextColor?.GetValue(State) != null)
{
textField.TextColor = textFieldAttrs.TextColor.GetValue(State);
}
if (textFieldAttrs.PlaceholderTextColor?.GetValue(State) != null)
{
textField.PlaceholderTextColor = textFieldAttrs.PlaceholderTextColor.GetValue(State);
}
if (textFieldAttrs.PrimaryCursorColor?.GetValue(State) != null)
{
textField.PrimaryCursorColor = textFieldAttrs.PrimaryCursorColor.GetValue(State);
}
if (textFieldAttrs.SecondaryCursorColor?.GetValue(State) != null)
{
textField.SecondaryCursorColor = textFieldAttrs.SecondaryCursorColor.GetValue(State);
}
if (textFieldAttrs.FontFamily != null)
{
textField.FontFamily = textFieldAttrs.FontFamily;
}
if (textFieldAttrs.PointSize?.GetValue(State) != null)
{
textField.PointSize = textFieldAttrs.PointSize.GetValue(State).Value;
}
if (textFieldAttrs.EnableCursorBlink != null)
{
textField.EnableCursorBlink = textFieldAttrs.EnableCursorBlink.Value;
}
if (textFieldAttrs.EnableSelection != null)
{
textField.EnableSelection = textFieldAttrs.EnableSelection.Value;
}
if (textFieldAttrs.CursorWidth != null)
{
textField.CursorWidth = textFieldAttrs.CursorWidth.Value;
}
if (textFieldAttrs.EnableEllipsis != null)
{
textField.Ellipsis = textFieldAttrs.EnableEllipsis.Value;
}
}
}
///
/// Dispose Control and all children on it.
///
/// Dispose type.
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void Dispose(DisposeTypes type)
{
if (disposed)
{
return;
}
if (type == DisposeTypes.Explicit)
{
StyleManager.Instance.ThemeChangedEvent -= OnThemeChangedEvent;
tapGestureDetector.Detected -= OnTapGestureDetected;
tapGestureDetector.Detach(this);
}
base.Dispose(type);
}
///
/// Get attribues, it is abstract function and must be override.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected abstract Attributes GetAttributes();
///
/// Called after a key event is received by the view that has had its focus set.
///
/// The key event.
/// True if the key event should be consumed.
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool OnKey(Key key)
{
return false;
}
///
/// Called after the size negotiation has been finished for this control.
/// The control is expected to assign this given size to itself or its children.
/// Should be overridden by derived classes if they need to layout views differently after certain operations like add or remove views, resize, or after changing specific properties.
/// As this function is called from inside the size negotiation algorithm, you cannot call RequestRelayout (the call would just be ignored).
///
/// The allocated size.
/// The control should add views to this container that it is not able to allocate a size for.
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public override void OnRelayout(Vector2 size, RelayoutContainer container)
{
OnUpdate();
}
///
/// Called when the control gain key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is gained.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public override void OnFocusGained()
{
isFocused = true;
}
///
/// Called when the control loses key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is lost.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public override void OnFocusLost()
{
isFocused = false;
}
///
/// Tap gesture callback.
///
/// The sender
/// The tap gesture event data
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected virtual void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e)
{
}
///
/// Called after a touch event is received by the owning view.
/// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).
///
/// The touch event.
/// True if the event should be consumed.
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool OnTouch(Touch touch)
{
return false;
}
///
/// Update by attributes.
///
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected virtual void OnUpdate()
{
}
///
/// Theme change callback when theme is changed, this callback will be trigger.
///
/// The sender
/// The event data
/// 6
/// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
protected virtual void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
{
}
private void Initialize(string style)
{
attributes = (style == null) ? GetAttributes() : GetAttributes(style);
State = ControlStates.Normal;
LeaveRequired = true;
StateFocusableOnTouchMode = false;
tapGestureDetector.Attach(this);
tapGestureDetector.Detected += OnTapGestureDetected;
StyleManager.Instance.ThemeChangedEvent += OnThemeChangedEvent;
}
private Attributes GetAttributes(string style)
{
Attributes attributes = StyleManager.Instance.GetAttributes(style);
if(attributes == null)
{
throw new InvalidOperationException($"There is no style {style}");
}
this.style = style;
return attributes;
}
}
}