Move getCluster code to a dedicated function for later usage
This commit is contained in:
parent
fe5b49e63a
commit
4deeac7dc8
@ -9,6 +9,7 @@
|
|||||||
#include "SColor.h"
|
#include "SColor.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
@ -125,6 +126,7 @@ namespace gui
|
|||||||
virtual void setUseGlyphLayoutsOnly(bool gls_only) = 0;
|
virtual void setUseGlyphLayoutsOnly(bool gls_only) = 0;
|
||||||
virtual bool useGlyphLayoutsOnly() const = 0;
|
virtual bool useGlyphLayoutsOnly() const = 0;
|
||||||
virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) {}
|
virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) {}
|
||||||
|
virtual s32 getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str) { return -1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,6 +393,89 @@ bool CGUIStaticText::OnEvent(const SEvent& event)
|
|||||||
return IGUIElement::OnEvent(event);
|
return IGUIElement::OnEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s32 CGUIStaticText::getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str)
|
||||||
|
{
|
||||||
|
core::position2di p;
|
||||||
|
p.X = x;
|
||||||
|
p.Y = y;
|
||||||
|
if (p.X < 0 || p.Y < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (m_glyph_layouts.empty())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
IGUIFont* font = getActiveFont();
|
||||||
|
std::vector<f32> width_per_line = gui::getGlyphLayoutsWidthPerLine(
|
||||||
|
m_glyph_layouts, font->getInverseShaping(), font->getScale());
|
||||||
|
if (width_per_line.empty())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Check if the line is RTL
|
||||||
|
core::rect<s32> position = getAbsolutePosition();
|
||||||
|
bool rtl = (m_glyph_layouts[0].flags & gui::GLF_RTL_LINE) != 0;
|
||||||
|
int offset = 0;
|
||||||
|
int cur_line = 0;
|
||||||
|
if (rtl)
|
||||||
|
offset = (s32)(position.getWidth() - width_per_line[cur_line]);
|
||||||
|
|
||||||
|
float next_line_height = font->getHeightPerLine();
|
||||||
|
if (width_per_line.size() > 1 &&
|
||||||
|
width_per_line.size() * next_line_height > position.getHeight())
|
||||||
|
{
|
||||||
|
next_line_height = (float)position.getHeight() /
|
||||||
|
(float)width_per_line.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = -1;
|
||||||
|
core::recti r;
|
||||||
|
r.UpperLeftCorner.X = r.LowerRightCorner.X = offset;
|
||||||
|
r.LowerRightCorner.Y = (int)next_line_height;
|
||||||
|
bool line_changed = false;
|
||||||
|
for (unsigned i = 0; i < m_glyph_layouts.size(); i++)
|
||||||
|
{
|
||||||
|
const GlyphLayout& glyph_layout = m_glyph_layouts[i];
|
||||||
|
if ((glyph_layout.flags & GLF_NEWLINE) != 0)
|
||||||
|
{
|
||||||
|
r.UpperLeftCorner.Y += (int)next_line_height;
|
||||||
|
r.LowerRightCorner.Y += (int)next_line_height;
|
||||||
|
cur_line++;
|
||||||
|
line_changed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line_changed)
|
||||||
|
{
|
||||||
|
line_changed = false;
|
||||||
|
rtl = (glyph_layout.flags & gui::GLF_RTL_LINE) != 0;
|
||||||
|
offset = 0;
|
||||||
|
if (rtl)
|
||||||
|
{
|
||||||
|
offset = (s32)
|
||||||
|
(position.getWidth() - width_per_line[cur_line]);
|
||||||
|
}
|
||||||
|
r.UpperLeftCorner.X = r.LowerRightCorner.X = offset;
|
||||||
|
}
|
||||||
|
r.LowerRightCorner.X += int(
|
||||||
|
(float)glyph_layout.x_advance * font->getInverseShaping() *
|
||||||
|
font->getScale());
|
||||||
|
if (r.isPointInside(p))
|
||||||
|
{
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
std::shared_ptr<std::u32string> s = m_glyph_layouts[idx].orig_string;
|
||||||
|
unsigned cluster = m_glyph_layouts[idx].cluster.front();
|
||||||
|
if (cluster > s->size())
|
||||||
|
return -1;
|
||||||
|
*out_orig_str = s;
|
||||||
|
return cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end namespace gui
|
} // end namespace gui
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ namespace gui
|
|||||||
//! called if an event happened.
|
//! called if an event happened.
|
||||||
virtual bool OnEvent(const SEvent& event);
|
virtual bool OnEvent(const SEvent& event);
|
||||||
virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) { m_callback = cb; }
|
virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) { m_callback = cb; }
|
||||||
|
virtual s32 getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Breaks the single text line.
|
//! Breaks the single text line.
|
||||||
|
@ -264,81 +264,11 @@ void NetworkingLobby::init()
|
|||||||
{
|
{
|
||||||
if (mouse.Event == EMIE_LMOUSE_PRESSED_DOWN)
|
if (mouse.Event == EMIE_LMOUSE_PRESSED_DOWN)
|
||||||
{
|
{
|
||||||
core::position2di p;
|
std::shared_ptr<std::u32string> s;
|
||||||
p.X = mouse.X - text->getAbsolutePosition().UpperLeftCorner.X;
|
int cluster = text->getCluster(
|
||||||
p.Y = mouse.Y - text->getAbsolutePosition().UpperLeftCorner.Y;
|
mouse.X - text->getAbsolutePosition().UpperLeftCorner.X,
|
||||||
if (p.X < 0 || p.Y < 0)
|
mouse.Y - text->getAbsolutePosition().UpperLeftCorner.Y, &s);
|
||||||
return false;
|
if (cluster == -1 || (unsigned)cluster > s->size())
|
||||||
|
|
||||||
const std::vector<GlyphLayout>& gls = text->getGlyphLayouts();
|
|
||||||
if (gls.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
gui::IGUIFont* font = GUIEngine::getFont();
|
|
||||||
auto width_per_line = gui::getGlyphLayoutsWidthPerLine(gls,
|
|
||||||
font->getInverseShaping(), font->getScale());
|
|
||||||
if (width_per_line.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if the line is RTL
|
|
||||||
auto position = text->getAbsolutePosition();
|
|
||||||
bool rtl = (gls[0].flags & gui::GLF_RTL_LINE) != 0;
|
|
||||||
int offset = 0;
|
|
||||||
int cur_line = 0;
|
|
||||||
if (rtl)
|
|
||||||
offset = (s32)(position.getWidth() - width_per_line[cur_line]);
|
|
||||||
|
|
||||||
float next_line_height = font->getHeightPerLine();
|
|
||||||
if (width_per_line.size() > 1 &&
|
|
||||||
width_per_line.size() * next_line_height > position.getHeight())
|
|
||||||
{
|
|
||||||
next_line_height = (float)position.getHeight() /
|
|
||||||
(float)width_per_line.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx = -1;
|
|
||||||
core::recti r;
|
|
||||||
r.UpperLeftCorner.X = r.LowerRightCorner.X = offset;
|
|
||||||
r.LowerRightCorner.Y = (int)next_line_height;
|
|
||||||
bool line_changed = false;
|
|
||||||
for (unsigned i = 0; i < gls.size(); i++)
|
|
||||||
{
|
|
||||||
const GlyphLayout& glyph_layout = gls[i];
|
|
||||||
if ((glyph_layout.flags & GLF_NEWLINE) != 0)
|
|
||||||
{
|
|
||||||
r.UpperLeftCorner.Y += (int)next_line_height;
|
|
||||||
r.LowerRightCorner.Y += (int)next_line_height;
|
|
||||||
cur_line++;
|
|
||||||
line_changed = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (line_changed)
|
|
||||||
{
|
|
||||||
line_changed = false;
|
|
||||||
rtl = (glyph_layout.flags & gui::GLF_RTL_LINE) != 0;
|
|
||||||
offset = 0;
|
|
||||||
if (rtl)
|
|
||||||
{
|
|
||||||
offset = (s32)
|
|
||||||
(position.getWidth() - width_per_line[cur_line]);
|
|
||||||
}
|
|
||||||
r.UpperLeftCorner.X = r.LowerRightCorner.X = offset;
|
|
||||||
}
|
|
||||||
r.LowerRightCorner.X += int(
|
|
||||||
(float)glyph_layout.x_advance * font->getInverseShaping() *
|
|
||||||
font->getScale());
|
|
||||||
if (r.isPointInside(p))
|
|
||||||
{
|
|
||||||
idx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (idx == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto s = gls[idx].orig_string;
|
|
||||||
unsigned cluster = gls[idx].cluster.front();
|
|
||||||
if (cluster > s->size())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t start = s->substr(0, cluster).rfind(U'\n');
|
size_t start = s->substr(0, cluster).rfind(U'\n');
|
||||||
@ -351,10 +281,9 @@ void NetworkingLobby::init()
|
|||||||
end = s->size();
|
end = s->size();
|
||||||
else
|
else
|
||||||
end += cluster - start;
|
end += cluster - start;
|
||||||
if (idx == -1)
|
|
||||||
return false;
|
|
||||||
std::u32string substr = s->substr(start, end);
|
std::u32string substr = s->substr(start, end);
|
||||||
int local_pos = (int)cluster - (int)start;
|
int local_pos = cluster - (int)start;
|
||||||
if ((size_t)local_pos > substr.size())
|
if ((size_t)local_pos > substr.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user