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