Difference between revisions of "PropertyFinder"
From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
(Link to API properties) |
m (because references rule) |
||
(9 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{VersionBadge|0.7}} | ||
+ | |||
=== Introduction === | === Introduction === | ||
This code creates a tool to list the properties associated with the widgets of a scheme. It loads the .scheme files from within the Scheme directory and displays the widgets defined within that scheme. Selecting a widget will list every property associated to that widget by default. And selecting a property will display its help. | This code creates a tool to list the properties associated with the widgets of a scheme. It loads the .scheme files from within the Scheme directory and displays the widgets defined within that scheme. Selecting a widget will list every property associated to that widget by default. And selecting a property will display its help. | ||
− | Please discuss this snippet within the [http://www.cegui.org.uk/phpBB2/viewtopic.php?p=11670#11670 Property Finder] thread. The properties for | + | Please discuss this snippet within the [http://www.cegui.org.uk/phpBB2/viewtopic.php?p=11670#11670 Property Finder] thread. The properties for widgets are presented in [[Property reference for TaharezLook]], [[Property reference for WindowsLook]], [[Property reference for Vanilla]] and [[Property reference for OgreTray]]. The CEGUI API also [http://www.cegui.org.uk/api_reference/classCEGUI_1_1Property.html lists the properties]. |
=== Files === | === Files === | ||
==== PropertyFinder.h ==== | ==== PropertyFinder.h ==== | ||
− | < | + | <source lang="cpp"> |
#ifndef _PropertyFinder_h_ | #ifndef _PropertyFinder_h_ | ||
#define _PropertyFinder_h_ | #define _PropertyFinder_h_ | ||
Line 14: | Line 16: | ||
#include "CEGUIDefaultResourceProvider.h" | #include "CEGUIDefaultResourceProvider.h" | ||
− | #include < | + | #include <stdio.h> |
− | #include < | + | #include <iostream> |
#include <map> | #include <map> | ||
#include <vector> | #include <vector> | ||
Line 24: | Line 26: | ||
public: | public: | ||
bool initialiseSample() | bool initialiseSample() | ||
− | + | { | |
− | + | using namespace CEGUI; | |
− | + | // The executable is stored within <cegui>/bin | |
− | + | // The following will change the location of the datafiles from their default of | |
− | + | // ../datafiles (which works well for the samples) to <cegui>/samples/datafiles | |
− | + | DefaultResourceProvider* rp = reinterpret_cast<DefaultResourceProvider*>(System::getSingleton().getResourceProvider()); | |
− | + | rp->setResourceGroupDirectory("fonts", "../samples/datafiles/fonts/"); | |
− | + | rp->setResourceGroupDirectory("imagesets", "../samples/datafiles/imagesets/"); | |
− | + | rp->setResourceGroupDirectory("layouts", "c:/programming/_Projects/CeguiTestBed/"); | |
− | + | rp->setResourceGroupDirectory("looknfeels", "../samples/datafiles/looknfeel/"); | |
− | + | rp->setResourceGroupDirectory("lua_scripts", "../samples/datafiles/lua_scripts/"); | |
− | + | rp->setResourceGroupDirectory("schemes", "../samples/datafiles/schemes/"); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | try | |
− | + | { | |
− | + | // Retrieve the window manager | |
− | + | WindowManager& winMgr = WindowManager::getSingleton(); | |
− | + | // Load the TaharezLook scheme and set up the default mouse cursor and font | |
− | + | Scheme* currentScheme = &SchemeManager::getSingleton().create("TaharezLook.scheme"); | |
− | + | System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow"); | |
− | + | FontManager::getSingleton().create("DejaVuSans-10.font"); | |
− | + | // Set the GUI Sheet | |
− | + | Window* sheet = winMgr.createWindow("DefaultWindow", "root_wnd"); | |
− | + | System::getSingleton().setGUISheet(sheet); | |
− | + | // Load a layout | |
− | + | Window* guiLayout = winMgr.loadWindowLayout("PropertyFinder.layout"); | |
− | + | sheet->addChildWindow(guiLayout); | |
− | + | // Retrieve the handle to the often used widgets | |
− | + | mSchemes = static_cast<CEGUI::Combobox*>(winMgr.getWindow("PropertyFinder/SchemeList")); | |
− | + | mWidgets = static_cast<CEGUI::Combobox*>(winMgr.getWindow("PropertyFinder/WidgetList")); | |
− | + | mProperties = static_cast<CEGUI::Listbox*>(winMgr.getWindow("PropertyFinder/Properties")); | |
− | + | mInformation = static_cast<CEGUI::MultiLineEditbox*>(winMgr.getWindow("PropertyFinder/Information")); | |
− | + | mRadioButton = static_cast<CEGUI::RadioButton*>(winMgr.getWindow("PropertyFinder/ExportWiki")); | |
− | + | // Configure the schemes | |
− | + | mSchemes->subscribeEvent(Combobox::EventTextChanged, Event::Subscriber(&DemoSample::onSchemeChanged, this)); | |
− | + | mSchemes->subscribeEvent(Combobox::EventListSelectionAccepted, Event::Subscriber(&DemoSample::onSchemeChanged, this)); | |
− | + | mSchemes->setSortingEnabled(true); | |
− | + | // Configure the widgets | |
− | + | mWidgets->subscribeEvent(Combobox::EventTextChanged, Event::Subscriber(&DemoSample::onWidgetChanged, this)); | |
− | + | mWidgets->subscribeEvent(Combobox::EventListSelectionAccepted, Event::Subscriber(&DemoSample::onWidgetChanged, this)); | |
− | + | mWidgets->setSortingEnabled(true); | |
− | + | // Configure the properties | |
− | + | mProperties->setSortingEnabled(true); | |
− | + | mProperties->setMultiselectEnabled(false); | |
− | + | mProperties->subscribeEvent(Listbox::EventSelectionChanged, Event::Subscriber(&DemoSample::onPropertyChanged, this)); | |
− | + | // Configure the export | |
− | + | CEGUI::PushButton* btnExport = static_cast<CEGUI::PushButton*>(winMgr.getWindow("PropertyFinder/Export")); | |
− | + | btnExport->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DemoSample::onExport, this)); | |
− | + | mRadioButton->setGroupID(1); | |
− | + | mRadioButton->setID(Wiki); | |
− | + | mRadioButton->setSelected(true); | |
− | + | CEGUI::RadioButton* radioButton = static_cast<CEGUI::RadioButton*>(winMgr.getWindow("PropertyFinder/ExportHtml")); | |
− | + | radioButton->setGroupID(1); | |
− | + | radioButton->setID(Html); | |
− | + | radioButton->setSelected(false); | |
− | + | radioButton = static_cast<CEGUI::RadioButton*>(winMgr.getWindow("PropertyFinder/ExportXml")); | |
− | + | radioButton->setGroupID(1); | |
− | + | radioButton->setID(Xml); | |
− | + | radioButton->setSelected(false); | |
− | + | // Load every scheme | |
− | + | loadEverySchemes(currentScheme); | |
− | + | } | |
− | + | catch (Exception &e) | |
− | + | { | |
− | + | #if defined( __WIN32__ ) || defined( _WIN32 ) | |
− | + | MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL); | |
− | + | #else | |
− | + | std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n"; | |
− | + | #endif | |
− | + | } | |
− | + | return true; | |
− | + | } | |
void cleanupSample(void) | void cleanupSample(void) | ||
− | + | { | |
− | + | } | |
− | + | void loadEverySchemes(CEGUI::Scheme* pCurrentScheme) | |
− | + | { | |
− | + | CEGUI::SchemeManager::getSingleton().createAll("*.scheme", "schemes"); | |
− | + | ||
− | + | ||
− | + | // Parse the loaded schemes and determine their internal names (as widget prefixes) | |
− | + | const CEGUI::String separator("/"); | |
− | + | CEGUI::String currentFal; | |
− | + | CEGUI::String::size_type pos; | |
− | + | CEGUI::String newLook, currentLook; | |
− | + | CEGUI::String widget; | |
− | + | CEGUI::WindowFactoryManager::FalagardMappingIterator itFalagardMapping = CEGUI::WindowFactoryManager::getSingleton().getFalagardMappingIterator(); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | while (!itFalagardMapping.isAtEnd()) | |
− | + | { | |
− | + | currentFal = itFalagardMapping.getCurrentKey(); | |
− | + | pos = currentFal.find(separator); | |
− | + | newLook = currentFal.substr(0, pos); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | if (currentLook.compare(newLook) != 0) | |
− | + | { | |
− | + | currentLook = newLook; | |
− | + | addScheme(newLook); | |
− | + | } | |
− | + | ||
− | + | ||
− | + | itFalagardMapping++; | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | // Select the "current" scheme | |
− | + | CEGUI::ListboxItem* current = mSchemes->findItemWithText(pCurrentScheme->getName(), 0); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | if (current) | |
− | + | { | |
− | + | mSchemes->setText(pCurrentScheme->getName()); | |
− | + | } | |
− | + | } | |
− | + | void addScheme(const CEGUI::String& pScheme) | |
− | + | { | |
− | + | if (!mSchemes->findItemWithText(pScheme, 0)) | |
− | + | { | |
− | + | // This scheme has not yet been added | |
− | + | CEGUI::ListboxTextItem* schemeItem = new CEGUI::ListboxTextItem(pScheme); | |
− | + | schemeItem->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush"); | |
− | + | mSchemes->addItem(schemeItem); | |
+ | } | ||
+ | } | ||
− | + | bool onSchemeChanged(const CEGUI::EventArgs& args) | |
− | + | { | |
− | + | // Refresh the widget list | |
− | + | mWidgets->resetList(); | |
− | + | getWidgets(mSchemes->getText()); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | CEGUI::ListboxTextItem* widgetItem; | |
− | + | WidgetList::iterator itWidgetList; | |
− | + | for (itWidgetList = mWidgetList.begin(); itWidgetList != mWidgetList.end(); itWidgetList++) | |
− | + | { | |
− | + | widgetItem = new CEGUI::ListboxTextItem((*itWidgetList)); | |
+ | widgetItem->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush"); | ||
+ | mWidgets->addItem(widgetItem); | ||
+ | } | ||
− | + | // Select the first widget | |
− | + | if (mWidgets->getItemCount() > 0) | |
− | + | { | |
− | + | mWidgets->setText(mWidgets->getListboxItemFromIndex(0)->getText()); | |
− | + | } | |
− | + | else | |
− | + | { | |
− | + | mWidgets->setText(""); | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | return true; | |
− | + | } | |
− | + | void getWidgets(const CEGUI::String& pScheme) | |
− | + | { | |
− | + | mWidgetList.clear(); | |
− | + | ||
− | + | ||
− | + | const CEGUI::String separator("/"); | |
− | + | CEGUI::String currentFal; | |
− | + | CEGUI::String::size_type pos; | |
− | + | CEGUI::String newLook; | |
− | + | CEGUI::String widget; | |
− | + | CEGUI::WindowFactoryManager::FalagardMappingIterator itFalagardMapping = CEGUI::WindowFactoryManager::getSingleton().getFalagardMappingIterator(); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | while (!itFalagardMapping.isAtEnd()) | |
− | + | { | |
− | + | currentFal = itFalagardMapping.getCurrentKey(); | |
− | + | pos = currentFal.find(separator); | |
− | + | newLook = currentFal.substr(0, pos); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | if (pScheme.compare(newLook) == 0) | |
− | + | { | |
+ | widget = currentFal.substr(pos + 1); | ||
+ | mWidgetList.push_back(widget); | ||
+ | } | ||
− | + | itFalagardMapping++; | |
− | + | } | |
− | + | ||
− | + | ||
− | + | std::sort(mWidgetList.begin(), mWidgetList.end()); | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | bool onWidgetChanged(const CEGUI::EventArgs& args) | |
− | + | { | |
− | + | // Refresh the property list | |
− | + | mProperties->resetList(); | |
− | + | getProperties(mSchemes->getText(), mWidgets->getText()); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | CEGUI::ListboxTextItem* propertyItem; | |
− | + | PropertyList::iterator itPropertyList; | |
− | + | for (itPropertyList = mPropertyList.begin(); itPropertyList != mPropertyList.end(); itPropertyList++) | |
− | + | { | |
− | + | propertyItem = new CEGUI::ListboxTextItem((*itPropertyList).first); | |
− | + | propertyItem->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush"); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | if ((*itPropertyList).second.falagard) | |
− | + | { | |
+ | propertyItem->setTextColours(CEGUI::colour(1.0f, 1.0f, .5f)); | ||
+ | } | ||
− | + | mProperties->addItem(propertyItem); | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | // Select the first property | |
+ | if (mProperties->getItemCount() > 0) | ||
+ | { | ||
+ | CEGUI::ListboxItem* selectedProperty = mProperties->getListboxItemFromIndex(0); | ||
+ | mProperties->setItemSelectState(selectedProperty, true); | ||
+ | mProperties->ensureItemIsVisible(selectedProperty); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | mInformation->setText(""); | ||
+ | } | ||
− | + | return true; | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | void getProperties(const CEGUI::String& pScheme, const CEGUI::String& pWidget) | |
− | + | { | |
− | + | const CEGUI::String separator("/"); | |
− | + | mPropertyList.clear(); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | try | |
− | + | { | |
− | + | CEGUI::Window* widget = CEGUI::WindowManager::getSingleton().createWindow(pScheme + separator + pWidget); | |
− | + | CEGUI::PropertySet::Iterator itPropertySet = ((CEGUI::PropertySet*) widget)->getIterator(); | |
− | + | ||
− | + | ||
+ | while (!itPropertySet.isAtEnd()) | ||
+ | { | ||
+ | PropertyInfo pi; | ||
+ | pi.help = (*itPropertySet)->getHelp(); | ||
+ | pi.falagard = dynamic_cast<CEGUI::PropertyDefinition*>(*itPropertySet) != 0; | ||
+ | mPropertyList[itPropertySet.getCurrentKey()] = pi; | ||
+ | itPropertySet++; | ||
+ | } | ||
− | + | CEGUI::WindowManager::getSingleton().destroyWindow(widget); | |
− | + | } | |
− | + | catch (...) | |
− | + | { | |
− | + | // Silently ignore errors | |
− | + | // TaharezLook/TabPane generates one such error | |
+ | } | ||
+ | } | ||
− | + | bool onPropertyChanged(const CEGUI::EventArgs& args) | |
− | + | { | |
− | + | // Display the appropriate help information | |
− | + | CEGUI::ListboxItem* selectedItem = mProperties->getFirstSelectedItem(); | |
− | + | ||
− | + | ||
− | + | ||
− | + | if (selectedItem) | |
− | + | { | |
− | + | PropertyList::iterator itPropertyList = mPropertyList.find(selectedItem->getText()); | |
− | + | ||
− | + | ||
− | + | ||
− | + | if (itPropertyList != mPropertyList.end()) | |
− | + | { | |
− | + | mInformation->setText((*itPropertyList).second.help); | |
− | + | } | |
− | + | } | |
− | + | else | |
− | + | { | |
− | + | mInformation->setText(""); | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | return true; | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | bool onExport(const CEGUI::EventArgs& args) | |
− | + | { | |
− | + | CEGUI::uint exportType = mRadioButton->getSelectedButtonInGroup()->getID(); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | switch (exportType) | |
− | + | { | |
− | + | case Wiki: | |
− | + | ExportWiki(); | |
− | + | break; | |
− | + | case Html: | |
− | + | ExportHtml(); | |
− | + | break; | |
+ | case Xml: | ||
+ | ExportXml(); | ||
+ | break; | ||
+ | } | ||
− | + | return true; | |
− | + | } | |
− | + | ||
− | + | void ExportWiki() | |
− | + | { | |
+ | std::ofstream out("PropertyFinder.txt"); | ||
+ | const CEGUI::String sectionHeader("==="); | ||
+ | const CEGUI::String widgetHeader("===="); | ||
+ | const CEGUI::String propertyHeader("===="); | ||
+ | const CEGUI::String falagardColor("bgcolor=\"#FFBF00\""); | ||
− | + | PropertyList completePropertyList; | |
− | + | ||
− | + | ||
− | + | CEGUI::String schemeName; | |
− | + | WidgetList::iterator itWidgetList; | |
− | + | PropertyList::iterator itPropertyList; | |
+ | |||
+ | const int propertiesPerLine = 5; | ||
+ | int propertiesOnLine; | ||
+ | |||
+ | /******************* Option 1 *******************/ | ||
+ | // Export every detected scheme | ||
+ | /* | ||
+ | for(size_t schemeItem = 0; schemeItem < mSchemes->getItemCount(); schemeItem++) | ||
+ | { | ||
+ | schemeName = mSchemes->getListboxItemFromIndex(schemeItem)->getText(); | ||
+ | getWidgets(schemeName); | ||
+ | if(mWidgetList.size() == 0) | ||
+ | { | ||
+ | continue; | ||
+ | } | ||
+ | */ | ||
+ | |||
+ | /******************* Option 2 *******************/ | ||
+ | // Only export the currently selected scheme | ||
+ | { | ||
+ | schemeName = mSchemes->getText(); | ||
+ | getWidgets(schemeName); | ||
+ | /************** End of the options **************/ | ||
+ | |||
+ | |||
+ | out << sectionHeader | ||
+ | << " " | ||
+ | << schemeName | ||
+ | << " " | ||
+ | << sectionHeader | ||
+ | << "\n"; | ||
+ | |||
+ | for (itWidgetList = mWidgetList.begin(); itWidgetList != mWidgetList.end(); itWidgetList++) | ||
+ | { | ||
+ | getProperties(schemeName, (*itWidgetList)); | ||
+ | |||
+ | if (mPropertyList.size() == 0) | ||
+ | { | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | out << widgetHeader | ||
+ | << " " | ||
+ | << (*itWidgetList) | ||
+ | << " " | ||
+ | << widgetHeader | ||
+ | << "\n"; | ||
+ | |||
+ | propertiesOnLine = 0; | ||
+ | out << "{| class=\"wikitable\" border=\"1\" \n"; | ||
+ | |||
+ | for (itPropertyList = mPropertyList.begin(); itPropertyList != mPropertyList.end(); itPropertyList++) | ||
+ | { | ||
+ | if (propertiesOnLine == propertiesPerLine) | ||
+ | { | ||
+ | out << "|-\n"; | ||
+ | propertiesOnLine = 0; | ||
+ | } | ||
+ | |||
+ | out << "| "; | ||
+ | |||
+ | if ((*itPropertyList).second.falagard) | ||
+ | { | ||
+ | out << falagardColor | ||
+ | << " | "; | ||
+ | } | ||
+ | |||
+ | out << "[[#" | ||
+ | << (*itPropertyList).first | ||
+ | << "]]\n"; | ||
+ | ++propertiesOnLine; | ||
+ | |||
+ | if (completePropertyList.find((*itPropertyList).first) == completePropertyList.end()) | ||
+ | { | ||
+ | completePropertyList[(*itPropertyList).first] = (*itPropertyList).second; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | out << "|}\n\n"; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | out << sectionHeader | ||
+ | << " Properties " | ||
+ | << sectionHeader | ||
+ | << "\n"; | ||
+ | const CEGUI::String falagardKeyword("Falagard"); | ||
+ | CEGUI::String::size_type falagardPos; | ||
+ | CEGUI::String propertyDescription; | ||
+ | PropertyList::iterator itCompletePropertyList; | ||
+ | |||
+ | for (itCompletePropertyList = completePropertyList.begin(); | ||
+ | itCompletePropertyList != completePropertyList.end(); | ||
+ | itCompletePropertyList++) | ||
+ | { | ||
+ | out << propertyHeader | ||
+ | << " " | ||
+ | << (*itCompletePropertyList).first | ||
+ | << " " | ||
+ | << propertyHeader | ||
+ | << "\n"; | ||
+ | |||
+ | propertyDescription = (*itCompletePropertyList).second.help; | ||
+ | falagardPos = (*itCompletePropertyList).second.help.find(falagardKeyword); | ||
+ | |||
+ | if (falagardPos != CEGUI::String::npos) | ||
+ | { | ||
+ | propertyDescription = propertyDescription.replace(falagardPos, | ||
+ | falagardKeyword.length(), | ||
+ | "<font COLOR=\"#FFBF00\">Falagard</font>"); | ||
+ | } | ||
+ | |||
+ | out << propertyDescription | ||
+ | << "\n\n"; | ||
+ | } | ||
+ | |||
+ | out.close(); | ||
+ | } | ||
+ | |||
+ | void ExportHtml() | ||
+ | { | ||
+ | } | ||
+ | |||
+ | void ExportXml() | ||
+ | { | ||
+ | } | ||
private: | private: | ||
− | + | // Widget containing the list of schemes | |
− | + | CEGUI::Combobox* mSchemes; | |
+ | |||
+ | // Widget containing the list of widgets in a scheme | ||
+ | CEGUI::Combobox* mWidgets; | ||
− | + | // Widget containing the list of properties | |
− | + | CEGUI::Listbox* mProperties; | |
− | + | // Type of list of widgets for a scheme | |
− | + | typedef std::vector<CEGUI::String> WidgetList; | |
− | + | // List of widgets for a scheme | |
− | + | WidgetList mWidgetList; | |
− | + | // Struct holding info for a property | |
− | + | struct PropertyInfo | |
+ | { | ||
+ | CEGUI::String help; | ||
+ | bool falagard; | ||
+ | }; | ||
− | + | // Type of list of properties for a widget <property, help> | |
− | + | typedef std::map<CEGUI::String, PropertyInfo> PropertyList; | |
− | + | // List of properties for a widget | |
− | + | PropertyList mPropertyList; | |
− | + | // Widget displaying additional information on a property | |
− | + | CEGUI::MultiLineEditbox* mInformation; | |
− | + | // Radiobutton part of a group | |
− | + | CEGUI::RadioButton* mRadioButton; | |
− | + | // Defines the types of export | |
− | + | enum ExportType {Wiki, Html, Xml}; | |
}; | }; | ||
#endif // _PropertyFinder_h_ | #endif // _PropertyFinder_h_ | ||
− | </ | + | </source> |
==== Main.cpp ==== | ==== Main.cpp ==== | ||
− | < | + | <source lang="cpp"> |
#if defined( __WIN32__ ) || defined( _WIN32 ) | #if defined( __WIN32__ ) || defined( _WIN32 ) | ||
#define WIN32_LEAN_AND_MEAN | #define WIN32_LEAN_AND_MEAN | ||
Line 528: | Line 529: | ||
return i; | return i; | ||
} | } | ||
− | </ | + | </source> |
==== PropertyFinder.layout ==== | ==== PropertyFinder.layout ==== | ||
− | < | + | <source lang="xml"> |
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||
Line 537: | Line 538: | ||
<Window Type="TaharezLook/FrameWindow" Name="PropertyFinder" > | <Window Type="TaharezLook/FrameWindow" Name="PropertyFinder" > | ||
<Property Name="Text" Value="Property Finder" /> | <Property Name="Text" Value="Property Finder" /> | ||
− | |||
<Property Name="InheritsAlpha" Value="False" /> | <Property Name="InheritsAlpha" Value="False" /> | ||
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | ||
Line 554: | Line 554: | ||
</Window> | </Window> | ||
<Window Type="TaharezLook/StaticText" Name="PropertyFinder/WidgetLabel" > | <Window Type="TaharezLook/StaticText" Name="PropertyFinder/WidgetLabel" > | ||
− | |||
<Property Name="Text" Value="Widget:" /> | <Property Name="Text" Value="Widget:" /> | ||
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | ||
Line 560: | Line 559: | ||
</Window> | </Window> | ||
<Window Type="TaharezLook/Combobox" Name="PropertyFinder/WidgetList" > | <Window Type="TaharezLook/Combobox" Name="PropertyFinder/WidgetList" > | ||
− | |||
<Property Name="ReadOnly" Value="True" /> | <Property Name="ReadOnly" Value="True" /> | ||
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | ||
Line 571: | Line 569: | ||
</Window> | </Window> | ||
<Window Type="TaharezLook/MultiLineEditbox" Name="PropertyFinder/Information" > | <Window Type="TaharezLook/MultiLineEditbox" Name="PropertyFinder/Information" > | ||
− | <Property Name="Text" > | + | <Property Name="Text" ></Property> |
− | </Property> | + | |
<Property Name="ReadOnly" Value="True" /> | <Property Name="ReadOnly" Value="True" /> | ||
<Property Name="MaxTextLength" Value="1073741823" /> | <Property Name="MaxTextLength" Value="1073741823" /> | ||
Line 590: | Line 587: | ||
</Window> | </Window> | ||
<Window Type="TaharezLook/RadioButton" Name="PropertyFinder/ExportHtml" > | <Window Type="TaharezLook/RadioButton" Name="PropertyFinder/ExportHtml" > | ||
− | |||
<Property Name="Text" Value="HTML" /> | <Property Name="Text" Value="HTML" /> | ||
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | ||
Line 596: | Line 592: | ||
</Window> | </Window> | ||
<Window Type="TaharezLook/RadioButton" Name="PropertyFinder/ExportXml" > | <Window Type="TaharezLook/RadioButton" Name="PropertyFinder/ExportXml" > | ||
− | |||
<Property Name="Text" Value="XML" /> | <Property Name="Text" Value="XML" /> | ||
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> | ||
Line 603: | Line 598: | ||
</Window> | </Window> | ||
</GUILayout> | </GUILayout> | ||
− | </ | + | </source> |
+ | |||
+ | [[Category:HowTo]] |
Latest revision as of 01:38, 6 March 2011
Written for CEGUI 0.7
Works with versions 0.7.x (obsolete)
Introduction
This code creates a tool to list the properties associated with the widgets of a scheme. It loads the .scheme files from within the Scheme directory and displays the widgets defined within that scheme. Selecting a widget will list every property associated to that widget by default. And selecting a property will display its help.
Please discuss this snippet within the Property Finder thread. The properties for widgets are presented in Property reference for TaharezLook, Property reference for WindowsLook, Property reference for Vanilla and Property reference for OgreTray. The CEGUI API also lists the properties.
Files
PropertyFinder.h
#ifndef _PropertyFinder_h_ #define _PropertyFinder_h_ #include "CEGuiSample.h" #include "CEGUI.h" #include "CEGUIDefaultResourceProvider.h" #include <stdio.h> #include <iostream> #include <map> #include <vector> #include <algorithm> class DemoSample : public CEGuiSample { public: bool initialiseSample() { using namespace CEGUI; // The executable is stored within <cegui>/bin // The following will change the location of the datafiles from their default of // ../datafiles (which works well for the samples) to <cegui>/samples/datafiles DefaultResourceProvider* rp = reinterpret_cast<DefaultResourceProvider*>(System::getSingleton().getResourceProvider()); rp->setResourceGroupDirectory("fonts", "../samples/datafiles/fonts/"); rp->setResourceGroupDirectory("imagesets", "../samples/datafiles/imagesets/"); rp->setResourceGroupDirectory("layouts", "c:/programming/_Projects/CeguiTestBed/"); rp->setResourceGroupDirectory("looknfeels", "../samples/datafiles/looknfeel/"); rp->setResourceGroupDirectory("lua_scripts", "../samples/datafiles/lua_scripts/"); rp->setResourceGroupDirectory("schemes", "../samples/datafiles/schemes/"); try { // Retrieve the window manager WindowManager& winMgr = WindowManager::getSingleton(); // Load the TaharezLook scheme and set up the default mouse cursor and font Scheme* currentScheme = &SchemeManager::getSingleton().create("TaharezLook.scheme"); System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow"); FontManager::getSingleton().create("DejaVuSans-10.font"); // Set the GUI Sheet Window* sheet = winMgr.createWindow("DefaultWindow", "root_wnd"); System::getSingleton().setGUISheet(sheet); // Load a layout Window* guiLayout = winMgr.loadWindowLayout("PropertyFinder.layout"); sheet->addChildWindow(guiLayout); // Retrieve the handle to the often used widgets mSchemes = static_cast<CEGUI::Combobox*>(winMgr.getWindow("PropertyFinder/SchemeList")); mWidgets = static_cast<CEGUI::Combobox*>(winMgr.getWindow("PropertyFinder/WidgetList")); mProperties = static_cast<CEGUI::Listbox*>(winMgr.getWindow("PropertyFinder/Properties")); mInformation = static_cast<CEGUI::MultiLineEditbox*>(winMgr.getWindow("PropertyFinder/Information")); mRadioButton = static_cast<CEGUI::RadioButton*>(winMgr.getWindow("PropertyFinder/ExportWiki")); // Configure the schemes mSchemes->subscribeEvent(Combobox::EventTextChanged, Event::Subscriber(&DemoSample::onSchemeChanged, this)); mSchemes->subscribeEvent(Combobox::EventListSelectionAccepted, Event::Subscriber(&DemoSample::onSchemeChanged, this)); mSchemes->setSortingEnabled(true); // Configure the widgets mWidgets->subscribeEvent(Combobox::EventTextChanged, Event::Subscriber(&DemoSample::onWidgetChanged, this)); mWidgets->subscribeEvent(Combobox::EventListSelectionAccepted, Event::Subscriber(&DemoSample::onWidgetChanged, this)); mWidgets->setSortingEnabled(true); // Configure the properties mProperties->setSortingEnabled(true); mProperties->setMultiselectEnabled(false); mProperties->subscribeEvent(Listbox::EventSelectionChanged, Event::Subscriber(&DemoSample::onPropertyChanged, this)); // Configure the export CEGUI::PushButton* btnExport = static_cast<CEGUI::PushButton*>(winMgr.getWindow("PropertyFinder/Export")); btnExport->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DemoSample::onExport, this)); mRadioButton->setGroupID(1); mRadioButton->setID(Wiki); mRadioButton->setSelected(true); CEGUI::RadioButton* radioButton = static_cast<CEGUI::RadioButton*>(winMgr.getWindow("PropertyFinder/ExportHtml")); radioButton->setGroupID(1); radioButton->setID(Html); radioButton->setSelected(false); radioButton = static_cast<CEGUI::RadioButton*>(winMgr.getWindow("PropertyFinder/ExportXml")); radioButton->setGroupID(1); radioButton->setID(Xml); radioButton->setSelected(false); // Load every scheme loadEverySchemes(currentScheme); } catch (Exception &e) { #if defined( __WIN32__ ) || defined( _WIN32 ) MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n"; #endif } return true; } void cleanupSample(void) { } void loadEverySchemes(CEGUI::Scheme* pCurrentScheme) { CEGUI::SchemeManager::getSingleton().createAll("*.scheme", "schemes"); // Parse the loaded schemes and determine their internal names (as widget prefixes) const CEGUI::String separator("/"); CEGUI::String currentFal; CEGUI::String::size_type pos; CEGUI::String newLook, currentLook; CEGUI::String widget; CEGUI::WindowFactoryManager::FalagardMappingIterator itFalagardMapping = CEGUI::WindowFactoryManager::getSingleton().getFalagardMappingIterator(); while (!itFalagardMapping.isAtEnd()) { currentFal = itFalagardMapping.getCurrentKey(); pos = currentFal.find(separator); newLook = currentFal.substr(0, pos); if (currentLook.compare(newLook) != 0) { currentLook = newLook; addScheme(newLook); } itFalagardMapping++; } // Select the "current" scheme CEGUI::ListboxItem* current = mSchemes->findItemWithText(pCurrentScheme->getName(), 0); if (current) { mSchemes->setText(pCurrentScheme->getName()); } } void addScheme(const CEGUI::String& pScheme) { if (!mSchemes->findItemWithText(pScheme, 0)) { // This scheme has not yet been added CEGUI::ListboxTextItem* schemeItem = new CEGUI::ListboxTextItem(pScheme); schemeItem->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush"); mSchemes->addItem(schemeItem); } } bool onSchemeChanged(const CEGUI::EventArgs& args) { // Refresh the widget list mWidgets->resetList(); getWidgets(mSchemes->getText()); CEGUI::ListboxTextItem* widgetItem; WidgetList::iterator itWidgetList; for (itWidgetList = mWidgetList.begin(); itWidgetList != mWidgetList.end(); itWidgetList++) { widgetItem = new CEGUI::ListboxTextItem((*itWidgetList)); widgetItem->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush"); mWidgets->addItem(widgetItem); } // Select the first widget if (mWidgets->getItemCount() > 0) { mWidgets->setText(mWidgets->getListboxItemFromIndex(0)->getText()); } else { mWidgets->setText(""); } return true; } void getWidgets(const CEGUI::String& pScheme) { mWidgetList.clear(); const CEGUI::String separator("/"); CEGUI::String currentFal; CEGUI::String::size_type pos; CEGUI::String newLook; CEGUI::String widget; CEGUI::WindowFactoryManager::FalagardMappingIterator itFalagardMapping = CEGUI::WindowFactoryManager::getSingleton().getFalagardMappingIterator(); while (!itFalagardMapping.isAtEnd()) { currentFal = itFalagardMapping.getCurrentKey(); pos = currentFal.find(separator); newLook = currentFal.substr(0, pos); if (pScheme.compare(newLook) == 0) { widget = currentFal.substr(pos + 1); mWidgetList.push_back(widget); } itFalagardMapping++; } std::sort(mWidgetList.begin(), mWidgetList.end()); } bool onWidgetChanged(const CEGUI::EventArgs& args) { // Refresh the property list mProperties->resetList(); getProperties(mSchemes->getText(), mWidgets->getText()); CEGUI::ListboxTextItem* propertyItem; PropertyList::iterator itPropertyList; for (itPropertyList = mPropertyList.begin(); itPropertyList != mPropertyList.end(); itPropertyList++) { propertyItem = new CEGUI::ListboxTextItem((*itPropertyList).first); propertyItem->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush"); if ((*itPropertyList).second.falagard) { propertyItem->setTextColours(CEGUI::colour(1.0f, 1.0f, .5f)); } mProperties->addItem(propertyItem); } // Select the first property if (mProperties->getItemCount() > 0) { CEGUI::ListboxItem* selectedProperty = mProperties->getListboxItemFromIndex(0); mProperties->setItemSelectState(selectedProperty, true); mProperties->ensureItemIsVisible(selectedProperty); } else { mInformation->setText(""); } return true; } void getProperties(const CEGUI::String& pScheme, const CEGUI::String& pWidget) { const CEGUI::String separator("/"); mPropertyList.clear(); try { CEGUI::Window* widget = CEGUI::WindowManager::getSingleton().createWindow(pScheme + separator + pWidget); CEGUI::PropertySet::Iterator itPropertySet = ((CEGUI::PropertySet*) widget)->getIterator(); while (!itPropertySet.isAtEnd()) { PropertyInfo pi; pi.help = (*itPropertySet)->getHelp(); pi.falagard = dynamic_cast<CEGUI::PropertyDefinition*>(*itPropertySet) != 0; mPropertyList[itPropertySet.getCurrentKey()] = pi; itPropertySet++; } CEGUI::WindowManager::getSingleton().destroyWindow(widget); } catch (...) { // Silently ignore errors // TaharezLook/TabPane generates one such error } } bool onPropertyChanged(const CEGUI::EventArgs& args) { // Display the appropriate help information CEGUI::ListboxItem* selectedItem = mProperties->getFirstSelectedItem(); if (selectedItem) { PropertyList::iterator itPropertyList = mPropertyList.find(selectedItem->getText()); if (itPropertyList != mPropertyList.end()) { mInformation->setText((*itPropertyList).second.help); } } else { mInformation->setText(""); } return true; } bool onExport(const CEGUI::EventArgs& args) { CEGUI::uint exportType = mRadioButton->getSelectedButtonInGroup()->getID(); switch (exportType) { case Wiki: ExportWiki(); break; case Html: ExportHtml(); break; case Xml: ExportXml(); break; } return true; } void ExportWiki() { std::ofstream out("PropertyFinder.txt"); const CEGUI::String sectionHeader("==="); const CEGUI::String widgetHeader("===="); const CEGUI::String propertyHeader("===="); const CEGUI::String falagardColor("bgcolor=\"#FFBF00\""); PropertyList completePropertyList; CEGUI::String schemeName; WidgetList::iterator itWidgetList; PropertyList::iterator itPropertyList; const int propertiesPerLine = 5; int propertiesOnLine; /******************* Option 1 *******************/ // Export every detected scheme /* for(size_t schemeItem = 0; schemeItem < mSchemes->getItemCount(); schemeItem++) { schemeName = mSchemes->getListboxItemFromIndex(schemeItem)->getText(); getWidgets(schemeName); if(mWidgetList.size() == 0) { continue; } */ /******************* Option 2 *******************/ // Only export the currently selected scheme { schemeName = mSchemes->getText(); getWidgets(schemeName); /************** End of the options **************/ out << sectionHeader << " " << schemeName << " " << sectionHeader << "\n"; for (itWidgetList = mWidgetList.begin(); itWidgetList != mWidgetList.end(); itWidgetList++) { getProperties(schemeName, (*itWidgetList)); if (mPropertyList.size() == 0) { continue; } out << widgetHeader << " " << (*itWidgetList) << " " << widgetHeader << "\n"; propertiesOnLine = 0; out << "{| class=\"wikitable\" border=\"1\" \n"; for (itPropertyList = mPropertyList.begin(); itPropertyList != mPropertyList.end(); itPropertyList++) { if (propertiesOnLine == propertiesPerLine) { out << "|-\n"; propertiesOnLine = 0; } out << "| "; if ((*itPropertyList).second.falagard) { out << falagardColor << " | "; } out << "[[#" << (*itPropertyList).first << "]]\n"; ++propertiesOnLine; if (completePropertyList.find((*itPropertyList).first) == completePropertyList.end()) { completePropertyList[(*itPropertyList).first] = (*itPropertyList).second; } } out << "|}\n\n"; } } out << sectionHeader << " Properties " << sectionHeader << "\n"; const CEGUI::String falagardKeyword("Falagard"); CEGUI::String::size_type falagardPos; CEGUI::String propertyDescription; PropertyList::iterator itCompletePropertyList; for (itCompletePropertyList = completePropertyList.begin(); itCompletePropertyList != completePropertyList.end(); itCompletePropertyList++) { out << propertyHeader << " " << (*itCompletePropertyList).first << " " << propertyHeader << "\n"; propertyDescription = (*itCompletePropertyList).second.help; falagardPos = (*itCompletePropertyList).second.help.find(falagardKeyword); if (falagardPos != CEGUI::String::npos) { propertyDescription = propertyDescription.replace(falagardPos, falagardKeyword.length(), "<font COLOR=\"#FFBF00\">Falagard</font>"); } out << propertyDescription << "\n\n"; } out.close(); } void ExportHtml() { } void ExportXml() { } private: // Widget containing the list of schemes CEGUI::Combobox* mSchemes; // Widget containing the list of widgets in a scheme CEGUI::Combobox* mWidgets; // Widget containing the list of properties CEGUI::Listbox* mProperties; // Type of list of widgets for a scheme typedef std::vector<CEGUI::String> WidgetList; // List of widgets for a scheme WidgetList mWidgetList; // Struct holding info for a property struct PropertyInfo { CEGUI::String help; bool falagard; }; // Type of list of properties for a widget <property, help> typedef std::map<CEGUI::String, PropertyInfo> PropertyList; // List of properties for a widget PropertyList mPropertyList; // Widget displaying additional information on a property CEGUI::MultiLineEditbox* mInformation; // Radiobutton part of a group CEGUI::RadioButton* mRadioButton; // Defines the types of export enum ExportType {Wiki, Html, Xml}; }; #endif // _PropertyFinder_h_
Main.cpp
#if defined( __WIN32__ ) || defined( _WIN32 ) #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include "windows.h" #endif #include "PropertyFinder.h" #if defined( __WIN32__ ) || defined( _WIN32 ) int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) #else int main(int argc, char *argv[]) #endif { DemoSample app; int i = app.run(); return i; }
PropertyFinder.layout
<?xml version="1.0" encoding="UTF-8"?> <GUILayout > <Window Type="TaharezLook/FrameWindow" Name="PropertyFinder" > <Property Name="Text" Value="Property Finder" /> <Property Name="InheritsAlpha" Value="False" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="TitlebarEnabled" Value="True" /> <Property Name="UnifiedAreaRect" Value="{{0.0643816,0},{0.0124997,0},{0.903446,0},{0.891667,0}}" /> <Window Type="TaharezLook/StaticText" Name="PropertyFinder/SchemeLabel" > <Property Name="Text" Value="Scheme:" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.019553,0},{0.0836117,0},{0.114991,0},{0.146434,0}}" /> </Window> <Window Type="TaharezLook/Combobox" Name="PropertyFinder/SchemeList" > <Property Name="ReadOnly" Value="True" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.116201,0},{0.0836117,0},{0.440692,0},{0.84974,0}}" /> <Property Name="MaxEditTextLength" Value="1073741823" /> </Window> <Window Type="TaharezLook/StaticText" Name="PropertyFinder/WidgetLabel" > <Property Name="Text" Value="Widget:" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.473929,0},{0.0836117,0},{0.569368,0},{0.146434,0}}" /> </Window> <Window Type="TaharezLook/Combobox" Name="PropertyFinder/WidgetList" > <Property Name="ReadOnly" Value="True" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.570578,0},{0.0836117,0},{0.969551,0},{0.823935,0}}" /> <Property Name="MaxEditTextLength" Value="1073741823" /> </Window> <Window Type="TaharezLook/Listbox" Name="PropertyFinder/Properties" > <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.019553,0},{0.164195,0},{0.440692,0},{0.89201,0}}" /> </Window> <Window Type="TaharezLook/MultiLineEditbox" Name="PropertyFinder/Information" > <Property Name="Text" ></Property> <Property Name="ReadOnly" Value="True" /> <Property Name="MaxTextLength" Value="1073741823" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.473929,0},{0.164195,0},{0.969551,0},{0.89201,0}}" /> </Window> <Window Type="TaharezLook/Button" Name="PropertyFinder/Export" > <Property Name="Text" Value="Export" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.019553,0},{0.904265,0},{0.161971,0},{0.983649,0}}" /> </Window> <Window Type="TaharezLook/RadioButton" Name="PropertyFinder/ExportWiki" > <Property Name="Text" Value="Wiki" /> <Property Name="Selected" Value="True" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.186517,0},{0.904265,0},{0.251611,0},{0.981279,0}}" /> </Window> <Window Type="TaharezLook/RadioButton" Name="PropertyFinder/ExportHtml" > <Property Name="Text" Value="HTML" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.271818,0},{0.904265,0},{0.336911,0},{0.98128,0}}" /> </Window> <Window Type="TaharezLook/RadioButton" Name="PropertyFinder/ExportXml" > <Property Name="Text" Value="XML" /> <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" /> <Property Name="UnifiedAreaRect" Value="{{0.357547,0},{0.904265,0},{0.42264,0},{0.98128,0}}" /> </Window> </Window> </GUILayout>