#include "RichLabel.h" #include "common/platform/Platform.h" #include "Format.h" using namespace ui; RichLabel::RichLabel(Point position, Point size, String text) : Label(position, size, "") { SetText(text); } void RichLabel::SetText(String newText) { Label::SetText(newText); std::vector newRegions; StringBuilder sb; auto it = newText.begin(); while (it != newText.end()) { auto find = [&newText](auto it, String::value_type ch) { while (it != newText.end()) { if (*it == ch) { break; } ++it; } return it; }; auto beginRegionIt = find(it, '{'); auto beginDataIt = find(beginRegionIt, ':'); auto beginTextIt = find(beginDataIt, '|'); auto endRegionIt = find(beginTextIt, '}'); if (endRegionIt == newText.end()) { break; } auto action = String(beginRegionIt + 1, beginDataIt); auto data = String(beginDataIt + 1, beginTextIt); auto text = String(beginTextIt + 1, endRegionIt); sb << String(it, beginRegionIt); auto good = false; if (action == "a" && data.size() && text.size()) { RichTextRegion region; region.begin = sb.Size(); sb << text; region.end = sb.Size(); region.action = RichTextRegion::LinkAction{ data.ToUtf8() }; newRegions.push_back(region); good = true; } if (!good) { sb << String(beginRegionIt, endRegionIt + 1); } it = endRegionIt + 1; } sb << String(it, newText.end()); auto newDisplayText = sb.Build(); Label::SetText(format::CleanString(newDisplayText, false, true, false)); Label::SetDisplayText(newDisplayText); regions = newRegions; } void RichLabel::OnMouseDown(int x, int y, unsigned button) { if (MouseDownInside) { int cursorPosition = displayTextWrapper.Point2Index(x - Position.X - textPosition.X, y - Position.Y - textPosition.Y).raw_index; for (auto const ®ion : regions) { if (region.begin <= cursorPosition && region.end > cursorPosition) { if (auto *linkAction = std::get_if(®ion.action)) { Platform::OpenURI(linkAction->uri); return; } } } } Label::OnMouseDown(x, y, button); }