Moving any Window

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

Written for CEGUI 0.5


Works with versions 0.5.x (obsolete)

Written for CEGUI 0.6


Works with versions 0.6.x (obsolete)

Written for CEGUI 0.7


Works with versions 0.7.x (obsolete)

Introduction

This bit of code shows how you can play with the CEGUI events to move any window, not just FrameWindows.

The current implementation listens for a right mouse click. When a CEGUI::Window* is right clicked it is flagged as being a "moving window". The GUI Sheet then subscribes to mouse move events, and upon a mouse movement event the "moving window"'s position is changed appropriately. Right clicking again releases the window.

A better implementation would be to have a border around the edge of the window. When the cursor would be positioned above that border it would display a moving cursor. Dragging (pressing down and holding the left mouse button) while above that border would move the window around.

Files

MovingAnyWindow.h

#ifndef _00MovingAnyWindow_h_
#define _00MovingAnyWindow_h_
 
#include "CEGuiSample.h"
#include "CEGUI.h"
 
class DemoSample : public CEGuiSample
{
public:
    // method to initialise the sample windows and events.
    bool initialiseSample()
	{
		using namespace CEGUI;
		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().loadScheme("TaharezLook.scheme");
			System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");
			if(!FontManager::getSingleton().isFontPresent("Commonwealth-10"))
				FontManager::getSingleton().createFont("Commonwealth-10.font");
 
			// Set the GUI Sheet
			Window* sheet = winMgr.createWindow("DefaultWindow", "root_wnd");
			System::getSingleton().setGUISheet(sheet);
 
			// Initially we are not moving any window
			mMovingWindow = 0;
 
			// We have not yet clicked on the button
			mClickCount = 0;
 
			// Create a button
			PushButton* pushButton = static_cast<PushButton*>(winMgr.createWindow("TaharezLook/Button", "Pushbutton"));
			sheet->addChildWindow(pushButton);
			pushButton->setPosition(UVector2(cegui_reldim(0.81f), cegui_reldim( 0.32f)));
			pushButton->setSize(UVector2(cegui_reldim(0.15f), cegui_reldim( 0.2f)));
			pushButton->setText("Click");
			pushButton->subscribeEvent(CEGUI::PushButton::EventMouseClick, Event::Subscriber(&DemoSample::onRightClick,	this));
			pushButton->subscribeEvent(CEGUI::PushButton::EventClicked, Event::Subscriber(&DemoSample::onLeftClick,		this));
 
			// Create a multicolum list
			MultiColumnList* mcl = static_cast<MultiColumnList*>(winMgr.createWindow("TaharezLook/MultiColumnList", "MultiColumnList"));
			sheet->addChildWindow(mcl);
			mcl->setPosition(UVector2(cegui_reldim(0.01f), cegui_reldim( 0.1f)));
			mcl->setSize(UVector2(cegui_reldim(0.5f), cegui_reldim( 0.8f)));
			mcl->subscribeEvent(CEGUI::MultiColumnList::EventMouseClick, Event::Subscriber(&DemoSample::onRightClick,	this));
		}
		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;
	}
 
    // method to perform any required cleanup operations.
    void cleanupSample(void)
	{
	}
 
	bool onRightClick(const CEGUI::EventArgs& pEventArgs)
	{
		using namespace CEGUI;
		const MouseEventArgs mouseEventArgs = static_cast<const MouseEventArgs&>(pEventArgs);
		if(mouseEventArgs.button == CEGUI::RightButton)
		{
			if(mMovingWindow)
			{
				// We were moving a window, stop doing so on a second right click
				mMovingEvent->disconnect();
				mMovingWindow = 0;
			}
			else
			{
				// Start moving a window when right clicking
				const WindowEventArgs windowEventArgs = static_cast<const WindowEventArgs&>(pEventArgs);
				mMovingWindow = windowEventArgs.window;
				mMovingEvent = System::getSingleton().getGUISheet()->subscribeEvent(CEGUI::Window::EventMouseMove, Event::Subscriber(&DemoSample::onWindowMove,	this));
				mMousePosInWindow = CoordConverter::screenToWindow(*mMovingWindow, MouseCursor::getSingleton().getPosition());
			}
			return false; // Do not propagate this event to other subscribers
		}
		return true;
	}
 
	bool onLeftClick(const CEGUI::EventArgs& pEventArgs)
	{
		// This is to check that the event is not propagated
		using namespace CEGUI;
		const WindowEventArgs windowEventArgs = static_cast<const WindowEventArgs&>(pEventArgs);
		++mClickCount;
		windowEventArgs.window->setText("Click " + CEGUI::PropertyHelper::intToString(mClickCount));
		return true;
	}
 
	bool onWindowMove(const CEGUI::EventArgs& pEventArgs)
	{
		using namespace CEGUI;
		const MouseEventArgs mouseEventArgs = static_cast<const MouseEventArgs&>(pEventArgs);
		Vector2 localMousePos = CoordConverter::screenToWindow(*mMovingWindow, mouseEventArgs.position);
		UVector2 mouseMoveOffset(cegui_absdim(localMousePos.d_x), cegui_absdim(localMousePos.d_y));
		UVector2 mouseOffsetInWindow(cegui_absdim(mMousePosInWindow.d_x), cegui_absdim(mMousePosInWindow.d_y));
		mMovingWindow->setPosition(mMovingWindow->getPosition() + mouseMoveOffset - mouseOffsetInWindow);
		return true;
	}
 
private:
	CEGUI::Window* mMovingWindow;
	CEGUI::Event::Connection mMovingEvent;
	CEGUI::Vector2 mMousePosInWindow;
	int mClickCount;
};
 
#endif // _00MovingAnyWindow_h_

main.cpp

#if defined( __WIN32__ ) || defined( _WIN32 )
	#define WIN32_LEAN_AND_MEAN
	#define NOMINMAX
	#include "windows.h"
#endif
 
#include "MovingAnyWindow.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();
}