PropertyFinder

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search

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>