When i create mutiple umg windows, the one created latest gets in front of all others. I would like that when clicking on a umg window it sets itself in front of all others. This is pretty standard behaviour in all applications. How would i achieve that?
Widgets added to the viewport most recently render on top, so you can remove from viewport and add again without destroying the widget.
Or, the method that gives you the most control, create a separate canvas widget and add it to the viewport as usual. From now on, whenever you add any widgets, instead of adding them to the viewport, add them to that canvas instead - this gives you access to the slots the canvas creates for its children, these slots have an int Z order parameter which directly controls which widgets render when - the higher the Z order, the more on top you are.
You can then, at any point, access the widget *as canvas slot *and set its details - this way you get dynamic access to anchors and all the goodies canvas has.
Thanks you for your answer!
I think i’ll go with add/remove workaround as you suggested.
The second thing is good too, but it’d require quite a lot of code refactoring. I wish someone made this clear when i started coding, some sort of a warning in the tutorials or the documentation because it’s pretty standard functionality.
With all that said, i think the smoothest solution would be to add possibility of setting a “global” Z order, cause it would prevent slightly annoying situations like this.
Add/remove workaround didn’t quite work out as i tought it would because it creates a new widget and loses the state of the previous one. So in order for this to work i’d have to add a nontrivial level of complexitiy to my code which would store the state of each widget and restore it once the new widget is created.
Create a widget reference. For as long as one exists, the widget should not be garbage collected. No need to store any states.
Yes i tried that, i stored the widget reference, then “removed from parent” and then widget reference “add to viewport”. but it doesn’t work for some reason. It dissapears and “add to viewport” doesn’t bring it back. Am i doing it wrong?
Should work as you describe; consider showing the bit of script responsible for adding & removing?
I will as soon as i get my hands on a computer.
So this is my code. It only removes the widget, but doesn’t bring it back.
First of all you need to make sure you do store the reference to the widgets you remove from the viewport. Currently, you’re using a temporary reference to flip the widgets, there’s no need for that. Is there anything (beside the viewport, that is) that is storing the reference to the widgets after they are created?
Also, you’re returning Event Reply which seems a bit odd, not sure what it does but it does not look right; return *Handled *instead - it might save you a headache further down the path.
The main issue here, though is the fact that you remove and add the widget to the viewport in the same Tick.
Here’s how I would do it:
A Custom Event in the widget that adds *self *to the Viewport:
And the onButtonDown:
Essentially, the widget that has the above implemented removes itself from the viewport and then adds itself back, on top - that’s providing you do not override the Z order in the hidden panel of the *Add To Viewport *node. This should simplify things quite a bit, no need to flip additional references.
Is this the effect you’re after:
Well, it seems that delay node did the trick. This does seem a little hacky but it worked. However i ran into another problem…maybe you’ll know how to solve it. So i want this “bring to front” functionality to work also if i hit a specific button on the window which is used to move the window around. But for some reason in the following piece of code “On Released” event is never being called…and it seems it’s never being called because i put “remove from parent” + “add to viewportwithdelay” combo in “On Pressed” event.
Under regular circumstances I’d blame not returning *Handled *in the *onButtonDown *here. You can’t have Up without Down preceding it.
In this case, well, buttons were never supposed to be dragged (or right clicked); the functionality behind Precise Click + draggable buttons hackaround was supposed to bedisabled (?). It looks to me as if you found a way of forcing it anyhow Do you have a reason to go this route? Or is this just about finding the offset?
Removing the widget from the viewport must be resetting the button’s state, it can’t fire its *Released *because it’s not *Pressed *after re-adding - a guesstimation. Now you’re getting yourself in a truly hacky territory. On the other hand, UMG does show its limitations as soon as you start thinking outside of the box.
This might be completely irrelevant here as I might be misunderstanding something but one piece of advice I could give you is to avoid using buttons for anything they’re not designed to do. You can simulate a button by using a border (it has overridable up / down / double click) and can be dragged around. I know the automated states and sound biding are tempting at first but the buttons don’t cooperate when make them do un-clicky things.
Your last statement seems to sum it up for me:
You remove it from the viewport, it’s no longer pressed. It’s not pressed, it can’t be released.
The canvas method I mentioned originally is by far the best approach I ever found when working with layered UIs. I regularly use several canvases nested in another *master *canvas and just switch the layer priority; within each layer, the widgets have their own Zs controlled directly. Not only can you control each layer with just an int but each widget in each layer, too.
It does complicate things a bit but once set up, it works. And you get access to the canvas slot, which more than handy!