diff --git a/TODO b/TODO index c5c23024..68502d57 100644 --- a/TODO +++ b/TODO @@ -24,28 +24,22 @@ == UI [bart] fix massive hotkeys when holding down a key [bart] tab widgets -[bart] add anchors API [bart] scrollbar [bart] scrollable widgets [bart] grid layout [bart] horizontal box layout [bart] move layout proprieties to widget style -[bart] move UICheckBox to lua -[bart] move UIWindow to lua [bart] multiline text editor widget [bart] multiline rich text widget [bart] create UIMessageBox, UIToolTip and UIInputBox -[bart] rework UI image style -[bart] class UIImage and UIText -[bart] add UI border [bart] fix style inheretance using a style translator [bart] find a way to add new widgets without focusing them [bart] fix moving windows and tooltips conflicts [bart] break UILabel lines [bart] review and make more error prone with more warnings -[bart] a real working border and background property in otui [bart] reapply anchor styles when adding new childs [bart] ui text selection +[bart] implement ui window moving policies break window anchors when moving diff --git a/modules/client_about/about.otui b/modules/client_about/about.otui index c25643c5..3647f376 100644 --- a/modules/client_about/about.otui +++ b/modules/client_about/about.otui @@ -1,6 +1,6 @@ MainWindow id: about - title: Info + text: Info size: 244 221 FlatPanel diff --git a/modules/client_entergame/characterlist.lua b/modules/client_entergame/characterlist.lua index 8da2c6b0..8ff72dc2 100644 --- a/modules/client_entergame/characterlist.lua +++ b/modules/client_entergame/characterlist.lua @@ -10,8 +10,10 @@ local function onCharactersWindowKeyPress(self, keyCode, keyText, keyboardModifi if keyboardModifiers == KeyboardNoModifier then if keyCode == KeyUp or keyCode == KeyTab then characterList:focusPreviousChild(ActiveFocusReason) + return true elseif keyCode == KeyDown then characterList:focusNextChild(ActiveFocusReason) + return true end end return false @@ -59,7 +61,7 @@ function CharacterList.create(characters, premDays) charactersWindow = displayUI('characterlist.otui') characterList = charactersWindow:getChildById('characterList') local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel') - charactersWindow.onKeyPress = onCharactersWindowKeyPress + connect(charactersWindow, {onKeyPress = onCharactersWindowKeyPress }) local focusLabel for i,characterInfo in ipairs(characters) do diff --git a/modules/client_entergame/characterlist.otui b/modules/client_entergame/characterlist.otui index bf459cd8..f54b8901 100644 --- a/modules/client_entergame/characterlist.otui +++ b/modules/client_entergame/characterlist.otui @@ -10,7 +10,7 @@ CharacterListLabel < Label MainWindow id: charactersWindow - title: Character List + text: Character List size: 250 248 @onEnter: CharacterList.doLogin() @onEscape: CharacterList.destroy() @@ -23,6 +23,8 @@ MainWindow margin-bottom: 5 margin-left: 16 margin-right: 16 + padding: 1 + focusable: false Label id: accountStatusLabel diff --git a/modules/client_entergame/entergame.otui b/modules/client_entergame/entergame.otui index a811fad1..323e4a44 100644 --- a/modules/client_entergame/entergame.otui +++ b/modules/client_entergame/entergame.otui @@ -1,6 +1,6 @@ MainWindow id: enterGame - title: Enter Game + text: Enter Game size: 236 240 @onEnter: EnterGame.doLogin() @onEscape: EnterGame.hide() diff --git a/modules/client_options/options.otui b/modules/client_options/options.otui index f9f4d6b3..43043454 100644 --- a/modules/client_options/options.otui +++ b/modules/client_options/options.otui @@ -18,7 +18,7 @@ OptionCheckBox < CheckBox MainWindow id: optionsWindow - title: Options + text: Options size: 286 280 @onEnter: Options.hide() @onEscape: Options.hide() diff --git a/modules/core_lib/util.lua b/modules/core_lib/util.lua index e4455bd8..b91829fd 100644 --- a/modules/core_lib/util.lua +++ b/modules/core_lib/util.lua @@ -99,6 +99,21 @@ function tonumber(v) return oldtonumber(v) end +function signalcall(param, ...) + if type(param) == 'function' then + return param(...) + elseif type(param) == 'table' then + for k,v in pairs(param) do + if param(...) then + return true + end + end + elseif func ~= nil then + error('attempt to call a non function value') + end + return false +end + function runscript(file) g_lua.runScript(resolvepath(file, 2)) end \ No newline at end of file diff --git a/modules/core_styles/styles/windows.otui b/modules/core_styles/styles/windows.otui index c51f877c..0aa2f3c3 100644 --- a/modules/core_styles/styles/windows.otui +++ b/modules/core_styles/styles/windows.otui @@ -3,16 +3,16 @@ Window < UIWindow size: 200 200 opacity: 1 color: white - head-height: 20 - head-text-align: center + text-offset: 0 2 + text-align: top move-policy: free stackable: true image-source: /core_styles/images/window.png image-border: 4 image-border-top: 20 - $pressed: - opacity: 0.75 + //$pressed: + // opacity: 0.75 $disabled: color: #aaaaaa88 @@ -20,8 +20,8 @@ Window < UIWindow MiniWindow < UIWindow font: verdana-11px-antialised size: 192 200 - head-height: 25 - head-text-align: center + text-offset: 0 5 + text-align: top margin-top: 10 margin-left: 6 margin-right: 6 diff --git a/modules/core_widgets/core_widgets.otmod b/modules/core_widgets/core_widgets.otmod index 1b2b7db3..0e7021a3 100644 --- a/modules/core_widgets/core_widgets.otmod +++ b/modules/core_widgets/core_widgets.otmod @@ -12,5 +12,6 @@ Module require 'uicombobox' require 'uiprogressbar' require 'uipopupmenu' + require 'uiwindow' require 'tooltip/tooltip' require 'messagebox/messagebox' \ No newline at end of file diff --git a/modules/core_widgets/messagebox/messagebox.lua b/modules/core_widgets/messagebox/messagebox.lua index d74868ec..cd0314fc 100644 --- a/modules/core_widgets/messagebox/messagebox.lua +++ b/modules/core_widgets/messagebox/messagebox.lua @@ -10,8 +10,9 @@ function MessageBox.create(title, text, flags) setmetatable(box, MessageBox) -- create messagebox window - local window = displayUI('messagebox.otui', { locked = true }) - window:setTitle(title) + local window = displayUI('messagebox.otui') + window:lock() + window:setText(title) local label = window:getChildById('messageBoxLabel') label:setText(text) diff --git a/modules/core_widgets/uiwindow.lua b/modules/core_widgets/uiwindow.lua new file mode 100644 index 00000000..b7de05a0 --- /dev/null +++ b/modules/core_widgets/uiwindow.lua @@ -0,0 +1,17 @@ +UIWindow = extends(UIWidget) + +function UIWindow.create() + local window = UIWindow.internalCreate() + window:setTextAlign(AlignTopCenter) + return window +end + +function UIWindow:onKeyPress(keyCode, keyText, keyboardModifiers) + if keyboardModifiers == KeyboardNoModifier then + if keyCode == KeyReturn or keyCode == KeyEnter then + signalcall(self.onEnter, self) + elseif keyCode == KeyEscape then + signalcall(self.onEscape, self) + end + end +end diff --git a/modules/game_outfit/outfit.otui b/modules/game_outfit/outfit.otui index db7c6a5b..e318fc82 100644 --- a/modules/game_outfit/outfit.otui +++ b/modules/game_outfit/outfit.otui @@ -3,7 +3,7 @@ Color < ColorBox anchors.left: head.right Window - title: Select Outfit + text: Select Outfit size: 550 280 anchors.horizontalCenter: parent.horizontalCenter diff --git a/modules/game_skills/skills.otui b/modules/game_skills/skills.otui index ac0af983..b033aadd 100644 --- a/modules/game_skills/skills.otui +++ b/modules/game_skills/skills.otui @@ -34,7 +34,7 @@ SkillPercentPanel < ProgressBar MiniWindow id: skillWindow - title: Skills + text: Skills size: 200 310 Panel diff --git a/modules/game_viplist/addvip.otui b/modules/game_viplist/addvip.otui index 542a462e..7ba9a150 100644 --- a/modules/game_viplist/addvip.otui +++ b/modules/game_viplist/addvip.otui @@ -1,6 +1,6 @@ MainWindow size: 256 128 - title: Add to VIP list + text: Add to VIP list @onEnter: VipList.addVip() @onEscape: VipList.destroyAddWindow() diff --git a/modules/game_viplist/viplist.otui b/modules/game_viplist/viplist.otui index a40918fa..2e270655 100644 --- a/modules/game_viplist/viplist.otui +++ b/modules/game_viplist/viplist.otui @@ -6,7 +6,7 @@ VipListLabel < GameLabel MiniWindow id: vipWindow - title: VIP List + text: VIP List UIWidget id: vipList diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 8c0f0cc9..271524a8 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -189,7 +189,6 @@ SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgettext.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgetbasestyle.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uilineedit.cpp - ${CMAKE_CURRENT_LIST_DIR}/ui/uiwindow.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uianchorlayout.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiverticallayout.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uilayout.cpp diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 43ed3cf6..6387a19d 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -307,12 +307,6 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("isAlwaysActive", &UILineEdit::isAlwaysActive); g_lua.bindClassMemberFunction("isTextHidden", &UILineEdit::isTextHidden); - // UIWindow - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIWindowPtr(new UIWindow); } ); - g_lua.bindClassMemberFunction("getTitle", &UIWindow::getTitle); - g_lua.bindClassMemberFunction("setTitle", &UIWindow::setTitle); - // UIFrameCounter g_lua.registerClass(); g_lua.bindClassStaticFunction("create", []{ return UIFrameCounterPtr(new UIFrameCounter); } ); diff --git a/src/framework/ui/declarations.h b/src/framework/ui/declarations.h index 4edcd4bd..9ca8997d 100644 --- a/src/framework/ui/declarations.h +++ b/src/framework/ui/declarations.h @@ -29,7 +29,6 @@ class UIManager; class UIWidget; class UILineEdit; class UIFrameCounter; -class UIWindow; class UILayout; class UIVerticalLayout; class UIAnchorLayout; @@ -39,7 +38,6 @@ typedef std::weak_ptr UIWidgetWeakPtr; typedef std::shared_ptr UILineEditPtr; typedef std::shared_ptr UIFrameCounterPtr; -typedef std::shared_ptr UIWindowPtr; typedef std::shared_ptr UILayoutPtr; typedef std::shared_ptr UIVerticalLayoutPtr; typedef std::shared_ptr UIAnchorLayoutPtr; diff --git a/src/framework/ui/ui.h b/src/framework/ui/ui.h index b4932993..f59f469e 100644 --- a/src/framework/ui/ui.h +++ b/src/framework/ui/ui.h @@ -26,7 +26,6 @@ #include "uimanager.h" #include "uiwidget.h" #include "uilineedit.h" -#include "uiwindow.h" #include "uiframecounter.h" #include "uilayout.h" #include "uiverticallayout.h" diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index cc81d58d..935f3057 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -722,7 +722,6 @@ int UIWidget::getChildIndex(const UIWidgetPtr& child) Rect UIWidget::getChildrenRect() { Rect rect = m_rect; - rect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left); rect.expand(-m_padding.top, -m_padding.right, -m_padding.bottom, -m_padding.left); return rect; } diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp index abc477e1..2ed1309f 100644 --- a/src/framework/ui/uiwidgettext.cpp +++ b/src/framework/ui/uiwidgettext.cpp @@ -34,9 +34,7 @@ void UIWidget::initText() void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode) { for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "icon") - setIcon(node->value()); - else if(node->tag() == "text") + if(node->tag() == "text") setText(node->value()); else if(node->tag() == "text-align") setTextAlign(Fw::translateAlignment(node->value())); diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp deleted file mode 100644 index 6ec6f0c2..00000000 --- a/src/framework/ui/uiwindow.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2010-2012 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 "uiwindow.h" -#include "uitranslator.h" -#include -#include -#include - -UIWindow::UIWindow() -{ - m_moving = false; - m_movePolicy = DONT_MOVE; - m_titleAlign = Fw::AlignCenter; - m_headHeight = 0; - m_oldIndex = -1; -} - -void UIWindow::draw() -{ - // render children - UIWidget::draw(); - - // draw window head text - Rect headTextRect = m_rect; - headTextRect.expandTop(-m_headTextOffset.y); - headTextRect.setHeight(m_headHeight); - if(m_titleAlign & Fw::AlignLeft) - headTextRect.expandLeft(-m_headTextOffset.x); - else if(m_titleAlign & Fw::AlignRight) - headTextRect.expandRight(-m_headTextOffset.x); - else { - headTextRect.expandLeft(-m_headTextOffset.x); - headTextRect.expandRight(-m_headTextOffset.x); - } - m_font->renderText(m_title, headTextRect, m_titleAlign, m_color); -} - -void UIWindow::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - - for(OTMLNodePtr node : styleNode->children()) { - if(node->tag() == "head-height") - m_headHeight = node->value(); - else if(node->tag() == "head-text-offset") - m_headTextOffset = node->value(); - else if(node->tag() == "title") - setTitle(node->value()); - else if(node->tag() == "head-text-align") - m_titleAlign = Fw::translateAlignment(node->value()); - else if(node->tag() == "move-policy") { - if(node->value() == "free") - m_movePolicy = FREE_MOVE; - else if(node->value() == "free updated") - m_movePolicy = FREE_UPDATED_MOVE; - else - m_movePolicy = DONT_MOVE; - } - } -} - -void UIWindow::onGeometryChange(const Rect& oldRect, const Rect& newRect) -{ - bindRectToParent(); - if(newRect == getRect()) - UIWidget::onGeometryChange(oldRect, newRect); -} - -bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button) -{ - if(m_movePolicy != DONT_MOVE && button == Fw::MouseLeftButton) { - UIWidgetPtr clickedChild = getChildByPos(mousePos); - //FIXME: recursively check for non phantom children - if(!clickedChild || clickedChild->isPhantom()) { - m_moving = true; - m_movingReference = mousePos - getRect().topLeft(); - m_oldIndex = getParent()->getChildIndex(asUIWidget()); - m_oldPos = getPos(); - getParent()->moveChildToTop(asUIWidget()); - } - } - return UIWidget::onMousePress(mousePos, button); -} - -void UIWindow::onMouseRelease(const Point& mousePos, Fw::MouseButton button) -{ - if(m_moving) { - if(m_movePolicy == FREE_UPDATED_MOVE) { - UIWidgetPtr parent = getParent(); - - // restore position before move - parent->moveChildToIndex(asUIWidget(), m_oldIndex); - setPos(m_oldPos); - - // calculate new index - int newIndex; - for(newIndex=parent->getChildCount();newIndex>1;--newIndex) { - UIWidgetPtr child = parent->getChildByIndex(newIndex); - if(mousePos.y >= child->getRect().top()) - break; - } - - // set the new index - parent->moveChildToIndex(asUIWidget(), newIndex); - updateParentLayout(); - } - m_moving = false; - } - UIWidget::onMouseRelease(mousePos, button); -} - -bool UIWindow::onMouseMove(const Point& mousePos, const Point& mouseMoved) -{ - if(m_moving) { - setPos(mousePos - m_movingReference); - return true; - } - return UIWidget::onMouseMove(mousePos, mouseMoved); -} - -bool UIWindow::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers) -{ - if(keyboardModifiers == Fw::KeyboardNoModifier) { - if(keyCode == Fw::KeyReturn || keyCode == Fw::KeyEnter) { - if(callLuaField("onEnter")) - return true; - } else if(keyCode == Fw::KeyEscape) { - if(callLuaField("onEscape")) - return true; - } - } - return UIWidget::onKeyPress(keyCode, keyText, keyboardModifiers); -} diff --git a/src/framework/ui/uiwindow.h b/src/framework/ui/uiwindow.h deleted file mode 100644 index 8648cb6f..00000000 --- a/src/framework/ui/uiwindow.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010-2012 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 UIWINDOW_H -#define UIWINDOW_H - -#include "uiwidget.h" - -class UIWindow : public UIWidget -{ - enum MovePolicy { - DONT_MOVE = 0, - FREE_MOVE, - FREE_UPDATED_MOVE - }; - -public: - UIWindow(); - virtual void draw(); - - void setTitle(const std::string& title) { m_title = title; } - std::string getTitle() const { return m_title; } - -protected: - virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect); - virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button); - virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button); - virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved); - virtual bool onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers); - -private: - std::string m_title; - bool m_moving; - MovePolicy m_movePolicy; - Fw::AlignmentFlag m_titleAlign; - Point m_headTextOffset; - Point m_movingReference; - Point m_oldPos; - int m_oldIndex; - int m_headHeight; -}; - -#endif