PropertyFinder

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Revision as of 12:08, 26 July 2010 by Crazyeddie (Talk | contribs) (Fixes / updates for 0.7.x compatibility)

Jump to: navigation, search

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 the widgets within the Taharez scheme are presented in [SetProperty] and SetProperty (WindowsLook). The Cegui API also lists the properties.

Files

PropertyFinder.h

<cpp/>

  1. ifndef _PropertyFinder_h_
  2. define _PropertyFinder_h_
  1. include "CEGuiSample.h"
  2. include "CEGUI.h"
  3. include "CEGUIDefaultResourceProvider.h"
  1. include <stdio.h>
  2. include <iostream>
  3. include <map>
  4. include <vector>
  5. 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)
       {
  1. if defined( __WIN32__ ) || defined( _WIN32 )
           MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL);
  1. else
           std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n";
  1. 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::getSingletonPtr()->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::getSingletonPtr()->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(),
                                     "Falagard");
           }
           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};

};

  1. endif // _PropertyFinder_h_

Main.cpp

<cpp/>

  1. if defined( __WIN32__ ) || defined( _WIN32 )

#define WIN32_LEAN_AND_MEAN #define NOMINMAX #include "windows.h"

  1. endif
  1. include "PropertyFinder.h"
  1. if defined( __WIN32__ ) || defined( _WIN32 )

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow)

  1. else

int main(int argc, char *argv[])

  1. 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>