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,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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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);
}

View File

@ -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<UIElement>(shared_from_this()); }

View File

@ -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);
}

View File

@ -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];

View File

@ -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)) {

View File

@ -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;

View File

@ -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<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:
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<UIWindow> UIWindowPtr;

View File

@ -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;