Rewrite message queue with GlyphLayout and fix #3922
This commit is contained in:
parent
2ff899e23e
commit
d666a350f6
@ -27,10 +27,7 @@
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
#include "IGUIElement.h"
|
||||
#include "IGUIEnvironment.h"
|
||||
#include "IGUIStaticText.h"
|
||||
|
||||
#include "GlyphLayout.h"
|
||||
#include <atomic>
|
||||
|
||||
using namespace GUIEngine;
|
||||
@ -96,16 +93,17 @@ private:
|
||||
* or friend-message::neutral. */
|
||||
std::string m_render_type;
|
||||
|
||||
/** The text label, can do linebreak if needed. */
|
||||
gui::IGUIStaticText* m_text;
|
||||
/** The text layout, can do linebreak if needed. */
|
||||
std::vector<gui::GlyphLayout> m_gls;
|
||||
|
||||
/** Drawing rectangle of text layout. */
|
||||
core::recti m_text_rect;
|
||||
public:
|
||||
TextMessage(MessageQueue::MessageType mt, const core::stringw &message) :
|
||||
Message(5.0f)
|
||||
{
|
||||
m_message_type = mt;
|
||||
m_message = message;
|
||||
m_text = NULL;
|
||||
assert(mt != MessageQueue::MT_PROGRESS);
|
||||
if (mt == MessageQueue::MT_ACHIEVEMENT)
|
||||
m_render_type = "achievement-message::neutral";
|
||||
@ -119,8 +117,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
~TextMessage()
|
||||
{
|
||||
assert(m_text != NULL);
|
||||
m_text->drop();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the type of the message.*/
|
||||
@ -130,39 +126,75 @@ public:
|
||||
/** Init the message text, do linebreak as required. */
|
||||
virtual void init()
|
||||
{
|
||||
if (m_text)
|
||||
m_text->drop();
|
||||
const GUIEngine::BoxRenderParams &brp =
|
||||
GUIEngine::getSkin()->getBoxRenderParams(m_render_type);
|
||||
const unsigned width = irr_driver->getActualScreenSize().Width;
|
||||
const unsigned height = irr_driver->getActualScreenSize().Height;
|
||||
const unsigned max_width = width - (brp.m_left_border +
|
||||
brp.m_right_border);
|
||||
m_text =
|
||||
GUIEngine::getGUIEnv()->addStaticText(m_message.c_str(),
|
||||
core::recti(0, 0, max_width, height));
|
||||
core::dimension2du dim(m_text->getTextWidth(),
|
||||
m_text->getTextHeight());
|
||||
dim.Width += brp.m_left_border + brp.m_right_border;
|
||||
gui::IGUIFont* font = GUIEngine::getFont();
|
||||
font->initGlyphLayouts(m_message, m_gls);
|
||||
// Reserve space for 5 lines of text, it will occupy the circle
|
||||
const int max_width = width - (brp.m_left_border +
|
||||
brp.m_right_border) - (font->getHeightPerLine() * 5);
|
||||
if (max_width < 0)
|
||||
{
|
||||
m_display_timer = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
int leftIconSize = dim.Height + 10;
|
||||
int x = (width - dim.Width) / 2;
|
||||
int y = height - int(1.5f * dim.Height);
|
||||
m_area = irr::core::recti(x, y, x + dim.Width, y + dim.Height);
|
||||
m_text->setRelativePosition(irr::core::recti(x + leftIconSize, y,
|
||||
x + dim.Width - 10, y + dim.Height));
|
||||
m_text->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
|
||||
m_text->grab();
|
||||
m_text->remove();
|
||||
gui::breakGlyphLayouts(m_gls, max_width, font->getInverseShaping(),
|
||||
font->getScale());
|
||||
core::dimension2du dim = gui::getGlyphLayoutsDimension(m_gls,
|
||||
font->getHeightPerLine(), font->getInverseShaping(),
|
||||
font->getScale());
|
||||
|
||||
if ((int)dim.Height > font->getHeightPerLine() * 5)
|
||||
{
|
||||
// Max 5 lines to prevent too long message from network chat
|
||||
int newline_count = 0;
|
||||
for (unsigned i = 0; i < m_gls.size(); i++)
|
||||
{
|
||||
if (m_gls[i].flags & gui::GLF_NEWLINE)
|
||||
{
|
||||
if (++newline_count >= 5)
|
||||
{
|
||||
m_gls.erase(m_gls.begin() + i, m_gls.end());
|
||||
dim.Height = font->getHeightPerLine() * 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int left_icon_size = dim.Height;
|
||||
int total_width = dim.Width + brp.m_left_border + brp.m_right_border +
|
||||
left_icon_size;
|
||||
int x = (width - total_width) / 2;
|
||||
int y = height - int(dim.Height) - font->getHeightPerLine() / 2;
|
||||
|
||||
if (x < 0 || y < 0)
|
||||
{
|
||||
m_gls.clear();
|
||||
m_display_timer = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
m_area = irr::core::recti(x, y, x + total_width, y + dim.Height);
|
||||
m_text_rect = core::recti(x, y, x + left_icon_size + total_width,
|
||||
y + dim.Height);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Draw the message. */
|
||||
virtual void draw(float dt)
|
||||
{
|
||||
if (m_gls.empty())
|
||||
{
|
||||
Message::draw(dt);
|
||||
return;
|
||||
}
|
||||
Message::draw(dt);
|
||||
GUIEngine::getSkin()->drawMessage(g_container, m_area, m_render_type);
|
||||
assert(m_text != NULL);
|
||||
m_text->draw();
|
||||
GUIEngine::getFont()->draw(m_gls, m_text_rect,
|
||||
GUIEngine::getSkin()->getColor("text::neutral"), true/*hcenter*/);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void remove() { delete this; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user