Page 1 of 1

Creating an arbitrary number of windows

Posted: Mon Jul 10, 2006 19:50
by cborders
Forgive me if this have been asked before I searched and couldn't find an answer.

I want to accomplish the same thing and in the GUI Demo That comes with Ogre where you can select the components and have them instantiated, but I want to do that with more complex componants like this:
Image
The trouble I am having is that when I create the .layout file it loads automatically at startup, which I could turn off by setting it invisible, but there also seems to be only 1 and I want to be able to instantiate an arbitrary number.

Posted: Mon Jul 10, 2006 20:46
by Rackle
The problem is that each time to load a .layout file you attempt to recreate windows with the same name; each window name must be unique.

Here's some imaginary code (it will NOT compile):

Code: Select all

CEGUI::Window* cloneLayoutContents(const CEGUI::String& layoutFile, const CEGUI::uint& id = 0)
  {
    /* Clones the window hierarchy contained within a .layout file
     * Format specifiers:
     *    0 forced digit: will be replaced by a digit or if here is no digit, by a zero
     *    # potential digit: will be replaced by a digit if there is one otherwise nothing
     *    ' literal character: the following character is to be treated as a character
     *    rather than a format specifier
     *
     * The following hierarchy is assumed:
     * ParentName000/
     *  child1Name
     *    subChild01Name
     *    subChild02Name
     *  child2Name
     *
     * After this function is called the following hierarchy will be present:
     * ParentName001/
     *  ParentName001/child1Name
     *    ParentName001/subChild01Name
     *    ParentName001/subChild02Name
     *  ParentName001/child2Name
     */

    using namespace CEGUI;
    String namePrefix;
    Window* clone = readLayout(layoutFile);
    String mask = clone->getName(); // The top-level window contains the mask for the lower level windows

    uint newID = id;
    while(true)
    {
      if(!ICU::formatText(String(newID), mask, "0", namePrefix))
        return 0; // Error formatting the window prefix
      if(!existsWindow(namePrefix))
        break;
      ++newID;
    }

    clone->setName(windowPrefix);
    renameClonedWindows(clone, windowPrefix);
    return clone;
  }

  void renameClonedWindows(const CEGUI::Window* parent, const CEGUI::String& namePrefix)
  {
    // Rename each child window by prefixing it with the top parent's name using namespace CEGUI;
    for(Window* child = parent->getFirstChild(), child, child = parent->getNextChild())
    {
      child->setName(namePrefix + child->getName());
      renameClonedWidgets(child, namePrefix);
    }
  }


ICU::formatText is coming from the Wiki entry called Formatted Numbers/Text.

My idea/concept is that the layout defines window names with zeros (000). The cloneLayoutContents() function loads the .layout file, creates all the 000 windows and subwindows, and then renames/increments them to 001. If you call this function a second time it would recreate the 000 version and then increment it to 002.

If you do go along and code this imaginary function please Wiki it.

Posted: Mon Jan 08, 2007 16:40
by Pompei2
Hello, now i ran into the situation where i need to create multiple windows out of one layout file. I remembered this post, but i see that the function CEGUI::Window::setName(..) doesn't seem to exist anymore, so how do i change the name of a widget now ?

EDIT:
hehe today is my finding day or what :) i found it by a lucky hazard it's the
WindowManager::renameWindow function.