implement line wrap for text messages
This commit is contained in:
parent
dd457b2b2f
commit
99ff5ce24c
|
@ -5,16 +5,15 @@ importStyle 'textmessage.otui'
|
||||||
|
|
||||||
-- private variables
|
-- private variables
|
||||||
local MessageTypes = {
|
local MessageTypes = {
|
||||||
consoleRed = { color = '#F55E5E', consoleTab = 'Server Log' },
|
consoleRed = { color = '#F55E5E', consoleTab = 'Default' }, -- 18
|
||||||
eventOrange = { color = '#FE6500', consoleTab = 'Default' },
|
consoleOrange = { color = '#FE6500', consoleTab = 'Default' }, -- 19/20
|
||||||
consoleOrange = { color = '#FE6500', consoleTab = 'Default' },
|
consoleBlue = { color = '#9F9DFD', consoleTab = 'Default' }, -- 27
|
||||||
warning = { color = '#F55E5E', consoleTab = 'Server Log', windowLocation = 'center' },
|
warning = { color = '#F55E5E', consoleTab = 'Server Log', windowLocation = 'center' }, -- 21
|
||||||
eventAdvance = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showEventMessagesInConsole' },
|
infoDescription = { color = '#00EB00', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showInfoMessagesInConsole' }, -- 25
|
||||||
eventDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showEventMessagesInConsole' },
|
eventAdvance = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showEventMessagesInConsole' }, -- 22
|
||||||
statusDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showStatusMessagesInConsole' },
|
eventDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showEventMessagesInConsole' }, -- 23
|
||||||
infoDescription = { color = '#00EB00', consoleTab = 'Server Log', windowLocation = 'center', consoleOption = 'showInfoMessagesInConsole' },
|
statusDefault = { color = '#FFFFFF', consoleTab = 'Server Log', windowLocation = 'bottom', consoleOption = 'showStatusMessagesInConsole' }, -- 24
|
||||||
statusSmall = { color = '#FFFFFF', windowLocation = 'bottom' },
|
statusSmall = { color = '#FFFFFF', windowLocation = 'bottom' }, -- 26
|
||||||
consoleBlue = { color = '#9F9DFD', consoleTab = 'Default' },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local bottomLabelWidget
|
local bottomLabelWidget
|
||||||
|
@ -48,6 +47,10 @@ local function displayMessage(msgtype, msg, time)
|
||||||
label:setStyle(style)
|
label:setStyle(style)
|
||||||
label:setColor(msgtype.color)
|
label:setColor(msgtype.color)
|
||||||
|
|
||||||
|
if msgtype.windowLocation == 'center' then
|
||||||
|
label:wrapText()
|
||||||
|
end
|
||||||
|
|
||||||
if not time then
|
if not time then
|
||||||
time = math.max(#msg * 75, 3000)
|
time = math.max(#msg * 75, 3000)
|
||||||
else
|
else
|
||||||
|
|
|
@ -2,9 +2,8 @@ CenterLabel < GameLabel
|
||||||
font: verdana-11px-rounded
|
font: verdana-11px-rounded
|
||||||
height: 64
|
height: 64
|
||||||
text-align: center
|
text-align: center
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.centerIn: parent
|
||||||
anchors.left: parent.left
|
size: 360 264
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
BottomLabel < GameLabel
|
BottomLabel < GameLabel
|
||||||
font: verdana-11px-rounded
|
font: verdana-11px-rounded
|
||||||
|
|
|
@ -282,3 +282,56 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
||||||
m_glyphsSize[glyph].resize(width, m_glyphHeight);
|
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<std::string> words;
|
||||||
|
std::vector<std::string> wordsSplit = Fw::split(text);
|
||||||
|
|
||||||
|
// break huge words into small ones
|
||||||
|
for(uint i=0;i<wordsSplit.size();++i) {
|
||||||
|
const std::string& word = wordsSplit[i];
|
||||||
|
int wordWidth = calculateTextRectSize(word).width();
|
||||||
|
if(wordWidth > maxWidth) {
|
||||||
|
std::string newWord;
|
||||||
|
for(uint j=0;j<word.length();++j) {
|
||||||
|
std::string candidate = newWord + word[j];
|
||||||
|
if(j != word.length() - 1)
|
||||||
|
candidate += "-";
|
||||||
|
int candidateWidth = calculateTextRectSize(candidate).width();
|
||||||
|
|
||||||
|
if(candidateWidth > 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<words.size();++i) {
|
||||||
|
std::string candidate = line + words[i];
|
||||||
|
int candidateWidth = calculateTextRectSize(candidate).width();
|
||||||
|
|
||||||
|
if(candidateWidth > 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;
|
||||||
|
}
|
|
@ -54,6 +54,8 @@ public:
|
||||||
/// Simulate render and calculate text size
|
/// Simulate render and calculate text size
|
||||||
Size calculateTextRectSize(const std::string& text);
|
Size calculateTextRectSize(const std::string& text);
|
||||||
|
|
||||||
|
std::string wrapText(const std::string& text, int maxWidth);
|
||||||
|
|
||||||
std::string getName() const { return m_name; }
|
std::string getName() const { return m_name; }
|
||||||
int getGlyphHeight() const { return m_glyphHeight; }
|
int getGlyphHeight() const { return m_glyphHeight; }
|
||||||
const Rect* getGlyphsTextureCoords() const { return m_glyphsTextureCoords; }
|
const Rect* getGlyphsTextureCoords() const { return m_glyphsTextureCoords; }
|
||||||
|
|
|
@ -266,6 +266,7 @@ void Application::registerLuaFunctions()
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getImageBorderLeft", &UIWidget::getImageBorderLeft);
|
g_lua.bindClassMemberFunction<UIWidget>("getImageBorderLeft", &UIWidget::getImageBorderLeft);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("resizeToText", &UIWidget::resizeToText);
|
g_lua.bindClassMemberFunction<UIWidget>("resizeToText", &UIWidget::resizeToText);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("clearText", &UIWidget::clearText);
|
g_lua.bindClassMemberFunction<UIWidget>("clearText", &UIWidget::clearText);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("wrapText", &UIWidget::wrapText);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setText", &UIWidget::setText);
|
g_lua.bindClassMemberFunction<UIWidget>("setText", &UIWidget::setText);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setTextAlign", &UIWidget::setTextAlign);
|
g_lua.bindClassMemberFunction<UIWidget>("setTextAlign", &UIWidget::setTextAlign);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setTextOffset", &UIWidget::setTextOffset);
|
g_lua.bindClassMemberFunction<UIWidget>("setTextOffset", &UIWidget::setTextOffset);
|
||||||
|
|
|
@ -434,6 +434,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
void resizeToText() { setSize(getTextSize()); }
|
void resizeToText() { setSize(getTextSize()); }
|
||||||
void clearText() { setText(""); }
|
void clearText() { setText(""); }
|
||||||
|
void wrapText();
|
||||||
|
|
||||||
void setText(const std::string& text);
|
void setText(const std::string& text);
|
||||||
void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; m_textMustRecache = true; }
|
void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; m_textMustRecache = true; }
|
||||||
|
|
|
@ -84,6 +84,11 @@ void UIWidget::onFontChange(const std::string& font)
|
||||||
callLuaField("onFontChange", font);
|
callLuaField("onFontChange", font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UIWidget::wrapText()
|
||||||
|
{
|
||||||
|
setText(m_font->wrapText(m_text, getWidth()));
|
||||||
|
}
|
||||||
|
|
||||||
void UIWidget::setText(const std::string& text)
|
void UIWidget::setText(const std::string& text)
|
||||||
{
|
{
|
||||||
if(m_text == text)
|
if(m_text == text)
|
||||||
|
|
|
@ -267,8 +267,8 @@ namespace Proto {
|
||||||
enum MessageTypes {
|
enum MessageTypes {
|
||||||
#if PROTOCOL==860
|
#if PROTOCOL==860
|
||||||
MessageConsoleRed = 18,
|
MessageConsoleRed = 18,
|
||||||
MessageEventOrange,
|
|
||||||
MessageConsoleOrange,
|
MessageConsoleOrange,
|
||||||
|
MessageConsoleOrange2,
|
||||||
MessageWarning,
|
MessageWarning,
|
||||||
MessageEventAdvance,
|
MessageEventAdvance,
|
||||||
MessageEventDefault,
|
MessageEventDefault,
|
||||||
|
@ -277,8 +277,8 @@ namespace Proto {
|
||||||
MessageStatusSmall,
|
MessageStatusSmall,
|
||||||
MessageConsoleBlue
|
MessageConsoleBlue
|
||||||
#elif PROTOCOL==862
|
#elif PROTOCOL==862
|
||||||
MessageEventOrange = 13,
|
MessageConsoleOrange = 13,
|
||||||
MessageConsoleOrange,
|
MessageConsoleOrange2,
|
||||||
MessageWarning,
|
MessageWarning,
|
||||||
MessageEventAdvance,
|
MessageEventAdvance,
|
||||||
MessageEventDefault,
|
MessageEventDefault,
|
||||||
|
@ -301,35 +301,21 @@ namespace Proto {
|
||||||
|
|
||||||
inline std::string translateSpeakType(int type) {
|
inline std::string translateSpeakType(int type) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Proto::SpeakSay:
|
case Proto::SpeakSay: return "say";
|
||||||
return "say";
|
case Proto::SpeakWhisper: return "whisper";
|
||||||
case Proto::SpeakWhisper:
|
case Proto::SpeakYell: return "yell";
|
||||||
return "whisper";
|
case Proto::SpeakMonsterSay: return "monsterSay";
|
||||||
case Proto::SpeakYell:
|
case Proto::SpeakMonsterYell: return "monsterYell";
|
||||||
return "yell";
|
case Proto::SpeakPrivateNpcToPlayer: return "npcToPlayer";
|
||||||
case Proto::SpeakMonsterSay:
|
case Proto::SpeakChannelYellow: return "channelYellow";
|
||||||
return "monsterSay";
|
case Proto::SpeakChannelWhite: return "channelWhite";
|
||||||
case Proto::SpeakMonsterYell:
|
case Proto::SpeakChannelRed: return "channelRed";
|
||||||
return "monsterYell";
|
case Proto::SpeakChannelRed2: return "channelRed";
|
||||||
case Proto::SpeakPrivateNpcToPlayer:
|
case Proto::SpeakChannelOrange: return "channelOrange";
|
||||||
return "npcToPlayer";
|
case Proto::SpeakPrivate: return "private";
|
||||||
case Proto::SpeakChannelYellow:
|
case Proto::SpeakPrivatePlayerToNpc: return "playerToNpc";
|
||||||
return "channelYellow";
|
case Proto::SpeakBroadcast: return "broadcast";
|
||||||
case Proto::SpeakChannelWhite:
|
case Proto::SpeakPrivateRed: return "privateRed";
|
||||||
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";
|
|
||||||
default:
|
default:
|
||||||
logError("unknown protocol speak type ", type);
|
logError("unknown protocol speak type ", type);
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
@ -337,36 +323,21 @@ namespace Proto {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int translateSpeakTypeDesc(const std::string& type) {
|
inline int translateSpeakTypeDesc(const std::string& type) {
|
||||||
if(type == "say")
|
if(type == "say") return Proto::SpeakSay;
|
||||||
return Proto::SpeakSay;
|
else if(type == "whisper") return Proto::SpeakWhisper;
|
||||||
else if(type == "whisper")
|
else if(type == "yell") return Proto::SpeakYell;
|
||||||
return Proto::SpeakWhisper;
|
else if(type == "monsterSay") return Proto::SpeakMonsterSay;
|
||||||
else if(type == "yell")
|
else if(type == "monsterYell") return Proto::SpeakMonsterYell;
|
||||||
return Proto::SpeakYell;
|
else if(type == "npcToPlayer") return Proto::SpeakPrivateNpcToPlayer;
|
||||||
else if(type == "monsterSay")
|
else if(type == "channelYellow") return Proto::SpeakChannelYellow;
|
||||||
return Proto::SpeakMonsterSay;
|
else if(type == "channelWhite") return Proto::SpeakChannelWhite;
|
||||||
else if(type == "monsterYell")
|
else if(type == "channelRed") return Proto::SpeakChannelRed;
|
||||||
return Proto::SpeakMonsterYell;
|
else if(type == "channelRed") return Proto::SpeakChannelRed2;
|
||||||
else if(type == "npcToPlayer")
|
else if(type == "channelOrange") return Proto::SpeakChannelOrange;
|
||||||
return Proto::SpeakPrivateNpcToPlayer;
|
else if(type == "private") return Proto::SpeakPrivate;
|
||||||
else if(type == "channelYellow")
|
else if(type == "playerToNpc") return Proto::SpeakPrivatePlayerToNpc;
|
||||||
return Proto::SpeakChannelYellow;
|
else if(type == "broadcast") return Proto::SpeakBroadcast;
|
||||||
else if(type == "channelWhite")
|
else if(type == "privateRed") return Proto::SpeakPrivateRed;
|
||||||
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 {
|
else {
|
||||||
logError("unknown protocol speak type desc ", type);
|
logError("unknown protocol speak type desc ", type);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -375,26 +346,16 @@ namespace Proto {
|
||||||
|
|
||||||
inline std::string translateTextMessageType(int type) {
|
inline std::string translateTextMessageType(int type) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Proto::MessageConsoleOrange:
|
case Proto::MessageConsoleOrange: return "consoleOrange";
|
||||||
return "consoleOrange";
|
case Proto::MessageConsoleOrange2: return "consoleOrange";
|
||||||
case Proto::MessageEventOrange:
|
case Proto::MessageWarning: return "warning";
|
||||||
return "eventOrange";
|
case Proto::MessageEventAdvance: return "eventAdvance";
|
||||||
case Proto::MessageWarning:
|
case Proto::MessageEventDefault: return "eventDefault";
|
||||||
return "warning";
|
case Proto::MessageStatusDefault: return "statusDefault";
|
||||||
case Proto::MessageEventAdvance:
|
case Proto::MessageInfoDescription: return "infoDescription";
|
||||||
return "eventAdvance";
|
case Proto::MessageStatusSmall: return "statusSmall";
|
||||||
case Proto::MessageEventDefault:
|
case Proto::MessageConsoleBlue: return "consoleBlue";
|
||||||
return "eventDefault";
|
case Proto::MessageConsoleRed: return "consoleRed";
|
||||||
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:
|
default:
|
||||||
logError("unknown protocol text message type ", type);
|
logError("unknown protocol text message type ", type);
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
|
Loading…
Reference in New Issue