ui::label tags support: bold, uline & strike

This commit is contained in:
Nikita Lisitsa 2022-05-21 20:23:50 +03:00
parent 711253bbfe
commit d40dd82268
2 changed files with 58 additions and 0 deletions

View file

@ -2,6 +2,7 @@
#include <psemek/ui/element.hpp>
#include <psemek/ui/box_shape.hpp>
#include <psemek/ui/tagged_text.hpp>
#include <string>
#include <string_view>
@ -39,6 +40,7 @@ namespace psemek::ui
explicit label(std::string text);
virtual void set_text(std::string text);
virtual void set_tagged_text(std::string text);
virtual std::string_view text() const { return text_; }
virtual void set_halign(halignment value);

View file

@ -2,6 +2,7 @@
#include <stdexcept>
#include <cctype>
#include <unordered_map>
namespace psemek::ui
{
@ -21,6 +22,61 @@ namespace psemek::ui
on_state_changed();
}
void label::set_tagged_text(std::string text)
{
text_ = std::move(text);
chunks_.clear();
auto parse_result = tagged_text::parse(text_);
std::unordered_map<std::string_view, int> tags_stack;
tags_stack["bold"] = 0;
tags_stack["uline"] = 0;
tags_stack["strike"] = 0;
for (auto const & token : parse_result.tokens)
{
if (auto text = std::get_if<std::string_view>(&token))
{
text_chunk chunk;
if (tags_stack["bold"] > 0)
chunk.style.set(text_style_flag::bold);
if (tags_stack["uline"] > 0)
chunk.style.set(text_style_flag::underline);
if (tags_stack["strike"] > 0)
chunk.style.set(text_style_flag::strikethrough);
chunk.text = *text;
chunks_.push_back(chunk);
}
else if (auto tag = std::get_if<tagged_text::opening_tag>(&token))
{
if (tag->type == "bold")
{
tags_stack["bold"] += 1;
}
else if (tag->type == "uline")
{
tags_stack["uline"] += 1;
}
else if (tag->type == "strike")
{
tags_stack["strike"] += 1;
}
else
throw std::runtime_error("unknown tag [" + std::string(tag->type) + "]");
}
else if (auto tag = std::get_if<tagged_text::closing_tag>(&token))
{
if (tags_stack[tag->type] == 0)
throw std::runtime_error("mismatched opening & closing tags for [" + std::string(tag->type) + "]");
tags_stack[tag->type] -= 1;
}
}
on_state_changed();
}
void label::set_halign(halignment value)
{
halign_ = value;