171 lines
4.2 KiB
C++
171 lines
4.2 KiB
C++
#pragma once
|
|
|
|
#include <psemek/ui/element.hpp>
|
|
#include <psemek/ui/box_shape.hpp>
|
|
#include <psemek/ui/tagged_text.hpp>
|
|
#include <psemek/ui/image_provider.hpp>
|
|
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <variant>
|
|
|
|
namespace psemek::ui
|
|
{
|
|
|
|
struct label
|
|
: element
|
|
{
|
|
enum class halignment
|
|
{
|
|
left,
|
|
center,
|
|
right,
|
|
stretch,
|
|
};
|
|
|
|
enum class valignment
|
|
{
|
|
top,
|
|
center,
|
|
bottom,
|
|
};
|
|
|
|
enum class overflow_mode
|
|
{
|
|
ignore,
|
|
drop,
|
|
ellipsis,
|
|
};
|
|
|
|
label() = default;
|
|
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_text_style(ui::text_style style);
|
|
virtual ui::text_style text_style() const { return text_style_; }
|
|
|
|
virtual void set_halign(halignment value);
|
|
virtual halignment halign() const { return halign_; }
|
|
|
|
virtual void set_valign(valignment value);
|
|
virtual valignment valign() const { return valign_; }
|
|
|
|
virtual void set_wrap(bool value);
|
|
virtual bool wrap() const { return wrap_; }
|
|
|
|
virtual void set_overflow(overflow_mode value);
|
|
virtual overflow_mode overflow() const { return overflow_; }
|
|
|
|
virtual void set_skip_spaces(bool value);
|
|
virtual bool skip_spaces() const { return skip_spaces_; }
|
|
|
|
virtual struct image_provider * set_image_provider(struct image_provider * provider);
|
|
virtual struct image_provider * image_provider() const { return image_provider_; }
|
|
|
|
virtual void set_tag_mapper(tagged_text::mapper mapper);
|
|
|
|
using link_mouseover_callback = std::function<void(std::optional<std::string> const &)>;
|
|
using link_callback = std::function<void(std::string const &)>;
|
|
|
|
virtual void on_link_mouseover(link_mouseover_callback callback);
|
|
virtual void on_link_click(link_callback callback);
|
|
|
|
struct shape const & shape() const override { return shape_; }
|
|
void reshape(math::box<float, 2> const & bbox) override;
|
|
|
|
bool on_event(ui::mouse_move const & e) override;
|
|
bool on_event(ui::mouse_click const & e) override;
|
|
|
|
math::box<float, 2> size_constraints() const override;
|
|
|
|
math::interval<float> width_constraints(float height) const override;
|
|
math::interval<float> height_constraints(float width) const override;
|
|
|
|
void style_updated() const override;
|
|
void own_style_updated() const override;
|
|
|
|
bool transparent() const override { return !hint(); }
|
|
|
|
void draw(painter & p) const override;
|
|
|
|
protected:
|
|
virtual void on_state_changed();
|
|
|
|
private:
|
|
halignment halign_ = halignment::left;
|
|
valignment valign_ = valignment::top;
|
|
bool wrap_ = true;
|
|
overflow_mode overflow_ = overflow_mode::ignore;
|
|
bool skip_spaces_ = false;
|
|
ui::text_style text_style_ = {};
|
|
|
|
struct image_provider * image_provider_ = nullptr;
|
|
tagged_text::mapper tag_mapper_ = nullptr;
|
|
|
|
link_mouseover_callback link_mouseover_callback_;
|
|
link_callback link_callback_;
|
|
|
|
box_shape shape_;
|
|
|
|
struct text_chunk
|
|
{
|
|
std::string text;
|
|
ui::text_style style; // to be OR'd with base style
|
|
std::optional<gfx::color_rgba> color;
|
|
std::optional<std::string> link;
|
|
};
|
|
|
|
struct image_chunk
|
|
{
|
|
std::string id;
|
|
std::optional<gfx::color_rgba> color;
|
|
std::optional<std::string> link;
|
|
};
|
|
|
|
using chunk = std::variant<text_chunk, image_chunk>;
|
|
|
|
std::string text_;
|
|
bool tagged_ = false;
|
|
std::vector<chunk> chunks_;
|
|
|
|
struct cached_state
|
|
{
|
|
struct image
|
|
{
|
|
math::box<float, 2> texcoords;
|
|
math::box<float, 2> position;
|
|
};
|
|
|
|
struct batch
|
|
{
|
|
gfx::texture_2d const * texture;
|
|
gfx::color_rgba color;
|
|
bool text;
|
|
std::vector<image> images;
|
|
};
|
|
|
|
std::vector<batch> batches;
|
|
math::vector<float, 2> size{0.f, 0.f};
|
|
|
|
fonts::font_type font_type = fonts::font_type::bitmap;
|
|
float sdf_scale = 0.f;
|
|
|
|
std::vector<std::pair<math::box<float, 2>, std::string>> link_bboxes;
|
|
};
|
|
|
|
mutable std::optional<cached_state> cached_state_;
|
|
mutable std::optional<cached_state> cached_state_inf_;
|
|
std::optional<std::string> selected_link_;
|
|
bool mouse_down_ = false;
|
|
|
|
void update_cached_state() const;
|
|
cached_state cached_state_for(math::box<float, 2> const & bbox) const;
|
|
|
|
mutable std::shared_ptr<gfx::texture_2d> single_white_pixel_texture_;
|
|
std::shared_ptr<gfx::texture_2d> single_white_pixel_texture() const;
|
|
};
|
|
|
|
}
|