Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Prevent pointer clicks through elements

Discussion in 'UI Toolkit' started by StripeGuy, Aug 22, 2023.

  1. StripeGuy

    StripeGuy

    Joined:
    Dec 30, 2016
    Posts:
    52
    I am making a drawing application using UI toolkit, but when I have an element "popup" over an the draw area, both the popup and the draw area get pointer clicks.

    I am using a callback for the drawarea, and tried both "Trickledown" and "NoTrickledown", but nothing blocks the clicks.

    ex callback for draw area:
    Code (CSharp):
    1. drawareaVisualElement.RegisterCallback<PointerDownEvent>(OnPointerDown, TrickleDown.NoTrickleDown);
    The popup element panels don't really have a callback (only the controls do - radiobuttons, etc.), so not sure how I would handle "trickledown" for the whole panel.
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,820
    Have you tried calling StopPropagation on the event inside of OnPointerDown?
     
  3. StripeGuy

    StripeGuy

    Joined:
    Dec 30, 2016
    Posts:
    52
    Hey, thanks for the quick reply :)

    So looking online I would use it as "evt.StopPropagation();". But when I put it under "OnPointerDown" or even "OnPointerEnter" of the draw area, clicks on my popup panel still "draw" under it.

    Would I need to add the StopPropagation() on my popup panel somehow instead?

    Edit: So I created an OnPointerDown callback for my popup panel, and in there I added the StopPropogation(). This seems to work now. But does that mean I have to create a callback for every single popup I create in my UI to stop the propogation? Or is there a universal way of defaulting to StopPropogation?
     
    Last edited: Aug 22, 2023
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,820
    Yes you will need to do it for every popup element.

    You may want to create a specific VisualElement type that does this

    Code (csharp):
    1. class BlockerElement : VisualElement {
    2.  #if UNITY_2023_2_OR_NEWER
    3.      protected override void HandleEventBubbleUp(EventBase evt) => OnHandleEvent(evt);
    4.  #else
    5.      protected override void ExecuteDefaultAction(EventBase evt) => OnHandleEvent(evt);
    6.  #endif
    7.  
    8.      void OnHandleEvent(EventBase evt)
    9.      {
    10.          if (evt is AttachToPanelEvent)
    11.               RegisterCallback<PointerDownEvent>(StopPointerPropagation, TrickleDown.TrickleDown);
    12.          else if (evt is DetachFromPanelEvent)
    13.               UnregisterCallback<PointerDownEvent>(StopPointerPropagation, TrickleDown.TrickleDown);
    14.      }
    15.      void StopPointerPropagation(PointerDownEvent evt) => evt.StopPropagation();
    16.  }
    This page has good information on how events propagate
    https://docs.unity3d.com/Manual/UIE-Events-Dispatching.html

    Depending how the hierarchy's built you may need to keep the "drawing" logic during the BubbleUp phase so the popups/overlays have a chance to stop event propagation before the canvas has a chance to handle the event itself
     
  5. StripeGuy

    StripeGuy

    Joined:
    Dec 30, 2016
    Posts:
    52
    That's awesome! :) Thank you so much for answering my question. Need more people like you on the Unity team.
     
    karl_jones likes this.
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,820
    I can't take full credit for that one, another team member gave me the answer :D
     
    StripeGuy likes this.