* Previously, the View did not support ControlState so that selector values are not applied to the View.
* Introduce a new property EnableControlState.
If this property is set to true, the View can have a touch related ControlState (such as Pressed) when touch.
By default, it is false in View, true in Control.
Note that if the value is true, the View will be a touch receptor.
Signed-off-by: Jiyun Yang <ji.yang@samsung.com>
Extension?.OnRelayout(this);
}
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override bool HandleControlStateOnTouch(Touch touch)
+ {
+ if (!IsEnabled || null == touch)
+ {
+ return false;
+ }
+
+ PointStateType state = touch.GetState(0);
+
+ switch (state)
+ {
+ case PointStateType.Down:
+ isPressed = true;
+ Extension?.SetTouchInfo(touch);
+ UpdateState();
+ return true;
+ case PointStateType.Interrupted:
+ isPressed = false;
+ UpdateState();
+ return true;
+ case PointStateType.Up:
+ {
+ bool clicked = isPressed && IsEnabled;
+
+ isPressed = false;
+
+ if (IsSelectable)
+ {
+ Extension?.SetTouchInfo(touch);
+ IsSelected = !IsSelected;
+ }
+ else
+ {
+ Extension?.SetTouchInfo(touch);
+ UpdateState();
+ }
+
+ if (clicked)
+ {
+ ClickedEventArgs eventArgs = new ClickedEventArgs();
+ OnClickedInternal(eventArgs);
+ }
+
+ return true;
+ }
+ default:
+ break;
+ }
+ return base.HandleControlStateOnTouch(touch);
+ }
+
/// <summary>
/// Update Button State.
/// </summary>
/// <since_tizen> 8 </since_tizen>
public override bool OnTouch(Touch touch)
{
- if (!IsEnabled || null == touch)
- {
- return false;
- }
-
- PointStateType state = touch.GetState(0);
-
- switch (state)
- {
- case PointStateType.Down:
- isPressed = true;
- Extension?.SetTouchInfo(touch);
- UpdateState();
- return true;
- case PointStateType.Interrupted:
- isPressed = false;
- UpdateState();
- return true;
- case PointStateType.Up:
- {
- bool clicked = isPressed && IsEnabled;
-
- isPressed = false;
-
- if (IsSelectable)
- {
- Extension?.SetTouchInfo(touch);
- IsSelected = !IsSelected;
- }
- else
- {
- Extension?.SetTouchInfo(touch);
- UpdateState();
- }
-
- if (clicked)
- {
- ClickedEventArgs eventArgs = new ClickedEventArgs();
- OnClickedInternal(eventArgs);
- }
-
- return true;
- }
- default:
- break;
- }
return base.OnTouch(touch);
}
protected virtual void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e) { }
/// <summary>
- /// Called after a touch event is received by the owning view.<br />
- /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
- /// </summary>
- /// <param name="touch">The touch event.</param>
- /// <returns>True if the event should be consumed.</returns>
- /// <since_tizen> 6 </since_tizen>
- /// 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)
- {
- // Handle Normal and Pressed states
- PointStateType state = touch.GetState(0);
- switch(state)
- {
- case PointStateType.Down:
- ControlState = ControlState.Pressed;
- break;
- case PointStateType.Interrupted:
- case PointStateType.Up:
- if (ControlState == ControlState.Pressed)
- {
- ControlState = ControlState.Normal;
- }
- break;
- default:
- break;
- }
- return false;
- }
-
- /// <summary>
/// Update by style.
/// </summary>
/// <since_tizen> 6 </since_tizen>
tapGestureDetector.Attach(this);
tapGestureDetector.Detected += OnTapGestureDetected;
+ EnableControlState = true;
+
StyleManager.Instance.ThemeChangedEvent += OnThemeChangedEvent;
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool OnTouch(Touch touch)
{
+ return base.OnTouch(touch);
+ }
+
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override bool HandleControlStateOnTouch(Touch touch)
+ {
if (false == IsEnabled)
{
return false;
}
PointStateType state = touch.GetState(0);
- bool ret = base.OnTouch(touch);
+ bool ret = base.HandleControlStateOnTouch(touch);
switch (state)
{
case PointStateType.Up:
/// <returns>The <see cref="ControlState"/> containing the result of the addition.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static ControlState operator +(ControlState lhs, ControlState rhs) => Create(lhs, rhs);
+
+ /// <summary>
+ /// The substraction operator.
+ /// </summary>
+ /// <param name="lhs">A <see cref="ControlState"/> on the left hand side.</param>
+ /// <param name="rhs">A <see cref="ControlState"/> on the right hand side.</param>
+ /// <returns>The <see cref="ControlState"/> containing the result of the substraction.</returns>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static ControlState operator -(ControlState lhs, ControlState rhs)
+ {
+ if (!lhs.IsCombined)
+ {
+ return ReferenceEquals(lhs, rhs) ? Normal : lhs;
+ }
+
+ var rest = lhs.stateList.Except(rhs.stateList);
+
+ if (rest.Count() == 0)
+ {
+ return Normal;
+ }
+
+ if (rest.Count() == 1)
+ {
+ return rest.First();
+ }
+
+ ControlState newState = new ControlState();
+ newState.stateList.AddRange(rest);
+ return newState;
+ }
}
/// <summary>
private ViewLayoutDirectionType? layoutDirection;
private Extents margin;
private float? weight;
+ private bool? enableControlState;
private Selector<ImageShadow> imageShadow;
private Selector<Shadow> boxShadow;
}
/// <summary>
+ /// The EnableControlState value of the View.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool? EnableControlState
+ {
+ get => (bool?)GetValue(EnableControlStateProperty);
+ set => SetValue(EnableControlStateProperty, value);
+ }
+
+ /// <summary>
/// Set style's bindable properties from the view.
/// </summary>
/// <param name="view">The view that includes property data.</param>
var viewStyle = (ViewStyle)bindable;
return viewStyle.cornerRadius;
});
+
+ /// <summary>
+ /// EnableControlState property
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static readonly BindableProperty EnableControlStateProperty = BindableProperty.Create("EnableControlState", typeof(bool?), typeof(ViewStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+ {
+ ((ViewStyle)bindable).enableControlState = (bool?)newValue;
+ },
+ defaultValueCreator: (bindable) =>
+ {
+ return ((ViewStyle)bindable).enableControlState;
+ });
}
}
}
/// <summary>
+ /// If this property is set to true, the View can have a touch related ControlState (such as Pressed) when touch.
+ /// By default, it is false in View, true in Control.
+ /// Note that if the value is true, the View will be a touch receptor.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool EnableControlState
+ {
+ get
+ {
+ return (bool)GetValue(EnableControlStateProperty);
+ }
+ set
+ {
+ SetValue(EnableControlStateProperty, value);
+ }
+ }
+
+ /// <summary>
/// Get Style, it is abstract function and must be override.
/// </summary>
/// <since_tizen> 6 </since_tizen>
[EditorBrowsable(EditorBrowsableState.Never)]
public static readonly BindableProperty XamlStyleProperty = BindableProperty.Create("XamlStyle", typeof(Style), typeof(View), default(Style), propertyChanged: (bindable, oldvalue, newvalue) => ((View)bindable)._mergedStyle.Style = (Style)newvalue);
+ /// <summary>
+ /// EnableControlState property
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static readonly BindableProperty EnableControlStateProperty = BindableProperty.Create(nameof(EnableControlState), typeof(bool), typeof(View), false, propertyChanged: (bindable, oldValue, newValue) =>
+ {
+ var view = (View)bindable;
+ bool prev = view.enableControlState;
+ view.enableControlState = (bool)newValue;
+
+ if (prev != view.enableControlState)
+ {
+ if (prev)
+ {
+ view.TouchEvent -= view.EmptyOnTouch;
+ }
+ else
+ {
+ view.TouchEvent += view.EmptyOnTouch;
+ }
+ }
+ },
+ defaultValueCreator: (bindable) =>
+ {
+ return ((View)bindable).enableControlState;
+ });
#region Selectors
internal static readonly BindableProperty BackgroundImageSelectorProperty = BindableProperty.Create("BackgroundImageSelector", typeof(Selector<string>), typeof(View), null, propertyChanged: (bindable, oldValue, newValue) =>
{
this.TouchSignal().Disconnect(_touchDataCallback);
}
-
}
}
e.Touch = Tizen.NUI.Touch.GetTouchFromPtr(touchData);
+ bool consumed = false;
+
if (_touchDataEventHandler != null)
{
- return _touchDataEventHandler(this, e);
+ consumed = _touchDataEventHandler(this, e);
}
- return false;
+
+ if (enableControlState && !consumed)
+ {
+ consumed = HandleControlStateOnTouch(e.Touch);
+ }
+
+ return consumed;
}
// Callback for View Hover signal
}
}
+ /// <summary>
+ /// Indicates that this View should listen Touch event to handle its ControlState.
+ /// </summary>
+ private bool enableControlState = false;
+
private int LeftFocusableViewId
{
get
Interop.View.delete_View(swigCPtr);
}
+ /// <summary>
+ /// The touch event handler for ControlState.
+ /// Please change ControlState value by touch state if needed.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual bool HandleControlStateOnTouch(Touch touch)
+ {
+ switch(touch.GetState(0))
+ {
+ case PointStateType.Down:
+ ControlState += ControlState.Pressed;
+ break;
+ case PointStateType.Interrupted:
+ case PointStateType.Up:
+ if (ControlState.Contains(ControlState.Pressed))
+ {
+ ControlState -= ControlState.Pressed;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
private void DisConnectFromSignals()
{
// Save current CPtr.
Tizen.NUI.Object.SetProperty(swigCPtr, View.Property.SHADOW, new PropertyValue(map));
}
}
+
+ private bool EmptyOnTouch(object target, TouchEventArgs args)
+ {
+ return false;
+ }
}
}