Changing schemes on the fly (like TestaSkin)

Forum for general chit-chat or off-topic discussion.

Moderators: CEGUI MVP, CEGUI Team

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Changing schemes on the fly (like TestaSkin)

Postby Rackle » Wed Apr 19, 2006 19:14

I would like to create an application where the look/skin can easily be changed. The application TestaSkin does this so I know it is possible.

My understanding of TestaSkin is that it creates .layout files where each widget is specified in a scheme-less manner: Button rather than TaharezLook/Button or WindowsLook/Button. For each scheme available (Horror1, Marti, TaharezLook and WindowsLook) there is a correspoding alias file (WidgetAliasesMarti.scheme for example). The application loads every scheme available and then loads one alias file, the alias file to determine which look to "activate".

Is this approach compatible with the soon to come version 0.5? And what of the Falagard system. Is there another method made available such as setFalagardScheme("scheme name")? I'm slightly confused as to how to proceed and how to effectively use the Falagard system versus the hard coded scheme/widget approach.

The FalagardDemo1 loads the VanillaSkin.scheme which specifies, among many others, WindowType="Vanilla/Titlebar" as well as TargetType="Falagard/Titlebar". Then it creates a static image with the scheme/widget syntax winMgr.createWindow("Vanilla/StaticImage"), seemingly forcing this scheme. Finally it loads the VanillaWindows.layout, which specifies widgets in the scheme/widget syntax such as <Window Type="Vanilla/StaticImage" Name="root">. The only difference with other layouts seems to be the TargetType="Falagard/Titlebar" bit.

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Thu Apr 20, 2006 01:11

I managed to compile TestaSkin and step through it via the debugger and managed to figure it out.

First, to compile TestaSkin I edited CEGUICommonFileDialog.h and commented #include "CEGUIHashMapTemplates.h" on line 5 as well as hash_map<string, _Path*> _currentPaths; on line 327. Then I edited CEGUICommonFileDialog.cpp and commented #include "CEGUIHashMapTemplates.h" on line 1, deleteAllEntriesFromHashMap (&_currentPaths); on line 277, _Path* path = getEntryFromHashMap (string(szDrive.c_str()), &_currentPaths); on line 975, and addEntryToHashMap (string(szDrive.c_str()), path, &_currentPaths); on line 987.

My application now loads "WindowsLookSkin.scheme" and "TaharezLookSkin.scheme" during initialization and selects one as the default skin, by loading either "WindowsLookWidgetAliases.scheme" or "TaharezLookWidgetAliases.scheme".

Switching from one skin to another involves:

1) unloading the current alias scheme with CEGUI::SchemeManager::getSingleton().unloadScheme("TaharezLookWidgetAliases");. The name to use is the one specified within the alias scheme file within the tag <GUIScheme Name="TaharezLookWidgetAliases">.

2) loading the new alias scheme with CEGUI::SchemeManager::getSingleton().loadScheme("../datafiles/schemes/TaharezLookWidgetAliases.scheme");

3) destroying the currently loaded layout with CEGUI::WindowManager::getSingleton().destroyWindow("Root");. The name "Root" comes from the line <Window Type="DefaultWindow" Name="Root" > from the layout file.

4) reloading the layout with CEGUI::WindowManager::getSingleton().loadWindowLayout() and adding it to the GUISheet with CEGUI::System::getSingletonPtr()->getGUISheet()->addChildWindow().

5) resubscribe to events

I edited the TaharezLookWidgetAliases.scheme file such that the Alias="" tags only contain the widget type, such as Alias="Button" rather than Alias="Taharez Button". I created a WindowsLookWidgetAliases.scheme by replacing the keyword "Taharez" with "Windows" within the TaharezLookWidgetAliases.scheme file. And finally I edited the layout created by the Layout Editor and removed every mention of Taharez/ in order to match the widget names I defined within the alias files.

I find this approach quite rough, drastic. I would have preferred to be able to unload the current scheme, load a new scheme, and then force a redraw with signalRedraw().

Hope this helps.

User avatar
gcarlton
Just can't stay away
Just can't stay away
Posts: 149
Joined: Wed Jan 12, 2005 12:06

Postby gcarlton » Thu Apr 20, 2006 04:44

Good to see you are making progress. I've wanted to switch over to the general widget names for a while, but haven't quite found the time to pore over the alias scheme changes and try to update all my datafiles. So alas, I'm stuck with the "TaherezLook/" prefix for now on everything.

As for the idea about a "signalRedraw", I don't think that is ever likely to be possible. Different aliases may create widgets of different C++ classes, and in particular the new classes may create a different set of automatic child widgets. So in changing scheme, the window tree would need some pretty serious pulling apart and putting back together. It sounds very messy - better just to scrap the lot and recreate the lot.

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Thu Apr 20, 2006 11:53

Hah, that didn't even occur to me. I just tested it and I changed the button in TaharezLook to a check box in WindowsLook. However I'm not sure what happens to the events: PushButton::EventClicked versus Checkbox::EventCheckStateChanged. It would seem we'd need to create them based on their current alias/redefinition. I will not pursue this new matter any further; I do not intend to change appearances in this manner.


Return to “Offtopic Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest