Child window properties from GUILayout: problem + fix

If you found a bug in our library or on our website, please report it in this section. In this forum you can also make concrete suggestions or feature requests.

Moderators: CEGUI MVP, CEGUI Team

marvinx
Just popping in
Just popping in
Posts: 12
Joined: Sat Feb 09, 2013 13:55

Child window properties from GUILayout: problem + fix

Postby marvinx » Tue Apr 23, 2013 14:07

Hi,

I discovered the following problem concerning the GUILayout XML element processing in CEGUI 0.7.7. I've created a GUILayout consisting of a custom ScrollablePane widget, a "DragMeAround"-like child FrameWindow for testing (added to the ContentArea of the pane), and another "Minimap" child FrameWindow. The latter FrameWindow shall be handled as special "NonClient" window of the ScrollablePane, i.e. it should not move when the pane is scrolled. In order to realize this feature I've overloaded the ScrollablePane::addChild_impl() methods as follows

Code: Select all

void ZoomableScrollPaneWidget::addChild_impl(Window* wnd)
{
  if ( wnd == NULL )
    CEGUI_THROW(NullObjectException("Invalid handle!"));

  // Check to see if 'wnd' is a regular non-client window, e.g. a Minimap
  if ( !wnd->isAutoWindow() && wnd->isNonClientWindow() )
  {
    // Do NOT treat this window as ScrollablePane content
    Window::addChild_impl(wnd);
  }
  else
  {
    // Use base implementation to handle other types of child widgets
    ScrollablePane::addChild_impl(wnd);
  }
} //  ZoomableScrollPaneWidget::addChild_impl


The corresponding GUILayout looks like:

Code: Select all

<GUILayout>
  <Window Type="DefaultWindow" Name="Root" >
    <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
    <Property Name="MousePassThroughEnabled" Value="True" />

    <!-- Define a ZoomableScrollPaneWidget -->
    <Window Type="ZoomableScrollPaneWidget" Name="Root/ScrollPane">
      <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
      <Property Name="ContentPaneAutoSized" Value="False" /> <!-- order matters! -->
      <Property Name="ContentArea" Value="l:0.0 t:0.0 r:2048.0 b:1152.0" />
      <Property Name="ForceVertScrollbar" Value="False" />
      <Property Name="ForceHorzScrollbar" Value="False" />

      <!-- Define a Minimap overlay (as NonClient child of our pane) -->
      <Window Type="DarkLook/FrameWindow" Name="Root/ScrollPane/Minimap" >
        <Property Name="UnifiedSize" Value="{{0,256},{0,256}}" />
        <Property Name="UnifiedPosition" Value="{{0.1,0},{0.1,0}}" />
        <Property Name="Text" Value="Minimap" />
        <Property Name="NonClient" Value="True" />
        <Property Name="AlwaysOnTop" Value="True" />

        <AutoWindow NameSuffix="__auto_clientarea__" >
          <Window Type="Vanilla/StaticImage" Name="ActiveScene" >
            <Property Name="UnifiedSize" Value="{{1,0},{1,0}}" />
            <Property Name="BackgroundEnabled" Value="False" />
            <Property Name="FrameEnabled" Value="False" />
            <Property Name="MousePassThroughEnabled" Value="True" />
          </Window>

          <Window Type="Vanilla/StaticImage" Name="BirdsEye" >
            <Property Name="UnifiedSize" Value="{{0.2,0},{0.2,0}}" />
            <Property Name="BackgroundEnabled" Value="True" />
            <Property Name="FrameEnabled" Value="False" />
            <Property Name="MousePassThroughEnabled" Value="False" />
            <Property Name="Alpha" Value="0.4" />
          </Window>
        </AutoWindow>
      </Window> <!-- end Root/ScrollPane/Minimap -->

      <!-- Define "DragMeAround" - FrameWindow as ScrollPane content -->
      <Window Type="DarkLook/FrameWindow" Name="Root/ScrollPane/Test" >
        <Property Name="UnifiedSize" Value="{{0,128},{0,128}}" />
        <Property Name="UnifiedPosition" Value="{{0.3,0},{0.2,0}}" />
        <Property Name="Text" Value="DragMeAround" />
      </Window>
    </Window> <!-- End Root/ScrollPane -->
  </Window> <!-- End Root -->
</GUILayout>


What's important here is that I set the "NonClient" property of the "Root/ScrollPane/Minimap" window to "True", so this child window should be specially handled within the overloaded addChild_impl() of my custom ScrollablePane widget.

I discovered the following problem: When loading the GUILayout, the GUILayout_xmlHandler will add the "Root/ScrollPane/Minimap" as child to "Root/ScrollPane" BEFORE setting its GUILayout properties, in particular, before setting the "NonClient" property to "True". So the overloaded ScrollablePane::addChild_impl() will not work as expected.

I have applied the following changes in class GUILayout_xmlHandler from CEGUI-0.7.7:

Code: Select all

void GUILayout_xmlHandler::elementWindowStart(const XMLAttributes& attributes)
{
    // get type of window to create
    String windowType(attributes.getValueAsString(WindowTypeAttribute));
    // get name for new window
    String windowName(attributes.getValueAsString(WindowNameAttribute));

    // attempt to create window
    CEGUI_TRY
    {
        Window* wnd = WindowManager::getSingleton().createWindow(windowType, d_namingPrefix + windowName);

//        // add this window to the current parent (if any)
//        if (!d_stack.empty())
//            d_stack.back().first->addChildWindow(wnd);
//        else
//            d_root = wnd;

        // Changed 04/23/2013, KS
        if (d_stack.empty())
          d_root = wnd;

        // make this window the top of the stack
        d_stack.push_back(WindowStackEntry(wnd,true));

        // tell it that it is being initialised
        wnd->beginInitialisation();
    }
  ...
}


Code: Select all

void GUILayout_xmlHandler::elementWindowEnd()
{
    // pop a window from the window stack
    if (!d_stack.empty())
    {
//        d_stack.back().first->endInitialisation();
        Window* wnd = d_stack.back().first;
        wnd->endInitialisation();
        d_stack.pop_back();

        // Added 04/23/2013, KS
        // - see also "Changed" section in elementWindowStart

        // Add 'wnd' to its parent window (if any)
        if ( !(wnd==d_root) && !d_stack.empty() )
          d_stack.back().first->addChildWindow(wnd);
    }
}


After recompiling the library the problem was fixed. The GUILayout was successfully loaded and all child window properties are now set to their configured values BEFORE the window is added to its parent.

I am not sure about the side effects of the above changes in other parts of the CEGUI library?! Maybe there a cases where this patch is not applicable?

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: Child window properties from GUILayout: problem + fix

Postby CrazyEddie » Fri Apr 26, 2013 16:24

I hate all of these temporal-like issues, where certain things depend upon something as 'simple' as when a child gets added to it's parent. These come up now and again and it royally sucks! :D

I am not sure about the side effects of the above changes in other parts of the CEGUI library?! Maybe there a cases where this patch is not applicable?

That's the major issue. We will need to sit down and weigh this very carefully and consider all the implications of such a change.

Can you add a mantis ticket (use your forum credentials) either containing the same information or at least a link back here. This way the issue will not be lost and forgotten. Thanks.

CE.

marvinx
Just popping in
Just popping in
Posts: 12
Joined: Sat Feb 09, 2013 13:55

Re: Child window properties from GUILayout: problem + fix

Postby marvinx » Fri Apr 26, 2013 20:53

Okay, I've added a new Mantis ticked. I would appreciate any suggestions for a workaround other than the proposed patch of the core library :wink:

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: Child window properties from GUILayout: problem + fix

Postby CrazyEddie » Mon Apr 29, 2013 16:25

The only thing I could come up with is to add the non-client windows as part of the looknfeel, this way it's made an autowindow and automatically gets added to the main window and not the content pane (similar to the scrollbars). I know this is not all that flexible - depending on your needs - but I could not come up with any other suggestion at the moment without requiring some modifications to the lib.

CE.

marvinx
Just popping in
Just popping in
Posts: 12
Joined: Sat Feb 09, 2013 13:55

Re: Child window properties from GUILayout: problem + fix

Postby marvinx » Mon Apr 29, 2013 20:10

Thanks for pointing out this. I think this should work for me :D


Return to “Bug Reports, Suggestions, Feature Requests”

Who is online

Users browsing this forum: No registered users and 3 guests