From dc39c965ccd03e4e061276f3ae02cc43d972b0d2 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Sat, 16 Apr 2011 16:46:31 -0300 Subject: [PATCH] window moving --- src/framework/core/input.h | 31 ++++++++++++------------ src/framework/platform/win32platform.cpp | 4 ++- src/framework/platform/x11platform.cpp | 6 ++++- src/framework/ui/uicontainer.cpp | 16 ++++++------ src/framework/ui/uielement.cpp | 21 ++++++++++++++++ src/framework/ui/uielement.h | 3 +++ src/framework/ui/uilayout.cpp | 13 +++++++--- src/framework/ui/uilayout.h | 2 ++ src/framework/ui/uitextedit.cpp | 4 +++ src/framework/ui/uitextedit.h | 5 ++-- src/framework/ui/uiwindow.cpp | 22 +++++++++++++++++ src/framework/ui/uiwindow.h | 6 ++++- src/framework/ui/uiwindowskin.h | 2 ++ 13 files changed, 102 insertions(+), 33 deletions(-) diff --git a/src/framework/core/input.h b/src/framework/core/input.h index 4bb25466..74fc9ebc 100644 --- a/src/framework/core/input.h +++ b/src/framework/core/input.h @@ -180,28 +180,29 @@ enum EEvent { EV_KEYBOARD = 2, EV_DOWN = 4, EV_UP = 8, - EV_MOUSE_MOVE = 32, - EV_MOUSE_WHEEL = 64, - EV_MOUSE_LEFT = 128, - EV_MOUSE_RIGHT = 256, - EV_MOUSE_MIDDLE = 512, + EV_MOUSE_WHEEL = 16, + EV_MOUSE_LEFT = 32, + EV_MOUSE_RIGHT = 64, + EV_MOUSE_MIDDLE = 128, - EV_TEXT_ENTER = EV_KEYBOARD | 1024, - EV_KEY_DOWN = EV_KEYBOARD | EV_DOWN, - EV_KEY_UP = EV_KEYBOARD | EV_UP, - EV_MOUSE_LDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_LEFT, - EV_MOUSE_LUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_LEFT, - EV_MOUSE_MDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_MIDDLE, - EV_MOUSE_MUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_MIDDLE, - EV_MOUSE_RDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_RIGHT, - EV_MOUSE_RUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_RIGHT, - EV_MOUSE_WHEEL_UP = EV_MOUSE | EV_MOUSE_WHEEL | EV_UP, + EV_TEXT_ENTER = EV_KEYBOARD | 256, + EV_KEY_DOWN = EV_KEYBOARD | EV_DOWN, + EV_KEY_UP = EV_KEYBOARD | EV_UP, + EV_MOUSE_MOVE = EV_MOUSE | 512, + EV_MOUSE_LDOWN = EV_MOUSE | EV_MOUSE_LEFT | EV_DOWN, + EV_MOUSE_LUP = EV_MOUSE | EV_MOUSE_LEFT | EV_UP, + EV_MOUSE_MDOWN = EV_MOUSE | EV_MOUSE_MIDDLE | EV_DOWN, + EV_MOUSE_MUP = EV_MOUSE | EV_MOUSE_MIDDLE | EV_UP, + EV_MOUSE_RDOWN = EV_MOUSE | EV_MOUSE_RIGHT | EV_DOWN, + EV_MOUSE_RUP = EV_MOUSE | EV_MOUSE_RIGHT | EV_UP, + EV_MOUSE_WHEEL_UP = EV_MOUSE | EV_MOUSE_WHEEL | EV_UP, EV_MOUSE_WHEEL_DOWN = EV_MOUSE | EV_MOUSE_WHEEL | EV_DOWN }; struct InputEvent { int type; Point mousePos; + Point mouseMoved; char keychar; uchar keycode; bool ctrl; diff --git a/src/framework/platform/win32platform.cpp b/src/framework/platform/win32platform.cpp index 4d65bfea..31a92813 100644 --- a/src/framework/platform/win32platform.cpp +++ b/src/framework/platform/win32platform.cpp @@ -589,7 +589,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: { inputEvent.type = EV_MOUSE_MOVE; - inputEvent.mousePos = Point(LOWORD(lParam), HIWORD(lParam)); + Point newMousePos(LOWORD(lParam), HIWORD(lParam)); + inputEvent.mouseMoved = newMousePos - inputEvent.mousePos; + inputEvent.mousePos = newMousePos; g_engine.onInputEvent(inputEvent); break; } diff --git a/src/framework/platform/x11platform.cpp b/src/framework/platform/x11platform.cpp index b7b1022e..7e7ae5cf 100644 --- a/src/framework/platform/x11platform.cpp +++ b/src/framework/platform/x11platform.cpp @@ -390,10 +390,14 @@ void Platform::poll() break; case MotionNotify: + { inputEvent.type = EV_MOUSE_MOVE; - inputEvent.mousePos = Point(event.xbutton.x, event.xbutton.y); + Point newMousePos(event.xbutton.x, event.xbutton.y); + inputEvent.mouseMoved = newMousePos - inputEvent.mousePos; + inputEvent.mousePos = newMousePos; g_engine.onInputEvent(inputEvent); break; + } case MapNotify: x11.visible = true; diff --git a/src/framework/ui/uicontainer.cpp b/src/framework/ui/uicontainer.cpp index 9b30765e..32c8aeaf 100644 --- a/src/framework/ui/uicontainer.cpp +++ b/src/framework/ui/uicontainer.cpp @@ -105,24 +105,22 @@ void UIContainer::onInputEvent(const InputEvent& event) // events should pass only when element is visible and enabled if(child->isEnabled() && child->isVisible()) { if(event.type & EV_KEYBOARD) { - // keyboard events only go to focused elements - if(child == getFocusedElement()) { + // keyboard events only go to focused elements or containers + if(child->asUIContainer() || child == getFocusedElement()) { shouldFire = true; } // mouse events } else if(event.type & EV_MOUSE) { - // mouse down and wheel events only go to elements that contains the mouse position - if(event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) { + // mouse down and wheel events only go to elements that contains the mouse position and are not containers + if((event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) && !child->asUIContainer()) { if(child->getRect().contains(event.mousePos)) { // focus it - if(event.type == EV_MOUSE_LDOWN) + if(event.type == EV_MOUSE_LDOWN && child->isFocusable()) setFocusedElement(child); shouldFire = true; } - } - // mouse move and mouse up events go to all elements - else { - shouldFire = false; + } else { + shouldFire = true; } } } diff --git a/src/framework/ui/uielement.cpp b/src/framework/ui/uielement.cpp index 772eac97..62958032 100644 --- a/src/framework/ui/uielement.cpp +++ b/src/framework/ui/uielement.cpp @@ -77,3 +77,24 @@ UIElementPtr UIElement::backwardsGetElementById(const std::string& id) element = getParent()->backwardsGetElementById(id); return element; } + +void UIElement::moveTo(Point pos) +{ + Rect newRect = getRect(); + newRect.moveTo(pos); + + // bound newRect to parent rect + UIContainerPtr parent = getParent(); + if(parent) { + Rect parentRect = parent->getRect(); + if(newRect.left() < parentRect.left()) + newRect.moveLeft(parentRect.left()); + if(newRect.top() < parentRect.top()) + newRect.moveTop(parentRect.top()); + if(newRect.bottom() > parentRect.bottom()) + newRect.moveBottom(parentRect.bottom()); + if(newRect.right() > parentRect.right()) + newRect.moveRight(parentRect.right()); + } + setRect(newRect); +} diff --git a/src/framework/ui/uielement.h b/src/framework/ui/uielement.h index 6d40d237..0f3d0cdd 100644 --- a/src/framework/ui/uielement.h +++ b/src/framework/ui/uielement.h @@ -52,6 +52,8 @@ public: UIElementPtr backwardsGetElementById(const std::string& id); + void moveTo(Point pos); + bool setSkin(const std::string& skinName); void setSkin(UIElementSkin *skin); UIElementSkin *getSkin() { return m_skin; } @@ -71,6 +73,7 @@ public: void setVisible(bool visible) { m_visible = visible; } bool isVisible() const { return m_visible; } + virtual bool isFocusable() const { return false; } UI::EElementType getElementType() const { return m_type; } UIElementPtr asUIElement() { return boost::static_pointer_cast(shared_from_this()); } diff --git a/src/framework/ui/uilayout.cpp b/src/framework/ui/uilayout.cpp index ea1a8138..299414b7 100644 --- a/src/framework/ui/uilayout.cpp +++ b/src/framework/ui/uilayout.cpp @@ -66,7 +66,7 @@ void UILayout::setRect(const Rect& rect) m_rect = rect; // rect updated, recalculate itself and anchored elements positions - recalculateLayout(); + recalculateAnchoredLayout(); } bool UILayout::addAnchor(EAnchorType type, const AnchorLine& anchorLine) @@ -141,14 +141,19 @@ void UILayout::recalculateLayout() } } + recalculateAnchoredLayout(); + + // fire layout update event + onLayoutRectChange(m_rect); +} + +void UILayout::recalculateAnchoredLayout() +{ // recalculate anchored elements positions for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) { UILayoutPtr element = (*it).lock(); if(element) element->recalculateLayout(); } - - // fire layotu update event - onLayoutRectChange(m_rect); } diff --git a/src/framework/ui/uilayout.h b/src/framework/ui/uilayout.h index de5fff7c..f757c323 100644 --- a/src/framework/ui/uilayout.h +++ b/src/framework/ui/uilayout.h @@ -114,6 +114,8 @@ protected: private: /// Recalculate itself and anchored elements positions void recalculateLayout(); + /// Recalculate anchored elements positions + void recalculateAnchoredLayout(); void addAnchoredElement(UILayoutPtr anchoredElement); AnchorLine m_anchors[6]; diff --git a/src/framework/ui/uitextedit.cpp b/src/framework/ui/uitextedit.cpp index 5c22b97d..c98a31c8 100644 --- a/src/framework/ui/uitextedit.cpp +++ b/src/framework/ui/uitextedit.cpp @@ -45,6 +45,10 @@ void UITextEdit::onInputEvent(const InputEvent& event) m_textArea.moveCursor(true); else if(event.keycode == KC_LEFT) m_textArea.moveCursor(false); + else if(event.keycode == KC_HOME) + m_textArea.setCursorPos(0); + else if(event.keycode == KC_END) + m_textArea.setCursorPos(m_textArea.getText().length()); } else if(event.type == EV_MOUSE_LDOWN) { } else if(event.type == EV_MOUSE_LUP && getRect().contains(event.mousePos)) { diff --git a/src/framework/ui/uitextedit.h b/src/framework/ui/uitextedit.h index eebf7abd..77b9bf4a 100644 --- a/src/framework/ui/uitextedit.h +++ b/src/framework/ui/uitextedit.h @@ -37,13 +37,14 @@ public: UITextEdit(); void onInputEvent(const InputEvent& event); + void onLayoutRectChange(const Rect& rect); + void onFocusChange(); void setText(const std::string& text); const std::string& getText() const { return m_textArea.getText(); } TextArea& getTextArea() { return m_textArea; } - void onLayoutRectChange(const Rect& rect); - void onFocusChange(); + bool isFocusable() const { return true; } private: TextArea m_textArea; diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp index 2fad0bfc..9a3915db 100644 --- a/src/framework/ui/uiwindow.cpp +++ b/src/framework/ui/uiwindow.cpp @@ -23,3 +23,25 @@ #include "uiwindow.h" +#include "uiwindowskin.h" + +void UIWindow::onInputEvent(const InputEvent& event) +{ + UIContainer::onInputEvent(event); + if(event.type == EV_MOUSE_LDOWN) { + UIWindowSkin *skin = static_cast(getSkin()); + Rect headRect = getRect(); + headRect.setHeight(skin->getHeadHeight()); + if(headRect.contains(event.mousePos)) { + m_moving = true; + } + } else if(event.type == EV_MOUSE_LUP) { + if(m_moving) { + m_moving = false; + } + } else if(event.type == EV_MOUSE_MOVE) { + if(m_moving) { + moveTo(getRect().topLeft() + event.mouseMoved); + } + } +} diff --git a/src/framework/ui/uiwindow.h b/src/framework/ui/uiwindow.h index 6fe5b0e4..bd4b14e6 100644 --- a/src/framework/ui/uiwindow.h +++ b/src/framework/ui/uiwindow.h @@ -32,13 +32,17 @@ class UIWindow : public UIContainer { public: UIWindow() : - UIContainer(UI::Window) { } + UIContainer(UI::Window), + m_moving(false) { } + + void onInputEvent(const InputEvent& event); void setTitle(const std::string& title) { m_title = title; } const std::string& getTitle() const { return m_title; } private: std::string m_title; + bool m_moving; }; typedef boost::shared_ptr UIWindowPtr; diff --git a/src/framework/ui/uiwindowskin.h b/src/framework/ui/uiwindowskin.h index cd968bdd..f6a0e59c 100644 --- a/src/framework/ui/uiwindowskin.h +++ b/src/framework/ui/uiwindowskin.h @@ -38,6 +38,8 @@ public: void load(const YAML::Node& node); void draw(UIElement *element); + int getHeadHeight() const { return m_headHeight; } + private: ImagePtr m_headImage; ImagePtr m_bodyImage;