implement combobox and do some ui rework

master
Eduardo Bart 12 vuotta sitten
vanhempi 02ae3ac616
commit b8150d160e

@ -1,6 +1,6 @@
OTClient is made available under the MIT License
Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
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

@ -3,6 +3,8 @@
function init()
local box = createWidget('ComboBox')
box:moveTo({x=100, y=8})
box:addOption('Option 1')
box:addOption('Option 2')
displayUI(box)
end

@ -132,3 +132,20 @@ MouseNoButton = 0
MouseLeftButton = 1
MouseRightButton = 2
MouseMidButton = 3
AlignNone = 0
AlignLeft = 1
AlignRight = 2
AlignTop = 4
AlignBottom = 8
AlignHorizontalCenter = 16
AlignVerticalCenter = 32
AlignTopLeft = 5
AlignTopRight = 6
AlignBottomLeft = 9
AlignBottomRight = 10
AlignLeftCenter = 33
AlignRightCenter = 34
AlignTopCenter = 20
AlignBottomCenter = 24
AlignCenter = 48

@ -1,6 +1,7 @@
CheckBox < UICheckBox
size: 12 12
box-size: 12 12
text-align: left
text-offset: 16 -1
color: #aaaaaa
background-color: #ffffffff

@ -2,7 +2,8 @@ ComboBox < UIComboBox
font: verdana-11px-antialised
color: #aaaaaa
size: 86 20
text-margin: 3
text-offset: 3 0
text-align: left
border-image:
source: /core_styles/images/combobox.png
border: 1

@ -7,6 +7,8 @@ Module
onLoad: |
require 'tooltip/tooltip'
require 'messagebox/messagebox'
require 'uibutton'
require 'uilabel'
require 'uicombobox'
require 'uipopupmenu'
return true

@ -49,9 +49,9 @@ local function onWidgetHoverChange(widget, hovered)
end
end
local function onWidgetStyleApply(widget, style)
if style and style.tooltip then
widget.tooltip = style.tooltip
local function onWidgetStyleApply(widget, styleName, styleNode)
if styleNode.tooltip then
widget.tooltip = styleNode.tooltip
end
end

@ -0,0 +1,7 @@
UIButton = extends(UIWidget)
function UIButton.create()
local button = UIButton.internalCreate()
button:setFocusable(false)
return button
end

@ -1 +1,41 @@
UIComboBox = extends(UIWidget)
function UIComboBox.create()
local combobox = UIComboBox.internalCreate()
combobox.options = {}
combobox.currentIndex = -1
return combobox
end
function UIComboBox:setCurrentOption(text)
if not self.options then return end
for i,v in ipairs(self.options) do
if v.text == text and self.currentIndex ~= i then
self.currentIndex = i
self:setText(text)
self:onOptionChange(text, data)
return
end
end
end
function UIComboBox:addOption(text, data)
table.insert(self.options, { text = text, data = data })
local index = #self.options
if index == 1 then self:setCurrentOption(text) end
return index
end
function UIComboBox:onMousePress(mousePos, mouseButton)
local menu = createWidget('PopupMenu', self)
for i,v in ipairs(self.options) do
menu:addOption(v.text, function() self:setCurrentOption(v.text) end)
end
menu:setWidth(self:getWidth())
menu:display({ x = self:getX(), y = self:getY() + self:getHeight() })
return true
end
function UIComboBox:onOptionChange(optionText, optionData)
-- nothing todo
end

@ -0,0 +1,9 @@
UILabel = extends(UIWidget)
function UILabel.create()
local label = UILabel.internalCreate()
label:setPhantom(true)
label:setFocusable(false)
label:setTextAlign(AlignLeft)
return label
end

@ -1,7 +1,5 @@
-- extends UIWidget
UIPopupMenu = extends(UIWidget)
-- public functions
function UIPopupMenu.create()
local menu = UIPopupMenu.internalCreate()
local layout = UIVerticalLayout.create(menu)
@ -10,41 +8,39 @@ function UIPopupMenu.create()
return menu
end
function UIPopupMenu.display(menu, pos)
displayUI(menu, {x = pos.x, y = pos.y})
menu:bindRectToParent()
menu:grabMouse()
menu:grabKeyboard()
return menu
function UIPopupMenu:display(pos)
displayUI(self, {x = pos.x, y = pos.y})
self:bindRectToParent()
self:grabMouse()
self:grabKeyboard()
end
function UIPopupMenu.addOption(menu, optionName, optionCallback)
local optionWidget = createWidget(menu:getStyleName() .. 'Button', menu)
local lastOptionWidget = menu:getLastChild()
function UIPopupMenu:addOption(optionName, optionCallback)
local optionWidget = createWidget(self:getStyleName() .. 'Button', self)
local lastOptionWidget = self:getLastChild()
optionWidget.onClick = function()
optionCallback()
menu:destroy()
self:destroy()
end
optionWidget:setText(optionName)
end
function UIPopupMenu.addSeparator(menu)
local separatorWidget = createWidget(menu:getStyleName() .. 'Separator', menu)
function UIPopupMenu:addSeparator()
createWidget(self:getStyleName() .. 'Separator', self)
end
-- hooked events
function UIPopupMenu.onMousePress(menu, mousePos, mouseButton)
-- clicks outside menu area destroys the menu
if not menu:containsPoint(mousePos) then
menu:destroy()
function UIPopupMenu:onMousePress(mousePos, mouseButton)
-- clicks outside self area destroys the self
if not self:containsPoint(mousePos) then
self:destroy()
return true
end
return false
end
function UIPopupMenu.onKeyPress(menu, keyCode, keyText, keyboardModifiers)
function UIPopupMenu:onKeyPress(keyCode, keyText, keyboardModifiers)
if keyCode == KeyEscape then
menu:destroy()
self:destroy()
return true
end
return false

@ -187,8 +187,6 @@ SET(framework_SOURCES ${framework_SOURCES}
# framework ui
${CMAKE_CURRENT_LIST_DIR}/ui/uimanager.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiwidget.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uilabel.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uibutton.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uilineedit.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uianchorlayout.cpp

@ -198,15 +198,15 @@ namespace Fw
AlignBottom = 8,
AlignHorizontalCenter = 16,
AlignVerticalCenter = 32,
AlignTopLeft = AlignTop | AlignLeft,
AlignTopRight = AlignTop | AlignRight,
AlignBottomLeft = AlignBottom | AlignLeft,
AlignBottomRight = AlignBottom | AlignRight,
AlignLeftCenter = AlignLeft | AlignVerticalCenter,
AlignRightCenter = AlignRight | AlignVerticalCenter,
AlignTopCenter = AlignTop | AlignHorizontalCenter,
AlignBottomCenter = AlignBottom | AlignHorizontalCenter,
AlignCenter = AlignVerticalCenter | AlignHorizontalCenter
AlignTopLeft = AlignTop | AlignLeft, // 5
AlignTopRight = AlignTop | AlignRight, // 6
AlignBottomLeft = AlignBottom | AlignLeft, // 9
AlignBottomRight = AlignBottom | AlignRight, // 10
AlignLeftCenter = AlignLeft | AlignVerticalCenter, // 33
AlignRightCenter = AlignRight | AlignVerticalCenter, // 34
AlignTopCenter = AlignTop | AlignHorizontalCenter, // 20
AlignBottomCenter = AlignBottom | AlignHorizontalCenter, // 24
AlignCenter = AlignVerticalCenter | AlignHorizontalCenter // 48
};
enum AnchorEdge {

@ -36,7 +36,7 @@ public:
bool hasFinished() { return m_finished; }
PointF getPosition() { return m_position; }
PointF getPos() { return m_position; }
PointF getVelocity() { return m_velocity; }
void setPos(const PointF& position) { m_position = position; }

@ -131,7 +131,7 @@ void AttractionAffector::updateParticle(const ParticlePtr& particle, double elap
if(!m_active)
return;
PointF pPosition = particle->getPosition();
PointF pPosition = particle->getPos();
PointF d = PointF(m_position.x - pPosition.x, pPosition.y - m_position.y);
if(d.length() == 0)
return;

@ -37,6 +37,9 @@ void Application::registerLuaFunctions()
g_lua.registerClass<UIWidget>();
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create<UIWidget>);
g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy);
g_lua.bindClassMemberFunction<UIWidget>("render", &UIWidget::render);
g_lua.bindClassMemberFunction<UIWidget>("renderSelf", &UIWidget::renderSelf);
g_lua.bindClassMemberFunction<UIWidget>("renderChildren", &UIWidget::renderChildren);
g_lua.bindClassMemberFunction<UIWidget>("setVisible", &UIWidget::setVisible);
g_lua.bindClassMemberFunction<UIWidget>("setEnabled", &UIWidget::setEnabled);
g_lua.bindClassMemberFunction<UIWidget>("setPressed", &UIWidget::setPressed);
@ -53,7 +56,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("setWidth", &UIWidget::setWidth);
g_lua.bindClassMemberFunction<UIWidget>("setHeight", &UIWidget::setHeight);
//g_lua.bindClassMemberFunction<UIWidget>("setImage", &UIWidget::setImage);
//g_lua.bindClassMemberFunction<UIWidget>("setFont", &UIWidget::setFont);
g_lua.bindClassMemberFunction<UIWidget>("setIcon", &UIWidget::setIcon);
g_lua.bindClassMemberFunction<UIWidget>("setOpacity", &UIWidget::setOpacity);
g_lua.bindClassMemberFunction<UIWidget>("setBackgroundColor", &UIWidget::setBackgroundColor);
g_lua.bindClassMemberFunction<UIWidget>("setForegroundColor", &UIWidget::setForegroundColor);
@ -61,10 +64,15 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("setMarginRight", &UIWidget::setMarginRight);
g_lua.bindClassMemberFunction<UIWidget>("setMarginBottom", &UIWidget::setMarginBottom);
g_lua.bindClassMemberFunction<UIWidget>("setMarginLeft", &UIWidget::setMarginLeft);
g_lua.bindClassMemberFunction<UIWidget>("setText", &UIWidget::setText);
g_lua.bindClassMemberFunction<UIWidget>("setTextAlign", &UIWidget::setTextAlign);
g_lua.bindClassMemberFunction<UIWidget>("setTextOffset", &UIWidget::setTextOffset);
g_lua.bindClassMemberFunction<UIWidget>("setFont", &UIWidget::setFont);
g_lua.bindClassMemberFunction<UIWidget>("setSizeFixed", &UIWidget::setSizeFixed);
g_lua.bindClassMemberFunction<UIWidget>("setLastFocusReason", &UIWidget::setLastFocusReason);
g_lua.bindClassMemberFunction<UIWidget>("bindRectToParent", &UIWidget::bindRectToParent);
g_lua.bindClassMemberFunction<UIWidget>("resize", &UIWidget::resize);
g_lua.bindClassMemberFunction<UIWidget>("resizeToText", &UIWidget::resizeToText);
g_lua.bindClassMemberFunction<UIWidget>("moveTo", &UIWidget::moveTo);
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
g_lua.bindClassMemberFunction<UIWidget>("show", &UIWidget::show);
@ -102,15 +110,13 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("getLayout", &UIWidget::getLayout);
g_lua.bindClassMemberFunction<UIWidget>("getParent", &UIWidget::getParent);
g_lua.bindClassMemberFunction<UIWidget>("getRootParent", &UIWidget::getRootParent);
g_lua.bindClassMemberFunction<UIWidget>("getPosition", &UIWidget::getPosition);
g_lua.bindClassMemberFunction<UIWidget>("getPos", &UIWidget::getPos);
g_lua.bindClassMemberFunction<UIWidget>("getSize", &UIWidget::getSize);
g_lua.bindClassMemberFunction<UIWidget>("getRect", &UIWidget::getRect);
g_lua.bindClassMemberFunction<UIWidget>("getX", &UIWidget::getX);
g_lua.bindClassMemberFunction<UIWidget>("getY", &UIWidget::getY);
g_lua.bindClassMemberFunction<UIWidget>("getWidth", &UIWidget::getWidth);
g_lua.bindClassMemberFunction<UIWidget>("getHeight", &UIWidget::getHeight);
//g_lua.bindClassMemberFunction<UIWidget>("getImage", &UIWidget::getImage);
//g_lua.bindClassMemberFunction<UIWidget>("getFont", &UIWidget::getFont);
g_lua.bindClassMemberFunction<UIWidget>("getForegroundColor", &UIWidget::getForegroundColor);
g_lua.bindClassMemberFunction<UIWidget>("getBackgroundColor", &UIWidget::getBackgroundColor);
g_lua.bindClassMemberFunction<UIWidget>("getOpacity", &UIWidget::getOpacity);
@ -118,6 +124,11 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("getMarginRight", &UIWidget::getMarginRight);
g_lua.bindClassMemberFunction<UIWidget>("getMarginBottom", &UIWidget::getMarginBottom);
g_lua.bindClassMemberFunction<UIWidget>("getMarginLeft", &UIWidget::getMarginLeft);
g_lua.bindClassMemberFunction<UIWidget>("getText", &UIWidget::getText);
g_lua.bindClassMemberFunction<UIWidget>("getTextAlign", &UIWidget::getTextAlign);
g_lua.bindClassMemberFunction<UIWidget>("getTextOffset", &UIWidget::getTextOffset);
g_lua.bindClassMemberFunction<UIWidget>("getFont", &UIWidget::getFont);
g_lua.bindClassMemberFunction<UIWidget>("getTextSize", &UIWidget::getTextSize);
g_lua.bindClassMemberFunction<UIWidget>("getLastFocusReason", &UIWidget::getLastFocusReason);
g_lua.bindClassMemberFunction<UIWidget>("getStyle", &UIWidget::getStyle);
g_lua.bindClassMemberFunction<UIWidget>("getStyleName", &UIWidget::getStyleName);
@ -169,32 +180,30 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIAnchorLayout>("centerIn", &UIAnchorLayout::centerIn);
g_lua.bindClassMemberFunction<UIAnchorLayout>("fill", &UIAnchorLayout::fill);
// UILabel
g_lua.registerClass<UILabel, UIWidget>();
g_lua.bindClassStaticFunction<UILabel>("create", &UIWidget::create<UILabel>);
g_lua.bindClassMemberFunction<UILabel>("getText", &UILabel::getText);
g_lua.bindClassMemberFunction<UILabel>("setText", &UILabel::setText);
g_lua.bindClassMemberFunction("resizeToText", &UILabel::resizeToText);
// UILabel
// UIProgressBar
g_lua.registerClass<UIProgressBar, UIWidget>();
g_lua.bindClassStaticFunction<UIProgressBar>("create", &UIWidget::create<UIProgressBar>);
g_lua.bindClassMemberFunction<UIProgressBar>("getPercent", &UIProgressBar::getPercent);
g_lua.bindClassMemberFunction<UIProgressBar>("setPercent", &UIProgressBar::setPercent);
// UIButton
g_lua.registerClass<UIButton, UIWidget>();
g_lua.bindClassStaticFunction<UIButton>("create", &UIWidget::create<UIButton>);
g_lua.bindClassMemberFunction<UIButton>("getText", &UIButton::getText);
g_lua.bindClassMemberFunction<UIButton>("setText", &UIButton::setText);
// UILineEdit
g_lua.registerClass<UILineEdit, UIWidget>();
g_lua.bindClassStaticFunction<UILineEdit>("create", &UIWidget::create<UILineEdit>);
g_lua.bindClassMemberFunction<UILineEdit>("getText", &UILineEdit::getText);
g_lua.bindClassMemberFunction<UILineEdit>("setText", &UILineEdit::setText);
g_lua.bindClassMemberFunction<UILineEdit>("clearText", &UILineEdit::clearText);
g_lua.bindClassMemberFunction<UILineEdit>("setTextHorizontalMargin", &UILineEdit::setTextHorizontalMargin);
g_lua.bindClassMemberFunction<UILineEdit>("setCursorPos", &UILineEdit::setCursorPos);
g_lua.bindClassMemberFunction<UILineEdit>("setCursorEnabled", &UILineEdit::setCursorEnabled);
g_lua.bindClassMemberFunction<UILineEdit>("setTextHidden", &UILineEdit::setTextHidden);
g_lua.bindClassMemberFunction<UILineEdit>("setAlwaysActive", &UILineEdit::setAlwaysActive);
g_lua.bindClassMemberFunction<UILineEdit>("moveCursor", &UILineEdit::moveCursor);
g_lua.bindClassMemberFunction<UILineEdit>("appendText", &UILineEdit::appendText);
g_lua.bindClassMemberFunction<UILineEdit>("removeCharacter", &UILineEdit::removeCharacter);
g_lua.bindClassMemberFunction<UILineEdit>("getDisplayedText", &UILineEdit::getDisplayedText);
g_lua.bindClassMemberFunction<UILineEdit>("getTextPos", &UILineEdit::getTextPos);
g_lua.bindClassMemberFunction<UILineEdit>("getTextHorizontalMargin", &UILineEdit::getTextHorizontalMargin);
g_lua.bindClassMemberFunction<UILineEdit>("getCursorPos", &UILineEdit::getCursorPos);
g_lua.bindClassMemberFunction<UILineEdit>("isCursorEnabled", &UILineEdit::isCursorEnabled);
g_lua.bindClassMemberFunction<UILineEdit>("isAlwaysActive", &UILineEdit::isAlwaysActive);
g_lua.bindClassMemberFunction<UILineEdit>("isTextHidden", &UILineEdit::isTextHidden);
// UICheckBox
g_lua.registerClass<UICheckBox, UIWidget>();
@ -202,7 +211,6 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UICheckBox>("isChecked", &UICheckBox::isChecked);
g_lua.bindClassMemberFunction<UICheckBox>("setChecked", &UICheckBox::setChecked);
// UIWindow
g_lua.registerClass<UIWindow, UIWidget>();
g_lua.bindClassStaticFunction<UIWindow>("create", &UIWidget::create<UIWindow>);

@ -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)
{
m_cursorPos = text.length();
blinkCursor();
update();
UIWidget::onTextChange(text);
}
void UILineEdit::onFontChange(const std::string& font)
{
UIWidget::onStyleApply(styleNode);
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);

@ -98,7 +98,7 @@ void Game::processTextMessage(int type, const std::string& message)
void Game::processInventoryChange(int slot, const ItemPtr& item)
{
if(item)
item->setPosition(Position(65535, slot, 0));
item->setPos(Position(65535, slot, 0));
g_lua.callGlobalField("Game","onInventoryChange", slot, item);
}
@ -162,8 +162,8 @@ void Game::turn(Otc::Direction direction)
void Game::look(const ThingPtr& thing)
{
// thing is at map
if(thing->getPosition().x != 65535) {
Position tilePos = thing->getPosition();
if(thing->getPos().x != 65535) {
Position tilePos = thing->getPos();
TilePtr tile = nullptr;
int stackpos = -1;
@ -182,21 +182,21 @@ void Game::look(const ThingPtr& thing)
}
// thing is at inventory
else
m_protocolGame->sendLookAt(thing->getPosition(), thing->getId(), 0);
m_protocolGame->sendLookAt(thing->getPos(), thing->getId(), 0);
}
void Game::use(const ThingPtr& thing)
{
// thing is at map
if(thing->getPosition().x != 65535) {
TilePtr tile = g_map.getTile(thing->getPosition());
if(thing->getPos().x != 65535) {
TilePtr tile = g_map.getTile(thing->getPos());
int stackpos = tile->getThingStackpos(thing);
if(stackpos != -1)
m_protocolGame->sendUseItem(thing->getPosition(), thing->getId(), stackpos, 0);
m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), stackpos, 0);
}
// thing is at inventory
else
m_protocolGame->sendUseItem(thing->getPosition(), thing->getId(), 0, 0); // last 0 has something to do with container
m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), 0, 0); // last 0 has something to do with container
}
void Game::talkChannel(int channelType, int channelId, const std::string& message)

@ -41,7 +41,7 @@ void Item::draw(const Point& p)
internalDraw(p, b);
}
void Item::setPosition(const Position& position)
void Item::setPos(const Position& position)
{
if(m_type->properties[ThingType::IsGround]) {
m_xPattern = position.x % m_type->dimensions[ThingType::PatternX];
@ -49,7 +49,7 @@ void Item::setPosition(const Position& position)
m_zPattern = position.z % m_type->dimensions[ThingType::PatternZ];
}
Thing::setPosition(position);
Thing::setPos(position);
}
void Item::setData(int data)

@ -37,7 +37,7 @@ public:
void draw(const Point& p);
void setPosition(const Position &position);
void setPos(const Position &position);
void setData(int data);
int getData() { return m_data; }

@ -35,7 +35,7 @@ void LocalPlayer::clientWalk(Otc::Direction direction)
{
// We're not walking, so start a client walk.
if(!m_walking) {
Position newPos = m_position + Position::getPositionFromDirection(direction);
Position newPos = m_position + Position::getPosFromDirection(direction);
Creature::walk(newPos, false);
m_clientWalking = true;
}
@ -49,7 +49,7 @@ void LocalPlayer::walk(const Position& position, bool inverse)
if(m_clientWalking) {
m_clientWalking = false;
Position pos = Position::getPositionFromDirection(m_direction);
Position pos = Position::getPosFromDirection(m_direction);
Point walkOffset = Point(m_walkOffset.x - pos.x * 32,
m_walkOffset.y - pos.y * 32);
@ -97,7 +97,7 @@ bool LocalPlayer::canWalk(Otc::Direction direction)
return false;
}
Position newPos = m_position + Position::getPositionFromDirection(direction);
Position newPos = m_position + Position::getPosFromDirection(direction);
TilePtr tile = g_map.getTile(newPos);
if(!tile->isWalkable()) {
// TODO: create enum for 17, white message on screen bottom and console.

@ -88,7 +88,7 @@ void Map::draw(const Rect& rect)
// after drawing all tiles, draw shots
for(const MissilePtr& shot : m_missilesAtFloor[iz]) {
Position missilePos = shot->getPosition();
Position missilePos = shot->getPos();
shot->draw(positionTo2D(missilePos) - m_drawOffset);
}
}
@ -132,7 +132,7 @@ void Map::draw(const Rect& rect)
// draw animated text
for(auto it = m_animatedTexts.begin(), end = m_animatedTexts.end(); it != end; ++it) {
Point pos = positionTo2D((*it)->getPosition()) - m_drawOffset;
Point pos = positionTo2D((*it)->getPos()) - m_drawOffset;
pos.x *= horizontalStretchFactor;
pos.y *= verticalStretchFactor;
(*it)->draw(rect.topLeft() + pos);
@ -140,7 +140,7 @@ void Map::draw(const Rect& rect)
// draw static text
for(auto it = m_staticTexts.begin(), end = m_staticTexts.end(); it != end; ++it) {
Point pos = positionTo2D((*it)->getPosition()) - m_drawOffset;
Point pos = positionTo2D((*it)->getPos()) - m_drawOffset;
pos.x *= horizontalStretchFactor;
pos.y *= verticalStretchFactor;
(*it)->draw(rect.topLeft() + pos);
@ -246,7 +246,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
m_creatures[creature->getId()] = creature;
}
else if(MissilePtr shot = thing->asMissile()) {
m_missilesAtFloor[shot->getPosition().z].push_back(shot);
m_missilesAtFloor[shot->getPos().z].push_back(shot);
}
else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) {
m_animatedTexts.push_back(animatedText);
@ -255,7 +255,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
bool mustAdd = true;
for(auto it = m_staticTexts.begin(), end = m_staticTexts.end(); it != end; ++it) {
StaticTextPtr cStaticText = *it;
if(cStaticText->getPosition() == pos) {
if(cStaticText->getPos() == pos) {
// try to combine messages
if(cStaticText->addMessage(staticText->getName(), staticText->getMessageType(), staticText->getFirstMessage())) {
mustAdd = false;
@ -276,7 +276,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
}
thing->start();
thing->setPosition(pos);
thing->setPos(pos);
}
ThingPtr Map::getThing(const Position& pos, int stackPos)
@ -298,9 +298,9 @@ void Map::removeThing(const ThingPtr& thing)
return;
if(MissilePtr shot = thing->asMissile()) {
auto it = std::find(m_missilesAtFloor[shot->getPosition().z].begin(), m_missilesAtFloor[shot->getPosition().z].end(), shot);
if(it != m_missilesAtFloor[shot->getPosition().z].end()) {
m_missilesAtFloor[shot->getPosition().z].erase(it);
auto it = std::find(m_missilesAtFloor[shot->getPos().z].begin(), m_missilesAtFloor[shot->getPos().z].end(), shot);
if(it != m_missilesAtFloor[shot->getPos().z].end()) {
m_missilesAtFloor[shot->getPos().z].erase(it);
}
return;
}
@ -317,7 +317,7 @@ void Map::removeThing(const ThingPtr& thing)
return;
}
if(TilePtr& tile = m_tiles[thing->getPosition()])
if(TilePtr& tile = m_tiles[thing->getPos()])
tile->removeThing(thing);
}

@ -44,10 +44,10 @@ public:
virtual void draw(const Point& p) = 0;
void setId(int id);
virtual void setPosition(const Position& position) { m_position = position; }
virtual void setPos(const Position& position) { m_position = position; }
int getId() const { return m_id; }
Position getPosition() const { return m_position; }
Position getPos() const { return m_position; }
int getStackPriority();
virtual ThingType *getType();
int getAnimationPhases() { return m_type->dimensions[ThingType::AnimationPhases]; }

@ -44,7 +44,7 @@ public:
ThingPtr removeThing(int stackPos);
ThingPtr removeThing(const ThingPtr& thing);
const Position& getPosition() { return m_position; }
const Position& getPos() { return m_position; }
int getDrawElevation() { return m_drawElevation; }
std::vector<CreaturePtr> getCreatures();
ItemPtr getGround();

@ -535,7 +535,7 @@ void ProtocolGame::parseMagicEffect(InputMessage& msg)
EffectPtr effect = EffectPtr(new Effect());
effect->setId(effectId);
effect->setPosition(pos);
effect->setPos(pos);
g_map.addThing(effect, pos);
}
@ -547,7 +547,7 @@ void ProtocolGame::parseAnimatedText(InputMessage& msg)
std::string text = msg.getString();
AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText);
animatedText->setPosition(position);
animatedText->setPos(position);
animatedText->setColor(color);
animatedText->setText(text);

@ -41,12 +41,12 @@ void UICreature::render()
renderChildren();
}
void UICreature::onStyleApply(const OTMLNodePtr& styleNode)
void UICreature::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
for(OTMLNodePtr node : styleNode->children()) {
if(node->tag() == "creature-margin")
m_creatureMargin = node->value<int>();
}
UIWidget::onStyleApply(styleNode);
UIWidget::onStyleApply(styleName, styleNode);
}

@ -38,7 +38,7 @@ public:
CreaturePtr getCreature() { return m_creature; }
protected:
virtual void onStyleApply(const OTMLNodePtr& styleNode);
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
private:
CreaturePtr m_creature;

@ -41,12 +41,12 @@ void UIItem::render()
renderChildren();
}
void UIItem::onStyleApply(const OTMLNodePtr& styleNode)
void UIItem::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
for(OTMLNodePtr node : styleNode->children()) {
if(node->tag() == "item margin")
m_itemMargin = node->value<int>();
}
UIWidget::onStyleApply(styleNode);
UIWidget::onStyleApply(styleName, styleNode);
}

@ -37,7 +37,7 @@ public:
ItemPtr getItem() { return m_item; }
protected:
virtual void onStyleApply(const OTMLNodePtr& styleNode);
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
private:
ItemPtr m_item;

@ -46,14 +46,14 @@ void UIMap::render()
renderChildren();
}
void UIMap::onStyleApply(const OTMLNodePtr& styleNode)
void UIMap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
for(OTMLNodePtr node : styleNode->children()) {
if(node->tag() == "map margin")
m_mapMargin = node->value<int>();
}
UIWidget::onStyleApply(styleNode);
UIWidget::onStyleApply(styleName, styleNode);
}
bool UIMap::onMousePress(const Point& mousePos, Fw::MouseButton button)

@ -33,7 +33,7 @@ public:
void render();
protected:
virtual void onStyleApply(const OTMLNodePtr& styleNode);
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect);

@ -33,7 +33,7 @@ public:
Position() : x(-1), y(-1), z(-1) { }
Position(int x, int y, int z) : x(x), y(y), z(z) { }
static Position getPositionFromDirection(Otc::Direction direction) {
static Position getPosFromDirection(Otc::Direction direction) {
switch(direction) {
case Otc::North:
return Position( 0, -1, 0);

@ -136,142 +136,6 @@
<item> displayUI </item>
<item> createWidget </item>
</list>
<list name="otclient-core-constants">
<item> AnchorNone </item>
<item> AnchorTop </item>
<item> AnchorBottom </item>
<item> AnchorLeft </item>
<item> AnchorRight </item>
<item> AnchorVerticalCenter </item>
<item> AnchorHorizontalCenter </item>
<item> LogDebug </item>
<item> LogInfo </item>
<item> LogWarning </item>
<item> LogError </item>
<item> LogFatal </item>
<item> ActiveFocusReason </item>
<item> KeyUnknown </item>
<item> KeyEscape </item>
<item> KeyTab </item>
<item> KeyBackspace </item>
<item> KeyReturn </item>
<item> KeyEnter </item>
<item> KeyInsert </item>
<item> KeyDelete </item>
<item> KeyPause </item>
<item> KeyPrintScreen </item>
<item> KeyHome </item>
<item> KeyEnd </item>
<item> KeyPageUp </item>
<item> KeyPageDown </item>
<item> KeyUp </item>
<item> KeyDown </item>
<item> KeyLeft </item>
<item> KeyRight </item>
<item> KeyNumLock </item>
<item> KeyScrollLock </item>
<item> KeyCapsLock </item>
<item> KeyCtrl </item>
<item> KeyShift </item>
<item> KeyAlt </item>
<item> KeyAltGr </item>
<item> KeyMeta </item>
<item> KeyMenu </item>
<item> KeySpace </item>
<item> KeyExclamation </item>
<item> KeyQuote </item>
<item> KeyNumberSign </item>
<item> KeyDollar </item>
<item> KeyPercent </item>
<item> KeyAmpersand </item>
<item> KeyApostrophe </item>
<item> KeyLeftParen </item>
<item> KeyRightParen </item>
<item> KeyAsterisk </item>
<item> KeyPlus </item>
<item> KeyComma </item>
<item> KeyMinus </item>
<item> KeyPeriod </item>
<item> KeySlash </item>
<item> Key0 </item>
<item> Key1 </item>
<item> Key2 </item>
<item> Key3 </item>
<item> Key4 </item>
<item> Key5 </item>
<item> Key6 </item>
<item> Key7 </item>
<item> Key8 </item>
<item> Key9 </item>
<item> KeyColon </item>
<item> KeySemicolon </item>
<item> KeyLess </item>
<item> KeyEqual </item>
<item> KeyGreater </item>
<item> KeyQuestion </item>
<item> KeyAtSign </item>
<item> KeyA </item>
<item> KeyB </item>
<item> KeyC </item>
<item> KeyD </item>
<item> KeyE </item>
<item> KeyF </item>
<item> KeyG </item>
<item> KeyH </item>
<item> KeyI </item>
<item> KeyJ </item>
<item> KeyK </item>
<item> KeyL </item>
<item> KeyM </item>
<item> KeyN </item>
<item> KeyO </item>
<item> KeyP </item>
<item> KeyQ </item>
<item> KeyR </item>
<item> KeyS </item>
<item> KeyT </item>
<item> KeyU </item>
<item> KeyV </item>
<item> KeyW </item>
<item> KeyX </item>
<item> KeyY </item>
<item> KeyZ </item>
<item> KeyLeftBracket </item>
<item> KeyBackslash </item>
<item> KeyRightBracket </item>
<item> KeyCaret </item>
<item> KeyUnderscore </item>
<item> KeyGrave </item>
<item> KeyLeftCurly </item>
<item> KeyBar </item>
<item> KeyRightCurly </item>
<item> KeyTilde </item>
<item> KeyF1 </item>
<item> KeyF2 </item>
<item> KeyF3 </item>
<item> KeyF4 </item>
<item> KeyF5 </item>
<item> KeyF6 </item>
<item> KeyF7 </item>
<item> KeyF8 </item>
<item> KeyF9 </item>
<item> KeyF10 </item>
<item> KeyF11 </item>
<item> KeyF12 </item>
<item> KeyboardNoModifier </item>
<item> KeyboardCtrlModifier </item>
<item> KeyboardAltModifier </item>
<item> KeyboardShiftModifier </item>
<item> MouseNoButton </item>
<item> MouseLeftButton </item>
<item> MouseRightButton </item>
<item> MouseMidButton </item>
</list>
<list name="attention">
<item> TODO </item>
<item> FIXME </item>
@ -302,7 +166,6 @@
<RegExpr attribute="Keyword" context="#stay" beginRegion="chunk" String="\bfunction\b" />
<keyword attribute="Keyword" context="#stay" String="keywords" />
<keyword attribute="Keyword" context="#stay" String="pseudo-variables" />
<keyword attribute="Otclient Core Const" context="#stay" String="otclient-core-constants" />
<RegExpr attribute="Keyword" context="#stay" endRegion="chunk" beginRegion="chunk" String="\belse\b" />
<RegExpr attribute="Keyword" context="#stay" endRegion="chunk" beginRegion="chunk" String="\belseif\b" />
<RegExpr attribute="Keyword" context="#stay" beginRegion="chunk" String="\bdo\b" />
@ -358,7 +221,6 @@
<itemData name="Lua Base Func" defStyleNum="dsNormal" color="#0057AE"/>
<itemData name="Otclient Core Func" defStyleNum="dsKeyword" color="#0057AE"/>
<itemData name="Const" defStyleNum="dsNormal" color="#a800ff"/>
<itemData name="Otclient Core Const" defStyleNum="dsNormal" color="#a42a38"/>
<itemData name="Global Class" defStyleNum="dsKeyword" color="#006E28"/>
<itemData name="Keyword" defStyleNum="dsKeyword"/>
<itemData name="Error" defStyleNum="dsError"/>

Ladataan…
Peruuta
Tallenna