Moving any Window
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(); }