From fdc908787005549b1a1630f4aa38b2a5919a548d Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Sun, 8 Jan 2012 20:32:55 -0200 Subject: [PATCH] implement chat colors, rework on UI layout update system --- modules/addon_terminal/terminal.lua | 1 - modules/client_options/options.lua | 3 +- modules/client_options/options.otui | 6 +- .../core_widgets/messagebox/messagebox.lua | 1 - modules/game/game.otmod | 2 +- modules/game_chat/chat.lua | 51 ------------- modules/game_console/console.lua | 60 ++++++++++++++++ .../chat.otmod => game_console/console.otmod} | 4 +- .../chat.otui => game_console/console.otui} | 12 ++-- modules/game_skills/skills.lua | 1 - modules/game_textmessage/textmessage.lua | 1 + src/framework/CMakeLists.txt | 5 +- src/framework/math/rect.h | 10 +-- src/framework/ui/uianchorlayout.cpp | 34 ++++----- src/framework/ui/uianchorlayout.h | 4 +- src/framework/ui/uilayout.cpp | 23 ++++++ src/framework/ui/uilayout.h | 13 +++- src/framework/ui/uiverticallayout.cpp | 72 ++++++++++--------- src/framework/ui/uiverticallayout.h | 18 +++-- src/framework/ui/uiwidget.cpp | 13 +++- src/framework/ui/uiwidget.h | 2 + src/framework/ui/uiwindow.cpp | 3 +- src/otclient/ui/uigame.cpp | 2 +- 23 files changed, 205 insertions(+), 136 deletions(-) delete mode 100644 modules/game_chat/chat.lua create mode 100644 modules/game_console/console.lua rename modules/{game_chat/chat.otmod => game_console/console.otmod} (74%) rename modules/{game_chat/chat.otui => game_console/console.otui} (75%) diff --git a/modules/addon_terminal/terminal.lua b/modules/addon_terminal/terminal.lua index 8d43f60e..b182a8a4 100644 --- a/modules/addon_terminal/terminal.lua +++ b/modules/addon_terminal/terminal.lua @@ -178,7 +178,6 @@ function Terminal.addLine(text, color) terminalBuffer:getChildByIndex(1):destroy() else terminalBuffer:setHeight(terminalBuffer:getHeight() + LabelHeight) - terminalBuffer:updateParentLayout() end end diff --git a/modules/client_options/options.lua b/modules/client_options/options.lua index 6fd7b4d9..37b5d30c 100644 --- a/modules/client_options/options.lua +++ b/modules/client_options/options.lua @@ -8,7 +8,8 @@ function Options.init() local booleanOptions = { vsync = true, showfps = true, fullscreen = false, - classicControl = false } + classicControl = false, + showLevelInConsole = false} for k,v in pairs(booleanOptions) do Settings.setDefault(k, v) diff --git a/modules/client_options/options.otui b/modules/client_options/options.otui index b3fe2daf..e1308578 100644 --- a/modules/client_options/options.otui +++ b/modules/client_options/options.otui @@ -19,7 +19,7 @@ OptionCheckBox < CheckBox MainWindow id: optionsWindow title: Options - size: 286 140 + size: 286 160 @onEnter: Options.hide() @onEscape: Options.hide() @@ -40,6 +40,10 @@ MainWindow id: classicControl text: Classic control + OptionCheckBox + id: showLevelInConsole + text: Show players level in console + Button text: Ok width: 64 diff --git a/modules/core_widgets/messagebox/messagebox.lua b/modules/core_widgets/messagebox/messagebox.lua index 8f2186db..d74868ec 100644 --- a/modules/core_widgets/messagebox/messagebox.lua +++ b/modules/core_widgets/messagebox/messagebox.lua @@ -20,7 +20,6 @@ function MessageBox.create(title, text, flags) -- set window size based on label size window:setWidth(math.max(label:getWidth() + 48, 120)) window:setHeight(label:getHeight() + 64) - window:updateParentLayout() -- setup messagebox first button local buttonRight = window:getChildById('messageBoxRightButton') diff --git a/modules/game/game.otmod b/modules/game/game.otmod index 51f916ed..ba7d4d99 100644 --- a/modules/game/game.otmod +++ b/modules/game/game.otmod @@ -10,7 +10,7 @@ Module - game_skills - game_textmessage - game_viplist - - game_chat + - game_console - game_outfit onLoad: | diff --git a/modules/game_chat/chat.lua b/modules/game_chat/chat.lua deleted file mode 100644 index 38a143ce..00000000 --- a/modules/game_chat/chat.lua +++ /dev/null @@ -1,51 +0,0 @@ -Chat = {} - --- private variables ---[[ -local SpeakTypes = { - say = { color = }, - whisper = { color = }, - yell, - monsterSay, - npcToPlayer, - cgannelYellow, - channelWhite, - channelRed, - channelOrange, - private, - playerToNpc, - broadcast, - privateRed -} -]]-- - -local chatPanel -local chatBuffer - --- public functions -function Chat.create() - chatPanel = displayUI('chat.otui', { parent = Game.gameBottomPanel } ) - chatBuffer = chatPanel:getChildById('chatBuffer') -end - -function Chat.destroy() - chatPanel:destroy() - chatPanel = nil -end - --- hooked events -local function onCreatureSpeak(name, level, msgtype, message) - style = 'ChatLabel' - if name and level > 0 then - message = name .. ' [' .. level .. ']: ' .. message - style = 'YellowChatLabel' - end - - local label = createWidget(style) - label:setText(message) - chatBuffer:addChild(label) -end - -connect(Game, { onLogin = Chat.create, - onLogout = Chat.destroy, - onCreatureSpeak = onCreatureSpeak}) \ No newline at end of file diff --git a/modules/game_console/console.lua b/modules/game_console/console.lua new file mode 100644 index 00000000..8b69bb71 --- /dev/null +++ b/modules/game_console/console.lua @@ -0,0 +1,60 @@ +Console = {} + +-- private variables +local SpeakTypes = { + say = { color = '#FFFF00' }, + whisper = { color = '#FFFF00' }, + yell = { color = '#FFFF00' }, + monsterSay = { color = '#FE6500' }, + npcToPlayer = { color = '#5FF7F7' }, + channelYellow = { color = '#FFFF00' }, + channelWhite = { color = '#FFFFFF' }, + channelRed = { color = '#F55E5E' }, + channelOrange = { color = '#FE6500' }, + private = { color = '#FFFF00' }, + playerToNpc = { color = '#9F9DFD' }, + broadcast = { color = '#F55E5E' }, + privateRed = { color = '#F55E5E' } +} + +local consolePanel +local consoleBuffer + +-- public functions +function Console.create() + consolePanel = displayUI('console.otui', { parent = Game.gameBottomPanel } ) + consoleBuffer = consolePanel:getChildById('consoleBuffer') +end + +function Console.destroy() + consolePanel:destroy() + consolePanel = nil +end + +function Console.addText(text, color) + color = color or 'white' + + local label = createWidget('ConsoleLabel', consoleBuffer) + label:setText(text) + label:setForegroundColor(color) +end + +-- hooked events +local function onCreatureSpeak(name, level, speaktypedesc, message) + speaktype = SpeakTypes[speaktypedesc] + if speaktype == nil then return end + + if name then + if Options.showLevelInConsole and level > 0 then + message = name .. ' [' .. level .. ']: ' .. message + else + message = name .. ': ' .. message + end + end + + Console.addText(message, speaktype.color) +end + +connect(Game, { onLogin = Console.create, + onLogout = Console.destroy, + onCreatureSpeak = onCreatureSpeak}) \ No newline at end of file diff --git a/modules/game_chat/chat.otmod b/modules/game_console/console.otmod similarity index 74% rename from modules/game_chat/chat.otmod rename to modules/game_console/console.otmod index 43ee0ee5..3a903985 100644 --- a/modules/game_chat/chat.otmod +++ b/modules/game_console/console.otmod @@ -1,7 +1,7 @@ Module - name: game_chat + name: game_console description: Manage chat window author: OTClient team website: https://github.com/edubart/otclient onLoad: | - require 'chat' + require 'console' diff --git a/modules/game_chat/chat.otui b/modules/game_console/console.otui similarity index 75% rename from modules/game_chat/chat.otui rename to modules/game_console/console.otui index 1972c8aa..340e874c 100644 --- a/modules/game_chat/chat.otui +++ b/modules/game_console/console.otui @@ -1,20 +1,18 @@ -ChatLabel < UILabel +ConsoleLabel < UILabel font: verdana-11px-antialised height: 14 - -YellowChatLabel < ChatLabel color: yellow Panel - id: chatPanel + id: consolePanel anchors.fill: parent Panel - id: chatBuffer + id: consoleBuffer anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.bottom: chatLineEdit.top + anchors.bottom: consoleLineEdit.top margin-right: 6 margin-left: 6 margin-bottom: 2 @@ -25,7 +23,7 @@ Panel focusable: false LineEdit - id: chatLineEdit + id: consoleLineEdit anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom diff --git a/modules/game_skills/skills.lua b/modules/game_skills/skills.lua index 153a1a6b..9cb52304 100644 --- a/modules/game_skills/skills.lua +++ b/modules/game_skills/skills.lua @@ -58,7 +58,6 @@ function Skills.onSkillButtonClick(button) else button:setHeight(21 - 6) end - button:updateParentLayout() end end diff --git a/modules/game_textmessage/textmessage.lua b/modules/game_textmessage/textmessage.lua index bda642c2..259bcb72 100644 --- a/modules/game_textmessage/textmessage.lua +++ b/modules/game_textmessage/textmessage.lua @@ -8,6 +8,7 @@ local MessageTypes = { warning = { color = '#F55E5E', showOnConsole = true, windowLocation = 'center' }, eventAdvance = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'center' }, eventDefault = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'bottom' }, + eventOrange = { color = '#FE6500', showOnConsole = true, windowLocation = 'bottom' }, statusDefault = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'bottom' }, infoDescription = { color = '#00EB00', showOnConsole = true, windowLocation = 'center' }, statusSmall = { color = '#FFFFFF', showOnConsole = false, windowLocation = 'bottom' }, diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 1ae3eb32..fc65aa43 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -39,10 +39,9 @@ FIND_PACKAGE(ZLIB REQUIRED) IF(CMAKE_COMPILER_IS_GNUCXX) SET(CXX_WARNS "-Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-unused-variable -Wno-switch -Wno-missing-field-initializers") SET(CMAKE_CXX_FLAGS "-std=gnu++0x -pipe ${CXX_WARNS}") - SET(CMAKE_CXX_FLAGS_FULLDEBUG "-O0 -g3 -ggdb3 -fno-inline") - SET(CMAKE_CXX_FLAGS_DEBUG "-O1 -g -ggdb -fno-inline") + SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline") SET(CMAKE_CXX_FLAGS_RELEASE "-O2") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -ggdb") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -ggdb -fno-inline") SET(CMAKE_CXX_LINK_FLAGS "-static-libgcc -static-libstdc++ -Wl,--as-needed") ENDIF(CMAKE_COMPILER_IS_GNUCXX) diff --git a/src/framework/math/rect.h b/src/framework/math/rect.h index f62b8e95..abc0ace6 100644 --- a/src/framework/math/rect.h +++ b/src/framework/math/rect.h @@ -257,18 +257,18 @@ public: return tmp; } - void bound(const TRect &r) { + void bound(const TRect &r, bool resize = false) { if(isNull() || r.isNull()) return; + if(right() > r.right()) + moveRight(r.right()); + if(bottom() > r.bottom()) + moveBottom(r.bottom()); if(left() < r.left()) moveLeft(r.left()); if(top() < r.top()) moveTop(r.top()); - if(bottom() > r.bottom()) - moveBottom(r.bottom()); - if(right() > r.right()) - moveRight(r.right()); } TRect& operator=(const TRect& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; } diff --git a/src/framework/ui/uianchorlayout.cpp b/src/framework/ui/uianchorlayout.cpp index 36735dcb..0b834342 100644 --- a/src/framework/ui/uianchorlayout.cpp +++ b/src/framework/ui/uianchorlayout.cpp @@ -71,23 +71,6 @@ void UIAnchorLayout::fill(const UIWidgetPtr& anchoredWidget, const std::string& addAnchor(anchoredWidget, Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom); } -void UIAnchorLayout::update() -{ - // reset all anchors groups update state - for(auto& it : m_anchorsGroups) { - UIAnchorGroup& anchorGroup = it.second; - anchorGroup.setUpdated(false); - } - - // update all anchors - for(auto& it : m_anchorsGroups) { - const UIWidgetPtr& widget = it.first; - UIAnchorGroup& anchorGroup = it.second; - if(!anchorGroup.isUpdated()) - updateWidget(widget, anchorGroup); - } -} - void UIAnchorLayout::addWidget(const UIWidgetPtr& widget) { update(); @@ -210,3 +193,20 @@ void UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch widget->setRect(newRect); anchorGroup.setUpdated(true); } + +void UIAnchorLayout::internalUpdate() +{ + // reset all anchors groups update state + for(auto& it : m_anchorsGroups) { + UIAnchorGroup& anchorGroup = it.second; + anchorGroup.setUpdated(false); + } + + // update all anchors + for(auto& it : m_anchorsGroups) { + const UIWidgetPtr& widget = it.first; + UIAnchorGroup& anchorGroup = it.second; + if(!anchorGroup.isUpdated()) + updateWidget(widget, anchorGroup); + } +} diff --git a/src/framework/ui/uianchorlayout.h b/src/framework/ui/uianchorlayout.h index c45adbb4..20197567 100644 --- a/src/framework/ui/uianchorlayout.h +++ b/src/framework/ui/uianchorlayout.h @@ -69,12 +69,14 @@ public: void centerIn(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId); void fill(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId); - void update(); void addWidget(const UIWidgetPtr& widget); void removeWidget(const UIWidgetPtr& widget); UIAnchorLayoutPtr asUIAnchorLayout() { return std::static_pointer_cast(shared_from_this()); } +protected: + void internalUpdate(); + private: void updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup); std::map m_anchorsGroups; diff --git a/src/framework/ui/uilayout.cpp b/src/framework/ui/uilayout.cpp index 6c0bca1b..8d1460de 100644 --- a/src/framework/ui/uilayout.cpp +++ b/src/framework/ui/uilayout.cpp @@ -21,3 +21,26 @@ */ #include "uilayout.h" + +#include + +void UILayout::update() +{ + assert(!m_updating); + m_updating = true; + internalUpdate(); + m_updating = false; +} + +void UILayout::updateLater() +{ + if(m_updateScheduled) + return; + + auto self = asUILayout(); + g_dispatcher.addEvent([self] { + self->m_updateScheduled = false; + self->update(); + }); + m_updateScheduled = true; +} diff --git a/src/framework/ui/uilayout.h b/src/framework/ui/uilayout.h index 91874ae6..b4cfc0de 100644 --- a/src/framework/ui/uilayout.h +++ b/src/framework/ui/uilayout.h @@ -32,16 +32,27 @@ class UILayout : public LuaObject public: UILayout(UIWidgetPtr parentWidget) : m_parentWidget(parentWidget) { } + void update(); + void updateLater(); + virtual void applyStyle(const OTMLNodePtr& styleNode) { } - virtual void update() = 0; virtual void addWidget(const UIWidgetPtr& widget) = 0; virtual void removeWidget(const UIWidgetPtr& widget) = 0; UIWidgetPtr getParentWidget() { return m_parentWidget.lock(); } + bool isUpdating() { return m_updating; } + virtual bool needsUpdatesOnChildChange() { return false; } + + UILayoutPtr asUILayout() { return std::static_pointer_cast(shared_from_this()); } virtual UIAnchorLayoutPtr asUIAnchorLayout() { return nullptr; } + virtual UIVerticalLayoutPtr asUIVerticalLayout() { return nullptr; } protected: + virtual void internalUpdate() = 0; + + Boolean m_updating; + Boolean m_updateScheduled; UIWidgetWeakPtr m_parentWidget; }; diff --git a/src/framework/ui/uiverticallayout.cpp b/src/framework/ui/uiverticallayout.cpp index 3c9ee70f..b9fd0008 100644 --- a/src/framework/ui/uiverticallayout.cpp +++ b/src/framework/ui/uiverticallayout.cpp @@ -23,12 +23,11 @@ #include "uiverticallayout.h" #include "uiwidget.h" #include +#include UIVerticalLayout::UIVerticalLayout(UIWidgetPtr parentWidget) : UILayout(parentWidget) { - m_alignBottom = false; - m_fitParent = false; m_spacing = 0; } @@ -46,7 +45,36 @@ void UIVerticalLayout::applyStyle(const OTMLNodePtr& styleNode) } } -void UIVerticalLayout::update() +void UIVerticalLayout::addWidget(const UIWidgetPtr& widget) +{ + update(); +} + +void UIVerticalLayout::removeWidget(const UIWidgetPtr& widget) +{ + update(); +} + +void UIVerticalLayout::setAlignBottom(bool aliginBottom) +{ + m_alignBottom = aliginBottom; + update(); +} + +void UIVerticalLayout::setSpacing(int spacing) +{ + m_spacing = spacing; + update(); +} + +void UIVerticalLayout::setFitParent(bool fitParent) +{ + m_fitParent = fitParent; + update(); +} + + +void UIVerticalLayout::internalUpdate() { UIWidgetPtr parentWidget = getParentWidget(); UIWidgetList widgets = parentWidget->getChildren(); @@ -88,34 +116,10 @@ void UIVerticalLayout::update() prefferedHeight -= m_spacing; - if(m_fitParent && prefferedHeight != parentWidget->getHeight()) - parentWidget->setHeight(prefferedHeight); -} - -void UIVerticalLayout::addWidget(const UIWidgetPtr& widget) -{ - update(); -} - -void UIVerticalLayout::removeWidget(const UIWidgetPtr& widget) -{ - update(); -} - -void UIVerticalLayout::setAlignBottom(bool aliginBottom) -{ - m_alignBottom = aliginBottom; - update(); -} - -void UIVerticalLayout::setSpacing(int spacing) -{ - m_spacing = spacing; - update(); -} - -void UIVerticalLayout::setFitParent(bool fitParent) -{ - m_fitParent = fitParent; - update(); -} + if(m_fitParent && prefferedHeight != parentWidget->getHeight()) { + // must set the preffered width later + g_dispatcher.addEvent([=] { + parentWidget->setHeight(prefferedHeight); + }); + } +} \ No newline at end of file diff --git a/src/framework/ui/uiverticallayout.h b/src/framework/ui/uiverticallayout.h index 028239e2..5552326f 100644 --- a/src/framework/ui/uiverticallayout.h +++ b/src/framework/ui/uiverticallayout.h @@ -30,18 +30,24 @@ class UIVerticalLayout : public UILayout public: UIVerticalLayout(UIWidgetPtr parentWidget); - virtual void applyStyle(const OTMLNodePtr& styleNode); - virtual void update(); - virtual void addWidget(const UIWidgetPtr& widget); - virtual void removeWidget(const UIWidgetPtr& widget); + void applyStyle(const OTMLNodePtr& styleNode); + void addWidget(const UIWidgetPtr& widget); + void removeWidget(const UIWidgetPtr& widget); void setAlignBottom(bool aliginBottom); void setSpacing(int spacing); void setFitParent(bool fitParent); + bool needsUpdatesOnChildChange() { return m_fitParent; } + + UIVerticalLayoutPtr asUIVerticalLayout() { return std::static_pointer_cast(shared_from_this()); } + +protected: + void internalUpdate(); + private: - bool m_alignBottom; - bool m_fitParent; + Boolean m_alignBottom; + Boolean m_fitParent; int m_spacing; }; diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 9377a0b4..456ec278 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -54,6 +54,9 @@ UIWidget::UIWidget() void UIWidget::destroy() { + if(m_destroyed) + logWarning("attempt to destroy widget '", m_id, "' two times"); + setVisible(false); setEnabled(false); @@ -71,6 +74,8 @@ void UIWidget::destroy() } callLuaField("onDestroy"); + + m_destroyed = true; } void UIWidget::render() @@ -289,7 +294,8 @@ void UIWidget::setRect(const Rect& rect) UIWidgetPtr self = asUIWidget(); g_dispatcher.addEvent([self, oldRect]() { self->m_updateEventScheduled = false; - self->onGeometryChange(oldRect, self->getRect()); + if(oldRect != self->getRect()) + self->onGeometryChange(oldRect, self->getRect()); }); m_updateEventScheduled = true; } @@ -777,6 +783,11 @@ void UIWidget::updateLayout() { if(m_layout) m_layout->update(); + + // children can affect the parent layout + if(UIWidgetPtr parent = getParent()) + if(UILayoutPtr parentLayout = parent->getLayout()) + parentLayout->updateLater(); } void UIWidget::applyStyle(const OTMLNodePtr& styleNode) diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 4178034a..b6abbc17 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -120,6 +120,7 @@ public: bool isFocusable() { return m_focusable; } bool isPhantom() { return m_phantom; } bool isSizeFixed() { return m_fixedSize; } + bool isDestroyed() { return m_destroyed; } bool containsPoint(const Point& point) { return m_rect.contains(point); } bool hasChildren() { return m_children.size() > 0; } bool hasChild(const UIWidgetPtr& child); @@ -230,6 +231,7 @@ protected: Boolean m_loadingStyle; Boolean m_updateStyleScheduled; Boolean m_firstOnStyle; + Boolean m_destroyed; Rect m_rect; UILayoutPtr m_layout; UIWidgetWeakPtr m_parent; diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp index c72053c2..93eb5a5b 100644 --- a/src/framework/ui/uiwindow.cpp +++ b/src/framework/ui/uiwindow.cpp @@ -83,7 +83,8 @@ void UIWindow::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty void UIWindow::onGeometryChange(const Rect& oldRect, const Rect& newRect) { bindRectToParent(); - UIWidget::onGeometryChange(oldRect, newRect); + if(newRect == getRect()) + UIWidget::onGeometryChange(oldRect, newRect); } bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button) diff --git a/src/otclient/ui/uigame.cpp b/src/otclient/ui/uigame.cpp index 08837a75..85eccbd9 100644 --- a/src/otclient/ui/uigame.cpp +++ b/src/otclient/ui/uigame.cpp @@ -27,7 +27,7 @@ bool UIGame::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers) { - UILineEditPtr chatLineEdit = std::dynamic_pointer_cast(getParent()->recursiveGetChildById("chatLineEdit")); + UILineEditPtr chatLineEdit = std::dynamic_pointer_cast(getParent()->recursiveGetChildById("consoleLineEdit")); if(keyboardModifiers == Fw::KeyboardNoModifier) { if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) {