Many UI improvements and minor fixes

master
Eduardo Bart 12 years ago
parent a8d3bb97ea
commit 5344a179a4

@ -273,7 +273,8 @@ namespace Fw
LastState = 512,
AlternateState = 1024,
DraggingState = 2048,
LastWidgetState = 4096
HiddenState = 4096,
LastWidgetState = 8192
};
enum DrawPane {

@ -311,3 +311,9 @@ std::string ResourceManager::getBaseDir()
return buffer;
}
std::string ResourceManager::guessFileType(const std::string& filename, const std::string& type)
{
if(g_resources.fileExists(filename))
return filename;
return filename + "." + type;
}

@ -70,6 +70,8 @@ public:
std::string getWorkDir() { return m_workDir; }
std::deque<std::string> getSearchPaths() { return m_searchPaths; }
std::string guessFileType(const std::string& filename, const std::string& type);
private:
std::string m_workDir;
std::string m_writeDir;

@ -83,7 +83,7 @@ bool UIGridLayout::internalUpdate()
int numColumns = m_numColumns;
if(m_flow && m_cellSize.width() > 0) {
numColumns = clippingRect.width() / (m_cellSize.width() + m_cellSpacing);
numColumns = (clippingRect.width() + m_cellSpacing) / (m_cellSize.width() + m_cellSpacing);
if(numColumns > 0) {
m_numColumns = numColumns;
m_numLines = std::ceil(widgets.size() / (float)numColumns);

@ -46,6 +46,7 @@ public:
void setFlow(bool enable) { m_flow = enable; update(); }
Size getCellSize() { return m_cellSize; }
int getCellSpacing() { return m_cellSpacing; }
int getNumColumns() { return m_numColumns; }
int getNumLines() { return m_numLines; }

@ -46,8 +46,8 @@ bool UIHorizontalLayout::internalUpdate()
std::reverse(widgets.begin(), widgets.end());
bool changed = false;
Rect clippingRect = parentWidget->getPaddingRect();
Point pos = (m_alignRight) ? clippingRect.topRight() : clippingRect.topLeft();
Rect paddingRect = parentWidget->getPaddingRect();
Point pos = (m_alignRight) ? paddingRect.topRight() : paddingRect.topLeft();
int preferredWidth = 0;
int gap;
@ -62,13 +62,19 @@ bool UIHorizontalLayout::internalUpdate()
preferredWidth += gap;
if(widget->isFixedSize()) {
// center it
pos.y = clippingRect.top() + (clippingRect.height() - (widget->getMarginTop() + widget->getHeight() + widget->getMarginBottom()))/2;
pos.y = std::max(pos.y, parentWidget->getY());
if(widget->getTextAlign() & Fw::AlignTop) {
pos.y = paddingRect.top() + widget->getMarginTop();
} else if(widget->getTextAlign() & Fw::AlignBottom) {
pos.y = paddingRect.bottom() - widget->getHeight() - widget->getMarginBottom();
pos.y = std::max(pos.y, paddingRect.top());
} else { // center it
pos.y = paddingRect.top() + (paddingRect.height() - (widget->getMarginTop() + widget->getHeight() + widget->getMarginBottom()))/2;
pos.y = std::max(pos.y, paddingRect.top());
}
} else {
// expand height
size.setHeight(clippingRect.height() - (widget->getMarginTop() + widget->getMarginBottom()));
pos.y = clippingRect.top() + (clippingRect.height() - size.height())/2;
size.setHeight(paddingRect.height() - (widget->getMarginTop() + widget->getMarginBottom()));
pos.y = paddingRect.top() + (paddingRect.height() - size.height())/2;
}
if(widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size)))

@ -39,6 +39,7 @@ public:
protected:
bool internalUpdate();
Fw::AlignmentFlag m_alignChidren;
stdext::boolean<false> m_alignRight;
};

@ -28,6 +28,7 @@
#include <framework/platform/platformwindow.h>
#include <framework/core/eventdispatcher.h>
#include <framework/core/application.h>
#include <framework/core/resourcemanager.h>
UIManager g_ui;
@ -149,7 +150,7 @@ void UIManager::inputEvent(const InputEvent& event)
break;
}
case Fw::MouseWheelInputEvent:
m_mouseReceiver->propagateOnMouseEvent(event.mousePos, widgetList);
m_rootWidget->propagateOnMouseEvent(event.mousePos, widgetList);
for(const UIWidgetPtr& widget : widgetList) {
if(widget->onMouseWheel(event.mousePos, event.wheelDirection))
break;
@ -219,9 +220,12 @@ void UIManager::updateHoveredWidget(bool now)
return;
m_hoverUpdateScheduled = false;
UIWidgetPtr hoveredWidget = m_rootWidget->recursiveGetChildByPos(g_window.getMousePosition(), false);
if(hoveredWidget && !hoveredWidget->isEnabled())
hoveredWidget = nullptr;
UIWidgetPtr hoveredWidget;
//if(!g_window.isMouseButtonPressed(Fw::MouseLeftButton) && !g_window.isMouseButtonPressed(Fw::MouseRightButton)) {
hoveredWidget = m_rootWidget->recursiveGetChildByPos(g_window.getMousePosition(), false);
if(hoveredWidget && !hoveredWidget->isEnabled())
hoveredWidget = nullptr;
//}
if(hoveredWidget != m_hoveredWidget) {
UIWidgetPtr oldHovered = m_hoveredWidget;
@ -304,9 +308,11 @@ void UIManager::clearStyles()
m_styles.clear();
}
bool UIManager::importStyle(const std::string& file)
bool UIManager::importStyle(std::string file)
{
try {
file = g_resources.guessFileType(file, "otui");
OTMLDocumentPtr doc = OTMLDocument::parse(file);
for(const OTMLNodePtr& styleNode : doc->children())
@ -385,9 +391,11 @@ std::string UIManager::getStyleClass(const std::string& styleName)
return "";
}
UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent)
UIWidgetPtr UIManager::loadUI(std::string file, const UIWidgetPtr& parent)
{
try {
file = g_resources.guessFileType(file, "otui");
OTMLDocumentPtr doc = OTMLDocument::parse(file);
UIWidgetPtr widget;
for(const OTMLNodePtr& node : doc->children()) {

@ -44,12 +44,12 @@ public:
void updateHoveredWidget(bool now = false);
void clearStyles();
bool importStyle(const std::string& file);
bool importStyle(std::string file);
void importStyleFromOTML(const OTMLNodePtr& styleNode);
OTMLNodePtr getStyle(const std::string& styleName);
std::string getStyleClass(const std::string& styleName);
UIWidgetPtr loadUI(const std::string& file, const UIWidgetPtr& parent);
UIWidgetPtr loadUI(std::string file, const UIWidgetPtr& parent);
UIWidgetPtr displayUI(const std::string& file) { return loadUI(file, m_rootWidget); }
UIWidgetPtr createWidget(const std::string& styleName, const UIWidgetPtr& parent);
UIWidgetPtr createWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent);

@ -96,6 +96,8 @@ Fw::WidgetState Fw::translateState(std::string state)
return Fw::AlternateState;
else if(state == "dragging")
return Fw::DraggingState;
else if(state == "hidden")
return Fw::HiddenState;
else
return Fw::InvalidState;
}

@ -47,8 +47,8 @@ bool UIVerticalLayout::internalUpdate()
if(m_alignBottom)
std::reverse(widgets.begin(), widgets.end());
Rect clippingRect = parentWidget->getPaddingRect();
Point pos = (m_alignBottom) ? clippingRect.bottomLeft() : clippingRect.topLeft();
Rect paddingRect = parentWidget->getPaddingRect();
Point pos = (m_alignBottom) ? paddingRect .bottomLeft() : paddingRect.topLeft();
int preferredHeight = 0;
int gap;
@ -64,12 +64,19 @@ bool UIVerticalLayout::internalUpdate()
if(widget->isFixedSize()) {
// center it
pos.x = clippingRect.left() + (clippingRect.width() - (widget->getMarginLeft() + widget->getWidth() + widget->getMarginRight()))/2;
pos.x = std::max(pos.x, parentWidget->getX());
if(widget->getTextAlign() & Fw::AlignLeft) {
pos.x = paddingRect.left() + widget->getMarginLeft();
} else if(widget->getTextAlign() & Fw::AlignLeft) {
pos.x = paddingRect.bottom() - widget->getHeight() - widget->getMarginBottom();
pos.x = std::max(pos.x, paddingRect.left());
} else {
pos.x = paddingRect.left() + (paddingRect.width() - (widget->getMarginLeft() + widget->getWidth() + widget->getMarginRight()))/2;
pos.x = std::max(pos.x, paddingRect.left());
}
} else {
// expand width
size.setWidth(clippingRect.width() - (widget->getMarginLeft() + widget->getMarginRight()));
pos.x = clippingRect.left() + (clippingRect.width() - size.width())/2;
size.setWidth(paddingRect.width() - (widget->getMarginLeft() + widget->getMarginRight()));
pos.x = paddingRect.left() + (paddingRect.width() - size.width())/2;
}
if(widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size)))

@ -124,17 +124,17 @@ void UIWidget::drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane)
void UIWidget::addChild(const UIWidgetPtr& child)
{
if(!child) {
g_logger.warning("attempt to add a null child into a UIWidget");
g_logger.traceWarning("attempt to add a null child into a UIWidget");
return;
}
if(child->isDestroyed()) {
g_logger.warning("attemp to add a destroyed child into a UIWidget");
g_logger.traceWarning("attemp to add a destroyed child into a UIWidget");
return;
}
if(hasChild(child)) {
g_logger.warning("attempt to add a child again into a UIWidget");
g_logger.traceWarning("attempt to add a child again into a UIWidget");
return;
}
@ -165,20 +165,20 @@ void UIWidget::addChild(const UIWidgetPtr& child)
void UIWidget::insertChild(int index, const UIWidgetPtr& child)
{
if(!child) {
g_logger.warning("attempt to insert a null child into a UIWidget");
g_logger.traceWarning("attempt to insert a null child into a UIWidget");
return;
}
if(hasChild(child)) {
g_logger.warning("attempt to insert a child again into a UIWidget");
g_logger.traceWarning("attempt to insert a child again into a UIWidget");
return;
}
index = index <= 0 ? (m_children.size() + index) : index-1;
if(!(index >= 0 && (uint)index <= m_children.size())) {
g_logger.traceError("attempt to insert a child in an invalid index");
return;
//g_logger.traceWarning("attempt to insert a child UIWidget into an invalid index, using nearest index...");
index = std::min(std::max(index, 0), (int)m_children.size());
}
// retrieve child by index
@ -232,7 +232,7 @@ void UIWidget::removeChild(UIWidgetPtr child)
g_ui.onWidgetDisappear(child);
} else
g_logger.error("attempt to remove an unknown child from a UIWidget");
g_logger.traceError("attempt to remove an unknown child from a UIWidget");
}
@ -376,7 +376,7 @@ void UIWidget::moveChildToIndex(const UIWidgetPtr& child, int index)
return;
if((uint)index - 1 > m_children.size()) {
g_logger.error(stdext::format("moving %s to index %d on %s", child->getId(), index, m_id));
g_logger.traceError(stdext::format("moving %s to index %d on %s", child->getId(), index, m_id));
return;
}
@ -472,7 +472,11 @@ void UIWidget::unlockChild(const UIWidgetPtr& child)
void UIWidget::mergeStyle(const OTMLNodePtr& styleNode)
{
applyStyle(styleNode);
std::string name = m_style->tag();
std::string source = m_style->source();
m_style->merge(styleNode);
m_style->setTag(name);
m_style->setSource(source);
updateStyle();
}
@ -491,7 +495,7 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
if(node->tag()[0] == '!') {
std::string tag = node->tag().substr(1);
std::string code = stdext::format("tostring(%s)", node->value().c_str());
std::string origin = "@" + node->source() + "[" + node->tag() + "]";
std::string origin = "@" + node->source() + ": [" + node->tag() + "]";
g_lua.evaluateExpression(code, origin);
std::string value = g_lua.popString();
@ -510,7 +514,7 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
}
m_firstOnStyle = false;
} catch(stdext::exception& e) {
g_logger.error(stdext::format("failed to apply style to widget '%s': %s", m_id, e.what()));
g_logger.traceError(stdext::format("failed to apply style to widget '%s': %s", m_id, e.what()));
}
m_loadingStyle = false;
}
@ -523,7 +527,7 @@ void UIWidget::addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedW
if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout())
anchorLayout->addAnchor(static_self_cast<UIWidget>(), anchoredEdge, hookedWidgetId, hookedEdge);
else
g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
}
void UIWidget::removeAnchor(Fw::AnchorEdge anchoredEdge)
@ -540,7 +544,7 @@ void UIWidget::centerIn(const std::string& hookedWidgetId)
anchorLayout->addAnchor(static_self_cast<UIWidget>(), Fw::AnchorHorizontalCenter, hookedWidgetId, Fw::AnchorHorizontalCenter);
anchorLayout->addAnchor(static_self_cast<UIWidget>(), Fw::AnchorVerticalCenter, hookedWidgetId, Fw::AnchorVerticalCenter);
} else
g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
}
void UIWidget::fill(const std::string& hookedWidgetId)
@ -554,7 +558,7 @@ void UIWidget::fill(const std::string& hookedWidgetId)
anchorLayout->addAnchor(static_self_cast<UIWidget>(), Fw::AnchorTop, hookedWidgetId, Fw::AnchorTop);
anchorLayout->addAnchor(static_self_cast<UIWidget>(), Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom);
} else
g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
}
void UIWidget::breakAnchors()
@ -751,7 +755,8 @@ void UIWidget::destroyChildren()
child->destroy();
}
layout->enableUpdates();
if(layout)
layout->enableUpdates();
}
void UIWidget::setId(const std::string& id)
@ -790,6 +795,9 @@ void UIWidget::setParent(const UIWidgetPtr& parent)
void UIWidget::setLayout(const UILayoutPtr& layout)
{
if(!layout)
stdext::throw_exception("attempt to set a nil layout to a widget");
if(m_layout)
m_layout->disableUpdates();
@ -893,14 +901,13 @@ void UIWidget::setVisible(bool visible)
updateParentLayout();
updateState(Fw::ActiveState);
updateState(Fw::HiddenState);
// visibility can change the current hovered widget
if(visible)
g_ui.onWidgetAppear(static_self_cast<UIWidget>());
else
g_ui.onWidgetDisappear(static_self_cast<UIWidget>());
callLuaField("onVisibilityChange", visible);
}
}
@ -956,16 +963,6 @@ void UIWidget::setVirtualOffset(const Point& offset)
m_layout->update();
}
bool UIWidget::isVisible()
{
if(!m_visible)
return false;
else if(UIWidgetPtr parent = getParent())
return parent->isVisible();
else
return static_self_cast<UIWidget>() == g_ui.getRootWidget();
}
bool UIWidget::isAnchored()
{
if(UIWidgetPtr parent = getParent())
@ -1289,6 +1286,19 @@ void UIWidget::updateState(Fw::WidgetState state)
newStatus = (getParent() && (getParent()->getChildIndex(static_self_cast<UIWidget>()) % 2) == 1);
break;
}
case Fw::HiddenState: {
bool visible = true;
UIWidgetPtr widget = static_self_cast<UIWidget>();
do {
if(!widget->isExplicitlyVisible()) {
visible = false;
break;
}
} while((widget = widget->getParent()));
newStatus = !visible;
updateChildren = newStatus != oldStatus;
break;
}
default:
return;
}
@ -1304,6 +1314,8 @@ void UIWidget::updateState(Fw::WidgetState state)
// disabled widgets cannot have hover state
if(state == Fw::DisabledState && !newStatus && isHovered()) {
g_ui.updateHoveredWidget();
} else if(state == Fw::HiddenState) {
onVisibilityChange(!newStatus);
}
}
}
@ -1414,7 +1426,7 @@ void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect)
// move children that is outside the parent rect to inside again
for(const UIWidgetPtr& child : m_children) {
if(!child->isAnchored())
if(!child->isAnchored() && child->isVisible())
child->bindRectToParent();
}
@ -1443,6 +1455,13 @@ void UIWidget::onHoverChange(bool hovered)
callLuaField("onHoverChange", hovered);
}
void UIWidget::onVisibilityChange(bool visible)
{
if(!isAnchored())
bindRectToParent();
callLuaField("onVisibilityChange", visible);
}
bool UIWidget::onDragEnter(const Point& mousePos)
{
return callLuaField<bool>("onDragEnter", mousePos);

@ -132,7 +132,6 @@ public:
void setAutoRepeatDelay(int delay) { m_autoRepeatDelay = delay; }
void setVirtualOffset(const Point& offset);
bool isVisible();
bool isAnchored();
bool isChildLocked(const UIWidgetPtr& child);
bool hasChild(const UIWidgetPtr& child);
@ -185,6 +184,7 @@ protected:
virtual void onFocusChange(bool focused, Fw::FocusReason reason);
virtual void onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason);
virtual void onHoverChange(bool hovered);
virtual void onVisibilityChange(bool visible);
virtual bool onDragEnter(const Point& mousePos);
virtual bool onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos);
virtual bool onDragMove(const Point& mousePos, const Point& mouseMoved);
@ -232,7 +232,8 @@ public:
bool isChecked() { return hasState(Fw::CheckedState); }
bool isOn() { return hasState(Fw::OnState); }
bool isDragging() { return hasState(Fw::DraggingState); }
bool isHidden() { return !isVisible(); }
bool isVisible() { return !hasState(Fw::HiddenState); }
bool isHidden() { return hasState(Fw::HiddenState); }
bool isExplicitlyEnabled() { return m_enabled; }
bool isExplicitlyVisible() { return m_visible; }
bool isFocusable() { return m_focusable; }
@ -280,6 +281,7 @@ protected:
Color m_iconColor;
Rect m_iconRect;
Rect m_iconClipRect;
Fw::AlignmentFlag m_iconAlign;
EdgeGroup<Color> m_borderColor;
EdgeGroup<int> m_borderWidth;
EdgeGroup<int> m_margin;
@ -306,14 +308,15 @@ public:
void setBackgroundRect(const Rect& rect) { m_backgroundRect = rect; }
void setIcon(const std::string& iconFile);
void setIconColor(const Color& color) { m_iconColor = color; }
void setIconOffsetX(int x) { m_iconRect.setX(x); }
void setIconOffsetY(int y) { m_iconRect.setX(y); }
void setIconOffset(const Point& pos) { m_iconRect.move(pos); }
void setIconOffsetX(int x) { m_iconOffset.x = x; }
void setIconOffsetY(int y) { m_iconOffset.y = y; }
void setIconOffset(const Point& pos) { m_iconOffset = pos; }
void setIconWidth(int width) { m_iconRect.setWidth(width); }
void setIconHeight(int height) { m_iconRect.setHeight(height); }
void setIconSize(const Size& size) { m_iconRect.resize(size); }
void setIconRect(const Rect& rect) { m_iconRect = rect; }
void setIconClip(const Rect& rect) { m_iconClipRect = rect; }
void setIconAlign(Fw::AlignmentFlag align) { m_iconAlign = align; }
void setBorderWidth(int width) { m_borderWidth.set(width); updateLayout(); }
void setBorderWidthTop(int width) { m_borderWidth.top = width; }
void setBorderWidthRight(int width) { m_borderWidth.right = width; }
@ -404,6 +407,7 @@ protected:
Rect m_imageClipRect;
Rect m_imageRect;
Color m_imageColor;
Point m_iconOffset;
stdext::boolean<false> m_imageFixedRatio;
stdext::boolean<false> m_imageRepeated;
stdext::boolean<false> m_imageSmooth;

@ -38,6 +38,7 @@ void UIWidget::initBaseStyle()
m_iconColor = Color::white;
m_color = Color::white;
m_opacity = 1.0f;
m_iconAlign = Fw::AlignNone;
// generate an unique id, this is need because anchored layouts find widgets by id
static unsigned long id = 1;
@ -102,6 +103,8 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
setIconRect(node->value<Rect>());
else if(node->tag() == "icon-clip")
setIconClip(node->value<Rect>());
else if(node->tag() == "icon-align")
setIconAlign(Fw::translateAlignment(node->value()));
else if(node->tag() == "opacity")
setOpacity(node->value<float>());
else if(node->tag() == "enabled")
@ -110,7 +113,7 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
setVisible(node->value<bool>());
else if(node->tag() == "checked")
setChecked(node->value<bool>());
else if(node->tag() == "dragable")
else if(node->tag() == "draggable")
setDraggable(node->value<bool>());
else if(node->tag() == "on")
setOn(node->value<bool>());
@ -306,14 +309,14 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
// load once
if(m_firstOnStyle) {
std::string funcName = node->tag().substr(1);
std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]";
std::string funcOrigin = "@" + node->source() + ": [" + node->tag() + "]";
g_lua.loadFunction(node->value(), funcOrigin);
luaSetField(funcName);
}
// lua fields value
} else if(stdext::starts_with(node->tag(), "&")) {
std::string fieldName = node->tag().substr(1);
std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]";
std::string fieldOrigin = "@" + node->source() + ": [" + node->tag() + "]";
g_lua.evaluateExpression(node->value(), fieldOrigin);
luaSetField(fieldName);
@ -375,7 +378,12 @@ void UIWidget::drawIcon(const Rect& screenCoords)
drawRect.resize(m_iconRect.size());
} else {
drawRect.resize(m_iconClipRect.size());
drawRect.moveCenter(screenCoords.center());
if(m_iconAlign == Fw::AlignNone)
drawRect.moveCenter(screenCoords.center());
else
drawRect.alignIn(screenCoords, m_iconAlign);
drawRect.translate(m_iconOffset);
}
g_painter->setColor(m_iconColor);
g_painter->drawTexturedRect(drawRect, m_icon, m_iconClipRect);
@ -385,6 +393,6 @@ void UIWidget::drawIcon(const Rect& screenCoords)
void UIWidget::setIcon(const std::string& iconFile)
{
m_icon = g_textures.getTexture(iconFile);
if(!m_iconClipRect.isValid())
if(m_icon && !m_iconClipRect.isValid())
m_iconClipRect = Rect(0, 0, m_icon->getSize());
}
}

@ -44,7 +44,7 @@ void UIWidget::updateText()
// update rect size
if(!m_rect.isValid() || m_textAutoResize) {
Size textBoxSize = getTextSize();
textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom);
textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom) + m_textOffset.toSize();
Size size = getSize();
if(size.width() <= 0 || (m_textAutoResize && !m_textWrap))
size.setWidth(textBoxSize.width());
@ -82,12 +82,13 @@ void UIWidget::drawText(const Rect& screenCoords)
return;
if(screenCoords != m_textCachedScreenCoords || m_textMustRecache) {
Rect coords = Rect(screenCoords.topLeft() + m_textOffset, screenCoords.bottomRight());
m_textMustRecache = false;
m_textCachedScreenCoords = screenCoords;
m_textCachedScreenCoords = coords;
m_textCoordsBuffer.clear();
m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_drawText, screenCoords.translated(m_textOffset), m_textAlign);
m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_drawText, coords, m_textAlign);
}
g_painter->setColor(m_color);

@ -284,6 +284,27 @@ public:
moveTop(r.top());
}
void alignIn(const TRect<T> &r, Fw::AlignmentFlag align) {
if(align == Fw::AlignTopLeft)
moveTopLeft(r.topLeft());
else if(align == Fw::AlignTopRight)
moveTopRight(r.topRight());
else if(align == Fw::AlignTopCenter)
moveTopCenter(r.topCenter());
else if(align == Fw::AlignBottomLeft)
moveBottomLeft(r.bottomLeft());
else if(align == Fw::AlignBottomRight)
moveBottomRight(r.bottomRight());
else if(align == Fw::AlignBottomCenter)
moveBottomCenter(r.bottomCenter());
else if(align == Fw::AlignLeftCenter)
moveCenterLeft(r.centerLeft());
else if(align == Fw::AlignCenter)
moveCenter(r.center());
else if(align == Fw::AlignRightCenter)
moveCenterRight(r.centerRight());
}
TRect<T>& operator=(const TRect<T>& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; }
bool operator==(const TRect<T>& other) const { return (x1 == other.x1 && y1 == other.y1 && x2 == other.x2 && y2 == other.y2); }
bool operator!=(const TRect<T>& other) const { return (x1 != other.x1 || y1 != other.y1 || x2 != other.x2 || y2 != other.y2); }

Loading…
Cancel
Save