Dialog System
From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
The default CEGUI implementation stores the currently specified values of the widgets such that closing and then reopening a window will redisplay those values. Presented here is a different approach, to allow values to be saved or cancelled.
Contents
WindowSystem.h
#ifndef _WindowSystem_h_
#define _WindowSystem_h_
#include "CEGUI.h"
#include "vector"
class WindowSystem
{
public:
WindowSystem();
enum WindowSystemEvents { open, ok, cancel, escape, apply, modified };
bool isModified(); // Return whether data within the window is modified
// Actions
virtual bool doOpen(); // Open the window
virtual bool doLoad(); // Assign the data into the widgets
virtual bool doSave(); // Assign the widgets into the data
virtual bool doClose(); // Close the window
void initialise(const CEGUI::String& window, bool visible, const CEGUI::String& parent = ""); // Initialise the window system
void bindEvent(const CEGUI::String& widget, const CEGUI::String& event, WindowSystem::WindowSystemEvents action); // Subscribe to window events
private:
// Events
bool onOpen(const CEGUI::EventArgs& e); // Open the window
bool onOk(const CEGUI::EventArgs& e); // Save the data and close the window
bool onCancel(const CEGUI::EventArgs& e); // Close the window
bool onEscape(const CEGUI::EventArgs& e); // Close the window
bool onApply(const CEGUI::EventArgs& e); // Save the data
bool onModified(const CEGUI::EventArgs& e); // A widget in the window has been modified
CEGUI::String m_parent; // Handle to the parent
CEGUI::String m_window; // Handle to the window
CEGUI::String m_apply; // Handle of the apply button
bool m_modal; // Whether the window is modal
bool m_modified; // Whether data within the window is modified
};
#endif // _WindowSystem_h_
WindowSystem.cpp
#include "WindowSystem.h"
#include "assert.h"
WindowSystem::WindowSystem()
{
m_modal = false;
}
bool WindowSystem::isModified()
{
// Return whether data within the window is modified
assert(!m_apply.empty() && "The isModified() function requires that you specify an \"Apply\" button");
return !CEGUI::WindowManager::getSingleton().getWindow(m_apply)->isDisabled();
}
bool WindowSystem::doOpen()
{
// Open the window
assert(!m_window.empty() && "You have forgotten to call initialise()");
if(m_modal)
{
// Displaying a modal window disables its parent
assert(!m_parent.empty() && "The value of m_modal or m_parent has become corrupted");
CEGUI::WindowManager::getSingleton().getWindow(m_parent)->setEnabled(false);
}
// Display the window
CEGUI::WindowManager::getSingleton().getWindow(m_window)->setVisible(true);
// Load the data into the widgets
return doLoad();
}
bool WindowSystem::doLoad()
{
// Populate the window widgets with data
// Note that this can also be used to simulate an undo for every widget
// present in the window
// Disable the apply button since there are no modifications
if(!m_apply.empty())
CEGUI::WindowManager::getSingleton().getWindow(m_apply)->setEnabled(false);
return true;
}
bool WindowSystem::doSave()
{
// Update the data with the inputs from the widgets
// Disable the apply button since there are no modifications
if(!m_apply.empty())
CEGUI::WindowManager::getSingleton().getWindow(m_apply)->setEnabled(false);
return true;
}
bool WindowSystem::doClose()
{
// Close the window
assert(!m_window.empty() && "You have forgotten to call initialise()");
if(m_modal)
{
// Closing a modal window enables its parent
assert(!m_parent.empty() && "The value of m_modal or m_parent has become corrupted");
CEGUI::WindowManager::getSingleton().getWindow(m_parent)->setEnabled(true);
}
CEGUI::WindowManager::getSingleton().getWindow(m_window)->setVisible(false);
return true;
}
void WindowSystem::initialise(const CEGUI::String& window, bool visible, const CEGUI::String& parent)
{
// Initialise the window system
// Specifying a parent makes this window modal
m_window = window;
CEGUI::WindowManager::getSingleton().getWindow(m_window)->setVisible(visible);
m_parent = parent;
m_modal = !m_parent.empty();
}
void WindowSystem::bindEvent(const CEGUI::String& widget, const CEGUI::String& widgetEvent, WindowSystemEvents action)
{
// Subscribe to events
CEGUI::Window* widgetHandle = CEGUI::WindowManager::getSingleton().getWindow(widget);
switch(action)
{
case open:
widgetHandle->subscribeEvent(widgetEvent, CEGUI::Event::Subscriber(&WindowSystem::onOpen, this));
break;
case ok:
widgetHandle->subscribeEvent(widgetEvent, CEGUI::Event::Subscriber(&WindowSystem::onOk, this));
break;
case cancel:
widgetHandle->subscribeEvent(widgetEvent, CEGUI::Event::Subscriber(&WindowSystem::onCancel, this));
break;
case escape:
widgetHandle->subscribeEvent(widgetEvent, CEGUI::Event::Subscriber(&WindowSystem::onEscape, this));
break;
case apply:
widgetHandle->subscribeEvent(widgetEvent, CEGUI::Event::Subscriber(&WindowSystem::onApply, this));
m_apply = widget;
break;
case modified:
if(!m_apply.empty())
widgetHandle->subscribeEvent(widgetEvent, CEGUI::Event::Subscriber(&WindowSystem::onModified, this));
break;
}
}
bool WindowSystem::onOpen(const CEGUI::EventArgs& e)
{
// Open the window
return doOpen();
}
bool WindowSystem::onOk(const CEGUI::EventArgs& e)
{
// The 'ok' button was pressed
// Respond by saving the data and closing the window
return doSave() && doClose();
}
bool WindowSystem::onCancel(const CEGUI::EventArgs& e)
{
// The 'cancel' button was pressed
// Respond by closing the window without saving the data
return doClose();
}
bool WindowSystem::onEscape(const CEGUI::EventArgs& e)
{
// The 'escape' key was pressed
// Respond by closing the dialog without saving the data
// Note that Win32AppHelper::doDirectInputEvents() intercepts this key
// This means that the escape key will NOT reach here
const CEGUI::KeyEventArgs& keyArgs = static_cast<const CEGUI::KeyEventArgs&>(e);
if(keyArgs.scancode == CEGUI::Key::Escape)
{
return doClose();
}
else
return false;
}
bool WindowSystem::onApply(const CEGUI::EventArgs& e)
{
// The 'apply' button was pressed
// Respond by saving the data without closing the window
return doSave();
}
bool WindowSystem::onModified(const CEGUI::EventArgs& e)
{
// A widget within the window was modified
// Respond by enabling the 'apply' button
CEGUI::WindowManager::getSingleton().getWindow(m_apply)->setEnabled(true);
return true;
}
WindowingSystemDemo.h
#ifndef _WindowingSystemDemo_h_
#define _WindowingSystemDemo_h_
#include "CEGuiSample.h"
#include "CEGUI.h"
#include "DemoUtils.h"
#include "WindowSystem.h"
class SimpleWindow : public WindowSystem
{
public:
void initWindow()
{
// Initialise the window
using namespace CEGUI;
// Initialise the windowing system
WindowSystem::initialise("winSimpleWindow", // The handle of this window
false); // Initially invisible
// A modeless window does not have a parent
// Subscribe to widget events
// Note that the "close" button is set to behave as an "ok" button
WindowSystem::bindEvent( "Toolbar_btnSimpleWindow", PushButton::EventClicked, WindowSystem::open);
WindowSystem::bindEvent( "SimpleWindow_btnClose", PushButton::EventClicked, WindowSystem::ok);
// Subscribe to window events
WindowSystem::bindEvent("winSimpleWindow", FrameWindow::EventCloseClicked, WindowSystem::cancel); // The 'X' button was clicked
WindowSystem::bindEvent("winSimpleWindow", FrameWindow::EventKeyDown, WindowSystem::escape); // The 'escape' key was pressed
}
protected:
bool doLoad()
{
// Handle the load action by placing data into widgets
CEGUI::WindowManager::getSingleton().getWindow("SimpleWindow_edtValue")->setText(dataString);
return WindowSystem::doLoad();
}
bool doSave()
{
// Handle the save action by moving widget data into variables
dataString = CEGUI::WindowManager::getSingleton().getWindow("SimpleWindow_edtValue")->getText();
return WindowSystem::doSave();
}
private:
CEGUI::String dataString; // Variable associated with the Editbox
};
//////////////////////////////////////////////
class SimpleDialog : public WindowSystem
{
public:
void initWindow()
{
// Initialise the dialog
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
// Initialise the windowing system
WindowSystem::initialise("dlgSimpleDialog", // The handle of this window
false, // Initially invisible
"winToolbar"); // The handle of its parent, making it a modal dialog
// Subscribe to widget events
WindowSystem::bindEvent( "Toolbar_btnSimpleDialog", PushButton::EventClicked, WindowSystem::open);
WindowSystem::bindEvent( "SimpleDialog_btnOk", PushButton::EventClicked, WindowSystem::ok);
WindowSystem::bindEvent( "SimpleDialog_btnCancel", PushButton::EventClicked, WindowSystem::cancel);
WindowSystem::bindEvent( "SimpleDialog_btnApply", PushButton::EventClicked, WindowSystem::apply);
// These events trigger a 'modified' event, activating the 'apply' button
WindowSystem::bindEvent( "SimpleDialog_edtValue", Editbox::EventTextChanged, WindowSystem::modified);
// Subscribe to window events
// Pressing the 'X' button will behave as a cancel
WindowSystem::bindEvent( "dlgSimpleDialog", FrameWindow::EventCloseClicked, WindowSystem::cancel); // The 'X' button was clicked
WindowSystem::bindEvent( "dlgSimpleDialog", FrameWindow::EventKeyDown, WindowSystem::escape); // The 'escape' key was pressed
}
protected:
bool doLoad()
{
// Handle the load action by placing data into widgets
CEGUI::WindowManager::getSingleton().getWindow("SimpleDialog_edtValue")->setText(dataString);
return WindowSystem::doLoad();
}
bool doSave()
{
// Handle the save action by moving widget data into variables
dataString = CEGUI::WindowManager::getSingleton().getWindow("SimpleDialog_edtValue")->getText();
return WindowSystem::doSave();
}
private:
CEGUI::String dataString;
};
//////////////////////////////////////////
class DemoSample : public CEGuiSample
{
public:
bool initialiseSample()
{
using namespace CEGUI;
try
{
initDemo("../datafiles/layouts/WindowingSystem.layout");
// Initialise the Simple Window and the Simple Dialog
simpleWindow.initWindow();
simpleDialog.initWindow();
}
catch(Exception &e)
{
ErrorMessage(e.getMessage().c_str(), "Error initializing the demo");
}
return true;
}
void cleanupSample(void)
{
}
private:
SimpleWindow simpleWindow;
SimpleDialog simpleDialog;
};
#endif // _WindowingSystemDemo_h_
main.cpp
#if defined( __WIN32__ ) || defined( _WIN32 )
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include "windows.h"
#endif
#include "WindowingSystemDemo.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;
return app.run();
}
WindowingSystem.layout
<?xml version="1.0" encoding="UTF-8"?>
<GUILayout>
<Window Type="DefaultWindow" Name="Root" >
<Property Name="UnifiedAreaRect" Value="{{0.000000,0.000000},{0.000000,0.000000},{1.000000,0.000000},{1.000000,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
<Window Type="TaharezLook/FrameWindow" Name="winToolbar" >
<Property Name="AlwaysOnTop" Value="True" />
<Property Name="CaptionColour" Value="00FFFFFF" />
<Property Name="CloseButtonEnabled" Value="False" />
<Property Name="EWSizingCursorImage" Value="set:TaharezLook image:MouseEsWeCursor" />
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseTarget" />
<Property Name="NESWSizingCursorImage" Value="set:TaharezLook image:MouseNeSwCursor" />
<Property Name="NSSizingCursorImage" Value="set:TaharezLook image:MouseNoSoCursor" />
<Property Name="NWSESizingCursorImage" Value="set:TaharezLook image:MouseNwSeCursor" />
<Property Name="Text" Value="Toolbar" />
<Property Name="TitlebarEnabled" Value="False" />
<Property Name="TitlebarFont" Value="Commonwealth-10" />
<Property Name="UnifiedAreaRect" Value="{{0.248750,0.000000},{0.010001,0.000000},{0.568749,0.000000},{0.081667,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
<Window Type="TaharezLook/Button" Name="Toolbar_btnSimpleWindow" >
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseArrow" />
<Property Name="Text" Value="Simple Window" />
<Property Name="UnifiedAreaRect" Value="{{0.065103,0.000000},{0.227595,0.000000},{0.475554,0.000000},{0.686899,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
<Window Type="TaharezLook/Button" Name="Toolbar_btnSimpleDialog" >
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseArrow" />
<Property Name="Text" Value="Simple Dialog" />
<Property Name="UnifiedAreaRect" Value="{{0.538253,0.000000},{0.227595,0.000000},{0.948703,0.000000},{0.686899,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
</Window>
<Window Type="TaharezLook/FrameWindow" Name="winSimpleWindow" >
<Property Name="CaptionColour" Value="00FFFFFF" />
<Property Name="EWSizingCursorImage" Value="set:TaharezLook image:MouseEsWeCursor" />
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseTarget" />
<Property Name="NESWSizingCursorImage" Value="set:TaharezLook image:MouseNeSwCursor" />
<Property Name="NSSizingCursorImage" Value="set:TaharezLook image:MouseNoSoCursor" />
<Property Name="NWSESizingCursorImage" Value="set:TaharezLook image:MouseNwSeCursor" />
<Property Name="Text" Value="Simple Window" />
<Property Name="TitlebarEnabled" Value="True" />
<Property Name="TitlebarFont" Value="Commonwealth-10" />
<Property Name="UnifiedAreaRect" Value="{{0.005000,0.000000},{0.168333,0.000000},{0.420000,0.000000},{0.511666,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
<Window Type="TaharezLook/Button" Name="SimpleWindow_btnClose" >
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseArrow" />
<Property Name="Text" Value="Close" />
<Property Name="UnifiedAreaRect" Value="{{0.688554,0.000000},{0.804855,0.000000},{0.938554,0.000000},{0.943204,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
<Window Type="TaharezLook/StaticText" Name="SimpleWindow_lblValue" >
<Property Name="BackgroundImage" Value="set:TaharezLook image:StaticBackdrop" />
<Property Name="BottomFrameImage" Value="set:TaharezLook image:StaticBottom" />
<Property Name="BottomLeftFrameImage" Value="set:TaharezLook image:StaticBottomLeft" />
<Property Name="BottomRightFrameImage" Value="set:TaharezLook image:StaticBottomRight" />
<Property Name="Font" Value="Commonwealth-10" />
<Property Name="LeftFrameImage" Value="set:TaharezLook image:StaticLeft" />
<Property Name="RightFrameImage" Value="set:TaharezLook image:StaticRight" />
<Property Name="Text" Value="Value:" />
<Property Name="TopFrameImage" Value="set:TaharezLook image:StaticTop" />
<Property Name="TopLeftFrameImage" Value="set:TaharezLook image:StaticTopLeft" />
<Property Name="TopRightFrameImage" Value="set:TaharezLook image:StaticTopRight" />
<Property Name="UnifiedAreaRect" Value="{{0.455591,0.000000},{0.430746,0.000000},{0.606068,0.000000},{0.569095,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
<Window Type="TaharezLook/Editbox" Name="SimpleWindow_edtValue" >
<Property Name="Font" Value="Commonwealth-10" />
<Property Name="MaxTextLength" Value="1073741823" />
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseTextBar" />
<Property Name="UnifiedAreaRect" Value="{{0.618241,0.000000},{0.430746,0.000000},{0.970525,0.000000},{0.569095,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
</Window>
<Window Type="TaharezLook/FrameWindow" Name="dlgSimpleDialog" >
<Property Name="CaptionColour" Value="00FFFFFF" />
<Property Name="EWSizingCursorImage" Value="set:TaharezLook image:MouseEsWeCursor" />
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseTarget" />
<Property Name="NESWSizingCursorImage" Value="set:TaharezLook image:MouseNeSwCursor" />
<Property Name="NSSizingCursorImage" Value="set:TaharezLook image:MouseNoSoCursor" />
<Property Name="NWSESizingCursorImage" Value="set:TaharezLook image:MouseNwSeCursor" />
<Property Name="Text" Value="Simple Dialog" />
<Property Name="TitlebarEnabled" Value="True" />
<Property Name="TitlebarFont" Value="Commonwealth-10" />
<Property Name="UnifiedAreaRect" Value="{{0.436250,0.000000},{0.165000,0.000000},{0.916249,0.000000},{0.508333,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
<Window Type="TaharezLook/Button" Name="SimpleDialog_btnOk" >
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseArrow" />
<Property Name="Text" Value="Ok" />
<Property Name="UnifiedAreaRect" Value="{{0.173754,0.000000},{0.804855,0.000000},{0.423754,0.000000},{0.943204,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
<Window Type="TaharezLook/Button" Name="SimpleDialog_btnCancel" >
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseArrow" />
<Property Name="Text" Value="Cancel" />
<Property Name="UnifiedAreaRect" Value="{{0.451828,0.000000},{0.804855,0.000000},{0.701828,0.000000},{0.943204,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
<Window Type="TaharezLook/Button" Name="SimpleDialog_btnApply" >
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseArrow" />
<Property Name="Text" Value="Apply" />
<Property Name="UnifiedAreaRect" Value="{{0.731230,0.000000},{0.804855,0.000000},{0.981230,0.000000},{0.943204,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
<Window Type="TaharezLook/Editbox" Name="SimpleDialog_edtValue" >
<Property Name="Font" Value="Commonwealth-10" />
<Property Name="MaxTextLength" Value="1073741823" />
<Property Name="MouseCursorImage" Value="set:TaharezLook image:MouseTextBar" />
<Property Name="UnifiedAreaRect" Value="{{0.626093,0.000000},{0.418446,0.000000},{0.971449,0.000000},{0.556795,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
<Window Type="TaharezLook/StaticText" Name="SimpleDialog_lblValue" >
<Property Name="BackgroundImage" Value="set:TaharezLook image:StaticBackdrop" />
<Property Name="BottomFrameImage" Value="set:TaharezLook image:StaticBottom" />
<Property Name="BottomLeftFrameImage" Value="set:TaharezLook image:StaticBottomLeft" />
<Property Name="BottomRightFrameImage" Value="set:TaharezLook image:StaticBottomRight" />
<Property Name="LeftFrameImage" Value="set:TaharezLook image:StaticLeft" />
<Property Name="RightFrameImage" Value="set:TaharezLook image:StaticRight" />
<Property Name="Text" Value="Value:" />
<Property Name="TopFrameImage" Value="set:TaharezLook image:StaticTop" />
<Property Name="TopLeftFrameImage" Value="set:TaharezLook image:StaticTopLeft" />
<Property Name="TopRightFrameImage" Value="set:TaharezLook image:StaticTopRight" />
<Property Name="UnifiedAreaRect" Value="{{0.482291,0.000000},{0.418446,0.000000},{0.617709,0.000000},{0.556795,0.000000}}" />
<Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
</Window>
</Window>
</Window>
</GUILayout>