GUI on Linux: problems with updating

Hi, all!
Is there anybody using Urho on Linux and using Urho GUI and running in window?
I guess nobody, as in this configuration GUI is as broken as it possibly could be.
What I guess, the layout is never updated on window changes. 3D layout works great,
this only affects GUI. Window change event works fine, but GUI seems to be ignoring it and
always works in 1024x768 which is set as default. In full screen everything works fine.

In the code I see that it should react on resolution, but for some reason it completely ignores
the changes.

I know Linux user base and especially desktop is in decline and probably will be at 0 soon,
so current support is not worth it, but are there any alternatives to stock GUI which would work
on Linux and be cross-platform? (I need Linux and Android support). I asked this question before,
but probably something changed over years?


./ -w -s -x 1920 -y 1080
Urho editor (current git master) seems to be working as expected on Linux here. :penguin:
although the right/bottom panels do not automatically fit to an expanded main window (this can be done manually).

I don’t see customizable architecture (i.e., desktop) or Linux going obscure soon. :slight_smile:

TurboBadger also works on Android.

I know I can do everything manually, redrawing from root widget, but
that is extremely tedious.
Also you manually set window resolution, which is not common case, as
generally it is set
by window manager.
As about desktop - I generally being told by windows people that there
is zero GUI problems
(at least no problems I report) so I guess it is either
system-specific problem or
I’m being trolled (which is not too impossible too).

What I do:

  1. I create dumb program which listens to resolution events, and I see
    valures change as I
    change window size, so SDL does everything right.
  2. I create single button which is aligned to center on top level. It
    is centered at
    1024x768 window center (the default resolution)
    No resolution changes affect this.

So to make GUI work for windowed resolution I have to manually redraw
all GUI elements,
right? I see that resolution change events are handled within GUI,
what is their purpose then?

Do you mean that the button stays at (512,384) regardless of resolution changes?

Yes, it is not following window center.
Also it looks like initially UI is fed by some default setting (1024x768) and
after wm changes resolution to 2560x1440 (in my case) the center ends
up near top left.
If I manually update (remove all GUI and re-create it), it sort of works.
I currently did manual GUI reset using timed updates. But if I
implement full GUI instead
of single button, I think that will not work too well. Is there some
shortcut instead of full manual update?

Try anchors of UI elements, (0.5, 0.5) for centering.

    Graphics *graphics = GetSubsystem<Graphics>();
    ResourceCache *cache = GetSubsystem<ResourceCache>();
    Input *input = GetSubsystem<Input>();
    UI *ui = GetSubsystem<UI>();

    XMLFile *style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
    Button *button = new Button(context_);
    button->SetMinAnchor(0.5f, 0.5f);
    button->SetMaxAnchor(0.5f, 0.5f);
    button->SetFixedSize(100, 60);
    SubscribeToEvent(button, E_RELEASED, URHO3D_HANDLER(Urho3DPlayer, StartGame));

Result is the same - centered around 1024x768 window.

I guess root UIElement is not updated on window changes.

True. Resize root in resize event handler. This plus anchors shall make things work.

1 Like

Thanks a lot! The problem is gone now.
I wonder, it should have worked even without this hack, but for some reason it won’t…
Anyway I now finally can continue with GUI. Thank you so much!

I’ve just checked. There’s UI::ResizeRootElement that’s called sometimes. I suppose it was designed to resize root element when needed. I’ll check it later.

I’ve just checked things. On windows, both for dx9 and gl, root element is resized automatically because of ChangeMode event.
IDK ashy it doesn’t work for you. What resize event do you subscribe in order to fix the problem?

Sorry for not answering, I was very sick for a while, so I could not find energy to check and post.

I did some investigation on my side. I do not do anything fancy, and GUI starts working.

void Urho3DPlayer::HandleScreenMode(StringHash eventType, VariantMap& eventData)

And I subscribe as
SubscribeToEvent(E_SCREENMODE, URHO3D_HANDLER(Urho3DPlayer, HandleScreenMode));

Using that I set size of root component with SetSize()

This is what I did first, and it works. When I dig farther, I see that it is already done in engine, so why
do I need this is a question. So I added log message to event handler and see that everything works fine and the same in both engine and my code. After that I disabled SetSize() in my event handler and it STILL WORKS.
After that I reverted changes to my code and checked, so no, problem is still there. So I left with
event handler printing log message, which makes thing work. No, I don’t want to touch it anymore.
Something weird is going on…

Anyway, moving forward from it - is there some way to address element size issues. While position issues can be handled by anchors, is there some similar way for sizes? The problem is that some UI elements
fail to size off parent and have to be sized manually (i.e. ScrollView). Is there some relative solution to make ScrollView to be of parent size without need to manually resize it every time window size changes?
I now use the above handler for that, but it looks not nice at all.

Sounds like really weird problem.

Sizes could be controlled via layout, I always prefer this way. It may be hard to configure sometimes tho.

What do you mean by layout? SetLayout() seems to have no effect on
ScrollView at all,
I still have to SetSize() to make it work. UIElement, Button, Window
do not have this problem.
The effect of SetLayout() is there but it does not affect size. i.e I
effect or LM_FREE effect on child elements after I set ScrollView size
via SetSize() but it refuses to use parent’s size, which is expected.

Urho UI is explicit. It does exactly what is said to do.
Sometimes it may be tricky to say what to do tho.

If you call SetSize, your element would have this size, whatever you do. Because you asked this element to have exactly this size.
If you want element to be resizable, set min and max sizes separately, then set parent layout, and it would resize elements according to min/max sizes and layout properties. Same with position and anchors.

The problem is that one have to guess what to do every time, because
behavior is not consistent and for no apparent reason. I.e. you don’t
need to Set{Min/Max/}Size() for majority of components (at least ones,
which I use, UIElment, Window, Button, Text) but need to do this for
some of them (ScrollView). I think consistency would be nice in this
case. Also, when you need resizeable UI it is often hard to properly
set sizes for all components, and it looks like attempt to patch-up
something broken, as I see no design idea in it. It looks random at
best. I think it doesn’t affect most game UIs as these do not use
anything except UIElement, Button and Text, but it looks like wanting
impossible things is my curse.

If you explain/draw excatly what kind of UI you’d like to have, it’d be easier to deal with.

Well, I do not want to put this burden on anyone, but since you’re asking…
I need 2 GUIs for different things - 1 is in-game relationship editor
and 2 - AI behavior tree
editing tool.
First one is (root is excluded)
---- ScrollView(LM_VERTICAL)
------ UIElement(LM_VERTICAL) (many of this)
-------- Text (Category1)
---------- UIElement(LM_VERTICAL) (many of this)
------------ Text (Category2)
-------------- UIElement(LM_VERTICAL) (many of this)
----------------UIElement(LM_HORIZONTAL) (many of this)
------------------Button(LM_VERTICAL, vcentered) (5 or less), person
-------------------Text(hcentered) (person name)
----Button (LM_VERTICAL) (about 8, actions on person object)
------Text (description of action for each button)
----UIElement (LM_VERTICAL) (property list)
------UIElement(LM_HORIZONTAL) (for each property)
--------Text (property name)
--------Text (property value)

Second one:

----ScrollView(LM__FREE) (node editor)
------Button (for each node, draggable, clickable)
------Sprite (making arrows using these, any other way?, lots for each
node connection)
----Button (for each control)
------Text (each button description)
----UIElement(LM_VERTICAL) (property editor)
------UIElement(LM_HORIZONTAL) (for each property)
--------Text (property name)
--------LineEdit (property data)

Both were implemented but are very rigid and unstable, unscalable,
hard to modify.

Then, what kind of scalability do you want to achieve?
Do you want to move&scale items within ScrollView automatically?