Skip to content

Commit

Permalink
fix: Prevent Shapes (mapped to svg) to stoll the pointer events when …
Browse files Browse the repository at this point in the history
…they are not visible
  • Loading branch information
Dr.Rx committed Mar 16, 2020
1 parent ad93fd5 commit fd4e1ab
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 40 deletions.
9 changes: 9 additions & 0 deletions src/Uno.UI.Wasm/WasmCSS/Uno.UI.css
Expand Up @@ -38,6 +38,15 @@ body {
transform: translate(0, 0);
}

svg.uno-uielement {
/*
The SVG elements are not intended to be a touch target (they are only a holder collection of child shapes),
instead it's their child SvgElement that should be the target of the pointer.
This also ensure that we are HitTestVisible only for shapes that has a fill.
*/
pointer-events: none;
}

.uno-frameworkelement.uno-clippedToBounds {
/*
This CSS class is applied when a control is a _clipping mode_:
Expand Down
25 changes: 6 additions & 19 deletions src/Uno.UI/UI/Xaml/Shapes/Shape.wasm.cs
Expand Up @@ -33,21 +33,6 @@ protected Shape() : base("svg", isSvg: true)
OnStretchUpdatedPartial();
}

private void OnSvgChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
=> OnChildrenChanged();

protected override void OnLoaded()
{
base.OnLoaded();
SvgChildren.CollectionChanged += OnSvgChildrenChanged;
}

protected override void OnUnloaded()
{
base.OnUnloaded();
SvgChildren.CollectionChanged -= OnSvgChildrenChanged;
}

protected void InitCommonShapeProperties() // Should be called from base class constructor
{
// Initialize
Expand All @@ -58,10 +43,6 @@ protected override void OnUnloaded()

protected abstract SvgElement GetMainSvgElement();

protected virtual void OnChildrenChanged()
{
}

partial void OnFillUpdatedPartial()
{
UpdateHitTest();
Expand Down Expand Up @@ -163,5 +144,11 @@ private UIElementCollection GetDefs()

return _defs.Defs;
}

private protected override void OnHitTestVisibilityChanged(HitTestVisibility oldValue, HitTestVisibility newValue)
{
// We don't invoke the base, so we stay at the default "pointer-events: none" defined in Uno.UI.css in class svg.uno-uielement.
// This is required to avoid this SVG element (which is actually only a collection) to stoll pointer events.
}
}
}
49 changes: 28 additions & 21 deletions src/Uno.UI/UI/Xaml/UIElement.Pointers.wasm.cs
Expand Up @@ -202,7 +202,7 @@ internal void UpdateHitTest()
this.CoerceValue(HitTestVisibilityProperty);
}

private enum HitTestVisibility
private protected enum HitTestVisibility
{
/// <summary>
/// The element and its children can't be targeted by hit-testing.
Expand Down Expand Up @@ -280,27 +280,34 @@ private static object CoerceHitTestVisibility(DependencyObject dependencyObject,

private static void OnHitTestVisibilityChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
if (dependencyObject is UIElement element && args.NewValue is HitTestVisibility hitTestVisibility)
if (dependencyObject is UIElement element
&& args.OldValue is HitTestVisibility oldValue
&& args.NewValue is HitTestVisibility newValue)
{
if (hitTestVisibility == HitTestVisibility.Visible)
{
// By default, elements have 'pointer-event' set to 'auto' (see Uno.UI.css .uno-uielement class).
// This means that they can be the target of hit-testing and will raise pointer events when interacted with.
// This is aligned with HitTestVisibilityProperty's default value of Visible.
element.SetStyle("pointer-events", "auto");
}
else
{
// If HitTestVisibilityProperty is calculated to Invisible or Collapsed,
// we don't want to be the target of hit-testing and raise any pointer events.
// This is done by setting 'pointer-events' to 'none'.
element.SetStyle("pointer-events", "none");
}

if (FeatureConfiguration.UIElement.AssignDOMXamlProperties)
{
element.UpdateDOMProperties();
}
element.OnHitTestVisibilityChanged(oldValue, newValue);
}
}

private protected virtual void OnHitTestVisibilityChanged(HitTestVisibility oldValue, HitTestVisibility newValue)
{
if (newValue == HitTestVisibility.Visible)
{
// By default, elements have 'pointer-event' set to 'auto' (see Uno.UI.css .uno-uielement class).
// This means that they can be the target of hit-testing and will raise pointer events when interacted with.
// This is aligned with HitTestVisibilityProperty's default value of Visible.
SetStyle("pointer-events", "auto");
}
else
{
// If HitTestVisibilityProperty is calculated to Invisible or Collapsed,
// we don't want to be the target of hit-testing and raise any pointer events.
// This is done by setting 'pointer-events' to 'none'.
SetStyle("pointer-events", "none");
}

if (FeatureConfiguration.UIElement.AssignDOMXamlProperties)
{
UpdateDOMProperties();
}
}
#endregion
Expand Down

0 comments on commit fd4e1ab

Please sign in to comment.