From f4f0d7e960cc4384138310719d7e95b4d80902da Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 28 Oct 2011 21:56:45 -0200 Subject: [PATCH] fixed ratio image drawing support --- src/framework/graphics/borderimage.cpp | 7 +-- src/framework/graphics/image.cpp | 40 ++++++++++------- src/framework/graphics/image.h | 5 ++- src/framework/graphics/texture.h | 2 +- src/framework/luascript/luavaluecasts.h | 4 +- src/framework/platform/x11platform.cpp | 2 +- src/framework/ui/uilineedit.cpp | 4 +- src/framework/ui/uiwidget.cpp | 6 ++- src/framework/ui/uiwindow.cpp | 60 +++++++++---------------- src/framework/ui/uiwindow.h | 2 +- 10 files changed, 65 insertions(+), 67 deletions(-) diff --git a/src/framework/graphics/borderimage.cpp b/src/framework/graphics/borderimage.cpp index 11f3ebeb..a27a2081 100644 --- a/src/framework/graphics/borderimage.cpp +++ b/src/framework/graphics/borderimage.cpp @@ -36,8 +36,9 @@ BorderImage::BorderImage(TexturePtr texture, const Rect& topRight, const Rect& bottomLeft, const Rect& bottomRight, - const Rect& center) : Image(texture) + const Rect& center) { + m_texture = texture; m_leftBorderTexCoords = left; m_rightBorderTexCoords = right; m_topBorderTexCoords = top; @@ -102,7 +103,7 @@ BorderImagePtr BorderImage::loadFromOTML(const OTMLNodePtr& borderImageNode) bottomBorder = Rect(subRect.left() + left, subRect.bottom() - bottom + 1, subRect.width() - right - left, bottom); topLeftCorner = Rect(subRect.left(), subRect.top(), left, top); topRightCorner = Rect(subRect.right() - right + 1, subRect.top(), right, top); - bottomLeftCorner = Rect(subRect.left(), subRect.bottom() - bottom, left, bottom); + bottomLeftCorner = Rect(subRect.left(), subRect.bottom() - bottom + 1, left, bottom); bottomRightCorner = Rect(subRect.right() - right + 1, subRect.bottom() - bottom + 1, right, bottom); center = Rect(subRect.left() + left, subRect.top() + top, subRect.width() - right - left, subRect.height() - top - bottom); @@ -184,7 +185,7 @@ void BorderImage::draw(const Rect& screenCoords) // bottom left corner rectCoords = Rect(screenCoords.left(), - screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(), + screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(), m_bottomLeftCornerTexCoords.size()); g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomLeftCornerTexCoords); diff --git a/src/framework/graphics/image.cpp b/src/framework/graphics/image.cpp index b2d5e381..dec7d3ba 100644 --- a/src/framework/graphics/image.cpp +++ b/src/framework/graphics/image.cpp @@ -27,37 +27,45 @@ #include -Image::Image(TexturePtr texture, Rect textureCoords) +Image::Image() { - m_texture = texture; - if(!textureCoords.isValid()) - m_textureCoords = Rect(0, 0, m_texture->getSize()); - else - m_textureCoords = textureCoords; + m_fixedRatio = false; } -ImagePtr Image::loadFromOTML(const OTMLNodePtr& imageNode) +void Image::loadFromOTML(const OTMLNodePtr& imageNode) { // load configs from otml node std::string source = imageNode->hasValue() ? imageNode->value() : imageNode->valueAt("source"); bool smooth = imageNode->valueAt("smooth", false); - Rect textureCoords = imageNode->valueAt("coords", Rect()); + m_textureCoords = imageNode->valueAt("coords", Rect()); + m_fixedRatio = imageNode->valueAt("fixed ratio", false); // load texture - TexturePtr texture = g_textures.getTexture(source); - if(!texture) + m_texture = g_textures.getTexture(source); + if(!m_texture) throw OTMLException(imageNode, "could not load image texture"); // enable texture bilinear filter if(smooth) - texture->enableBilinearFilter(); - - // create image - return ImagePtr(new Image(texture, textureCoords)); + m_texture->enableBilinearFilter(); } void Image::draw(const Rect& screenCoords) { - if(m_texture) - g_graphics.drawTexturedRect(screenCoords, m_texture, m_textureCoords); + if(m_texture) { + if(m_fixedRatio) { + const Size& texSize = m_texture->getSize(); + Size texCoordsSize = screenCoords.size(); + texCoordsSize.scale(texSize, Fw::KeepAspectRatio); + Point texCoordsOffset; + if(texSize.height() > texCoordsSize.height()) + texCoordsOffset.y = (texSize.height() - texCoordsSize.height())/2; + else if(texSize.width() > texCoordsSize.width()) + texCoordsOffset.x = (texSize.width() - texCoordsSize.width())/2; + + g_graphics.drawTexturedRect(screenCoords, m_texture, Rect(texCoordsOffset, texCoordsSize)); + } else { + g_graphics.drawTexturedRect(screenCoords, m_texture, m_textureCoords); + } + } } diff --git a/src/framework/graphics/image.h b/src/framework/graphics/image.h index ad029d86..a63c0707 100644 --- a/src/framework/graphics/image.h +++ b/src/framework/graphics/image.h @@ -30,15 +30,16 @@ class Image { public: - Image(TexturePtr texture, Rect textureCoords = Rect()); + Image(); - static ImagePtr loadFromOTML(const OTMLNodePtr& imageNode); + void loadFromOTML(const OTMLNodePtr& imageNode); virtual void draw(const Rect& screenCoords); protected: TexturePtr m_texture; Rect m_textureCoords; + bool m_fixedRatio; }; #endif diff --git a/src/framework/graphics/texture.h b/src/framework/graphics/texture.h index 6196c9b7..e0e88795 100644 --- a/src/framework/graphics/texture.h +++ b/src/framework/graphics/texture.h @@ -44,7 +44,7 @@ public: int getWidth() const { return m_size.width(); } int getHeight() const { return m_size.height(); } - const Size getSize() const { return m_size; } + const Size& getSize() const { return m_size; } const Size& getGlSize() const { return m_glSize; } bool isEmpty() const { return m_textureId == 0; } diff --git a/src/framework/luascript/luavaluecasts.h b/src/framework/luascript/luavaluecasts.h index a4d4260a..f4c3abe8 100644 --- a/src/framework/luascript/luavaluecasts.h +++ b/src/framework/luascript/luavaluecasts.h @@ -155,7 +155,7 @@ bool luavalue_cast(int index, std::function& func) { // weak references are used here, this means that the script must hold another reference // to this function, otherwise it will expire int funcWeakRef = g_lua.weakRef(); - func = [=](Args... args...) { + func = [=](Args... args) { // note that we must catch exceptions, because this lambda can be called from anywhere // and most of them won't catch exceptions (e.g. dispatcher) g_lua.getWeakRef(funcWeakRef); @@ -187,7 +187,7 @@ luavalue_cast(int index, std::function& func) { // weak references are used here, this means that the script must hold another reference // to this function, otherwise it will expire int funcWeakRef = g_lua.weakRef(); - func = [=](Args... args...) -> Ret { + func = [=](Args... args) -> Ret { // note that we must catch exceptions, because this lambda can be called from anywhere // and most of them won't catch exceptions (e.g. dispatcher) try { diff --git a/src/framework/platform/x11platform.cpp b/src/framework/platform/x11platform.cpp index 895146ed..d15b2dd8 100644 --- a/src/framework/platform/x11platform.cpp +++ b/src/framework/platform/x11platform.cpp @@ -888,7 +888,7 @@ std::string Platform::generateBacktrace(int maxLevel) } if(i > 1) ss << "\n"; - ss << line; + ss << i << ": " << line; } free(tracebackBuffer); } diff --git a/src/framework/ui/uilineedit.cpp b/src/framework/ui/uilineedit.cpp index ad2b523f..75493e32 100644 --- a/src/framework/ui/uilineedit.cpp +++ b/src/framework/ui/uilineedit.cpp @@ -31,7 +31,7 @@ UILineEdit::UILineEdit() m_align = Fw::AlignLeftCenter; m_cursorPos = 0; m_startRenderPos = 0; - m_textHorizontalMargin = 3; + m_textHorizontalMargin = 0; m_textHidden = false; blinkCursor(); } @@ -381,6 +381,8 @@ void UILineEdit::onStyleApply(const OTMLNodePtr& styleNode) setCursorPos(m_text.length()); } else if(node->tag() == "text hidden") { setTextHidden(node->value()); + } else if(node->tag() == "text margin") { + m_textHorizontalMargin = node->value(); } } } diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index e3e89a93..57095def 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -102,7 +102,7 @@ void UIWidget::render() child->render(); // debug draw box - //g_graphics.bindColor(Color::green); + //g_graphics.bindColor(Fw::green); //g_graphics.drawBoundingRect(child->getRect()); //g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Color::red); @@ -709,7 +709,9 @@ void UIWidget::onStyleApply(const OTMLNodePtr& styleNode) for(const OTMLNodePtr& node : styleNode->children()) { // background image if(node->tag() == "image") { - setImage(Image::loadFromOTML(node)); + ImagePtr image = ImagePtr(new Image); + image->loadFromOTML(node); + setImage(image); } else if(node->tag() == "border-image") { setImage(BorderImage::loadFromOTML(node)); diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp index 0e5295ed..8614d155 100644 --- a/src/framework/ui/uiwindow.cpp +++ b/src/framework/ui/uiwindow.cpp @@ -31,39 +31,29 @@ void UIWindow::setup() UIWidget::setup(); m_moving = false; m_headHeight = 0; - m_headMargin = 0; m_titleAlign = Fw::AlignCenter; } void UIWindow::render() { - // draw window head - Rect headRect = getRect(); - headRect.setHeight(m_headHeight); - - if(m_headImage && m_headHeight > 0) { - g_graphics.bindColor(m_backgroundColor); - m_headImage->draw(headRect); + // render children + UIWidget::render(); - // draw window head text - Rect headTextRect = headRect; - if(m_titleAlign & Fw::AlignLeft) - headTextRect.addLeft(-m_headMargin); - else if(m_titleAlign & Fw::AlignRight) - headTextRect.addRight(-m_headMargin); - m_font->renderText(m_title, headTextRect, m_titleAlign, m_foregroundColor); - } + // draw window head - // draw window body - Rect bodyRect = getRect(); - bodyRect.setTop(headRect.bottom() + 1); - if(m_bodyImage) { - g_graphics.bindColor(m_backgroundColor); - m_bodyImage->draw(bodyRect); + // draw window head text + Rect headTextRect = m_rect; + headTextRect.addTop(-m_headOffset.y); + headTextRect.setHeight(m_headHeight); + if(m_titleAlign & Fw::AlignLeft) + headTextRect.addLeft(-m_headOffset.x); + else if(m_titleAlign & Fw::AlignRight) + headTextRect.addRight(-m_headOffset.x); + else { + headTextRect.addLeft(-m_headOffset.x); + headTextRect.addRight(-m_headOffset.x); } - - // render children - UIWidget::render(); + m_font->renderText(m_title, headTextRect, m_titleAlign, m_foregroundColor); } void UIWindow::onStyleApply(const OTMLNodePtr& styleNode) @@ -71,20 +61,14 @@ void UIWindow::onStyleApply(const OTMLNodePtr& styleNode) UIWidget::onStyleApply(styleNode); for(OTMLNodePtr node : styleNode->children()) { - if(node->tag() == "head") { - if(OTMLNodePtr cnode = node->get("border-image")) - m_headImage = BorderImage::loadFromOTML(cnode); - m_headHeight = node->valueAt("height", m_headImage->getDefaultSize().height()); - m_headMargin = node->valueAt("margin", 0); - m_titleAlign = Fw::translateAlignment(node->valueAt("text align", std::string("center"))); - } - else if(node->tag() == "body") { - if(OTMLNodePtr cnode = node->get("border-image")) - m_bodyImage = BorderImage::loadFromOTML(cnode); - } - else if(node->tag() == "title") { + if(node->tag() == "head height") + m_headHeight = node->value(); + else if(node->tag() == "head offset") + m_headOffset = node->value(); + else if(node->tag() == "title") setTitle(node->value()); - } + else if(node->tag() == "head text align") + m_titleAlign = Fw::translateAlignment(node->value()); else if(node->tag() == "onEnter") { g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]"); luaSetField(node->tag()); diff --git a/src/framework/ui/uiwindow.h b/src/framework/ui/uiwindow.h index 30ddb99a..d87c67f4 100644 --- a/src/framework/ui/uiwindow.h +++ b/src/framework/ui/uiwindow.h @@ -52,7 +52,7 @@ private: BorderImagePtr m_headImage; ImagePtr m_bodyImage; int m_headHeight; - int m_headMargin; + Point m_headOffset; Fw::AlignmentFlag m_titleAlign; };