PropertyFinder

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Revision as of 10:37, 3 March 2011 by Kulik (Talk | contribs)

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 the widgets within the Taharez scheme 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::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(),
                                      "<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>