diff --git a/modules/core/core.otmod b/modules/core/core.otmod index 7a0a1201..57a52e66 100644 --- a/modules/core/core.otmod +++ b/modules/core/core.otmod @@ -18,5 +18,6 @@ Module require 'ui' require 'gfx' require 'messagebox/messagebox' + require 'tooltip/tooltip' return true diff --git a/modules/core/tooltip/tooltip.lua b/modules/core/tooltip/tooltip.lua new file mode 100644 index 00000000..b263fff4 --- /dev/null +++ b/modules/core/tooltip/tooltip.lua @@ -0,0 +1,40 @@ +ToolTip = {} + +-- private variables +local currentToolTip + +-- private functions +local function moveToolTip(tooltip) + local pos = getMouseCursorPos() + pos.y = pos.y + 1 + local xdif = getScreenSize().width - (pos.x + tooltip:getWidth()) + if xdif < 2 then + pos.x = pos.x - tooltip:getWidth() - 3 + else + pos.x = pos.x + 10 + end + tooltip:moveTo(pos) +end + +-- public functions +function ToolTip.display(text) + ToolTip.hide() + if text then + currentToolTip = UI.loadAndDisplay('/core/tooltip/tooltip.otui', UI.root) + currentToolTip.onMouseMove = moveToolTip + local label = currentToolTip:getChildById('toolTipText') + label:setText(text) + label:resizeToText() + local size = label:getSize() + size.width = size.width + 4 + size.height = size.height + 4 + currentToolTip:setSize(size) + end +end + +function ToolTip.hide() + if currentToolTip then + currentToolTip:destroy() + currentToolTip = nil + end +end diff --git a/modules/core/tooltip/tooltip.otui b/modules/core/tooltip/tooltip.otui new file mode 100644 index 00000000..12ce8874 --- /dev/null +++ b/modules/core/tooltip/tooltip.otui @@ -0,0 +1,9 @@ +RectPanel + background-color: #111111bb + size: 200 200 + id: toolTip + focusable: false + + Label + id: toolTipText + anchors.centerIn: parent \ No newline at end of file diff --git a/modules/core_styles/styles/buttons.otui b/modules/core_styles/styles/buttons.otui index 4551809c..e1f005ef 100644 --- a/modules/core_styles/styles/buttons.otui +++ b/modules/core_styles/styles/buttons.otui @@ -23,7 +23,17 @@ Button < UIButton color: #999999 background-color: #ffffff88 -TopButton < UIButton +ToolTipButton < UIButton + onHoverChange: | + function(self, hovered) + if hovered then + ToolTip.display(self:getStyle().tooltip) + else + ToolTip:hide() + end + end + +TopButton < ToolTipButton background-color: white size: 26 25 text-translate: 0 0 diff --git a/modules/topmenu/topmenu.otui b/modules/topmenu/topmenu.otui index 7a0d0fca..540204ae 100644 --- a/modules/topmenu/topmenu.otui +++ b/modules/topmenu/topmenu.otui @@ -11,6 +11,7 @@ TopPanel anchors.left: parent.left margin.top: 4 margin.left: 6 + tooltip: Options onClick: Options.create() UIWidget @@ -23,6 +24,7 @@ TopPanel anchors.top: prev.top anchors.left: prev.right margin.left: 6 + tooltip: Enter game with a character onClick: | if Game.isOnline() then CharacterList.show() @@ -41,6 +43,7 @@ TopPanel anchors.right: parent.right margin.top: 4 margin.right: 6 + tooltip: Logout onClick: | if Game.isOnline() then Game.logout(false) @@ -59,6 +62,7 @@ TopPanel anchors.right: prev.left margin.top: 4 margin.right: 6 + tooltip: About OTClient onClick: About.create() UIWidget diff --git a/src/framework/luascript/luabinder.h b/src/framework/luascript/luabinder.h index 9ca5c82d..8a6796f0 100644 --- a/src/framework/luascript/luabinder.h +++ b/src/framework/luascript/luabinder.h @@ -186,6 +186,16 @@ namespace luabinder Tuple>(f); } + template + LuaCppFunction bind_fun(const std::_Bind(Obj*, Holders...)>& f) { + typedef typename std::tuple ArgsTuple; + typedef typename std::tuple HoldersTuple; + typedef typename get_holded_tuple::type Tuple; + return bind_fun_specializer::type, + decltype(f), + Tuple>(f); + } + /// Bind customized functions already bound by std::bind template LuaCppFunction bind_fun(const std::_Bind(Obj*, std::_Placeholder<1>)>& f) { diff --git a/src/framework/luascript/luafunctions.cpp b/src/framework/luascript/luafunctions.cpp index a8c85e10..7605b89b 100644 --- a/src/framework/luascript/luafunctions.cpp +++ b/src/framework/luascript/luafunctions.cpp @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include void LuaInterface::registerFunctions() { @@ -42,6 +45,10 @@ void LuaInterface::registerFunctions() g_lua.bindClassMemberFunction("setWidth", &UIWidget::setWidth); g_lua.bindClassMemberFunction("getHeight", &UIWidget::getHeight); g_lua.bindClassMemberFunction("setHeight", &UIWidget::setHeight); + g_lua.bindClassMemberFunction("getSize", &UIWidget::getSize); + g_lua.bindClassMemberFunction("setSize", &UIWidget::resize); + g_lua.bindClassMemberFunction("getPosition", &UIWidget::getPosition); + g_lua.bindClassMemberFunction("moveTo", &UIWidget::moveTo); g_lua.bindClassMemberFunction("getParent", &UIWidget::getParent); g_lua.bindClassMemberFunction("setParent", &UIWidget::setParent); g_lua.bindClassMemberFunction("getBackgroundColor", &UIWidget::getBackgroundColor); @@ -51,6 +58,7 @@ void LuaInterface::registerFunctions() g_lua.bindClassMemberFunction("getOpacity", &UIWidget::getOpacity); g_lua.bindClassMemberFunction("setOpacity", &UIWidget::setOpacity); g_lua.bindClassMemberFunction("setStyle", &UIWidget::setStyle); + g_lua.bindClassMemberFunction("getStyle", &UIWidget::getStyle); g_lua.bindClassMemberFunction("getMarginTop", &UIWidget::getMarginTop); g_lua.bindClassMemberFunction("setMarginTop", &UIWidget::setMarginTop); g_lua.bindClassMemberFunction("getMarginBottom", &UIWidget::getMarginBottom); @@ -139,4 +147,6 @@ void LuaInterface::registerFunctions() g_lua.bindGlobalFunction("getRootWidget", std::bind(&UIManager::getRootWidget, &g_ui)); g_lua.bindGlobalFunction("addEvent", std::bind(&EventDispatcher::addEvent, &g_dispatcher, _1, false)); g_lua.bindGlobalFunction("scheduleEvent", std::bind(&EventDispatcher::scheduleEvent, &g_dispatcher, _1, _2)); + g_lua.bindGlobalFunction("getMouseCursorPos", std::bind(&Platform::getMouseCursorPos, &g_platform)); + g_lua.bindGlobalFunction("getScreenSize", std::bind(&Graphics::getScreenSize, &g_graphics)); } diff --git a/src/framework/luascript/luavaluecasts.cpp b/src/framework/luascript/luavaluecasts.cpp index d759b060..a285bd8b 100644 --- a/src/framework/luascript/luavaluecasts.cpp +++ b/src/framework/luascript/luavaluecasts.cpp @@ -199,6 +199,33 @@ bool luavalue_cast(int index, Point& point) return true; } +// size +void push_luavalue(const Size& size) +{ + g_lua.newTable(); + g_lua.pushInteger(size.width()); + g_lua.setField("width"); + g_lua.pushInteger(size.height()); + g_lua.setField("height"); +} + +bool luavalue_cast(int index, Size& size) +{ + if(g_lua.isTable(index)) { + g_lua.getField("width", index); + size.setWidth(g_lua.popInteger()); + g_lua.getField("height", index); + size.setHeight(g_lua.popInteger()); + return true; + } else if(g_lua.isString()) { + return Fw::cast(g_lua.toString(index), size); + } else if(g_lua.isNil()) { + size = Size(); + return true; + } + return true; +} + // otml nodes void push_luavalue(const OTMLNodePtr& node) { diff --git a/src/framework/ui/uibutton.cpp b/src/framework/ui/uibutton.cpp index 61e2212a..c0b9cb81 100644 --- a/src/framework/ui/uibutton.cpp +++ b/src/framework/ui/uibutton.cpp @@ -53,9 +53,6 @@ void UIButton::onStyleApply(const OTMLNodePtr& styleNode) m_textTranslate = node->value(); } else if(node->tag() == "text") { m_text = node->value(); - } else if(node->tag() == "onClick") { - g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]"); - luaSetField(node->tag()); } } } diff --git a/src/framework/ui/uiverticallayout.cpp b/src/framework/ui/uiverticallayout.cpp index 0e1963f7..69ab5944 100644 --- a/src/framework/ui/uiverticallayout.cpp +++ b/src/framework/ui/uiverticallayout.cpp @@ -57,7 +57,7 @@ void UIVerticalLayout::update() void UIVerticalLayout::addWidget(const UIWidgetPtr& widget) { - // needed to be correcly sorted on update + // needed to be correctly sorted on the following update widget->setY(9999); update(); } diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 8c07a5d7..c26b424b 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -841,6 +841,11 @@ void UIWidget::onStyleApply(const OTMLNodePtr& styleNode) anchorLayout->addAnchor(asUIWidget(), anchoredEdge, hookedWidgetId, hookedEdge); } + } else if(node->tag() == "onClick" || + node->tag() == "onHoverChange") { + dump << node->tag(); + g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]"); + luaSetField(node->tag()); } } } @@ -858,6 +863,10 @@ void UIWidget::onFocusChange(bool focused, Fw::FocusReason reason) void UIWidget::onHoverChange(bool hovered) { callLuaField("onHoverChange", hovered); + + // check for new hovered elements when the current widget is removed + if(!hovered && !getParent()) + g_ui.getRootWidget()->updateState(Fw::HoverState); } bool UIWidget::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers) diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 92105e56..409374b8 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -119,6 +119,7 @@ public: int getMarginTop() const { return m_marginTop; } int getMarginBottom() const { return m_marginBottom; } Fw::FocusReason getLastFocusReason() const { return m_lastFocusReason; } + OTMLNodePtr getStyle() const { return m_style; } UIWidgetList getChildren() const { return m_children; } UIWidgetPtr getFocusedChild() const { return m_focusedChild; }