From 99ff5ce24cba5f4285732d1d795d99da58dd6007 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Tue, 24 Jan 2012 22:50:30 -0200 Subject: [PATCH] implement line wrap for text messages --- modules/game_textmessage/textmessage.lua | 23 ++-- modules/game_textmessage/textmessage.otui | 5 +- src/framework/graphics/font.cpp | 53 +++++++++ src/framework/graphics/font.h | 2 + src/framework/luafunctions.cpp | 1 + src/framework/ui/uiwidget.h | 1 + src/framework/ui/uiwidgettext.cpp | 5 + src/otclient/net/protocolcodes.h | 125 ++++++++-------------- 8 files changed, 120 insertions(+), 95 deletions(-) diff --git a/modules/game_textmessage/textmessage.lua b/modules/game_textmessage/textmessage.lua index 4cda34c1..d25ba262 100644 --- a/modules/game_textmessage/textmessage.lua +++ b/modules/game_textmessage/textmessage.lua @@ -5,16 +5,15 @@ importStyle 'textmessage.otui' -- private variables local MessageTypes = { - consoleRed = { color = '#F55E5E', consoleTab = 'Server Log' }, - eventOrange = { color = '#FE6500', consoleTab = 'Default' }, - consoleOrange = { color = '#FE6500', consoleTab = 'Default' }, - warning = { color = '#F55E5E', consoleTab = 'Server Log', windowLocation = 'center' }, - eventAdvance = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showEventMessagesInConsole' }, - eventDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showEventMessagesInConsole' }, - statusDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showStatusMessagesInConsole' }, - infoDescription = { color = '#00EB00', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showInfoMessagesInConsole' }, - statusSmall = { color = '#FFFFFF', windowLocation = 'bottom' }, - consoleBlue = { color = '#9F9DFD', consoleTab = 'Default' }, + consoleRed = { color = '#F55E5E', consoleTab = 'Default' }, -- 18 + consoleOrange = { color = '#FE6500', consoleTab = 'Default' }, -- 19/20 + consoleBlue = { color = '#9F9DFD', consoleTab = 'Default' }, -- 27 + warning = { color = '#F55E5E', consoleTab = 'Server Log', windowLocation = 'center' }, -- 21 + infoDescription = { color = '#00EB00', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showInfoMessagesInConsole' }, -- 25 + eventAdvance = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showEventMessagesInConsole' }, -- 22 + eventDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showEventMessagesInConsole' }, -- 23 + statusDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showStatusMessagesInConsole' }, -- 24 + statusSmall = { color = '#FFFFFF', windowLocation = 'bottom' }, -- 26 } local bottomLabelWidget @@ -48,6 +47,10 @@ local function displayMessage(msgtype, msg, time) label:setStyle(style) label:setColor(msgtype.color) + if msgtype.windowLocation == 'center' then + label:wrapText() + end + if not time then time = math.max(#msg * 75, 3000) else diff --git a/modules/game_textmessage/textmessage.otui b/modules/game_textmessage/textmessage.otui index aad8bee6..9a8ef01f 100644 --- a/modules/game_textmessage/textmessage.otui +++ b/modules/game_textmessage/textmessage.otui @@ -2,9 +2,8 @@ CenterLabel < GameLabel font: verdana-11px-rounded height: 64 text-align: center - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: parent.right + anchors.centerIn: parent + size: 360 264 BottomLabel < GameLabel font: verdana-11px-rounded diff --git a/src/framework/graphics/font.cpp b/src/framework/graphics/font.cpp index a0bebd12..c61ef2e6 100644 --- a/src/framework/graphics/font.cpp +++ b/src/framework/graphics/font.cpp @@ -282,3 +282,56 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize) m_glyphsSize[glyph].resize(width, m_glyphHeight); } } + +std::string Font::wrapText(const std::string& text, int maxWidth) +{ + std::string outText; + std::string line; + std::vector words; + std::vector wordsSplit = Fw::split(text); + + // break huge words into small ones + for(uint i=0;i maxWidth) { + std::string newWord; + for(uint j=0;j maxWidth) { + newWord += "-"; + words.push_back(newWord); + newWord = ""; + } + + newWord += word[j]; + } + + words.push_back(newWord); + } else + words.push_back(word); + } + + // compose lines + for(uint i=0;i maxWidth) { + if(!line.empty()) + outText += line.substr(0, line.length()-1) + "\n"; + line = ""; + } + + line += words[i] + " "; + } + + outText += line; + outText = outText.substr(0, outText.length()-1); + + return outText; +} \ No newline at end of file diff --git a/src/framework/graphics/font.h b/src/framework/graphics/font.h index 1b4f1752..5160860d 100644 --- a/src/framework/graphics/font.h +++ b/src/framework/graphics/font.h @@ -54,6 +54,8 @@ public: /// Simulate render and calculate text size Size calculateTextRectSize(const std::string& text); + std::string wrapText(const std::string& text, int maxWidth); + std::string getName() const { return m_name; } int getGlyphHeight() const { return m_glyphHeight; } const Rect* getGlyphsTextureCoords() const { return m_glyphsTextureCoords; } diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 44899235..922b9b28 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -266,6 +266,7 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("getImageBorderLeft", &UIWidget::getImageBorderLeft); g_lua.bindClassMemberFunction("resizeToText", &UIWidget::resizeToText); g_lua.bindClassMemberFunction("clearText", &UIWidget::clearText); + g_lua.bindClassMemberFunction("wrapText", &UIWidget::wrapText); g_lua.bindClassMemberFunction("setText", &UIWidget::setText); g_lua.bindClassMemberFunction("setTextAlign", &UIWidget::setTextAlign); g_lua.bindClassMemberFunction("setTextOffset", &UIWidget::setTextOffset); diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index c0157de6..06ffd3d9 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -434,6 +434,7 @@ protected: public: void resizeToText() { setSize(getTextSize()); } void clearText() { setText(""); } + void wrapText(); void setText(const std::string& text); void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; m_textMustRecache = true; } diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp index aa53e9f3..87e95af6 100644 --- a/src/framework/ui/uiwidgettext.cpp +++ b/src/framework/ui/uiwidgettext.cpp @@ -84,6 +84,11 @@ void UIWidget::onFontChange(const std::string& font) callLuaField("onFontChange", font); } +void UIWidget::wrapText() +{ + setText(m_font->wrapText(m_text, getWidth())); +} + void UIWidget::setText(const std::string& text) { if(m_text == text) diff --git a/src/otclient/net/protocolcodes.h b/src/otclient/net/protocolcodes.h index 14100230..599ad384 100644 --- a/src/otclient/net/protocolcodes.h +++ b/src/otclient/net/protocolcodes.h @@ -267,8 +267,8 @@ namespace Proto { enum MessageTypes { #if PROTOCOL==860 MessageConsoleRed = 18, - MessageEventOrange, MessageConsoleOrange, + MessageConsoleOrange2, MessageWarning, MessageEventAdvance, MessageEventDefault, @@ -277,8 +277,8 @@ namespace Proto { MessageStatusSmall, MessageConsoleBlue #elif PROTOCOL==862 - MessageEventOrange = 13, - MessageConsoleOrange, + MessageConsoleOrange = 13, + MessageConsoleOrange2, MessageWarning, MessageEventAdvance, MessageEventDefault, @@ -301,35 +301,21 @@ namespace Proto { inline std::string translateSpeakType(int type) { switch(type) { - case Proto::SpeakSay: - return "say"; - case Proto::SpeakWhisper: - return "whisper"; - case Proto::SpeakYell: - return "yell"; - case Proto::SpeakMonsterSay: - return "monsterSay"; - case Proto::SpeakMonsterYell: - return "monsterYell"; - case Proto::SpeakPrivateNpcToPlayer: - return "npcToPlayer"; - case Proto::SpeakChannelYellow: - return "channelYellow"; - case Proto::SpeakChannelWhite: - return "channelWhite"; - case Proto::SpeakChannelRed: - case Proto::SpeakChannelRed2: - return "channelRed"; - case Proto::SpeakChannelOrange: - return "channelOrange"; - case Proto::SpeakPrivate: - return "private"; - case Proto::SpeakPrivatePlayerToNpc: - return "playerToNpc"; - case Proto::SpeakBroadcast: - return "broadcast"; - case Proto::SpeakPrivateRed: - return "privateRed"; + case Proto::SpeakSay: return "say"; + case Proto::SpeakWhisper: return "whisper"; + case Proto::SpeakYell: return "yell"; + case Proto::SpeakMonsterSay: return "monsterSay"; + case Proto::SpeakMonsterYell: return "monsterYell"; + case Proto::SpeakPrivateNpcToPlayer: return "npcToPlayer"; + case Proto::SpeakChannelYellow: return "channelYellow"; + case Proto::SpeakChannelWhite: return "channelWhite"; + case Proto::SpeakChannelRed: return "channelRed"; + case Proto::SpeakChannelRed2: return "channelRed"; + case Proto::SpeakChannelOrange: return "channelOrange"; + case Proto::SpeakPrivate: return "private"; + case Proto::SpeakPrivatePlayerToNpc: return "playerToNpc"; + case Proto::SpeakBroadcast: return "broadcast"; + case Proto::SpeakPrivateRed: return "privateRed"; default: logError("unknown protocol speak type ", type); return "unknown"; @@ -337,36 +323,21 @@ namespace Proto { } inline int translateSpeakTypeDesc(const std::string& type) { - if(type == "say") - return Proto::SpeakSay; - else if(type == "whisper") - return Proto::SpeakWhisper; - else if(type == "yell") - return Proto::SpeakYell; - else if(type == "monsterSay") - return Proto::SpeakMonsterSay; - else if(type == "monsterYell") - return Proto::SpeakMonsterYell; - else if(type == "npcToPlayer") - return Proto::SpeakPrivateNpcToPlayer; - else if(type == "channelYellow") - return Proto::SpeakChannelYellow; - else if(type == "channelWhite") - return Proto::SpeakChannelWhite; - else if(type == "channelRed") - return Proto::SpeakChannelRed; - else if(type == "channelRed") - return Proto::SpeakChannelRed2; - else if(type == "channelOrange") - return Proto::SpeakChannelOrange; - else if(type == "private") - return Proto::SpeakPrivate; - else if(type == "playerToNpc") - return Proto::SpeakPrivatePlayerToNpc; - else if(type == "broadcast") - return Proto::SpeakBroadcast; - else if(type == "privateRed") - return Proto::SpeakPrivateRed; + if(type == "say") return Proto::SpeakSay; + else if(type == "whisper") return Proto::SpeakWhisper; + else if(type == "yell") return Proto::SpeakYell; + else if(type == "monsterSay") return Proto::SpeakMonsterSay; + else if(type == "monsterYell") return Proto::SpeakMonsterYell; + else if(type == "npcToPlayer") return Proto::SpeakPrivateNpcToPlayer; + else if(type == "channelYellow") return Proto::SpeakChannelYellow; + else if(type == "channelWhite") return Proto::SpeakChannelWhite; + else if(type == "channelRed") return Proto::SpeakChannelRed; + else if(type == "channelRed") return Proto::SpeakChannelRed2; + else if(type == "channelOrange") return Proto::SpeakChannelOrange; + else if(type == "private") return Proto::SpeakPrivate; + else if(type == "playerToNpc") return Proto::SpeakPrivatePlayerToNpc; + else if(type == "broadcast") return Proto::SpeakBroadcast; + else if(type == "privateRed") return Proto::SpeakPrivateRed; else { logError("unknown protocol speak type desc ", type); return 0; @@ -375,26 +346,16 @@ namespace Proto { inline std::string translateTextMessageType(int type) { switch(type) { - case Proto::MessageConsoleOrange: - return "consoleOrange"; - case Proto::MessageEventOrange: - return "eventOrange"; - case Proto::MessageWarning: - return "warning"; - case Proto::MessageEventAdvance: - return "eventAdvance"; - case Proto::MessageEventDefault: - return "eventDefault"; - case Proto::MessageStatusDefault: - return "statusDefault"; - case Proto::MessageInfoDescription: - return "infoDescription"; - case Proto::MessageStatusSmall: - return "statusSmall"; - case Proto::MessageConsoleBlue: - return "consoleBlue"; - case Proto::MessageConsoleRed: - return "consoleRed"; + case Proto::MessageConsoleOrange: return "consoleOrange"; + case Proto::MessageConsoleOrange2: return "consoleOrange"; + case Proto::MessageWarning: return "warning"; + case Proto::MessageEventAdvance: return "eventAdvance"; + case Proto::MessageEventDefault: return "eventDefault"; + case Proto::MessageStatusDefault: return "statusDefault"; + case Proto::MessageInfoDescription: return "infoDescription"; + case Proto::MessageStatusSmall: return "statusSmall"; + case Proto::MessageConsoleBlue: return "consoleBlue"; + case Proto::MessageConsoleRed: return "consoleRed"; default: logError("unknown protocol text message type ", type); return "unknown";