Dialog System

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Revision as of 07:08, 1 May 2006 by Rackle (Talk | contribs)

Jump to: navigation, search

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.

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>