Search Unity

Feedback Type ahead suggest box problem: cannot setup EditorWindow.Popup/DropDown screen space positioning

Discussion in 'UI Toolkit' started by PassivePicasso, Oct 21, 2019.

  1. PassivePicasso

    PassivePicasso

    Joined:
    Sep 17, 2012
    Posts:
    100
    I've been working on some UIElements framework code and I wanted to implement a type ahead search box.

    This would be a TextField with an associated popup control that can display the options, a fairly simple control to build overall.
    However it requires a small display opens below the text box that can present that data for selection.

    I was able to get a simple solution using pure UIElements up and running but I ran into a problem with render order.
    The PopupWindow element provided with UIElements states it is "A UIElements window, displayed on top of other content." Which is demonstrably false.
    PopupWindow derives from TextElement which derives from BindableElement. None of these elements include code which would bypass UIElements structure focused render order, which is consistent with statements about the UIElements render order. however the statement for the element was misleading.

    This means PopupWindow, the seemingly easy solution, could never solve the problem of needing a popup window inside an Inspector. You can get a hacky solution by moving the PopupWindow to the end of the rootVisualElement's children, but this causes problems with style sheet application, and is obviously not a good solution even though it solves the render order problem. this hacky solution isn't limited to PopupWindow and so popup window's importance becomes very limited other than that it provides a guaranteed style which is helpful when moving elements outside the scope of your styles.

    Your options are risking having your controls render under other inspectors or other inspector elements, or move your controls outside the scope of your inspector, which doesn't seem advisable.
    With either of those solutions, the popup is still clipped by the bounds of the window and requires custom code to keep the popup inside the window bounds in those scenarios.

    Looking into the issue further, it seems that the only way to solve this would be to launch an EditorWindow as a drop down or popup, which would be an acceptable solution as it still falls within the design constraint of being primarily focused on UIElements since the EditorWindow's content can be UIElements.

    However, it appears that there is no way to get the coordinates of the TextField in screen space, making it impossible.
    I wanted to post this as a use case example, and a request to solve this problem.

    Can we either make PopupWindow a specialized implementation that opens an actual popup window with populated contents and transfered style sheets form the originating VisualTree?
    If not can we get something within UIElements to get the screen space pixel coordinates and dimensions of a UIElements control?

    Additionally, if someone knows that I've missed something and there is a way to accomplish this, please enlighten me.

    As an experienced WPF Developer those two features are a corner stone of making powerful interactive software UI. this issue is likely much less important in a game environment, but it still may be desired in some cases.
     
    Last edited: Oct 21, 2019
  2. PassivePicasso

    PassivePicasso

    Joined:
    Sep 17, 2012
    Posts:
    100
    For anyone curious enough to be looking, I did find a way to accomplish this inside the editor, however its still hacky as it requires reflection.

    The panel object that is available in the visual tree can be used to find the current windows location by using reflection to extract the ownerObject property and then its screenPosition property, which contains the necessary information to conduct a transformation of the positions into screen space.

    This is great, but it would be nice to have a non-reflective path here.

    That being said it still presents a problem of EditorWindows taking focus when shown, which I may also be able to resolve, but I suspect it will also involve reflection.
     
    brunocoimbra likes this.
  3. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    Yes, this was not entirely correct. The issue with the doc here has been noted and should be fixed.

    This is an area we need to improve. For now, your solution is what I would recommend. But we are tracking this and should have something better eventually. There is a possible non-reflection based solution but I wouldn't say it's much cleaner:
    Code (CSharp):
    1. Resources.FindAllObjectsOfType<EditorWindow>.Where(e => e.rootVisualElement.panel == element.panel).First().position
    What's the problem in this case? Don't you want the new popup window to take focus?
     
  4. PassivePicasso

    PassivePicasso

    Joined:
    Sep 17, 2012
    Posts:
    100
    No, I was setting up a search suggest box, so if the popup takes focus then the textbox loses focus, so you can't continue to type.
    A few work-arounds could be used, such as forwarding keyboard input from the popup to the text box, but that is definitely going to be error prone.
    I tried just reacquiring focus in the text box, though I don't remember what I specifically did, I didn't have any success there.

    I've actually completely solved this problem, and I have the whole project up on github.
    Visual Templates is setup as a package manager package, and the examples is just a plain git repo, the folder can be cloned into a subfolder of Assets in a unity project. MIT Licensed, so if UT sees ideas here to steal, have at it, I'm all for making UIElements better for everyone.
    https://github.com/PassivePicasso/VisualTemplates
    https://github.com/PassivePicasso/VisualTemplatesExamples

    If you look at
    https://github.com/PassivePicasso/V...r/Editor/Resources/Templates/EntityModel.uxml
    You'll see the SearchSuggest box in the uxml with some children which setup its suggestion list.
    I did a number of things here for usability, I wanted a popup not bound to the window space that doesn't take focus when opened and can be forwarded events from a different window to control selection.

    https://github.com/PassivePicasso/VisualTemplates/blob/master/Editor/SearchSuggest.cs#L159

    You can see here, that I setup the suggest box popup information like mentioned above for getting the screen space coordinates.
    I also reflected out one of the internal ShowPopup methods, ShowPopupWithMode so I can show the popup without it taking focus (can we make this public maybe?)

    I think UT has an opportunity here to improve the PopupWindow control so that it in fact is always rendered on top of other elements, and as importantly not bound to the window space.

    Perhaps there are some caveats that are not immediately apparent with my solution
    I hope my examples are helpful to improve UIElements further.

    PPS:
    Styling was a problem with this solution, I had difficulty trying to inject style into the popup window, I was trying to transfer the stylesheeds attached to the Searchsuggest into the created popup to maintain the stylesheet flow, but I was unsuccessful.
    After creating the popup and adding the optionList, I had tried just iterating over SearchSuggest.styleSheets then adding those styleSheets to the editorWindow.rootVisualElement.styleSheets but it didn't work. As I'm writing this I'm wondering if maybe that was too low in the hierarchy for the styles to propagate.

    PS: Search Suggest is an awesome control that everyone should have easy access to, as it makes significantly better interfaces easier to create, and honestly they are not hard to implement in a simple fashion.
    Perhaps ya'll could make a standard one? :D
     
    Last edited: Oct 29, 2019
    StephanieRowlinson likes this.
  5. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    Ah, the auto-complete/suggestion box use case makes sense.

    This should have worked. Unless the styles are not applied to the elements for some reason. I would try hard-coding the same stylesheets on your Suggestion popup and making sure all selectors work. If that's the case, you may be running into a bug.

    Thanks for sharing your solution! I can't say if we'll make a standard one right now but we'll certainly consider it.
     
    StephanieRowlinson likes this.