remake widgets's anchor layouts

This commit is contained in:
Eduardo Bart 2011-08-21 16:43:05 -03:00
parent b410921e32
commit f266b9fbc6
23 changed files with 365 additions and 364 deletions

View File

@ -128,7 +128,6 @@ SET(SOURCES
src/framework/ui/uibutton.cpp src/framework/ui/uibutton.cpp
src/framework/ui/uilineedit.cpp src/framework/ui/uilineedit.cpp
src/framework/ui/uiwindow.cpp src/framework/ui/uiwindow.cpp
src/framework/ui/uianchorlayout.cpp
src/framework/ui/uianchor.cpp src/framework/ui/uianchor.cpp
src/framework/ui/uilist.cpp src/framework/ui/uilist.cpp
) )

View File

@ -1,4 +1,4 @@
-- AnchorPoint -- AnchorEdge
AnchorNone = 0 AnchorNone = 0
AnchorTop = 1 AnchorTop = 1
AnchorBottom = 2 AnchorBottom = 2

View File

@ -29,7 +29,7 @@ enum AlignmentFlag {
AlignCenter = AlignVerticalCenter | AlignHorizontalCenter AlignCenter = AlignVerticalCenter | AlignHorizontalCenter
}; };
enum AnchorPoint { enum AnchorEdge {
AnchorNone = 0, AnchorNone = 0,
AnchorTop, AnchorTop,
AnchorBottom, AnchorBottom,

View File

@ -5,27 +5,23 @@
#include "const.h" #include "const.h"
class UIManager; class UIManager;
class UILayout; class UIAnchor;
class UIAnchorLayout;
class UIStyle;
class UIWidget; class UIWidget;
class UILabel; class UILabel;
class UIButton; class UIButton;
class UILineEdit; class UILineEdit;
class UIWindow; class UIWindow;
class UIConsole;
typedef std::shared_ptr<UIWidget> UIWidgetPtr; typedef std::shared_ptr<UIWidget> UIWidgetPtr;
typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr; typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr;
typedef std::deque<UIWidgetPtr> UIWidgetList;
typedef std::shared_ptr<UILayout> UILayoutPtr;
typedef std::shared_ptr<UIAnchorLayout> UIAnchorLayoutPtr;
typedef std::shared_ptr<UIStyle> UIStylePtr;
typedef std::shared_ptr<UILabel> UILabelPtr; typedef std::shared_ptr<UILabel> UILabelPtr;
typedef std::shared_ptr<UIButton> UIButtonPtr; typedef std::shared_ptr<UIButton> UIButtonPtr;
typedef std::shared_ptr<UILineEdit> UILineEditPtr; typedef std::shared_ptr<UILineEdit> UILineEditPtr;
typedef std::shared_ptr<UIWindow> UIWindowPtr; typedef std::shared_ptr<UIWindow> UIWindowPtr;
typedef std::shared_ptr<UIConsole> UIConsolePtr;
typedef std::vector<UIAnchor> UIAnchorList;
typedef std::deque<UIWidgetPtr> UIWidgetList;
typedef std::deque<UIWidgetWeakPtr> UIWeakWidgetList;
#endif #endif

View File

@ -5,7 +5,6 @@
#include "uiwidget.h" #include "uiwidget.h"
#include "uibutton.h" #include "uibutton.h"
#include "uilabel.h" #include "uilabel.h"
#include "uilayout.h"
#include "uilineedit.h" #include "uilineedit.h"
#include "uiwindow.h" #include "uiwindow.h"

View File

@ -1,45 +1,31 @@
#include "uianchor.h" #include "uianchor.h"
#include "uiwidget.h" #include "uiwidget.h"
UIAnchor::UIAnchor(const UIWidgetPtr& anchoredWidget, AnchorPoint anchoredEdge, const AnchorLine& anchorLine) UIAnchor::UIAnchor(AnchorEdge anchoredEdge, const std::string& hookedWidgetId, AnchorEdge hookedEdge) :
: m_anchoredWidget(anchoredWidget), m_anchoredEdge(anchoredEdge), m_anchorLine(anchorLine) { m_anchoredEdge(anchoredEdge), m_hookedWidgetId(hookedWidgetId), m_hookedEdge(hookedEdge) {
} }
UIWidgetPtr UIAnchor::getAnchorLineWidget() const { int UIAnchor::getHookedPoint() const {
UIWidgetPtr anchoredWidget = m_anchoredWidget.lock(); UIWidgetPtr hookedWidget = getHookedWidget();
if(anchoredWidget && !anchoredWidget->isDestroyed())
return anchoredWidget->backwardsGetWidgetById(m_anchorLine.widgetId);
return nullptr;
}
if(hookedWidget) {
UIWidgetPtr UIAnchor::getAnchoredWidget() const { switch(m_hookedEdge) {
return m_anchoredWidget.lock();
}
AnchorPoint UIAnchor::getAnchoredEdge() const {
return m_anchoredEdge;
}
int UIAnchor::getAnchorLinePoint() const {
UIWidgetPtr anchorLineWidget = getAnchorLineWidget();
if(anchorLineWidget) {
switch(m_anchorLine.edge) {
case AnchorLeft: case AnchorLeft:
return anchorLineWidget->getGeometry().left(); return hookedWidget->getRect().left();
case AnchorRight: case AnchorRight:
return anchorLineWidget->getGeometry().right(); return hookedWidget->getRect().right();
case AnchorTop: case AnchorTop:
return anchorLineWidget->getGeometry().top(); return hookedWidget->getRect().top();
case AnchorBottom: case AnchorBottom:
return anchorLineWidget->getGeometry().bottom(); return hookedWidget->getRect().bottom();
case AnchorHorizontalCenter: case AnchorHorizontalCenter:
return anchorLineWidget->getGeometry().horizontalCenter(); return hookedWidget->getRect().horizontalCenter();
case AnchorVerticalCenter: case AnchorVerticalCenter:
return anchorLineWidget->getGeometry().verticalCenter(); return hookedWidget->getRect().verticalCenter();
default: default:
break; break;
} }
} }
return -9999;
return INVALID_POINT;
} }

View File

@ -3,25 +3,27 @@
#include "declarations.h" #include "declarations.h"
struct AnchorLine {
AnchorLine(std::string widgetId, AnchorPoint edge) : widgetId(widgetId), edge(edge) { }
std::string widgetId;
AnchorPoint edge;
};
class UIAnchor class UIAnchor
{ {
public: public:
UIAnchor(const UIWidgetPtr& anchoredWidget, AnchorPoint anchoredEdge, const AnchorLine& anchorLine); enum {
UIWidgetPtr getAnchorLineWidget() const; INVALID_POINT = -999999
UIWidgetPtr getAnchoredWidget() const; };
AnchorPoint getAnchoredEdge() const;
int getAnchorLinePoint() const; UIAnchor(AnchorEdge anchoredEdge, const std::string& hookedWidgetId, AnchorEdge hookedEdge);
AnchorEdge getAnchoredEdge() const { return m_anchoredEdge; }
UIWidgetPtr getHookedWidget() const { return m_hookedWidget.lock(); }
std::string getHookedWidgetId() const { return m_hookedWidgetId; }
int getHookedPoint() const;
void setHookedWidget(const UIWidgetPtr hookedWidget) { m_hookedWidget = hookedWidget; }
private: private:
UIWidgetWeakPtr m_anchoredWidget; AnchorEdge m_anchoredEdge;
AnchorPoint m_anchoredEdge; UIWidgetWeakPtr m_hookedWidget;
AnchorLine m_anchorLine; std::string m_hookedWidgetId;
AnchorEdge m_hookedEdge;
}; };
#endif #endif

View File

@ -1,123 +0,0 @@
#include "uianchorlayout.h"
#include "uiwidget.h"
bool UIAnchorLayout::addAnchor(const UIWidgetPtr& anchoredWidget, AnchorPoint anchoredEdge, const AnchorLine& anchorLine)
{
UIAnchor anchor(anchoredWidget, anchoredEdge, anchorLine);
UIWidgetPtr anchorLineWidget = anchor.getAnchorLineWidget();
/*
if(!anchorLineWidget) {
logError("could not find the widget to anchor on, wrong id?");
return false;
}
*/
// we can never anchor with itself
if(anchoredWidget == anchorLineWidget) {
logError("anchoring with itself is not possible");
return false;
}
// we must never anchor to an anchor child
if(anchoredWidget && hasWidgetInAnchorTree(anchorLineWidget, anchoredWidget)) {
logError("anchors is miss configured, you must never make an anchor chains in loops");
return false;
}
// avoid duplicated anchors
for(auto it = m_anchors.begin(); it != m_anchors.end(); ++it) {
const UIAnchor& otherAnchor = *it;
if(otherAnchor.getAnchoredWidget() == anchoredWidget && otherAnchor.getAnchoredEdge() == anchoredEdge) {
m_anchors.erase(it);
break;
}
}
// setup the anchor
m_anchors.push_back(anchor);
// recalculate anchored widget layout
updateWidget(anchoredWidget);
return true;
}
void UIAnchorLayout::updateWidget(const UIWidgetPtr& widget)
{
Rect rect = widget->getGeometry();
bool verticalMoved = false;
bool horizontalMoved = false;
// FIXME: release expired anchors
for(const UIAnchor& anchor : m_anchors) {
if(anchor.getAnchoredWidget() == widget && anchor.getAnchorLineWidget()) {
int point = anchor.getAnchorLinePoint();
switch(anchor.getAnchoredEdge()) {
case AnchorHorizontalCenter:
rect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight());
horizontalMoved = true;
break;
case AnchorLeft:
if(!horizontalMoved) {
rect.moveLeft(point + widget->getMarginLeft());
horizontalMoved = true;
} else
rect.setLeft(point + widget->getMarginLeft());
break;
case AnchorRight:
if(!horizontalMoved) {
rect.moveRight(point - widget->getMarginRight());
horizontalMoved = true;
} else
rect.setRight(point - widget->getMarginRight());
break;
case AnchorVerticalCenter:
rect.moveVerticalCenter(point + widget->getMarginTop() - widget->getMarginBottom());
verticalMoved = true;
break;
case AnchorTop:
if(!verticalMoved) {
rect.moveTop(point + widget->getMarginTop());
verticalMoved = true;
} else
rect.setTop(point + widget->getMarginTop());
break;
case AnchorBottom:
if(!verticalMoved) {
rect.moveBottom(point - widget->getMarginBottom());
verticalMoved = true;
} else
rect.setBottom(point - widget->getMarginBottom());
break;
default:
break;
}
}
}
if(rect != widget->getGeometry())
widget->setGeometry(rect);
}
void UIAnchorLayout::updateWidgetChildren(const UIWidgetPtr& parent)
{
for(const UIAnchor& anchor : m_anchors) {
if(anchor.getAnchorLineWidget() == parent) {
UIWidgetPtr child = anchor.getAnchoredWidget();
if(child)
updateWidget(child);
}
}
}
bool UIAnchorLayout::hasWidgetInAnchorTree(const UIWidgetPtr& widget, const UIWidgetPtr& treeAnchor)
{
for(const UIAnchor& anchor : m_anchors) {
if(anchor.getAnchorLineWidget() == treeAnchor) {
if(anchor.getAnchoredWidget() == widget || hasWidgetInAnchorTree(widget, anchor.getAnchoredWidget()))
return true;
}
}
return false;
}

View File

@ -1,20 +0,0 @@
#ifndef UIANCHORLAYOUT_H
#define UIANCHORLAYOUT_H
#include "uilayout.h"
#include "uianchor.h"
class UIAnchorLayout : public UILayout
{
public:
bool addAnchor(const UIWidgetPtr& anchoredWidget, AnchorPoint anchoredEdge, const AnchorLine& anchorLine);
void updateWidget(const UIWidgetPtr& widget);
void updateWidgetChildren(const UIWidgetPtr& parent);
bool hasWidgetInAnchorTree(const UIWidgetPtr& widget, const UIWidgetPtr& treeAnchor);
private:
std::list<UIAnchor> m_anchors;
};
#endif

View File

@ -63,7 +63,7 @@ void UIButton::render()
UIWidget::render(); UIWidget::render();
const ButtonStateStyle& currentStyle = m_statesStyle[m_state]; const ButtonStateStyle& currentStyle = m_statesStyle[m_state];
Rect textRect = getGeometry(); Rect textRect = getRect();
if(currentStyle.image) { if(currentStyle.image) {
g_graphics.bindColor(currentStyle.color); g_graphics.bindColor(currentStyle.color);
@ -93,7 +93,7 @@ void UIButton::onMousePress(UIMouseEvent& event)
void UIButton::onMouseRelease(UIMouseEvent& event) void UIButton::onMouseRelease(UIMouseEvent& event)
{ {
if(m_state == ButtonDown) { if(m_state == ButtonDown) {
if(m_onClick && getGeometry().contains(event.pos())) if(m_onClick && getRect().contains(event.pos()))
m_onClick(); m_onClick();
m_state = (isHovered() && isEnabled()) ? ButtonHover : ButtonUp; m_state = (isHovered() && isEnabled()) ? ButtonHover : ButtonUp;
} else } else

View File

@ -88,10 +88,10 @@ private:
bool m_hovered; bool m_hovered;
}; };
class UIGeometryUpdateEvent : public UIEvent class UIRectUpdateEvent : public UIEvent
{ {
public: public:
UIGeometryUpdateEvent(const Rect& oldRect, const Rect& rect) UIRectUpdateEvent(const Rect& oldRect, const Rect& rect)
: m_oldRect(oldRect), m_rect(rect) { } : m_oldRect(oldRect), m_rect(rect) { }
Point pos() const { return m_rect.topLeft(); } Point pos() const { return m_rect.topLeft(); }

View File

@ -1,2 +0,0 @@
#include "uilayout.h"

View File

@ -1,13 +0,0 @@
#ifndef UILAYOUT_H
#define UILAYOUT_H
#include "declarations.h"
class UILayout
{
public:
virtual void updateWidget(const UIWidgetPtr& widget) = 0;
virtual void updateWidgetChildren(const UIWidgetPtr& widget) = 0;
};
#endif

View File

@ -18,7 +18,6 @@ UILineEdit::UILineEdit() : UIWidget(UITypeLabel)
UILineEditPtr UILineEdit::create() UILineEditPtr UILineEdit::create()
{ {
UILineEditPtr lineEdit(new UILineEdit); UILineEditPtr lineEdit(new UILineEdit);
lineEdit->setStyle("LineEdit");
return lineEdit; return lineEdit;
} }
@ -38,13 +37,16 @@ void UILineEdit::render()
{ {
UIWidget::render(); UIWidget::render();
if(!m_rect.isValid())
return;
//TODO: text rendering could be much optimized by using vertex buffer or caching the render into a texture //TODO: text rendering could be much optimized by using vertex buffer or caching the render into a texture
int textLength = m_text.length(); int textLength = m_text.length();
const TexturePtr& texture = m_font->getTexture(); const TexturePtr& texture = m_font->getTexture();
for(int i=0;i<textLength;++i) {
for(int i=0;i<textLength;++i)
g_graphics.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]); g_graphics.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
}
// render cursor // render cursor
if(isExplicitlyEnabled() && hasFocus() && m_cursorPos >= 0) { if(isExplicitlyEnabled() && hasFocus() && m_cursorPos >= 0) {
@ -334,7 +336,7 @@ int UILineEdit::getTextPos(Point pos)
return candidatePos; return candidatePos;
} }
void UILineEdit::onGeometryUpdate(UIGeometryUpdateEvent& event) void UILineEdit::onRectUpdate(UIRectUpdateEvent& event)
{ {
update(); update();
} }

View File

@ -30,7 +30,7 @@ public:
int getTextPos(Point pos); int getTextPos(Point pos);
protected: protected:
virtual void onGeometryUpdate(UIGeometryUpdateEvent& event); virtual void onRectUpdate(UIRectUpdateEvent& event);
virtual void onFocusChange(UIFocusEvent& event); virtual void onFocusChange(UIFocusEvent& event);
virtual void onKeyPress(UIKeyEvent& event); virtual void onKeyPress(UIKeyEvent& event);
virtual void onMousePress(UIMouseEvent& event); virtual void onMousePress(UIMouseEvent& event);

View File

@ -1,6 +1,5 @@
#include "uimanager.h" #include "uimanager.h"
#include "ui.h" #include "ui.h"
#include "uianchorlayout.h"
#include <framework/otml/otml.h> #include <framework/otml/otml.h>
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
@ -13,9 +12,6 @@ void UIManager::init()
m_rootWidget = UIWidgetPtr(new UIWidget); m_rootWidget = UIWidgetPtr(new UIWidget);
m_rootWidget->setId("root"); m_rootWidget->setId("root");
m_rootWidget->setHovered(true); m_rootWidget->setHovered(true);
UIAnchorLayoutPtr anchorLayout(new UIAnchorLayout);
m_rootWidget->setLayout(anchorLayout);
m_rootWidget->resize(g_graphics.getScreenSize()); m_rootWidget->resize(g_graphics.getScreenSize());
} }
@ -187,7 +183,7 @@ UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode)
throw OTMLException(styleNode, "cannot determine widget type"); throw OTMLException(styleNode, "cannot determine widget type");
widget->loadStyleFromOTML(styleNode); widget->loadStyleFromOTML(styleNode);
widget->updateGeometry(); widget->updateLayout();
for(const OTMLNodePtr& childNode : widgetNode->children()) { for(const OTMLNodePtr& childNode : widgetNode->children()) {
if(!childNode->isUnique()) if(!childNode->isUnique())

View File

@ -1,7 +1,5 @@
#include "uiwidget.h" #include "uiwidget.h"
#include "uimanager.h" #include "uimanager.h"
#include "uilayout.h"
#include "uianchorlayout.h"
#include <framework/core/eventdispatcher.h> #include <framework/core/eventdispatcher.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
@ -9,6 +7,7 @@
#include <framework/graphics/fontmanager.h> #include <framework/graphics/fontmanager.h>
#include <framework/otml/otmlnode.h> #include <framework/otml/otmlnode.h>
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include "uianchor.h"
UIWidget::UIWidget(UIWidgetType type) UIWidget::UIWidget(UIWidgetType type)
{ {
@ -18,7 +17,10 @@ UIWidget::UIWidget(UIWidgetType type)
m_hovered = false; m_hovered = false;
m_focusable = true; m_focusable = true;
m_destroyed = false; m_destroyed = false;
m_updateScheduled = false; m_layoutUpdated = true;
m_updateEventScheduled = false;
m_layoutUpdateScheduled = false;
m_childrenLayoutUpdateScheduled = false;
m_opacity = 255; m_opacity = 255;
m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = 0; m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = 0;
m_backgroundColor = Color::white; m_backgroundColor = Color::white;
@ -158,7 +160,7 @@ void UIWidget::loadStyleFromOTML(const OTMLNodePtr& styleNode)
} else if(what == "centerIn") { } else if(what == "centerIn") {
centerIn(node->value()); centerIn(node->value());
} else { } else {
AnchorPoint myEdge = fw::translateAnchorPoint(what); AnchorEdge myEdge = fw::translateAnchorEdge(what);
std::string anchorDescription = node->value(); std::string anchorDescription = node->value();
std::vector<std::string> split; std::vector<std::string> split;
@ -167,15 +169,15 @@ void UIWidget::loadStyleFromOTML(const OTMLNodePtr& styleNode)
throw OTMLException(node, "invalid anchor description"); throw OTMLException(node, "invalid anchor description");
std::string target = split[0]; std::string target = split[0];
AnchorPoint targetEdge = fw::translateAnchorPoint(split[1]); AnchorEdge hookedEdge = fw::translateAnchorEdge(split[1]);
if(myEdge == AnchorNone) if(myEdge == AnchorNone)
throw OTMLException(node, "invalid anchor edge"); throw OTMLException(node, "invalid anchor edge");
if(targetEdge == AnchorNone) if(hookedEdge == AnchorNone)
throw OTMLException(node, "invalid anchor target edge"); throw OTMLException(node, "invalid anchor target edge");
addAnchor(myEdge, target, targetEdge); addAnchor(myEdge, target, hookedEdge);
} }
} }
else if(node->tag() == "onLoad") { else if(node->tag() == "onLoad") {
@ -190,7 +192,7 @@ void UIWidget::render()
assert(!m_destroyed); assert(!m_destroyed);
if(m_image) if(m_image)
m_image->draw(getGeometry()); m_image->draw(getRect());
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
if(child->isExplicitlyVisible()) { if(child->isExplicitlyVisible()) {
@ -203,23 +205,13 @@ void UIWidget::render()
// debug draw box // debug draw box
//g_graphics.bindColor(Color::green); //g_graphics.bindColor(Color::green);
//g_graphics.drawBoundingRect(child->getGeometry()); //g_graphics.drawBoundingRect(child->getRect());
g_graphics.setOpacity(oldOpacity); g_graphics.setOpacity(oldOpacity);
} }
} }
} }
void UIWidget::updateGeometry()
{
assert(!m_destroyed);
if(UILayoutPtr layout = getLayout()) {
layout->updateWidget(asUIWidget());
layout->updateWidgetChildren(asUIWidget());
}
}
void UIWidget::setParent(const UIWidgetPtr& parent) void UIWidget::setParent(const UIWidgetPtr& parent)
{ {
assert(!m_destroyed); assert(!m_destroyed);
@ -247,32 +239,33 @@ void UIWidget::setStyle(const std::string& styleName)
loadStyleFromOTML(styleNode); loadStyleFromOTML(styleNode);
// forces layout recalculation // forces layout recalculation
updateGeometry(); updateLayout();
} catch(std::exception& e) { } catch(std::exception& e) {
logError("couldn't change widget '", m_id, "' style: ", e.what()); logError("couldn't change widget '", m_id, "' style: ", e.what());
} }
} }
void UIWidget::setGeometry(const Rect& rect) void UIWidget::setRect(const Rect& rect)
{ {
assert(!m_destroyed); assert(!m_destroyed);
Rect oldRect = m_rect; Rect oldRect = m_rect;
m_rect = rect; m_rect = rect;
if(UILayoutPtr layout = getLayout())
layout->updateWidgetChildren(asUIWidget());
// avoid massive updates // updates children geometry
if(!m_updateScheduled) { updateChildrenLayout();
// avoid massive update events
if(!m_updateEventScheduled) {
UIWidgetPtr self = asUIWidget(); UIWidgetPtr self = asUIWidget();
g_dispatcher.addEvent([self, oldRect]() { g_dispatcher.addEvent([self, oldRect]() {
self->m_updateScheduled = false; self->m_updateEventScheduled = false;
UIGeometryUpdateEvent e(oldRect, self->getGeometry()); UIRectUpdateEvent e(oldRect, self->getRect());
// this widget could be destroyed before the event happens // this widget could be destroyed before the event happens
if(!self->isDestroyed()) if(!self->isDestroyed())
self->onGeometryUpdate(e); self->onRectUpdate(e);
}); });
m_updateScheduled = true; m_updateEventScheduled = true;
} }
} }
@ -310,16 +303,12 @@ bool UIWidget::hasChild(const UIWidgetPtr& child)
return false; return false;
} }
UILayoutPtr UIWidget::getLayout() const UIWidgetPtr UIWidget::getRootParent()
{ {
assert(!m_destroyed); if(UIWidgetPtr parent = getParent())
return parent->getRootParent();
if(m_layout) else
return m_layout; return asUIWidget();
else if(getParent() && getParent()->getLayout())
return getParent()->getLayout();
// fallback to root layout
return g_ui.getRootWidget()->getLayout();
} }
UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild) UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild)
@ -383,7 +372,7 @@ UIWidgetPtr UIWidget::getChildByPos(const Point& childPos)
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
const UIWidgetPtr& widget = (*it); const UIWidgetPtr& widget = (*it);
if(widget->isExplicitlyVisible() && widget->getGeometry().contains(childPos)) if(widget->isExplicitlyVisible() && widget->getRect().contains(childPos))
return widget; return widget;
} }
@ -399,35 +388,19 @@ UIWidgetPtr UIWidget::getChildByIndex(int childIndex)
return nullptr; return nullptr;
} }
UIWidgetPtr UIWidget::recursiveGetChildById(const std::string& childId) UIWidgetPtr UIWidget::recursiveGetChildById(const std::string& id)
{ {
assert(!m_destroyed); assert(!m_destroyed);
if(getId() == childId || childId == "self") UIWidgetPtr widget = getChildById(id);
return asUIWidget(); if(!widget) {
else if(childId == "parent")
return getParent();
else if(childId == "root")
return g_ui.getRootWidget();
else if(childId == "prev") {
if(UIWidgetPtr parent = getParent())
return parent->getChildBefore(asUIWidget());
} else if(childId == "next") {
if(UIWidgetPtr parent = getParent())
return parent->getChildAfter(asUIWidget());
} else {
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
if(child->getId() == childId) widget = child->recursiveGetChildById(id);
return child; if(widget)
} break;
for(const UIWidgetPtr& child : m_children) {
if(UIWidgetPtr subChild = child->recursiveGetChildById(childId)) {
if(subChild->getId() == childId)
return subChild;
}
} }
} }
return nullptr; return widget;
} }
UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos) UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos)
@ -435,7 +408,7 @@ UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos)
assert(!m_destroyed); assert(!m_destroyed);
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
if(child->getGeometry().contains(childPos)) { if(child->getRect().contains(childPos)) {
if(UIWidgetPtr subChild = child->recursiveGetChildByPos(childPos)) if(UIWidgetPtr subChild = child->recursiveGetChildByPos(childPos))
return subChild; return subChild;
return child; return child;
@ -449,27 +422,12 @@ UIWidgetPtr UIWidget::backwardsGetWidgetById(const std::string& id)
{ {
assert(!m_destroyed); assert(!m_destroyed);
UIWidgetPtr widget; UIWidgetPtr widget = getChildById(id);
if(getId() == id || id == "self") if(!widget) {
widget = asUIWidget();
else if(id == "parent")
widget = getParent();
else if(id == "root")
widget = g_ui.getRootWidget();
else if(id == "prev") {
if(UIWidgetPtr parent = getParent())
widget = parent->getChildBefore(asUIWidget());
} else if(id == "next") {
if(UIWidgetPtr parent = getParent())
widget = parent->getChildAfter(asUIWidget());
} else {
widget = recursiveGetChildById(id);
if(widget)
return widget;
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
widget = parent->backwardsGetWidgetById(id); widget = parent->backwardsGetWidgetById(id);
} }
return widget; return widget;
} }
@ -503,8 +461,11 @@ void UIWidget::addChild(const UIWidgetPtr& childToAdd)
m_children.push_back(childToAdd); m_children.push_back(childToAdd);
childToAdd->setParent(asUIWidget()); childToAdd->setParent(asUIWidget());
// updates geometry // recalculate anchors
updateGeometry(); getRootParent()->recalculateAnchoredWidgets();
// may need to update children layout
updateChildrenLayout();
// always focus new children // always focus new children
if(childToAdd->isFocusable()) if(childToAdd->isFocusable())
@ -529,8 +490,11 @@ void UIWidget::insertChild(const UIWidgetPtr& childToInsert, int index)
m_children.insert(it, childToInsert); m_children.insert(it, childToInsert);
childToInsert->setParent(asUIWidget()); childToInsert->setParent(asUIWidget());
// updates geometry // recalculate anchors
updateGeometry(); getRootParent()->recalculateAnchoredWidgets();
// may need to update children layout
updateChildrenLayout();
} }
void UIWidget::removeChild(const UIWidgetPtr& childToRemove) void UIWidget::removeChild(const UIWidgetPtr& childToRemove)
@ -555,6 +519,13 @@ void UIWidget::removeChild(const UIWidgetPtr& childToRemove)
// reset child parent // reset child parent
assert(childToRemove->getParent() == asUIWidget()); assert(childToRemove->getParent() == asUIWidget());
childToRemove->setParent(nullptr); childToRemove->setParent(nullptr);
// recalculate anchors
UIWidgetPtr parent = getRootParent();
parent->recalculateAnchoredWidgets();
// may need to update children layout
updateChildrenLayout();
} }
void UIWidget::focusNextChild(FocusReason reason) void UIWidget::focusNextChild(FocusReason reason)
@ -633,32 +604,227 @@ void UIWidget::unlockChild(const UIWidgetPtr& childToUnlock)
} }
} }
void UIWidget::addAnchor(AnchorPoint edge, const std::string& targetId, AnchorPoint targetEdge) void UIWidget::updateLayout()
{ {
assert(!m_destroyed); assert(!m_destroyed);
UIAnchorLayoutPtr layout = std::dynamic_pointer_cast<UIAnchorLayout>(getLayout()); if(!m_layoutUpdateScheduled) {
assert(layout); m_layoutUpdateScheduled = true;
if(layout) UIWidgetPtr self = asUIWidget();
layout->addAnchor(asUIWidget(), edge, AnchorLine(targetId, targetEdge)); g_dispatcher.addEvent([self] {
self->m_layoutUpdateScheduled = false;
if(!self->isDestroyed())
self->internalUpdateLayout();
});
}
} }
void UIWidget::centerIn(const std::string& targetId) void UIWidget::updateChildrenLayout()
{ {
assert(!m_destroyed); assert(!m_destroyed);
addAnchor(AnchorHorizontalCenter, targetId, AnchorHorizontalCenter); if(!m_childrenLayoutUpdateScheduled) {
addAnchor(AnchorVerticalCenter, targetId, AnchorVerticalCenter); m_childrenLayoutUpdateScheduled = true;
UIWidgetPtr self = asUIWidget();
g_dispatcher.addEvent([self] {
self->m_childrenLayoutUpdateScheduled = false;
if(!self->isDestroyed())
self->internalUpdateChildrenLayout();
});
}
} }
void UIWidget::fill(const std::string& targetId) bool UIWidget::addAnchor(AnchorEdge edge, const std::string& hookedWidgetId, AnchorEdge hookedEdge)
{ {
assert(!m_destroyed); assert(!m_destroyed);
addAnchor(AnchorLeft, targetId, AnchorLeft); UIAnchor anchor(edge, hookedWidgetId, hookedEdge);
addAnchor(AnchorRight, targetId, AnchorRight);
addAnchor(AnchorTop, targetId, AnchorTop); UIWidgetPtr hookedWidget = backwardsGetWidgetById(hookedWidgetId);
addAnchor(AnchorBottom, targetId, AnchorBottom); anchor.setHookedWidget(hookedWidget);
// we can never anchor with itself
if(hookedWidget == asUIWidget()) {
logError("anchoring with itself is not possible");
return false;
}
// we must never anchor to an anchor child
//TODO: this check
// duplicated anchors must be replaced
for(auto it = m_anchors.begin(); it != m_anchors.end(); ++it) {
const UIAnchor& otherAnchor = *it;
if(otherAnchor.getAnchoredEdge() == edge) {
m_anchors.erase(it);
break;
}
}
m_anchors.push_back(anchor);
updateLayout();
return true;
}
void UIWidget::centerIn(const std::string& hookedWidgetId)
{
assert(!m_destroyed);
addAnchor(AnchorHorizontalCenter, hookedWidgetId, AnchorHorizontalCenter);
addAnchor(AnchorVerticalCenter, hookedWidgetId, AnchorVerticalCenter);
}
void UIWidget::fill(const std::string& hookedWidgetId)
{
assert(!m_destroyed);
addAnchor(AnchorLeft, hookedWidgetId, AnchorLeft);
addAnchor(AnchorRight, hookedWidgetId, AnchorRight);
addAnchor(AnchorTop, hookedWidgetId, AnchorTop);
addAnchor(AnchorBottom, hookedWidgetId, AnchorBottom);
}
void UIWidget::internalUpdateLayout()
{
assert(!m_destroyed);
for(const UIAnchor& anchor : m_anchors) {
// ignore invalid anchors
if(!anchor.getHookedWidget())
continue;
// the update should only happens if the hooked widget is already updated
if(!anchor.getHookedWidget()->m_layoutUpdated)
return;
}
Rect newRect = m_rect;
bool verticalMoved = false;
bool horizontalMoved = false;
// calculate new rect based on anchors
for(const UIAnchor& anchor : m_anchors) {
int point = anchor.getHookedPoint();
// ignore invalid anchors
if(point == UIAnchor::INVALID_POINT)
continue;
switch(anchor.getAnchoredEdge()) {
case AnchorHorizontalCenter:
newRect.moveHorizontalCenter(point + getMarginLeft() - getMarginRight());
horizontalMoved = true;
break;
case AnchorLeft:
if(!horizontalMoved) {
newRect.moveLeft(point + getMarginLeft());
horizontalMoved = true;
} else
newRect.setLeft(point + getMarginLeft());
break;
case AnchorRight:
if(!horizontalMoved) {
newRect.moveRight(point - getMarginRight());
horizontalMoved = true;
} else
newRect.setRight(point - getMarginRight());
break;
case AnchorVerticalCenter:
newRect.moveVerticalCenter(point + getMarginTop() - getMarginBottom());
verticalMoved = true;
break;
case AnchorTop:
if(!verticalMoved) {
newRect.moveTop(point + getMarginTop());
verticalMoved = true;
} else
newRect.setTop(point + getMarginTop());
break;
case AnchorBottom:
if(!verticalMoved) {
newRect.moveBottom(point - getMarginBottom());
verticalMoved = true;
} else
newRect.setBottom(point - getMarginBottom());
break;
default:
break;
}
}
m_layoutUpdated = true;
// changes the rect only if really needed
if(newRect != m_rect) {
// setRect will update children layout too
setRect(newRect);
} else {
// update children
internalUpdateChildrenLayout();
}
}
void UIWidget::internalUpdateChildrenLayout()
{
assert(!m_destroyed);
// reset all children anchors update state
resetLayoutUpdateState(false);
// update children layouts
for(const UIWidgetWeakPtr& anchoredWidgetWeak : m_anchoredWidgets) {
if(UIWidgetPtr anchoredWidget = anchoredWidgetWeak.lock())
anchoredWidget->updateLayout();
}
}
void UIWidget::resetLayoutUpdateState(bool resetOwn)
{
if(resetOwn)
m_layoutUpdated = false;
// resets children layout update state too
for(const UIWidgetWeakPtr& anchoredWidgetWeak : m_anchoredWidgets) {
if(UIWidgetPtr anchoredWidget = anchoredWidgetWeak.lock())
anchoredWidget->resetLayoutUpdateState(true);
}
}
void UIWidget::addAnchoredWidget(const UIWidgetPtr& widget)
{
// prevent duplicated anchored widgets
for(const UIWidgetWeakPtr& anchoredWidget : m_anchoredWidgets)
if(anchoredWidget.lock() == widget)
return;
m_anchoredWidgets.push_back(widget);
}
void UIWidget::recalculateAnchoredWidgets()
{
clearAnchoredWidgets();
computeAnchoredWidgets();
}
void UIWidget::clearAnchoredWidgets()
{
m_anchoredWidgets.clear();
for(const UIWidgetPtr& child : m_children)
child->clearAnchoredWidgets();
}
void UIWidget::computeAnchoredWidgets()
{
// update anchors's hooked widget
for(UIAnchor& anchor : m_anchors) {
UIWidgetPtr hookedWidget = backwardsGetWidgetById(anchor.getHookedWidgetId());
anchor.setHookedWidget(hookedWidget);
if(hookedWidget)
hookedWidget->addAnchoredWidget(asUIWidget());
}
for(const UIWidgetPtr& child : m_children)
child->computeAnchoredWidgets();
} }
void UIWidget::onFocusChange(UIFocusEvent& event) void UIWidget::onFocusChange(UIFocusEvent& event)
@ -726,7 +892,7 @@ void UIWidget::onMousePress(UIMouseEvent& event)
continue; continue;
// mouse press events only go to children that contains the mouse position // mouse press events only go to children that contains the mouse position
if(child->getGeometry().contains(event.pos()) && child == getChildByPos(event.pos())) { if(child->getRect().contains(event.pos()) && child == getChildByPos(event.pos())) {
// focus it // focus it
if(child->isFocusable()) if(child->isFocusable())
focusChild(child, MouseFocusReason); focusChild(child, MouseFocusReason);
@ -775,7 +941,7 @@ void UIWidget::onMouseMove(UIMouseEvent& event)
// check if the mouse is relally over this child // check if the mouse is relally over this child
bool overChild = (isHovered() && bool overChild = (isHovered() &&
child->getGeometry().contains(event.pos()) && child->getRect().contains(event.pos()) &&
child == getChildByPos(event.pos())); child == getChildByPos(event.pos()));
if(overChild != child->isHovered()) { if(overChild != child->isHovered()) {
child->setHovered(overChild); child->setHovered(overChild);
@ -806,7 +972,7 @@ void UIWidget::onMouseWheel(UIMouseEvent& event)
continue; continue;
// mouse wheel events only go to children that contains the mouse position // mouse wheel events only go to children that contains the mouse position
if(child->getGeometry().contains(event.pos()) && child == getChildByPos(event.pos())) { if(child->getRect().contains(event.pos()) && child == getChildByPos(event.pos())) {
event.accept(); event.accept();
child->onMouseWheel(event); child->onMouseWheel(event);
} }

View File

@ -27,34 +27,30 @@ public:
/// Draw widget on screen /// Draw widget on screen
virtual void render(); virtual void render();
/// Notifies the layout system that this widget has changed and may need to change geometry
void updateGeometry();
void setEnabled(bool enable) { m_enabled = enable; } void setEnabled(bool enable) { m_enabled = enable; }
void setLayout(const UILayoutPtr& layout) { m_layout = layout; }
void setId(const std::string& id) { m_id = id; } void setId(const std::string& id) { m_id = id; }
void setFocusable(bool focusable) { m_focusable = focusable; } void setFocusable(bool focusable) { m_focusable = focusable; }
void setHovered(bool hovered) { m_hovered = hovered; } void setHovered(bool hovered) { m_hovered = hovered; }
void setVisible(bool visible) { m_visible = visible; } void setVisible(bool visible) { m_visible = visible; }
void setParent(const UIWidgetPtr& parent); void setParent(const UIWidgetPtr& parent);
void setStyle(const std::string& styleName); void setStyle(const std::string& styleName);
void setGeometry(const Rect& rect); void setRect(const Rect& rect);
void setX(int x) { move(Point(x, getY())); } void setX(int x) { move(Point(x, getY())); }
void setY(int y) { move(Point(getX(), y)); } void setY(int y) { move(Point(getX(), y)); }
void setWidth(int width) { resize(Size(width, getHeight())); } void setWidth(int width) { resize(Size(width, getHeight())); }
void setHeight(int height) { resize(Size(getWidth(), height)); } void setHeight(int height) { resize(Size(getWidth(), height)); }
void resize(const Size& size) { setGeometry(Rect(getPosition(), size)); updateGeometry(); } void resize(const Size& size) { setRect(Rect(getPosition(), size)); }
void move(const Point& pos) { setGeometry(Rect(pos, getSize())); } void move(const Point& pos) { setRect(Rect(pos, getSize())); }
void setImage(const ImagePtr& image) { m_image = image; } void setImage(const ImagePtr& image) { m_image = image; }
virtual void setFont(const FontPtr& font) { m_font = font; } virtual void setFont(const FontPtr& font) { m_font = font; }
void setOpacity(int opacity) { m_opacity = opacity; } void setOpacity(int opacity) { m_opacity = opacity; }
void setBackgroundColor(const Color& color) { m_backgroundColor = color; } void setBackgroundColor(const Color& color) { m_backgroundColor = color; }
void setForegroundColor(const Color& color) { m_foregroundColor = color; } void setForegroundColor(const Color& color) { m_foregroundColor = color; }
void setMarginLeft(int margin) { m_marginLeft = margin; updateGeometry(); } void setMarginLeft(int margin) { m_marginLeft = margin; updateLayout(); }
void setMarginRight(int margin) { m_marginRight = margin; updateGeometry(); } void setMarginRight(int margin) { m_marginRight = margin; updateLayout(); }
void setMarginTop(int margin) { m_marginTop = margin; updateGeometry(); } void setMarginTop(int margin) { m_marginTop = margin; updateLayout(); }
void setMarginBottom(int margin) { m_marginBottom = margin; updateGeometry(); } void setMarginBottom(int margin) { m_marginBottom = margin; updateLayout(); }
void hide() { setVisible(false); } void hide() { setVisible(false); }
void show() { setVisible(true); } void show() { setVisible(true); }
@ -72,13 +68,13 @@ public:
bool hasChild(const UIWidgetPtr& child); bool hasChild(const UIWidgetPtr& child);
UIWidgetType getWidgetType() const { return m_type; } UIWidgetType getWidgetType() const { return m_type; }
UILayoutPtr getLayout() const;
std::string getId() const { return m_id; } std::string getId() const { return m_id; }
int getChildCount() const { return m_children.size(); } int getChildCount() const { return m_children.size(); }
UIWidgetPtr getParent() const { return m_parent.lock(); } UIWidgetPtr getParent() const { return m_parent.lock(); }
UIWidgetPtr getRootParent();
Point getPosition() const { return m_rect.topLeft(); } Point getPosition() const { return m_rect.topLeft(); }
Size getSize() const { return m_rect.size(); } Size getSize() const { return m_rect.size(); }
Rect getGeometry() const { return m_rect; } Rect getRect() const { return m_rect; }
int getX() const { return m_rect.x(); } int getX() const { return m_rect.x(); }
int getY() const { return m_rect.y(); } int getY() const { return m_rect.y(); }
int getWidth() const { return m_rect.width(); } int getWidth() const { return m_rect.width(); }
@ -101,7 +97,7 @@ public:
UIWidgetPtr getChildById(const std::string& childId); UIWidgetPtr getChildById(const std::string& childId);
UIWidgetPtr getChildByPos(const Point& childPos); UIWidgetPtr getChildByPos(const Point& childPos);
UIWidgetPtr getChildByIndex(int childIndex); UIWidgetPtr getChildByIndex(int childIndex);
UIWidgetPtr recursiveGetChildById(const std::string& childId); UIWidgetPtr recursiveGetChildById(const std::string& id);
UIWidgetPtr recursiveGetChildByPos(const Point& childPos); UIWidgetPtr recursiveGetChildByPos(const Point& childPos);
UIWidgetPtr backwardsGetWidgetById(const std::string& id); UIWidgetPtr backwardsGetWidgetById(const std::string& id);
@ -114,16 +110,33 @@ public:
void lockChild(const UIWidgetPtr& childToLock); void lockChild(const UIWidgetPtr& childToLock);
void unlockChild(const UIWidgetPtr& childToUnlock); void unlockChild(const UIWidgetPtr& childToUnlock);
// for using only with anchor layouts void updateLayout();
void addAnchor(AnchorPoint edge, const std::string& targetId, AnchorPoint targetEdge); void updateChildrenLayout();
void centerIn(const std::string& targetId);
void fill(const std::string& targetId); bool addAnchor(AnchorEdge edge, const std::string& hookedWidgetId, AnchorEdge hookedEdge);
void centerIn(const std::string& hookedWidgetId);
void fill(const std::string& hookedWidgetId);
UIWidgetPtr asUIWidget() { return std::static_pointer_cast<UIWidget>(shared_from_this()); } UIWidgetPtr asUIWidget() { return std::static_pointer_cast<UIWidget>(shared_from_this()); }
private:
void internalUpdateLayout();
void internalUpdateChildrenLayout();
void addAnchoredWidget(const UIWidgetPtr& widget);
void recalculateAnchoredWidgets();
void clearAnchoredWidgets();
void computeAnchoredWidgets();
void resetLayoutUpdateState(bool resetOwn);
bool m_layoutUpdated;
bool m_updateEventScheduled;
bool m_layoutUpdateScheduled;
bool m_childrenLayoutUpdateScheduled;
protected: protected:
/// Triggered when widget is moved or resized /// Triggered when widget is moved or resized
virtual void onGeometryUpdate(UIGeometryUpdateEvent& event) { } virtual void onRectUpdate(UIRectUpdateEvent& event) { }
// Triggered when widget change visibility/enabled/style/children/parent/layout/... // Triggered when widget change visibility/enabled/style/children/parent/layout/...
//virtual void onChange(const UIEvent& event); //virtual void onChange(const UIEvent& event);
/// Triggered when widget gets or loses focus /// Triggered when widget gets or loses focus
@ -155,9 +168,9 @@ protected:
bool m_hovered; bool m_hovered;
bool m_focusable; bool m_focusable;
bool m_destroyed; bool m_destroyed;
bool m_updateScheduled;
Rect m_rect; Rect m_rect;
UILayoutPtr m_layout; UIAnchorList m_anchors;
UIWeakWidgetList m_anchoredWidgets;
UIWidgetWeakPtr m_parent; UIWidgetWeakPtr m_parent;
UIWidgetList m_children; UIWidgetList m_children;
UIWidgetList m_lockedWidgets; UIWidgetList m_lockedWidgets;

View File

@ -42,7 +42,7 @@ void UIWindow::loadStyleFromOTML(const OTMLNodePtr& styleNode)
void UIWindow::render() void UIWindow::render()
{ {
// draw window head // draw window head
Rect headRect = getGeometry(); Rect headRect = getRect();
headRect.setHeight(m_headHeight); headRect.setHeight(m_headHeight);
if(m_headImage && m_headHeight > 0) { if(m_headImage && m_headHeight > 0) {
@ -58,7 +58,7 @@ void UIWindow::render()
} }
// draw window body // draw window body
Rect bodyRect = getGeometry(); Rect bodyRect = getRect();
bodyRect.setTop(headRect.bottom() + 1); bodyRect.setTop(headRect.bottom() + 1);
if(m_bodyImage) if(m_bodyImage)
m_bodyImage->draw(bodyRect); m_bodyImage->draw(bodyRect);
@ -67,13 +67,13 @@ void UIWindow::render()
UIWidget::render(); UIWidget::render();
} }
void UIWindow::onGeometryUpdate(UIGeometryUpdateEvent& event) void UIWindow::onRectUpdate(UIRectUpdateEvent& event)
{ {
// bind window rect to parent rect // bind window rect to parent rect
Rect boundRect = event.rect(); Rect boundRect = event.rect();
UIWidgetPtr parent = getParent(); UIWidgetPtr parent = getParent();
if(parent) { if(parent) {
Rect parentRect = parent->getGeometry(); Rect parentRect = parent->getRect();
if(boundRect.left() < parentRect.left()) if(boundRect.left() < parentRect.left())
boundRect.moveLeft(parentRect.left()); boundRect.moveLeft(parentRect.left());
if(boundRect.top() < parentRect.top()) if(boundRect.top() < parentRect.top())
@ -85,7 +85,7 @@ void UIWindow::onGeometryUpdate(UIGeometryUpdateEvent& event)
} }
if(boundRect != event.rect()) if(boundRect != event.rect())
setGeometry(boundRect); setRect(boundRect);
} }
void UIWindow::onFocusChange(UIFocusEvent& event) void UIWindow::onFocusChange(UIFocusEvent& event)
@ -97,11 +97,11 @@ void UIWindow::onFocusChange(UIFocusEvent& event)
void UIWindow::onMousePress(UIMouseEvent& event) void UIWindow::onMousePress(UIMouseEvent& event)
{ {
Rect headRect = getGeometry(); Rect headRect = getRect();
headRect.setHeight(m_headHeight); headRect.setHeight(m_headHeight);
if(headRect.contains(event.pos())) { if(headRect.contains(event.pos())) {
m_moving = true; m_moving = true;
m_movingReference = event.pos() - getGeometry().topLeft(); m_movingReference = event.pos() - getRect().topLeft();
} else } else
UIWidget::onMousePress(event); UIWidget::onMousePress(event);
} }

View File

@ -17,7 +17,7 @@ public:
std::string getTitle() const { return m_title; } std::string getTitle() const { return m_title; }
protected: protected:
virtual void onGeometryUpdate(UIGeometryUpdateEvent& event); virtual void onRectUpdate(UIRectUpdateEvent& event);
virtual void onFocusChange(UIFocusEvent& event); virtual void onFocusChange(UIFocusEvent& event);
virtual void onMousePress(UIMouseEvent& event); virtual void onMousePress(UIMouseEvent& event);
virtual void onMouseRelease(UIMouseEvent& event); virtual void onMouseRelease(UIMouseEvent& event);

View File

@ -25,7 +25,7 @@ AlignmentFlag fw::translateAlignment(std::string aligment)
return AlignCenter; return AlignCenter;
} }
AnchorPoint fw::translateAnchorPoint(const std::string& anchorPoint) AnchorEdge fw::translateAnchorEdge(const std::string& anchorPoint)
{ {
if(anchorPoint == "left") if(anchorPoint == "left")
return AnchorLeft; return AnchorLeft;

View File

@ -7,7 +7,7 @@
namespace fw { namespace fw {
AlignmentFlag translateAlignment(std::string aligment); AlignmentFlag translateAlignment(std::string aligment);
AnchorPoint translateAnchorPoint(const std::string& anchorPoint); AnchorEdge translateAnchorEdge(const std::string& anchorPoint);
}; };

View File

@ -34,7 +34,7 @@ void Tile::draw(int x, int y, int step)
if(thingAttributes.alwaysOnTopOrder == 1) { if(thingAttributes.alwaysOnTopOrder == 1) {
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
font->renderText("T1", Rect(x + 5, y+5, 100, 100)); //font->renderText("T1", Rect(x + 5, y+5, 100, 100));
m_drawNextOffset += thingAttributes.drawNextOffset; m_drawNextOffset += thingAttributes.drawNextOffset;
} }
@ -45,7 +45,7 @@ void Tile::draw(int x, int y, int step)
if(thingAttributes.alwaysOnTopOrder == 2) { if(thingAttributes.alwaysOnTopOrder == 2) {
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
font->renderText("T2", Rect(x + 5, y+5, 100, 100)); //font->renderText("T2", Rect(x + 5, y+5, 100, 100));
m_drawNextOffset += thingAttributes.drawNextOffset; m_drawNextOffset += thingAttributes.drawNextOffset;
} }
} }
@ -53,7 +53,7 @@ void Tile::draw(int x, int y, int step)
for(const ThingPtr& thing : m_itemsBottom) { for(const ThingPtr& thing : m_itemsBottom) {
const ThingAttributes& thingAttributes = thing->getAttributes(); const ThingAttributes& thingAttributes = thing->getAttributes();
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
font->renderText("B0", Rect(x + 5, y+5, 100, 100)); //font->renderText("B0", Rect(x + 5, y+5, 100, 100));
m_drawNextOffset += thingAttributes.drawNextOffset; m_drawNextOffset += thingAttributes.drawNextOffset;
} }
@ -69,7 +69,7 @@ void Tile::draw(int x, int y, int step)
if(thingAttributes.alwaysOnTopOrder == 3) { if(thingAttributes.alwaysOnTopOrder == 3) {
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset); thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
font->renderText("T3", Rect(x + 5, y+5, 100, 100)); //font->renderText("T3", Rect(x + 5, y+5, 100, 100));
m_drawNextOffset += thingAttributes.drawNextOffset; m_drawNextOffset += thingAttributes.drawNextOffset;
} }
} }