Search Unity

Problems with resizing a popup at runtime

Discussion in 'UI Toolkit' started by GroundCombo, Sep 16, 2020.

  1. GroundCombo

    GroundCombo

    Joined:
    Jan 23, 2015
    Posts:
    29
    I'm experimenting with a simple use case of positioning an on-hover popup over a game object, using a SpriteRenderer, BoxCollider2D and OnMouseOver. What I have currently is:

    - activate a popup GameObject with a UIDocument and reparent it to a container document
    - set visible=false for the popup root element (structure: root -> border element -> label inside the border)
    - set the Label text
    - wait for GeometryChangedEvent on root
    - position the element over the gameobject with RuntimePanelUtils.CameraTransformWorldToPanel(), using Label.resolvedStyle.width and height for offsets
    - set visible=true

    1) Is there currently any way of emulating a pivot point, so that I could simply set the element's position and have it stretch "upwards" as the text changes?

    2) On the first activation of the popup gameobject, I'm getting a GeometryChangedEvent followed by a ChangeEvent for the text (for debugging purposes), but after the text change the geometry is not changed again and text.resolvedStyle.width is zero. On the second activation I do get another GeometryChangedEvent after the text change as expected. Could this be a bug or is it something I am missing?

    This is the test layout I'm using.
    Code (csharp):
    1.  
    2. <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    3.     <ui:VisualElement name="PopupRoot" style="flex-direction: row; flex-basis: auto; align-items: flex-end; justify-content: flex-start; flex-grow: 0; flex-shrink: 0; display: flex;">
    4.         <ui:VisualElement name="Border" style="border-left-color: rgb(230, 230, 230); border-right-color: rgb(230, 230, 230); border-top-color: rgb(230, 230, 230); border-bottom-color: rgb(230, 230, 230); border-left-width: 2px; border-right-width: 2px; border-top-width: 2px; border-bottom-width: 2px; background-image: url(&apos;/Assets/Sprites/solidwhite.png&apos;); -unity-background-image-tint-color: rgba(255, 255, 255, 0.78); flex-grow: 0; flex-shrink: 0; justify-content: flex-start; align-items: center; flex-basis: auto; flex-direction: column;">
    5.             <ui:Label display-tooltip-when-elided="false" name="Text" style="margin-left: 8px; margin-right: 8px; margin-top: 8px; margin-bottom: 8px; font-size: 16px; padding-left: 0; padding-right: 0; padding-top: 0; padding-bottom: 0;" />
    6.         </ui:VisualElement>
    7.     </ui:VisualElement>
    8. </ui:UXML>
    9.  
     
  2. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    1,003
    One way to do it is to position your content in an intermediate parent element, and then transform the parent. For example, if you want to pivot around the center and your content is 100x50 pixels, you can add it to a new parent and position it at (-50, -25).

    I'm not sure I understand what your mean by the first and second activations. Are you referring to when you set the visibility to true?
     
  3. GroundCombo

    GroundCombo

    Joined:
    Jan 23, 2015
    Posts:
    29
    The content size depends on the displayed text though, so it's pretty much the same thing I am doing now except that I'm setting the transform position instead of an element position inside the hierarchy. I was curious about an equivalent of the pivot point in uGUI, but I can deal with manual positioning (assuming I can get the text size problems sorted out).

    I'm calling gameobject.SetActive(true) when showing the popup, and SetActive(false) when it is hidden. However, I did some more testing and the actual problem seems to be that GeometryChanged is not sent if the text height is not changed. So:

    - set the gameobject active, visible=false
    - register GeometryChangedEvent
    - get GeometryChanged, label.resolvedStyle.width = 0 (text not set yet)
    - set visible=true
    - text is received from elsewhere and set to the label (this initial layout sequence could use some refining, still experimenting)
    - no geometry change

    If I now keep changing the label text to a random one-line string, I won't get geometry events. As soon as I change the text to a multi-line string, I get the event and the text width is correct. Now the geometry stays unchanged again, even though the element is resizing its width, until I switch back to one-line strings.
     
  4. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    1,003
    GroundCombo likes this.
  5. GroundCombo

    GroundCombo

    Joined:
    Jan 23, 2015
    Posts:
    29
    That may indeed be a better fit here, thanks. I didn't notice it and GeometryChanged seemed like the obvious first thing to try.