mirror of
https://github.com/edubart/otclient.git
synced 2025-10-19 22:13:27 +02:00
implement combobox and do some ui rework
This commit is contained in:
@@ -25,8 +25,6 @@
|
||||
|
||||
#include "uimanager.h"
|
||||
#include "uiwidget.h"
|
||||
#include "uibutton.h"
|
||||
#include "uilabel.h"
|
||||
#include "uilineedit.h"
|
||||
#include "uiwindow.h"
|
||||
#include "uiframecounter.h"
|
||||
|
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uibutton.h"
|
||||
#include <framework/graphics/borderimage.h>
|
||||
#include <framework/graphics/font.h>
|
||||
#include <framework/otml/otmlnode.h>
|
||||
#include <framework/luascript/luainterface.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/texture.h>
|
||||
#include <framework/graphics/texturemanager.h>
|
||||
|
||||
UIButton::UIButton()
|
||||
{
|
||||
m_focusable = false;
|
||||
}
|
||||
|
||||
void UIButton::render()
|
||||
{
|
||||
UIWidget::render();
|
||||
|
||||
if(m_icon) {
|
||||
Rect iconRect;
|
||||
iconRect.resize(m_icon->getSize());
|
||||
iconRect.moveCenter(m_rect.center());
|
||||
g_painter.drawTexturedRect(iconRect, m_icon);
|
||||
}
|
||||
|
||||
Rect textRect = m_rect;
|
||||
textRect.translate(m_textOffset);
|
||||
m_font->renderText(m_text, textRect, Fw::AlignCenter, m_foregroundColor);
|
||||
}
|
||||
|
||||
void UIButton::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
for(OTMLNodePtr node : styleNode->children()) {
|
||||
if(node->tag() == "text-offset")
|
||||
m_textOffset = node->value<Point>();
|
||||
else if(node->tag() == "text")
|
||||
m_text = node->value();
|
||||
else if(node->tag() == "icon")
|
||||
m_icon = g_textures.getTexture(node->value());
|
||||
}
|
||||
}
|
||||
|
||||
void UIButton::onMouseRelease(const Point& mousePos, Fw::MouseButton button)
|
||||
{
|
||||
if(isPressed() && getRect().contains(mousePos)) {
|
||||
callLuaField("onClick");
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UIBUTTON_H
|
||||
#define UIBUTTON_H
|
||||
|
||||
#include "uiwidget.h"
|
||||
|
||||
class UIButton : public UIWidget
|
||||
{
|
||||
public:
|
||||
UIButton();
|
||||
|
||||
virtual void render();
|
||||
|
||||
void setText(const std::string& text) { m_text = text; }
|
||||
std::string getText() const { return m_text; }
|
||||
|
||||
UIButtonPtr asUIButton() { return std::static_pointer_cast<UIButton>(shared_from_this()); }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
|
||||
|
||||
Point m_textOffset;
|
||||
TexturePtr m_icon;
|
||||
std::string m_text;
|
||||
};
|
||||
|
||||
#endif
|
@@ -58,9 +58,9 @@ void UICheckBox::onMouseRelease(const Point& mousePos, Fw::MouseButton button)
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
|
||||
void UICheckBox::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
void UICheckBox::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(OTMLNodePtr node : styleNode->children()) {
|
||||
if(node->tag() == "text-offset")
|
||||
|
@@ -40,7 +40,7 @@ public:
|
||||
UICheckBoxPtr asUICheckBox() { return std::static_pointer_cast<UICheckBox>(shared_from_this()); }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
|
||||
|
||||
std::string m_text;
|
||||
|
@@ -50,9 +50,9 @@ void UIFrameCounter::render()
|
||||
m_font->renderText(m_fpsText, m_rect, m_align, Fw::white);
|
||||
}
|
||||
|
||||
void UIFrameCounter::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
void UIFrameCounter::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "align")
|
||||
|
@@ -36,7 +36,7 @@ public:
|
||||
int getFrameCount() { return m_frameCount; }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
|
||||
private:
|
||||
Fw::AlignmentFlag m_align;
|
||||
|
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uilabel.h"
|
||||
#include "uitranslator.h"
|
||||
#include <framework/graphics/font.h>
|
||||
#include <framework/otml/otmlnode.h>
|
||||
|
||||
UILabel::UILabel()
|
||||
{
|
||||
m_focusable = false;
|
||||
m_phantom = true;
|
||||
m_textAlign = Fw::AlignLeft;
|
||||
}
|
||||
|
||||
void UILabel::render()
|
||||
{
|
||||
UIWidget::render();
|
||||
Rect textRect = m_rect;
|
||||
textRect.setTopLeft(textRect.topLeft() + m_textOffset);
|
||||
m_font->renderText(m_text, textRect, m_textAlign, m_foregroundColor);
|
||||
}
|
||||
|
||||
void UILabel::setText(const std::string& text)
|
||||
{
|
||||
m_text = text;
|
||||
|
||||
// auto resize
|
||||
if(!m_fixedSize && !m_rect.isValid()) {
|
||||
Size textSize = m_font->calculateTextRectSize(m_text);
|
||||
if(m_rect.width() <= 0)
|
||||
m_rect.setWidth(textSize.width());
|
||||
if(m_rect.height() <= 0)
|
||||
m_rect.setHeight(textSize.height());
|
||||
}
|
||||
}
|
||||
|
||||
void UILabel::resizeToText()
|
||||
{
|
||||
resize(m_font->calculateTextRectSize(m_text));
|
||||
}
|
||||
|
||||
void UILabel::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "text")
|
||||
setText(node->value());
|
||||
else if(node->tag() == "text-align")
|
||||
setTextAlign(Fw::translateAlignment(node->value()));
|
||||
else if(node->tag() == "text-offset") {
|
||||
setTextOffset(node->value<Point>());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UILABEL_H
|
||||
#define UILABEL_H
|
||||
|
||||
#include "uiwidget.h"
|
||||
|
||||
class UILabel : public UIWidget
|
||||
{
|
||||
public:
|
||||
UILabel();
|
||||
virtual void render();
|
||||
|
||||
void resizeToText();
|
||||
|
||||
void setText(const std::string& text);
|
||||
void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; }
|
||||
void setTextOffset(const Point& offset) { m_textOffset = offset; }
|
||||
|
||||
std::string getText() const { return m_text; }
|
||||
Fw::AlignmentFlag getTextAlign() const { return m_textAlign; }
|
||||
Point getTextOffset() const { return m_textOffset; }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
|
||||
private:
|
||||
std::string m_text;
|
||||
Point m_textOffset;
|
||||
Fw::AlignmentFlag m_textAlign;
|
||||
};
|
||||
|
||||
#endif
|
@@ -29,8 +29,8 @@
|
||||
|
||||
UILineEdit::UILineEdit()
|
||||
{
|
||||
m_align = Fw::AlignLeftCenter;
|
||||
m_cursorPos = 0;
|
||||
m_textAlign = Fw::AlignLeftCenter;
|
||||
m_startRenderPos = 0;
|
||||
m_textHorizontalMargin = 0;
|
||||
m_textHidden = false;
|
||||
@@ -38,9 +38,12 @@ UILineEdit::UILineEdit()
|
||||
blinkCursor();
|
||||
}
|
||||
|
||||
void UILineEdit::render()
|
||||
void UILineEdit::renderSelf()
|
||||
{
|
||||
UIWidget::render();
|
||||
drawBackground(m_rect);
|
||||
drawBorder(m_rect);
|
||||
drawImage(m_rect);
|
||||
drawIcon(m_rect);
|
||||
|
||||
//TODO: text rendering could be much optimized by using vertex buffer or caching the render into a texture
|
||||
|
||||
@@ -81,7 +84,7 @@ void UILineEdit::update()
|
||||
|
||||
// map glyphs positions
|
||||
Size textBoxSize;
|
||||
const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_align, &textBoxSize);
|
||||
const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
|
||||
const Rect *glyphsTextureCoords = m_font->getGlyphsTextureCoords();
|
||||
const Size *glyphsSize = m_font->getGlyphsSize();
|
||||
int glyph;
|
||||
@@ -141,16 +144,16 @@ void UILineEdit::update()
|
||||
textScreenCoords.addRight(-m_textHorizontalMargin);
|
||||
m_drawArea = textScreenCoords;
|
||||
|
||||
if(m_align & Fw::AlignBottom) {
|
||||
if(m_textAlign & Fw::AlignBottom) {
|
||||
m_drawArea.translate(0, textScreenCoords.height() - textBoxSize.height());
|
||||
} else if(m_align & Fw::AlignVerticalCenter) {
|
||||
} else if(m_textAlign & Fw::AlignVerticalCenter) {
|
||||
m_drawArea.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2);
|
||||
} else { // AlignTop
|
||||
}
|
||||
|
||||
if(m_align & Fw::AlignRight) {
|
||||
if(m_textAlign & Fw::AlignRight) {
|
||||
m_drawArea.translate(textScreenCoords.width() - textBoxSize.width(), 0);
|
||||
} else if(m_align & Fw::AlignHorizontalCenter) {
|
||||
} else if(m_textAlign & Fw::AlignHorizontalCenter) {
|
||||
m_drawArea.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0);
|
||||
} else { // AlignLeft
|
||||
|
||||
@@ -169,17 +172,17 @@ void UILineEdit::update()
|
||||
Rect glyphTextureCoords = glyphsTextureCoords[glyph];
|
||||
|
||||
// first translate to align position
|
||||
if(m_align & Fw::AlignBottom) {
|
||||
if(m_textAlign & Fw::AlignBottom) {
|
||||
glyphScreenCoords.translate(0, textScreenCoords.height() - textBoxSize.height());
|
||||
} else if(m_align & Fw::AlignVerticalCenter) {
|
||||
} else if(m_textAlign & Fw::AlignVerticalCenter) {
|
||||
glyphScreenCoords.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2);
|
||||
} else { // AlignTop
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
if(m_align & Fw::AlignRight) {
|
||||
if(m_textAlign & Fw::AlignRight) {
|
||||
glyphScreenCoords.translate(textScreenCoords.width() - textBoxSize.width(), 0);
|
||||
} else if(m_align & Fw::AlignHorizontalCenter) {
|
||||
} else if(m_textAlign & Fw::AlignHorizontalCenter) {
|
||||
glyphScreenCoords.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0);
|
||||
} else { // AlignLeft
|
||||
// nothing to do
|
||||
@@ -225,38 +228,12 @@ void UILineEdit::update()
|
||||
}
|
||||
}
|
||||
|
||||
void UILineEdit::setFont(const FontPtr& font)
|
||||
void UILineEdit::setTextHorizontalMargin(int margin)
|
||||
{
|
||||
if(m_font != font) {
|
||||
m_font = font;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void UILineEdit::setText(const std::string& text)
|
||||
{
|
||||
if(m_text != text) {
|
||||
m_text = text;
|
||||
m_cursorPos = text.length();
|
||||
blinkCursor();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void UILineEdit::setTextHidden(bool hidden)
|
||||
{
|
||||
m_textHidden = true;
|
||||
m_textHorizontalMargin = margin;
|
||||
update();
|
||||
}
|
||||
|
||||
void UILineEdit::setAlign(Fw::AlignmentFlag align)
|
||||
{
|
||||
if(m_align != align) {
|
||||
m_align = align;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void UILineEdit::setCursorPos(int pos)
|
||||
{
|
||||
if(pos != m_cursorPos) {
|
||||
@@ -280,6 +257,17 @@ void UILineEdit::setCursorEnabled(bool enable)
|
||||
update();
|
||||
}
|
||||
|
||||
void UILineEdit::setTextHidden(bool hidden)
|
||||
{
|
||||
m_textHidden = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void UILineEdit::setAlwaysActive(bool enable)
|
||||
{
|
||||
m_alwaysActive = enable;
|
||||
}
|
||||
|
||||
void UILineEdit::appendText(std::string text)
|
||||
{
|
||||
if(m_cursorPos >= 0) {
|
||||
@@ -373,21 +361,34 @@ std::string UILineEdit::getDisplayedText()
|
||||
return m_text;
|
||||
}
|
||||
|
||||
void UILineEdit::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
void UILineEdit::onTextChange(const std::string& text)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
m_cursorPos = text.length();
|
||||
blinkCursor();
|
||||
update();
|
||||
UIWidget::onTextChange(text);
|
||||
}
|
||||
|
||||
void UILineEdit::onFontChange(const std::string& font)
|
||||
{
|
||||
update();
|
||||
UIWidget::onFontChange(font);
|
||||
}
|
||||
|
||||
void UILineEdit::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "text") {
|
||||
setText(node->value());
|
||||
setCursorPos(m_text.length());
|
||||
} else if(node->tag() == "text-hidden") {
|
||||
} else if(node->tag() == "text-hidden")
|
||||
setTextHidden(node->value<bool>());
|
||||
} else if(node->tag() == "text-margin") {
|
||||
m_textHorizontalMargin = node->value<int>();
|
||||
} else if(node->tag() == "always-active") {
|
||||
m_alwaysActive = true;
|
||||
}
|
||||
else if(node->tag() == "text-margin")
|
||||
setTextHorizontalMargin(node->value<int>());
|
||||
else if(node->tag() == "always-active")
|
||||
setAlwaysActive(node->value<bool>());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,30 +30,35 @@ class UILineEdit : public UIWidget
|
||||
public:
|
||||
UILineEdit();
|
||||
|
||||
virtual void render();
|
||||
virtual void renderSelf();
|
||||
|
||||
private:
|
||||
void update();
|
||||
|
||||
void setText(const std::string& text);
|
||||
void setTextHidden(bool hidden);
|
||||
void setAlign(Fw::AlignmentFlag align);
|
||||
public:
|
||||
void setTextHorizontalMargin(int margin);
|
||||
void setCursorPos(int pos);
|
||||
void setCursorEnabled(bool enable = true);
|
||||
void setCursorEnabled(bool enable);
|
||||
void setTextHidden(bool hidden);
|
||||
void setAlwaysActive(bool enable);
|
||||
|
||||
void clearText() { setText(""); }
|
||||
void moveCursor(bool right);
|
||||
void appendText(std::string text);
|
||||
void appendCharacter(char c);
|
||||
void removeCharacter(bool right);
|
||||
|
||||
void setFont(const FontPtr& font);
|
||||
std::string getText() const { return m_text; }
|
||||
std::string getDisplayedText();
|
||||
int getTextPos(Point pos);
|
||||
int getCursorPos() const { return m_cursorPos; }
|
||||
int getTextHorizontalMargin() { return m_textHorizontalMargin; }
|
||||
int getCursorPos() { return m_cursorPos; }
|
||||
bool isCursorEnabled() { return m_cursorPos != -1; }
|
||||
bool isAlwaysActive() { return m_alwaysActive; }
|
||||
bool isTextHidden() { return m_textHidden; }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void onTextChange(const std::string& text);
|
||||
virtual void onFontChange(const std::string& font);
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect);
|
||||
virtual void onFocusChange(bool focused, Fw::FocusReason reason);
|
||||
virtual bool onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers);
|
||||
@@ -62,9 +67,7 @@ protected:
|
||||
private:
|
||||
void blinkCursor();
|
||||
|
||||
std::string m_text;
|
||||
Rect m_drawArea;
|
||||
Fw::AlignmentFlag m_align;
|
||||
int m_cursorPos;
|
||||
Point m_startInternalPos;
|
||||
int m_startRenderPos;
|
||||
|
@@ -54,7 +54,7 @@ void UIVerticalLayout::update()
|
||||
if(m_alignBottom)
|
||||
std::reverse(widgets.begin(), widgets.end());
|
||||
|
||||
Point pos = (m_alignBottom) ? parentWidget->getRect().bottomLeft() : parentWidget->getPosition();
|
||||
Point pos = (m_alignBottom) ? parentWidget->getRect().bottomLeft() : parentWidget->getPos();
|
||||
int prefferedHeight = 0;
|
||||
int gap;
|
||||
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include <framework/otml/otmlnode.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/platform/platformwindow.h>
|
||||
#include <framework/graphics/texturemanager.h>
|
||||
|
||||
UIWidget::UIWidget()
|
||||
{
|
||||
@@ -41,6 +42,10 @@ UIWidget::UIWidget()
|
||||
m_font = g_fonts.getDefaultFont();
|
||||
m_opacity = 255;
|
||||
m_marginTop = m_marginRight = m_marginBottom = m_marginLeft = 0;
|
||||
//m_backgroundColor = Fw::alpha;
|
||||
m_backgroundColor = Fw::white;
|
||||
m_foregroundColor = Fw::white;
|
||||
m_textAlign = Fw::AlignCenter;
|
||||
|
||||
// generate an unique id, this is need because anchored layouts find widgets by id
|
||||
static unsigned long id = 1;
|
||||
@@ -74,11 +79,12 @@ void UIWidget::render()
|
||||
|
||||
void UIWidget::renderSelf()
|
||||
{
|
||||
// draw background
|
||||
if(m_image) {
|
||||
g_painter.setColor(m_backgroundColor);
|
||||
m_image->draw(m_rect);
|
||||
}
|
||||
// draw style components in order
|
||||
drawBackground(m_rect);
|
||||
drawBorder(m_rect);
|
||||
drawImage(m_rect);
|
||||
drawIcon(m_rect);
|
||||
drawText(m_rect);
|
||||
}
|
||||
|
||||
void UIWidget::renderChildren()
|
||||
@@ -86,7 +92,10 @@ void UIWidget::renderChildren()
|
||||
// draw children
|
||||
for(const UIWidgetPtr& child : m_children) {
|
||||
// render only visible children with a valid rect inside our rect
|
||||
if(child->isExplicitlyVisible() && child->getRect().isValid() && child->getRect().intersects(m_rect)) {
|
||||
if(child->isExplicitlyVisible() &&
|
||||
child->getRect().isValid() &&
|
||||
child->getRect().intersects(m_rect) &&
|
||||
child->getOpacity() > 0) {
|
||||
// store current graphics opacity
|
||||
int oldOpacity = g_painter.getOpacity();
|
||||
|
||||
@@ -99,13 +108,63 @@ void UIWidget::renderChildren()
|
||||
// debug draw box
|
||||
//g_painter.setColor(Fw::green);
|
||||
//g_painter.drawBoundingRect(child->getRect());
|
||||
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Fw::red);
|
||||
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPos() + Point(2, 0), Fw::red);
|
||||
|
||||
g_painter.setOpacity(oldOpacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIWidget::drawBackground(const Rect& screenCoords)
|
||||
{
|
||||
/*
|
||||
if(m_backgroundColor.a() > 0) {
|
||||
g_painter.setColor(m_backgroundColor);
|
||||
g_painter.drawFilledRect(screenCoords);
|
||||
//g_painter.drawFilledRect(screenCoords.expanded(-m_borderWidth));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void UIWidget::drawBorder(const Rect& screenCoords)
|
||||
{
|
||||
/*
|
||||
if(m_borderWidth > 0 && m_borderColor.a() > 0) {
|
||||
g_painter.bindColor(m_borderColor);
|
||||
g_painter.drawBoundingRect(screenCoords, m_borderWidth);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void UIWidget::drawImage(const Rect& screenCoords)
|
||||
{
|
||||
if(m_image) {
|
||||
g_painter.setColor(m_backgroundColor);
|
||||
m_image->draw(screenCoords);
|
||||
}
|
||||
}
|
||||
|
||||
void UIWidget::drawIcon(const Rect& screenCoords)
|
||||
{
|
||||
if(m_icon) {
|
||||
Rect iconRect;
|
||||
iconRect.resize(m_icon->getSize());
|
||||
iconRect.moveCenter(screenCoords.center());
|
||||
g_painter.setColor(Fw::white);
|
||||
g_painter.drawTexturedRect(iconRect, m_icon);
|
||||
}
|
||||
}
|
||||
|
||||
void UIWidget::drawText(const Rect& screenCoords)
|
||||
{
|
||||
g_painter.setColor(m_foregroundColor);
|
||||
if(m_text.length() > 0 && m_foregroundColor.a() > 0) {
|
||||
Rect textRect = screenCoords;
|
||||
textRect.translate(m_textOffset);
|
||||
m_font->renderText(m_text, textRect, m_textAlign, m_foregroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
void UIWidget::setEnabled(bool enabled)
|
||||
{
|
||||
if(enabled != m_enabled) {
|
||||
@@ -215,6 +274,36 @@ void UIWidget::setRect(const Rect& rect)
|
||||
m_updateEventScheduled = true;
|
||||
}
|
||||
|
||||
void UIWidget::setIcon(const std::string& iconFile)
|
||||
{
|
||||
m_icon = g_textures.getTexture(iconFile);
|
||||
}
|
||||
|
||||
void UIWidget::setText(const std::string& text)
|
||||
{
|
||||
if(m_text != text) {
|
||||
m_text = text;
|
||||
|
||||
// update rect size
|
||||
if(!m_rect.isValid()) {
|
||||
Size textSize = m_font->calculateTextRectSize(m_text);
|
||||
Size newSize = getSize();
|
||||
if(newSize.width() <= 0)
|
||||
newSize.setWidth(textSize.width());
|
||||
if(newSize.height() <= 0)
|
||||
newSize.setHeight(textSize.height());
|
||||
resize(newSize);
|
||||
}
|
||||
|
||||
onTextChange(text);
|
||||
}
|
||||
}
|
||||
|
||||
void UIWidget::setFont(const std::string& fontName)
|
||||
{
|
||||
m_font = g_fonts.getFont(fontName);
|
||||
}
|
||||
|
||||
void UIWidget::bindRectToParent()
|
||||
{
|
||||
Rect boundRect = m_rect;
|
||||
@@ -672,8 +761,8 @@ void UIWidget::updateLayout()
|
||||
void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
try {
|
||||
onStyleApply(styleNode);
|
||||
callLuaField("onStyleApply", styleNode);
|
||||
onStyleApply(styleNode->tag(), styleNode);
|
||||
callLuaField("onStyleApply", styleNode->tag(), styleNode);
|
||||
} catch(Exception& e) {
|
||||
logError("Failed to apply style to widget '", m_id, "' style: ", e.what());
|
||||
}
|
||||
@@ -862,7 +951,7 @@ void UIWidget::updateStyle()
|
||||
m_stateStyle = newStateStyle;
|
||||
}
|
||||
|
||||
void UIWidget::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
// first set id
|
||||
if(const OTMLNodePtr& node = styleNode->get("id"))
|
||||
@@ -878,8 +967,16 @@ void UIWidget::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
}
|
||||
else if(node->tag() == "border-image")
|
||||
setImage(BorderImage::loadFromOTML(node));
|
||||
if(node->tag() == "icon")
|
||||
setIcon(node->value());
|
||||
else if(node->tag() == "text")
|
||||
setText(node->value());
|
||||
else if(node->tag() == "text-align")
|
||||
setTextAlign(Fw::translateAlignment(node->value()));
|
||||
else if(node->tag() == "text-offset")
|
||||
setTextOffset(node->value<Point>());
|
||||
else if(node->tag() == "font")
|
||||
setFont(g_fonts.getFont(node->value()));
|
||||
setFont(node->value());
|
||||
else if(node->tag() == "color")
|
||||
setForegroundColor(node->value<Color>());
|
||||
else if(node->tag() == "background-color")
|
||||
@@ -902,7 +999,7 @@ void UIWidget::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
setHeight(node->value<int>());
|
||||
else if(node->tag() == "fixed-size")
|
||||
setSizeFixed(node->value<bool>());
|
||||
else if(node->tag() == "position")
|
||||
else if(node->tag() == "pos")
|
||||
moveTo(node->value<Point>());
|
||||
else if(node->tag() == "x")
|
||||
setX(node->value<int>());
|
||||
@@ -1007,7 +1104,7 @@ void UIWidget::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
}
|
||||
// lua functions
|
||||
} else if(boost::starts_with(node->tag(), "@")) {
|
||||
// on load once
|
||||
// load once
|
||||
if(m_firstOnStyle) {
|
||||
std::string funcName = node->tag().substr(1);
|
||||
std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]";
|
||||
@@ -1051,6 +1148,17 @@ void UIWidget::onHoverChange(bool hovered)
|
||||
g_ui.getRootWidget()->updateState(Fw::HoverState);
|
||||
}
|
||||
|
||||
|
||||
void UIWidget::onTextChange(const std::string& text)
|
||||
{
|
||||
callLuaField("onTextChange", text);
|
||||
}
|
||||
|
||||
void UIWidget::onFontChange(const std::string& font)
|
||||
{
|
||||
callLuaField("onFontChange", font);
|
||||
}
|
||||
|
||||
bool UIWidget::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers)
|
||||
{
|
||||
if(callLuaField<bool>("onKeyPress", keyCode, keyText, keyboardModifiers))
|
||||
@@ -1140,6 +1248,9 @@ bool UIWidget::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
||||
|
||||
void UIWidget::onMouseRelease(const Point& mousePos, Fw::MouseButton button)
|
||||
{
|
||||
if(isPressed() && getRect().contains(mousePos))
|
||||
callLuaField("onClick");
|
||||
|
||||
callLuaField("onMouseRelease", mousePos, button);
|
||||
|
||||
// do a backup of children list, because it may change while looping it
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <framework/luascript/luaobject.h>
|
||||
#include <framework/graphics/declarations.h>
|
||||
#include <framework/otml/otmlnode.h>
|
||||
#include <framework/graphics/font.h>
|
||||
|
||||
class UIWidget : public LuaObject
|
||||
{
|
||||
@@ -40,9 +41,17 @@ public:
|
||||
void destroy();
|
||||
|
||||
virtual void render();
|
||||
void renderSelf();
|
||||
void renderChildren();
|
||||
virtual void renderSelf();
|
||||
virtual void renderChildren();
|
||||
|
||||
protected:
|
||||
void drawBackground(const Rect& screenCoords);
|
||||
void drawBorder(const Rect& screenCoords);
|
||||
void drawImage(const Rect& screenCoords);
|
||||
void drawIcon(const Rect& screenCoords);
|
||||
void drawText(const Rect& screenCoords);
|
||||
|
||||
public:
|
||||
void setVisible(bool visible);
|
||||
void setEnabled(bool enabled);
|
||||
void setPressed(bool pressed) { m_pressed = pressed; updateState(Fw::PressedState); }
|
||||
@@ -59,7 +68,7 @@ public:
|
||||
void setWidth(int width) { resize(Size(width, getHeight())); }
|
||||
void setHeight(int height) { resize(Size(getWidth(), height)); }
|
||||
void setImage(const ImagePtr& image) { m_image = image; }
|
||||
virtual void setFont(const FontPtr& font) { m_font = font; }
|
||||
void setIcon(const std::string& iconFile);
|
||||
void setOpacity(int opacity) { m_opacity = opacity; }
|
||||
void setBackgroundColor(const Color& color) { m_backgroundColor = color; }
|
||||
void setForegroundColor(const Color& color) { m_foregroundColor = color; }
|
||||
@@ -67,11 +76,16 @@ public:
|
||||
void setMarginRight(int margin) { m_marginRight = margin; updateParentLayout(); }
|
||||
void setMarginBottom(int margin) { m_marginBottom = margin; updateParentLayout(); }
|
||||
void setMarginLeft(int margin) { m_marginLeft = margin; updateParentLayout(); }
|
||||
void setText(const std::string& text);
|
||||
void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; }
|
||||
void setTextOffset(const Point& offset) { m_textOffset = offset; }
|
||||
void setFont(const std::string& fontName);
|
||||
void setSizeFixed(bool fixed) { m_fixedSize = fixed; updateParentLayout(); }
|
||||
void setLastFocusReason(Fw::FocusReason reason) { m_lastFocusReason = reason; }
|
||||
|
||||
void bindRectToParent();
|
||||
void resize(const Size& size) { setRect(Rect(getPosition(), size)); }
|
||||
void resize(const Size& size) { setRect(Rect(getPos(), size)); }
|
||||
void resizeToText() { resize(getTextSize()); }
|
||||
void moveTo(const Point& pos) { setRect(Rect(pos, getSize())); }
|
||||
void hide() { setVisible(false); }
|
||||
void show() { setVisible(true); }
|
||||
@@ -84,6 +98,7 @@ public:
|
||||
void ungrabMouse();
|
||||
void grabKeyboard();
|
||||
void ungrabKeyboard();
|
||||
void clearText() { setText(""); }
|
||||
|
||||
bool isActive() { return hasState(Fw::ActiveState); }
|
||||
bool isEnabled() { return !hasState(Fw::DisabledState); }
|
||||
@@ -111,15 +126,13 @@ public:
|
||||
UILayoutPtr getLayout() { return m_layout; }
|
||||
UIWidgetPtr getParent() { return m_parent.lock(); }
|
||||
UIWidgetPtr getRootParent();
|
||||
Point getPosition() { return m_rect.topLeft(); }
|
||||
Point getPos() { return m_rect.topLeft(); }
|
||||
Size getSize() { return m_rect.size(); }
|
||||
Rect getRect() { return m_rect; }
|
||||
int getX() { return m_rect.x(); }
|
||||
int getY() { return m_rect.y(); }
|
||||
int getWidth() { return m_rect.width(); }
|
||||
int getHeight() { return m_rect.height(); }
|
||||
ImagePtr getImage() { return m_image; }
|
||||
FontPtr getFont() { return m_font; }
|
||||
Color getForegroundColor() { return m_foregroundColor; }
|
||||
Color getBackgroundColor() { return m_backgroundColor; }
|
||||
int getOpacity() { return m_opacity; }
|
||||
@@ -127,6 +140,12 @@ public:
|
||||
int getMarginRight() { return m_marginRight; }
|
||||
int getMarginBottom() { return m_marginBottom; }
|
||||
int getMarginLeft() { return m_marginLeft; }
|
||||
std::string getText() { return m_text; }
|
||||
Fw::AlignmentFlag getTextAlign() { return m_textAlign; }
|
||||
Point getTextOffset() { return m_textOffset; }
|
||||
std::string getFont() { return m_font->getName(); }
|
||||
Size getTextSize() { return m_font->calculateTextRectSize(m_text); }
|
||||
|
||||
Fw::FocusReason getLastFocusReason() { return m_lastFocusReason; }
|
||||
OTMLNodePtr getStyle() { return m_style; }
|
||||
std::string getStyleName() { return m_style->tag(); }
|
||||
@@ -175,27 +194,18 @@ private:
|
||||
void updateStyle();
|
||||
|
||||
protected:
|
||||
/// Triggered when widget style is changed
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
/// Triggered when widget is moved or resized
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect);
|
||||
/// Triggered when widget gets or loses focus
|
||||
virtual void onFocusChange(bool focused, Fw::FocusReason reason);
|
||||
/// Triggered when the mouse enters or leaves widget area
|
||||
virtual void onHoverChange(bool hovered);
|
||||
/// Triggered when user presses key while widget has focus
|
||||
virtual void onTextChange(const std::string& text);
|
||||
virtual void onFontChange(const std::string& font);
|
||||
virtual bool onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers);
|
||||
/// Triggered when user releases key while widget has focus
|
||||
virtual bool onKeyRelease(uchar keyCode, std::string keyText, int keyboardModifiers);
|
||||
/// Triggered when a mouse button is pressed down while mouse pointer is inside widget area
|
||||
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
|
||||
/// Triggered when a mouse button is released
|
||||
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
|
||||
/// Triggered when mouse moves (even when the mouse is outside widget area)
|
||||
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
|
||||
/// Triggered when mouse middle button wheels inside widget area
|
||||
virtual bool onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction);
|
||||
|
||||
friend class UIManager;
|
||||
|
||||
protected:
|
||||
@@ -218,6 +228,7 @@ protected:
|
||||
OTMLNodePtr m_style;
|
||||
OTMLNodePtr m_stateStyle;
|
||||
ImagePtr m_image;
|
||||
TexturePtr m_icon;
|
||||
FontPtr m_font;
|
||||
Color m_backgroundColor;
|
||||
Color m_foregroundColor;
|
||||
@@ -227,6 +238,9 @@ protected:
|
||||
int m_marginRight;
|
||||
int m_marginBottom;
|
||||
int m_marginLeft;
|
||||
std::string m_text;
|
||||
Point m_textOffset;
|
||||
Fw::AlignmentFlag m_textAlign;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -56,9 +56,9 @@ void UIWindow::render()
|
||||
m_font->renderText(m_title, headTextRect, m_titleAlign, m_foregroundColor);
|
||||
}
|
||||
|
||||
void UIWindow::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
void UIWindow::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(OTMLNodePtr node : styleNode->children()) {
|
||||
if(node->tag() == "head-height")
|
||||
@@ -94,7 +94,7 @@ bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
||||
m_moving = true;
|
||||
m_movingReference = mousePos - getRect().topLeft();
|
||||
m_oldIndex = getParent()->getChildIndex(asUIWidget());
|
||||
m_oldPos = getPosition();
|
||||
m_oldPos = getPos();
|
||||
getParent()->moveChildToTop(asUIWidget());
|
||||
}
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ public:
|
||||
std::string getTitle() const { return m_title; }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect);
|
||||
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
|
||||
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
|
||||
|
Reference in New Issue
Block a user