window moving

This commit is contained in:
Eduardo Bart 2011-04-16 16:46:31 -03:00
parent 9b02312bf8
commit dc39c965cc
13 changed files with 102 additions and 33 deletions

View File

@ -180,21 +180,21 @@ enum EEvent {
EV_KEYBOARD = 2, EV_KEYBOARD = 2,
EV_DOWN = 4, EV_DOWN = 4,
EV_UP = 8, EV_UP = 8,
EV_MOUSE_MOVE = 32, EV_MOUSE_WHEEL = 16,
EV_MOUSE_WHEEL = 64, EV_MOUSE_LEFT = 32,
EV_MOUSE_LEFT = 128, EV_MOUSE_RIGHT = 64,
EV_MOUSE_RIGHT = 256, EV_MOUSE_MIDDLE = 128,
EV_MOUSE_MIDDLE = 512,
EV_TEXT_ENTER = EV_KEYBOARD | 1024, EV_TEXT_ENTER = EV_KEYBOARD | 256,
EV_KEY_DOWN = EV_KEYBOARD | EV_DOWN, EV_KEY_DOWN = EV_KEYBOARD | EV_DOWN,
EV_KEY_UP = EV_KEYBOARD | EV_UP, EV_KEY_UP = EV_KEYBOARD | EV_UP,
EV_MOUSE_LDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_LEFT, EV_MOUSE_MOVE = EV_MOUSE | 512,
EV_MOUSE_LUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_LEFT, EV_MOUSE_LDOWN = EV_MOUSE | EV_MOUSE_LEFT | EV_DOWN,
EV_MOUSE_MDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_MIDDLE, EV_MOUSE_LUP = EV_MOUSE | EV_MOUSE_LEFT | EV_UP,
EV_MOUSE_MUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_MIDDLE, EV_MOUSE_MDOWN = EV_MOUSE | EV_MOUSE_MIDDLE | EV_DOWN,
EV_MOUSE_RDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_RIGHT, EV_MOUSE_MUP = EV_MOUSE | EV_MOUSE_MIDDLE | EV_UP,
EV_MOUSE_RUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_RIGHT, 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_UP = EV_MOUSE | EV_MOUSE_WHEEL | EV_UP,
EV_MOUSE_WHEEL_DOWN = EV_MOUSE | EV_MOUSE_WHEEL | EV_DOWN EV_MOUSE_WHEEL_DOWN = EV_MOUSE | EV_MOUSE_WHEEL | EV_DOWN
}; };
@ -202,6 +202,7 @@ enum EEvent {
struct InputEvent { struct InputEvent {
int type; int type;
Point mousePos; Point mousePos;
Point mouseMoved;
char keychar; char keychar;
uchar keycode; uchar keycode;
bool ctrl; bool ctrl;

View File

@ -589,7 +589,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
{ {
inputEvent.type = EV_MOUSE_MOVE; 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); g_engine.onInputEvent(inputEvent);
break; break;
} }

View File

@ -390,10 +390,14 @@ void Platform::poll()
break; break;
case MotionNotify: case MotionNotify:
{
inputEvent.type = EV_MOUSE_MOVE; 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); g_engine.onInputEvent(inputEvent);
break; break;
}
case MapNotify: case MapNotify:
x11.visible = true; x11.visible = true;

View File

@ -105,24 +105,22 @@ void UIContainer::onInputEvent(const InputEvent& event)
// events should pass only when element is visible and enabled // events should pass only when element is visible and enabled
if(child->isEnabled() && child->isVisible()) { if(child->isEnabled() && child->isVisible()) {
if(event.type & EV_KEYBOARD) { if(event.type & EV_KEYBOARD) {
// keyboard events only go to focused elements // keyboard events only go to focused elements or containers
if(child == getFocusedElement()) { if(child->asUIContainer() || child == getFocusedElement()) {
shouldFire = true; shouldFire = true;
} }
// mouse events // mouse events
} else if(event.type & EV_MOUSE) { } else if(event.type & EV_MOUSE) {
// mouse down and wheel events only go to elements that contains the mouse position // 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) { if((event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) && !child->asUIContainer()) {
if(child->getRect().contains(event.mousePos)) { if(child->getRect().contains(event.mousePos)) {
// focus it // focus it
if(event.type == EV_MOUSE_LDOWN) if(event.type == EV_MOUSE_LDOWN && child->isFocusable())
setFocusedElement(child); setFocusedElement(child);
shouldFire = true; shouldFire = true;
} }
} } else {
// mouse move and mouse up events go to all elements shouldFire = true;
else {
shouldFire = false;
} }
} }
} }

View File

@ -77,3 +77,24 @@ UIElementPtr UIElement::backwardsGetElementById(const std::string& id)
element = getParent()->backwardsGetElementById(id); element = getParent()->backwardsGetElementById(id);
return element; 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);
}

View File

@ -52,6 +52,8 @@ public:
UIElementPtr backwardsGetElementById(const std::string& id); UIElementPtr backwardsGetElementById(const std::string& id);
void moveTo(Point pos);
bool setSkin(const std::string& skinName); bool setSkin(const std::string& skinName);
void setSkin(UIElementSkin *skin); void setSkin(UIElementSkin *skin);
UIElementSkin *getSkin() { return m_skin; } UIElementSkin *getSkin() { return m_skin; }
@ -71,6 +73,7 @@ public:
void setVisible(bool visible) { m_visible = visible; } void setVisible(bool visible) { m_visible = visible; }
bool isVisible() const { return m_visible; } bool isVisible() const { return m_visible; }
virtual bool isFocusable() const { return false; }
UI::EElementType getElementType() const { return m_type; } UI::EElementType getElementType() const { return m_type; }
UIElementPtr asUIElement() { return boost::static_pointer_cast<UIElement>(shared_from_this()); } UIElementPtr asUIElement() { return boost::static_pointer_cast<UIElement>(shared_from_this()); }

View File

@ -66,7 +66,7 @@ void UILayout::setRect(const Rect& rect)
m_rect = rect; m_rect = rect;
// rect updated, recalculate itself and anchored elements positions // rect updated, recalculate itself and anchored elements positions
recalculateLayout(); recalculateAnchoredLayout();
} }
bool UILayout::addAnchor(EAnchorType type, const AnchorLine& anchorLine) 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 // recalculate anchored elements positions
for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) { for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) {
UILayoutPtr element = (*it).lock(); UILayoutPtr element = (*it).lock();
if(element) if(element)
element->recalculateLayout(); element->recalculateLayout();
} }
// fire layotu update event
onLayoutRectChange(m_rect);
} }

View File

@ -114,6 +114,8 @@ protected:
private: private:
/// Recalculate itself and anchored elements positions /// Recalculate itself and anchored elements positions
void recalculateLayout(); void recalculateLayout();
/// Recalculate anchored elements positions
void recalculateAnchoredLayout();
void addAnchoredElement(UILayoutPtr anchoredElement); void addAnchoredElement(UILayoutPtr anchoredElement);
AnchorLine m_anchors[6]; AnchorLine m_anchors[6];

View File

@ -45,6 +45,10 @@ void UITextEdit::onInputEvent(const InputEvent& event)
m_textArea.moveCursor(true); m_textArea.moveCursor(true);
else if(event.keycode == KC_LEFT) else if(event.keycode == KC_LEFT)
m_textArea.moveCursor(false); 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_LDOWN) {
} else if(event.type == EV_MOUSE_LUP && getRect().contains(event.mousePos)) { } else if(event.type == EV_MOUSE_LUP && getRect().contains(event.mousePos)) {

View File

@ -37,13 +37,14 @@ public:
UITextEdit(); UITextEdit();
void onInputEvent(const InputEvent& event); void onInputEvent(const InputEvent& event);
void onLayoutRectChange(const Rect& rect);
void onFocusChange();
void setText(const std::string& text); void setText(const std::string& text);
const std::string& getText() const { return m_textArea.getText(); } const std::string& getText() const { return m_textArea.getText(); }
TextArea& getTextArea() { return m_textArea; } TextArea& getTextArea() { return m_textArea; }
void onLayoutRectChange(const Rect& rect); bool isFocusable() const { return true; }
void onFocusChange();
private: private:
TextArea m_textArea; TextArea m_textArea;

View File

@ -23,3 +23,25 @@
#include "uiwindow.h" #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<UIWindowSkin*>(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);
}
}
}

View File

@ -32,13 +32,17 @@ class UIWindow : public UIContainer
{ {
public: public:
UIWindow() : UIWindow() :
UIContainer(UI::Window) { } UIContainer(UI::Window),
m_moving(false) { }
void onInputEvent(const InputEvent& event);
void setTitle(const std::string& title) { m_title = title; } void setTitle(const std::string& title) { m_title = title; }
const std::string& getTitle() const { return m_title; } const std::string& getTitle() const { return m_title; }
private: private:
std::string m_title; std::string m_title;
bool m_moving;
}; };
typedef boost::shared_ptr<UIWindow> UIWindowPtr; typedef boost::shared_ptr<UIWindow> UIWindowPtr;

View File

@ -38,6 +38,8 @@ public:
void load(const YAML::Node& node); void load(const YAML::Node& node);
void draw(UIElement *element); void draw(UIElement *element);
int getHeadHeight() const { return m_headHeight; }
private: private:
ImagePtr m_headImage; ImagePtr m_headImage;
ImagePtr m_bodyImage; ImagePtr m_bodyImage;