implement chat colors, rework on UI layout update system

This commit is contained in:
Eduardo Bart 2012-01-08 20:32:55 -02:00
parent 23ebcd9048
commit fdc9087870
23 changed files with 205 additions and 136 deletions

View File

@ -178,7 +178,6 @@ function Terminal.addLine(text, color)
terminalBuffer:getChildByIndex(1):destroy() terminalBuffer:getChildByIndex(1):destroy()
else else
terminalBuffer:setHeight(terminalBuffer:getHeight() + LabelHeight) terminalBuffer:setHeight(terminalBuffer:getHeight() + LabelHeight)
terminalBuffer:updateParentLayout()
end end
end end

View File

@ -8,7 +8,8 @@ function Options.init()
local booleanOptions = { vsync = true, local booleanOptions = { vsync = true,
showfps = true, showfps = true,
fullscreen = false, fullscreen = false,
classicControl = false } classicControl = false,
showLevelInConsole = false}
for k,v in pairs(booleanOptions) do for k,v in pairs(booleanOptions) do
Settings.setDefault(k, v) Settings.setDefault(k, v)

View File

@ -19,7 +19,7 @@ OptionCheckBox < CheckBox
MainWindow MainWindow
id: optionsWindow id: optionsWindow
title: Options title: Options
size: 286 140 size: 286 160
@onEnter: Options.hide() @onEnter: Options.hide()
@onEscape: Options.hide() @onEscape: Options.hide()
@ -40,6 +40,10 @@ MainWindow
id: classicControl id: classicControl
text: Classic control text: Classic control
OptionCheckBox
id: showLevelInConsole
text: Show players level in console
Button Button
text: Ok text: Ok
width: 64 width: 64

View File

@ -20,7 +20,6 @@ function MessageBox.create(title, text, flags)
-- set window size based on label size -- set window size based on label size
window:setWidth(math.max(label:getWidth() + 48, 120)) window:setWidth(math.max(label:getWidth() + 48, 120))
window:setHeight(label:getHeight() + 64) window:setHeight(label:getHeight() + 64)
window:updateParentLayout()
-- setup messagebox first button -- setup messagebox first button
local buttonRight = window:getChildById('messageBoxRightButton') local buttonRight = window:getChildById('messageBoxRightButton')

View File

@ -10,7 +10,7 @@ Module
- game_skills - game_skills
- game_textmessage - game_textmessage
- game_viplist - game_viplist
- game_chat - game_console
- game_outfit - game_outfit
onLoad: | onLoad: |

View File

@ -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})

View File

@ -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})

View File

@ -1,7 +1,7 @@
Module Module
name: game_chat name: game_console
description: Manage chat window description: Manage chat window
author: OTClient team author: OTClient team
website: https://github.com/edubart/otclient website: https://github.com/edubart/otclient
onLoad: | onLoad: |
require 'chat' require 'console'

View File

@ -1,20 +1,18 @@
ChatLabel < UILabel ConsoleLabel < UILabel
font: verdana-11px-antialised font: verdana-11px-antialised
height: 14 height: 14
YellowChatLabel < ChatLabel
color: yellow color: yellow
Panel Panel
id: chatPanel id: consolePanel
anchors.fill: parent anchors.fill: parent
Panel Panel
id: chatBuffer id: consoleBuffer
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: chatLineEdit.top anchors.bottom: consoleLineEdit.top
margin-right: 6 margin-right: 6
margin-left: 6 margin-left: 6
margin-bottom: 2 margin-bottom: 2
@ -25,7 +23,7 @@ Panel
focusable: false focusable: false
LineEdit LineEdit
id: chatLineEdit id: consoleLineEdit
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom

View File

@ -58,7 +58,6 @@ function Skills.onSkillButtonClick(button)
else else
button:setHeight(21 - 6) button:setHeight(21 - 6)
end end
button:updateParentLayout()
end end
end end

View File

@ -8,6 +8,7 @@ local MessageTypes = {
warning = { color = '#F55E5E', showOnConsole = true, windowLocation = 'center' }, warning = { color = '#F55E5E', showOnConsole = true, windowLocation = 'center' },
eventAdvance = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'center' }, eventAdvance = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'center' },
eventDefault = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'bottom' }, eventDefault = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'bottom' },
eventOrange = { color = '#FE6500', showOnConsole = true, windowLocation = 'bottom' },
statusDefault = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'bottom' }, statusDefault = { color = '#FFFFFF', showOnConsole = true, windowLocation = 'bottom' },
infoDescription = { color = '#00EB00', showOnConsole = true, windowLocation = 'center' }, infoDescription = { color = '#00EB00', showOnConsole = true, windowLocation = 'center' },
statusSmall = { color = '#FFFFFF', showOnConsole = false, windowLocation = 'bottom' }, statusSmall = { color = '#FFFFFF', showOnConsole = false, windowLocation = 'bottom' },

View File

@ -39,10 +39,9 @@ FIND_PACKAGE(ZLIB REQUIRED)
IF(CMAKE_COMPILER_IS_GNUCXX) 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(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 "-std=gnu++0x -pipe ${CXX_WARNS}")
SET(CMAKE_CXX_FLAGS_FULLDEBUG "-O0 -g3 -ggdb3 -fno-inline") SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline")
SET(CMAKE_CXX_FLAGS_DEBUG "-O1 -g -ggdb -fno-inline")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2") 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") SET(CMAKE_CXX_LINK_FLAGS "-static-libgcc -static-libstdc++ -Wl,--as-needed")
ENDIF(CMAKE_COMPILER_IS_GNUCXX) ENDIF(CMAKE_COMPILER_IS_GNUCXX)

View File

@ -257,18 +257,18 @@ public:
return tmp; return tmp;
} }
void bound(const TRect<T> &r) { void bound(const TRect<T> &r, bool resize = false) {
if(isNull() || r.isNull()) if(isNull() || r.isNull())
return; return;
if(right() > r.right())
moveRight(r.right());
if(bottom() > r.bottom())
moveBottom(r.bottom());
if(left() < r.left()) if(left() < r.left())
moveLeft(r.left()); moveLeft(r.left());
if(top() < r.top()) if(top() < r.top())
moveTop(r.top()); moveTop(r.top());
if(bottom() > r.bottom())
moveBottom(r.bottom());
if(right() > r.right())
moveRight(r.right());
} }
TRect<T>& operator=(const TRect<T>& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; } TRect<T>& operator=(const TRect<T>& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; }

View File

@ -71,23 +71,6 @@ void UIAnchorLayout::fill(const UIWidgetPtr& anchoredWidget, const std::string&
addAnchor(anchoredWidget, Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom); 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) void UIAnchorLayout::addWidget(const UIWidgetPtr& widget)
{ {
update(); update();
@ -210,3 +193,20 @@ void UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
widget->setRect(newRect); widget->setRect(newRect);
anchorGroup.setUpdated(true); 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);
}
}

View File

@ -69,12 +69,14 @@ public:
void centerIn(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId); void centerIn(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId);
void fill(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId); void fill(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId);
void update();
void addWidget(const UIWidgetPtr& widget); void addWidget(const UIWidgetPtr& widget);
void removeWidget(const UIWidgetPtr& widget); void removeWidget(const UIWidgetPtr& widget);
UIAnchorLayoutPtr asUIAnchorLayout() { return std::static_pointer_cast<UIAnchorLayout>(shared_from_this()); } UIAnchorLayoutPtr asUIAnchorLayout() { return std::static_pointer_cast<UIAnchorLayout>(shared_from_this()); }
protected:
void internalUpdate();
private: private:
void updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup); void updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup);
std::map<UIWidgetPtr, UIAnchorGroup> m_anchorsGroups; std::map<UIWidgetPtr, UIAnchorGroup> m_anchorsGroups;

View File

@ -21,3 +21,26 @@
*/ */
#include "uilayout.h" #include "uilayout.h"
#include <framework/core/eventdispatcher.h>
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;
}

View File

@ -32,16 +32,27 @@ class UILayout : public LuaObject
public: public:
UILayout(UIWidgetPtr parentWidget) : m_parentWidget(parentWidget) { } UILayout(UIWidgetPtr parentWidget) : m_parentWidget(parentWidget) { }
void update();
void updateLater();
virtual void applyStyle(const OTMLNodePtr& styleNode) { } virtual void applyStyle(const OTMLNodePtr& styleNode) { }
virtual void update() = 0;
virtual void addWidget(const UIWidgetPtr& widget) = 0; virtual void addWidget(const UIWidgetPtr& widget) = 0;
virtual void removeWidget(const UIWidgetPtr& widget) = 0; virtual void removeWidget(const UIWidgetPtr& widget) = 0;
UIWidgetPtr getParentWidget() { return m_parentWidget.lock(); } UIWidgetPtr getParentWidget() { return m_parentWidget.lock(); }
bool isUpdating() { return m_updating; }
virtual bool needsUpdatesOnChildChange() { return false; }
UILayoutPtr asUILayout() { return std::static_pointer_cast<UILayout>(shared_from_this()); }
virtual UIAnchorLayoutPtr asUIAnchorLayout() { return nullptr; } virtual UIAnchorLayoutPtr asUIAnchorLayout() { return nullptr; }
virtual UIVerticalLayoutPtr asUIVerticalLayout() { return nullptr; }
protected: protected:
virtual void internalUpdate() = 0;
Boolean<false> m_updating;
Boolean<false> m_updateScheduled;
UIWidgetWeakPtr m_parentWidget; UIWidgetWeakPtr m_parentWidget;
}; };

View File

@ -23,12 +23,11 @@
#include "uiverticallayout.h" #include "uiverticallayout.h"
#include "uiwidget.h" #include "uiwidget.h"
#include <framework/otml/otml.h> #include <framework/otml/otml.h>
#include <framework/core/eventdispatcher.h>
UIVerticalLayout::UIVerticalLayout(UIWidgetPtr parentWidget) UIVerticalLayout::UIVerticalLayout(UIWidgetPtr parentWidget)
: UILayout(parentWidget) : UILayout(parentWidget)
{ {
m_alignBottom = false;
m_fitParent = false;
m_spacing = 0; 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(); UIWidgetPtr parentWidget = getParentWidget();
UIWidgetList widgets = parentWidget->getChildren(); UIWidgetList widgets = parentWidget->getChildren();
@ -88,34 +116,10 @@ void UIVerticalLayout::update()
prefferedHeight -= m_spacing; prefferedHeight -= m_spacing;
if(m_fitParent && prefferedHeight != parentWidget->getHeight()) if(m_fitParent && prefferedHeight != parentWidget->getHeight()) {
parentWidget->setHeight(prefferedHeight); // must set the preffered width later
} g_dispatcher.addEvent([=] {
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();
}

View File

@ -30,18 +30,24 @@ class UIVerticalLayout : public UILayout
public: public:
UIVerticalLayout(UIWidgetPtr parentWidget); UIVerticalLayout(UIWidgetPtr parentWidget);
virtual void applyStyle(const OTMLNodePtr& styleNode); void applyStyle(const OTMLNodePtr& styleNode);
virtual void update(); void addWidget(const UIWidgetPtr& widget);
virtual void addWidget(const UIWidgetPtr& widget); void removeWidget(const UIWidgetPtr& widget);
virtual void removeWidget(const UIWidgetPtr& widget);
void setAlignBottom(bool aliginBottom); void setAlignBottom(bool aliginBottom);
void setSpacing(int spacing); void setSpacing(int spacing);
void setFitParent(bool fitParent); void setFitParent(bool fitParent);
bool needsUpdatesOnChildChange() { return m_fitParent; }
UIVerticalLayoutPtr asUIVerticalLayout() { return std::static_pointer_cast<UIVerticalLayout>(shared_from_this()); }
protected:
void internalUpdate();
private: private:
bool m_alignBottom; Boolean<false> m_alignBottom;
bool m_fitParent; Boolean<false> m_fitParent;
int m_spacing; int m_spacing;
}; };

View File

@ -54,6 +54,9 @@ UIWidget::UIWidget()
void UIWidget::destroy() void UIWidget::destroy()
{ {
if(m_destroyed)
logWarning("attempt to destroy widget '", m_id, "' two times");
setVisible(false); setVisible(false);
setEnabled(false); setEnabled(false);
@ -71,6 +74,8 @@ void UIWidget::destroy()
} }
callLuaField("onDestroy"); callLuaField("onDestroy");
m_destroyed = true;
} }
void UIWidget::render() void UIWidget::render()
@ -289,7 +294,8 @@ void UIWidget::setRect(const Rect& rect)
UIWidgetPtr self = asUIWidget(); UIWidgetPtr self = asUIWidget();
g_dispatcher.addEvent([self, oldRect]() { g_dispatcher.addEvent([self, oldRect]() {
self->m_updateEventScheduled = false; self->m_updateEventScheduled = false;
self->onGeometryChange(oldRect, self->getRect()); if(oldRect != self->getRect())
self->onGeometryChange(oldRect, self->getRect());
}); });
m_updateEventScheduled = true; m_updateEventScheduled = true;
} }
@ -777,6 +783,11 @@ void UIWidget::updateLayout()
{ {
if(m_layout) if(m_layout)
m_layout->update(); 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) void UIWidget::applyStyle(const OTMLNodePtr& styleNode)

View File

@ -120,6 +120,7 @@ public:
bool isFocusable() { return m_focusable; } bool isFocusable() { return m_focusable; }
bool isPhantom() { return m_phantom; } bool isPhantom() { return m_phantom; }
bool isSizeFixed() { return m_fixedSize; } bool isSizeFixed() { return m_fixedSize; }
bool isDestroyed() { return m_destroyed; }
bool containsPoint(const Point& point) { return m_rect.contains(point); } bool containsPoint(const Point& point) { return m_rect.contains(point); }
bool hasChildren() { return m_children.size() > 0; } bool hasChildren() { return m_children.size() > 0; }
bool hasChild(const UIWidgetPtr& child); bool hasChild(const UIWidgetPtr& child);
@ -230,6 +231,7 @@ protected:
Boolean<false> m_loadingStyle; Boolean<false> m_loadingStyle;
Boolean<false> m_updateStyleScheduled; Boolean<false> m_updateStyleScheduled;
Boolean<true> m_firstOnStyle; Boolean<true> m_firstOnStyle;
Boolean<false> m_destroyed;
Rect m_rect; Rect m_rect;
UILayoutPtr m_layout; UILayoutPtr m_layout;
UIWidgetWeakPtr m_parent; UIWidgetWeakPtr m_parent;

View File

@ -83,7 +83,8 @@ void UIWindow::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty
void UIWindow::onGeometryChange(const Rect& oldRect, const Rect& newRect) void UIWindow::onGeometryChange(const Rect& oldRect, const Rect& newRect)
{ {
bindRectToParent(); bindRectToParent();
UIWidget::onGeometryChange(oldRect, newRect); if(newRect == getRect())
UIWidget::onGeometryChange(oldRect, newRect);
} }
bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button) bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button)

View File

@ -27,7 +27,7 @@
bool UIGame::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers) bool UIGame::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers)
{ {
UILineEditPtr chatLineEdit = std::dynamic_pointer_cast<UILineEdit>(getParent()->recursiveGetChildById("chatLineEdit")); UILineEditPtr chatLineEdit = std::dynamic_pointer_cast<UILineEdit>(getParent()->recursiveGetChildById("consoleLineEdit"));
if(keyboardModifiers == Fw::KeyboardNoModifier) { if(keyboardModifiers == Fw::KeyboardNoModifier) {
if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) { if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) {