185 lines
6.5 KiB
C++
185 lines
6.5 KiB
C++
#pragma once
|
|
#include <functional>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
#include "../Axis/export.h"
|
|
#include "../architecture/Render_Data.h"
|
|
#include "../base/Color.h"
|
|
#include "../base/Geometry.h"
|
|
#include "../base/Style.h"
|
|
#include "../base/Text.h"
|
|
#include "../render/Canvas.h"
|
|
namespace renderive {
|
|
struct Render_Frame_Snapshot;
|
|
struct Hover_Tooltip_State;
|
|
struct Hover_Tooltip_Provider;
|
|
struct LIB_DECL Hover_Tooltip_State {
|
|
virtual ~Hover_Tooltip_State() = default;
|
|
Hover_Tooltip_State() {
|
|
tooltip_background_brush = Brush{Color::white(), Brush_Style::Solid};
|
|
tooltip_text_pen = Pen{Color::black()};
|
|
}
|
|
int hover_info_left = 4;
|
|
int hover_info_top = 4;
|
|
int hover_info_right = 4;
|
|
int hover_info_bottom = 4;
|
|
Brush tooltip_background_brush;
|
|
Font hover_info_font;
|
|
Pen tooltip_text_pen;
|
|
bool use_hover_tooltip = true;
|
|
bool hover_info_active = false;
|
|
Point hover_position;
|
|
void draw_hover_tooltip(Canvas* canvas, Abs_Axis* domain_axis, Abs_Axis* value_axis, Hover_Tooltip_Provider* renderable, const Render_Frame_Snapshot* snapshot = nullptr);
|
|
bool can_show_hover(Renderable* able) const;
|
|
};
|
|
struct LIB_DECL Hover_Tooltip_Provider {
|
|
struct Hover_Read_Guard {
|
|
Hover_Read_Guard() = default;
|
|
Hover_Read_Guard(Hover_Tooltip_State* state, Render_State_Read_Guard guard)
|
|
: state(state), guard(std::move(guard)) {}
|
|
Hover_Read_Guard(const Hover_Read_Guard&) = delete;
|
|
Hover_Read_Guard& operator=(const Hover_Read_Guard&) = delete;
|
|
Hover_Read_Guard(Hover_Read_Guard&&) noexcept = default;
|
|
Hover_Read_Guard& operator=(Hover_Read_Guard&&) noexcept = default;
|
|
~Hover_Read_Guard() = default;
|
|
Hover_Tooltip_State* operator->() const {
|
|
return state;
|
|
}
|
|
explicit operator bool() const {
|
|
return state && guard;
|
|
}
|
|
|
|
Hover_Tooltip_State* state{};
|
|
Render_State_Read_Guard guard;
|
|
};
|
|
|
|
struct Hover_Edit_Guard {
|
|
Hover_Edit_Guard() = default;
|
|
Hover_Edit_Guard(Hover_Tooltip_State* state, Render_State_Write_Guard guard)
|
|
: state(state), guard(std::move(guard)) {}
|
|
Hover_Edit_Guard(const Hover_Edit_Guard&) = delete;
|
|
Hover_Edit_Guard& operator=(const Hover_Edit_Guard&) = delete;
|
|
Hover_Edit_Guard(Hover_Edit_Guard&&) noexcept = default;
|
|
Hover_Edit_Guard& operator=(Hover_Edit_Guard&&) noexcept = default;
|
|
~Hover_Edit_Guard() = default;
|
|
Hover_Tooltip_State* operator->() const {
|
|
return state;
|
|
}
|
|
explicit operator bool() const {
|
|
return state && guard;
|
|
}
|
|
|
|
Hover_Tooltip_State* state{};
|
|
Render_State_Write_Guard guard;
|
|
};
|
|
virtual std::vector<std::string> build_hover_lines(Abs_Axis* h, Abs_Axis* v, Point pos, const Render_Frame_Snapshot* snapshot = nullptr);
|
|
virtual ~Hover_Tooltip_Provider() = default;
|
|
virtual void draw_hover_tooltip(Canvas* canvas, Abs_Axis* h, Abs_Axis* v) {
|
|
auto state = begin_hover_read();
|
|
if (state)
|
|
state->draw_hover_tooltip(canvas, h, v, this);
|
|
}
|
|
virtual bool hover_ok(Renderable* able) {
|
|
auto state = begin_hover_read();
|
|
return state && state->can_show_hover(able);
|
|
}
|
|
virtual bool hit_test_hover(Point pos) {
|
|
(void)pos;
|
|
return true;
|
|
}
|
|
bool hover_tooltip_enabled() {
|
|
auto state = begin_hover_read();
|
|
return state && state->use_hover_tooltip;
|
|
}
|
|
void set_use_hover_info(bool use) {
|
|
auto edit = begin_hover_edit();
|
|
if (!edit)
|
|
return;
|
|
edit->use_hover_tooltip = use;
|
|
}
|
|
void set_hover_tooltip_font(const Font& font) {
|
|
auto edit = begin_hover_edit();
|
|
if (!edit)
|
|
return;
|
|
edit->hover_info_font = font;
|
|
}
|
|
Font hover_tooltip_font() {
|
|
auto state = begin_hover_read();
|
|
return state ? state->hover_info_font : Font{};
|
|
}
|
|
Brush hover_info_background_brush() {
|
|
auto state = begin_hover_read();
|
|
return state ? state->tooltip_background_brush : Brush{};
|
|
}
|
|
void set_hover_tooltip_background_brush(const Brush& brush) {
|
|
auto edit = begin_hover_edit();
|
|
if (!edit)
|
|
return;
|
|
edit->tooltip_background_brush = brush.color.a != 0 ? brush : Brush{};
|
|
}
|
|
Pen tooltip_text_pen() {
|
|
auto state = begin_hover_read();
|
|
return state ? state->tooltip_text_pen : Pen{.style = Line_Style::None};
|
|
}
|
|
void set_tooltip_text_pen(const Pen& pen) {
|
|
auto edit = begin_hover_edit();
|
|
if (!edit)
|
|
return;
|
|
edit->tooltip_text_pen = pen.color.a != 0 ? pen : Pen{.style = Line_Style::None};
|
|
}
|
|
void get_hover_tooltip_contents_margins(int& left, int& top, int& right, int& bottom) {
|
|
auto s = begin_hover_read();
|
|
if (!s) {
|
|
left = top = right = bottom = 0;
|
|
return;
|
|
}
|
|
left = s->hover_info_left;
|
|
top = s->hover_info_top;
|
|
right = s->hover_info_right;
|
|
bottom = s->hover_info_bottom;
|
|
}
|
|
void set_hover_tooltip_contents_margins(int left, int top, int right, int bottom) {
|
|
auto edit = begin_hover_edit();
|
|
if (!edit)
|
|
return;
|
|
edit->hover_info_left = left;
|
|
edit->hover_info_top = top;
|
|
edit->hover_info_right = right;
|
|
edit->hover_info_bottom = bottom;
|
|
}
|
|
Hover_Edit_Guard begin_hover_edit() {
|
|
return begin_hover_edit_impl();
|
|
}
|
|
Hover_Read_Guard begin_hover_read() {
|
|
return begin_hover_read_impl();
|
|
}
|
|
private:
|
|
virtual Hover_Read_Guard begin_hover_read_impl() = 0;
|
|
virtual Hover_Edit_Guard begin_hover_edit_impl() = 0;
|
|
};
|
|
template <typename That>
|
|
struct LIB_DECL Hover_Tooltip_Mixin : Hover_Tooltip_Provider {
|
|
private:
|
|
That* that() {
|
|
return static_cast<That*>(this);
|
|
}
|
|
Hover_Read_Guard begin_hover_read_impl() override {
|
|
auto t = that();
|
|
auto guard = t->d_ptr->acquire_state_read(Renderable_State_Role::Edit);
|
|
auto* state = dynamic_cast<Hover_Tooltip_State*>(guard.state);
|
|
if (!state)
|
|
return {};
|
|
return Hover_Read_Guard(state, std::move(guard));
|
|
}
|
|
Hover_Edit_Guard begin_hover_edit_impl() override {
|
|
auto t = that();
|
|
auto guard = t->d_ptr->acquire_edit_state();
|
|
auto* state = dynamic_cast<Hover_Tooltip_State*>(guard.state);
|
|
if (!state)
|
|
return {};
|
|
return Hover_Edit_Guard(state, std::move(guard));
|
|
}
|
|
};
|
|
} // namespace renderive
|