[Solved] Element::SetPosition() and SequentialLayoutContainers

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

[Solved] Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Wed Mar 08, 2017 21:54

Hey everyone,

I recently wrapped some of my UI items in SequentialLayoutContainers in order to give me greater flexibility in what is displayed in my UI windows. I'm running into an issue though where setting the position of the parent window (via SetPosition()) is not updating the position of the container, leaving its child elements in their old position. If I remove the layout container, everything works as expected.

Here's part of the layout for the window:

Code: Select all

<Window name="PlayStateTileInfo_FrameWindow"  type="TaharezLook/FrameWindow" >

    <Property name="Size" value="{{0,325},{0,350}}" />
    <Property name="FrameEnabled" value="true" />
    <Property name="Disabled" value="true" />
    <Property name="Visible" value="false" />
    <Property name="Text" value="Tile Information" />
    <Property name="TitlebarEnabled" value="true" />
    <Property name="CloseButtonEnabled" value="true" />
    <Property name="RollUpEnabled" value="false" />
    <Property name="SizingEnabled" value="false" />
           
    <!-- Coordinates Information  -->
    <Window name="GPSCoordinates_HLC" type="HorizontalLayoutContainer" >
        <Property name="Position" value="{{0.1,-15.0},{0.05,-12.5}}" />
        <Property name="Size" value="{{1.0,0.0},{0.0,25.0}}" />             
           
        <Window name="GPSCoordinatesTag_Label"  type="TaharezLook/Label" >
            <Property name="Text" value="Coordinates:" />
            <Property name="Size" value="{{0.0,0.0},{0.0,25.0}}" />
            <Property name="HorzFormatting" value="LeftAligned" />
        </Window>

        <Window name="GPSCoordinates_Label"  type="TaharezLook/Label" >
            <Property name="Size" value="{{0,0.0},{0,25}}" />
            <Property name="HorzFormatting" value="LeftAligned" />
            <Property name="Margin" value="{top:{0.0,0.0},left:{0.05,0.0},bottom:{0.0,0.0},right:{0.0,0.0}}" />
        </Window>               
           
    </Window>
       
</Window>


Here's the code updating the position

Code: Select all

tileContentsWindow = static_cast< CEGUI::FrameWindow * >( m_uiSheet->getChildRecursive("PlayStateTileInfo_FrameWindow"));
tileContentsWindow ->setPosition( CEGUI::UVector2(
                                                   CEGUI::UDim( 0.f, mouseX + 40 ),
                                                   CEGUI::UDim( 0.f, mouseY - 100 ) ) );


Any thoughts on why the update to the position is not being propagated properly? Thank you in advance for the help :D

CEGUI Info

Code: Select all

---- Version: 0.8.4 (Build: Jul 13 2016 Static Debug Microsoft Windows MSVC++ 11.0 32 bit) ----
---- Renderer module is: CEGUI::OgreRenderer - Official OGRE based 2nd generation renderer module. ----
---- XML Parser module is: CEGUI::RapidXMLParser - Official RapidXML based parser module for CEGUI ----
---- Image Codec module is: OgreImageCodec - Integrated ImageCodec using the Ogre engine. ----
---- Scripting module is: None ----

User avatar
Ident
CEGUI Team
Posts: 1824
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Element::SetPosition() and SequentialLayoutContainers

Postby Ident » Wed Mar 08, 2017 22:04

Is there any chance you could try out v0-8 from the repository? we recently fixed a bug regarding FrameWindow positions not being propagated properly to the children. It could be related.
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Wed Mar 08, 2017 22:19

Do you mean 0.8.7 for CEGUI? I'm not using CEED, which is what appears to be a v0-8.

I can certainly try it; will take a bit while I set everything up.

User avatar
Ident
CEGUI Team
Posts: 1824
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Element::SetPosition() and SequentialLayoutContainers

Postby Ident » Wed Mar 08, 2017 22:53

v0-8 is a CEGUI branch, not CEED. There is also a CEED branch v0-8 but that is just made to go along with CEGUI v0-8.

Link:
https://bitbucket.org/cegui/cegui/src/c ... 1/?at=v0-8

This is what is going to be 0.8.8
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Wed Mar 08, 2017 23:28

Ah, I see. I'll DL it and let you know what I find. (Will be a bit)

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Thu Mar 09, 2017 00:27

Updating the version to the 0-8 branch did not make a difference :-/. The child elements remained in the old position after the parent window of the LayoutContainer was moved.

In order to debug this better, how are positional updates propagated to the children? Is it somehow different from dragging? Because that works without issue.

Edit:
I tried tracing the behavior of the window ( concentrating on Element::notifyScreenAreaChanged() ) and compared the behavior of a mouse drag with the setPosition() call (basically, the one that works and the one that doesn't). As far as I can tell, there is little difference between the two; the children of the LayoutContainer do get called during this updated. I'll keep digging, as the difference should be here.

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Thu Mar 09, 2017 22:39

Brief Update: Updating the size of one of the child windows inside the LayoutContainer after the position of the parent window has been modified results in the child position being updated properly. Could the child window not be getting properly set to dirty when inside a layout container? (Though, I admit, that it appears that it is; at least notifyScreenAreaChanged() is called on it)

Any thoughts on where to look next, Ident?

User avatar
Ident
CEGUI Team
Posts: 1824
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Element::SetPosition() and SequentialLayoutContainers

Postby Ident » Thu Mar 09, 2017 22:57

LayoutContainers are relatively new compared to some other widgets, there could easily be bugs.

I did not write them so I got no clue where to look next, I probably know as much as you at this point and would just have to do what you are doing.

What you can try is to call notifyDisplaySizeChanged on the child after the parent container position was changed. If this changes something then this likely means "something" wasnt set dirty that probably should have. :pint:
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Fri Mar 10, 2017 23:16

Al'right, this has taken me down quite the Rabbit Hole, but I believe I have an answer.

When the position of a Window is set ( Element::setArea_impl() ), it first invalidates its unclipped rects (both outer and inner), updates the size of its area, then propagates the changes to its children through the onMoved() event.

The children follow a similar pattern ( Window::notifyScreenAreaChanged() ), first invalidating their own unclipped rects, passing the event to their children, then updating their geometry. As the children update their geometry, they make calls to Element::getUnclippedOuterRect() which, since it was invalidated previously, now gets recalculated in Element::getUnclippedOuterRect_impl(), which itself updates the outter rect for the parent.

The problem for LayoutContainers, as I see it, is that they only mark their unclipped rects *AFTER* they've passed the notifyScreenAreaChanged() to their children. Specifically:

Code: Select all

void LayoutContainer::notifyScreenAreaChanged(bool recursive)
{
    Window::notifyScreenAreaChanged(recursive);
   
    d_clientChildContentArea.invalidateCache();
}


This means all the children are re-calculating their position with the old position of the layout container. If you perform a change to any of the LayoutContainer's children after the original call to setPosition(), the children will correctly update the LayoutContainer's area (since it was marked dirty) and be updated correctly.

This actually explains why mouse dragging works... or at least appears to. The fact that my app is going at 300 FPS means that, at most, positional updates are going to be 1 or 2 pixels away from the last update, so I'd never really notice.

My fix was the following:

Code: Select all

void LayoutContainer::notifyScreenAreaChanged(bool recursive)
{
    d_clientChildContentArea.invalidateCache();
   
    Window::notifyScreenAreaChanged(recursive);
}


As far as I can tell, positional updates are now being carried out correctly (in my brief test case). Does this seem like a valid analysis? Would this change hurt anything else?

User avatar
Ident
CEGUI Team
Posts: 1824
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Element::SetPosition() and SequentialLayoutContainers

Postby Ident » Sat Mar 11, 2017 10:17

I do not see what could go wrong by doing this. Have you played around with it enough to be confident about it being non-breaking? The sample browser uses a bunch of layout containers if I remember right , so that might be a good case to test. If you want you can make a pull-request on v0-8 and i ll look at it.
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Sat Mar 11, 2017 18:51

I will do so, but give me until Monday. I promised myself a bit of time off this weekend :pint:

User avatar
Ident
CEGUI Team
Posts: 1824
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Element::SetPosition() and SequentialLayoutContainers

Postby Ident » Sat Mar 11, 2017 23:35

I will even give you time until Wednesday! :pint:
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Mon Mar 13, 2017 23:02

I tried out the changes on a few of my UI elements which are heavy on layout containers (both Horizontal and Vertical; haven't tried Grid) and, as far as I can tell, everything is working as expected.

The pull request should be on your desk. (If not, here's the link). Let me know if there's anything else you need.

User avatar
Ident
CEGUI Team
Posts: 1824
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Element::SetPosition() and SequentialLayoutContainers

Postby Ident » Tue Mar 14, 2017 19:41

You need to make a PR against the official CEGUI bitbucket, not against your own fork
https://confluence.atlassian.com/bitbuc ... 20593.html
CrazyEddie: "I don't like GUIs"

TheWanderer
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Feb 03, 2016 21:58

Re: Element::SetPosition() and SequentialLayoutContainers

Postby TheWanderer » Tue Mar 14, 2017 23:03

Sorry about that; first time using BitBucket. :)

Updated link!


Return to “Help”

Who is online

Users browsing this forum: Google [Bot] and 9 guests