仍然闪烁
This commit is contained in:
+107
-38
@@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
#include "../architecture/Render_Lease.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../render/Render_Frame_Snapshot.h"
|
||||
#include "Abs_Axis.h"
|
||||
#include "blend2d/blend2d.h"
|
||||
namespace renderive {
|
||||
@@ -16,38 +17,73 @@ struct Abs_Axis_Render_State : Render_State, Abs_Axis_Prop {
|
||||
}
|
||||
};
|
||||
struct Abs_Axis_Input_Data : Input_Data {};
|
||||
struct Axis_Frame_Snapshot {
|
||||
Orientation orientation = Orientation::Horizontal;
|
||||
Range coord_range{0.0, 1.0};
|
||||
Range pixel_range{0.0, 1.0};
|
||||
[[nodiscard]] double coord_to_pixel(double coord) const {
|
||||
if (coord_range.length() == 0.0)
|
||||
return pixel_range.origin;
|
||||
return pixel_range.origin + pixel_range.length() * (coord - coord_range.origin) / coord_range.length();
|
||||
}
|
||||
[[nodiscard]] double pixel_to_coord(double pixel) const {
|
||||
if (pixel_range.length() == 0.0)
|
||||
return coord_range.origin;
|
||||
return coord_range.origin + coord_range.length() * (pixel - pixel_range.origin) / pixel_range.length();
|
||||
}
|
||||
[[nodiscard]] int pixel_size() const {
|
||||
return static_cast<int>(std::max(1.0, pixel_range.size()));
|
||||
}
|
||||
};
|
||||
struct Abs_Axis_Private : Typed_Render_Data<Abs_Axis, Abs_Axis_Render_State, Abs_Axis_Input_Data> {
|
||||
int tick_count = 2;
|
||||
[[nodiscard]] Abs_Axis_Render_State* edit_axis_state() {
|
||||
return edit_state();
|
||||
}
|
||||
[[nodiscard]] Abs_Axis_Render_State* render_axis_state() {
|
||||
return render_state();
|
||||
return static_cast<Abs_Axis_Render_State*>(state(Renderable_State_Role::Render));
|
||||
}
|
||||
[[nodiscard]] Abs_Axis_Render_State* render_axis_state(const Renderable_Frame_View& frame_view) const {
|
||||
return render_state(frame_view);
|
||||
}
|
||||
static int pixel_start_of(const Abs_Axis_Render_State* s) {
|
||||
return s->orientation == Orientation::Horizontal ? s->x : s->y;
|
||||
}
|
||||
static Axis_Frame_Snapshot axis_frame_snapshot(const Abs_Axis_Render_State* s) {
|
||||
if (!s)
|
||||
return {};
|
||||
double pixel_start = static_cast<double>(pixel_start_of(s));
|
||||
return Axis_Frame_Snapshot{
|
||||
s->orientation,
|
||||
Range{s->coord_start, s->coord_start + s->coord_length},
|
||||
Range{pixel_start, pixel_start + static_cast<double>(s->pixel_length)}
|
||||
};
|
||||
}
|
||||
virtual Axis_Frame_Snapshot frame_snapshot(const Render_Frame_Snapshot&, const Renderable_Frame_View& frame_view) {
|
||||
return axis_frame_snapshot(render_axis_state(frame_view));
|
||||
}
|
||||
double get_mantissa(double input, double* magnitude = nullptr);
|
||||
[[nodiscard]] double clean_mantissa(double input);
|
||||
[[nodiscard]] double pick_closest(double target, const std::vector<double>& candidates);
|
||||
void prepare_data(const Render_Frame_Snapshot&) override {
|
||||
sync_state_pipeline();
|
||||
}
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Abs_Axis_Render_State* s = render_axis_state();
|
||||
void prepare_data(const Render_Frame_Snapshot&, const Renderable_Frame_View&) override {}
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view) override {
|
||||
Abs_Axis_Render_State* s = render_axis_state(frame_view);
|
||||
if (!s)
|
||||
return;
|
||||
Axis_Frame_Snapshot axis_snapshot = frame_snapshot(snapshot, frame_view);
|
||||
const int pixel_start = pixel_start_of(s);
|
||||
Range range = {s->coord_start, s->coord_start + s->coord_length};
|
||||
Range range = axis_snapshot.coord_range;
|
||||
double tick_step = get_tick_step(range);
|
||||
std::vector<double> ticks = create_tick_vector(tick_step, range);
|
||||
std::vector<double> ticks = create_frame_tick_vector(tick_step, range, s, snapshot, frame_view);
|
||||
while (!ticks.empty() && !range.contains(ticks.back())) {
|
||||
ticks.pop_back();
|
||||
}
|
||||
int sub_tick_count = get_sub_tick_count(tick_step);
|
||||
std::vector<double> sub_ticks = create_sub_tick_vector(sub_tick_count, ticks, range);
|
||||
std::vector<double> sub_ticks = create_frame_sub_tick_vector(sub_tick_count, ticks, range, s, snapshot, frame_view);
|
||||
while (!sub_ticks.empty() && !range.contains(sub_ticks.back())) {
|
||||
sub_ticks.pop_back();
|
||||
}
|
||||
std::vector<std::string> labels = render_label_vector(ticks);
|
||||
std::vector<std::string> labels = create_frame_label_vector(ticks, s, snapshot, frame_view);
|
||||
Text_Metrics tm = canvas.measure_text(!s->unit_text_font.valid() ? "0" : " ");
|
||||
double h = tm.line_height();
|
||||
canvas.set_pen(Pen{.color = s->color});
|
||||
@@ -56,7 +92,7 @@ struct Abs_Axis_Private : Typed_Render_Data<Abs_Axis, Abs_Axis_Render_State, Abs
|
||||
int n = (int)ticks.size();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
double tick = ticks[i];
|
||||
double x = render_coord_to_pixel(tick);
|
||||
double x = axis_snapshot.coord_to_pixel(tick);
|
||||
canvas.draw_line({x, (double)s->y}, {x, (double)(s->y + s->tick_length)});
|
||||
const std::string& label = labels[i];
|
||||
PointF start{x, (double)(s->y + s->tick_length)};
|
||||
@@ -67,7 +103,7 @@ struct Abs_Axis_Private : Typed_Render_Data<Abs_Axis, Abs_Axis_Render_State, Abs
|
||||
canvas.restore();
|
||||
}
|
||||
for (double tick : sub_ticks) {
|
||||
double x = render_coord_to_pixel(tick);
|
||||
double x = axis_snapshot.coord_to_pixel(tick);
|
||||
canvas.draw_line({x, (double)s->y}, {x, (double)(s->y + s->sub_tick_length)});
|
||||
}
|
||||
}
|
||||
@@ -76,7 +112,7 @@ struct Abs_Axis_Private : Typed_Render_Data<Abs_Axis, Abs_Axis_Render_State, Abs
|
||||
int n = (int)ticks.size();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
double tick = ticks[i];
|
||||
double y = render_coord_to_pixel(tick);
|
||||
double y = axis_snapshot.coord_to_pixel(tick);
|
||||
const std::string& label = labels[i];
|
||||
canvas.draw_line({(double)s->x, y}, {(double)(s->x + s->tick_length), y});
|
||||
PointF start{(double)(s->x + s->tick_length * 2), y + h / 2.0};
|
||||
@@ -87,7 +123,7 @@ struct Abs_Axis_Private : Typed_Render_Data<Abs_Axis, Abs_Axis_Render_State, Abs
|
||||
canvas.restore();
|
||||
}
|
||||
for (double tick : sub_ticks) {
|
||||
double y = render_coord_to_pixel(tick);
|
||||
double y = axis_snapshot.coord_to_pixel(tick);
|
||||
canvas.draw_line({(double)s->x, y}, {(double)(s->x + s->sub_tick_length), y});
|
||||
}
|
||||
}
|
||||
@@ -131,6 +167,18 @@ struct Abs_Axis_Private : Typed_Render_Data<Abs_Axis, Abs_Axis_Render_State, Abs
|
||||
virtual std::vector<double> create_sub_tick_vector(int sub_tick_count, const std::vector<double>& ticks, const Range& range);
|
||||
virtual std::string get_tick_label(double tick, Abs_Axis_Render_State* state);
|
||||
virtual std::vector<std::string> create_label_vector(const std::vector<double>& ticks, Abs_Axis_Render_State* state);
|
||||
virtual std::vector<double> create_frame_tick_vector(double tick_step, const Range& range, Abs_Axis_Render_State*, const Render_Frame_Snapshot&, const Renderable_Frame_View&) {
|
||||
return create_tick_vector(tick_step, range);
|
||||
}
|
||||
virtual std::vector<double> create_frame_sub_tick_vector(int sub_tick_count, const std::vector<double>& ticks, const Range& range, Abs_Axis_Render_State*, const Render_Frame_Snapshot&, const Renderable_Frame_View&) {
|
||||
return create_sub_tick_vector(sub_tick_count, ticks, range);
|
||||
}
|
||||
virtual std::vector<std::string> create_frame_label_vector(const std::vector<double>& ticks, Abs_Axis_Render_State* state, const Render_Frame_Snapshot&, const Renderable_Frame_View&) {
|
||||
return create_label_vector(ticks, state);
|
||||
}
|
||||
virtual std::string frame_tick_label(double tick, const Render_Frame_Snapshot&, const Renderable_Frame_View& frame_view) {
|
||||
return get_tick_label(tick, render_axis_state(frame_view));
|
||||
}
|
||||
[[nodiscard]] double edit_pixel_to_coord(double pixel) {
|
||||
return pixel_to_coord(pixel, edit_axis_state());
|
||||
}
|
||||
@@ -167,24 +215,6 @@ struct Abs_Axis_Private : Typed_Render_Data<Abs_Axis, Abs_Axis_Render_State, Abs
|
||||
return create_label_vector(ticks, render_axis_state());
|
||||
}
|
||||
};
|
||||
struct Axis_Frame_Snapshot {
|
||||
Orientation orientation = Orientation::Horizontal;
|
||||
Range coord_range{0.0, 1.0};
|
||||
Range pixel_range{0.0, 1.0};
|
||||
[[nodiscard]] double coord_to_pixel(double coord) const {
|
||||
if (coord_range.length() == 0.0)
|
||||
return pixel_range.origin;
|
||||
return pixel_range.origin + pixel_range.length() * (coord - coord_range.origin) / coord_range.length();
|
||||
}
|
||||
[[nodiscard]] double pixel_to_coord(double pixel) const {
|
||||
if (pixel_range.length() == 0.0)
|
||||
return coord_range.origin;
|
||||
return coord_range.origin + coord_range.length() * (pixel - pixel_range.origin) / pixel_range.length();
|
||||
}
|
||||
[[nodiscard]] int pixel_size() const {
|
||||
return static_cast<int>(std::max(1.0, pixel_range.size()));
|
||||
}
|
||||
};
|
||||
struct Axis_Mapping_2D {
|
||||
Axis_Frame_Snapshot domain;
|
||||
Axis_Frame_Snapshot value;
|
||||
@@ -228,18 +258,30 @@ struct Axis_Basis_2D {
|
||||
}
|
||||
};
|
||||
struct Axis_Render_Access final {
|
||||
static Axis_Frame_Snapshot snapshot_from_state(const Abs_Axis_Render_State* s) {
|
||||
return Abs_Axis_Private::axis_frame_snapshot(s);
|
||||
}
|
||||
static Axis_Frame_Snapshot snapshot(Abs_Axis* axis) {
|
||||
const auto* s = axis->d()->render_axis_state();
|
||||
double pixel_start = static_cast<double>(Abs_Axis_Private::pixel_start_of(s));
|
||||
return Axis_Frame_Snapshot{
|
||||
s->orientation,
|
||||
Range{s->coord_start, s->coord_start + s->coord_length},
|
||||
Range{pixel_start, pixel_start + static_cast<double>(s->pixel_length)}
|
||||
};
|
||||
return snapshot_from_state(s);
|
||||
}
|
||||
static const Abs_Axis_Render_State* frame_state(Abs_Axis* axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
const auto* node = frame_snapshot.frame_node_for(axis);
|
||||
if (!node)
|
||||
return nullptr;
|
||||
return dynamic_cast<const Abs_Axis_Render_State*>(node->frame_view.state);
|
||||
}
|
||||
static Axis_Frame_Snapshot snapshot(Abs_Axis* axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
if (const auto* node = frame_snapshot.frame_node_for(axis))
|
||||
return axis->d()->frame_snapshot(frame_snapshot, node->frame_view);
|
||||
return snapshot(axis);
|
||||
}
|
||||
static Axis_Mapping_2D mapping(Abs_Axis* domain_axis, Abs_Axis* value_axis) {
|
||||
return Axis_Mapping_2D{snapshot(domain_axis), snapshot(value_axis)};
|
||||
}
|
||||
static Axis_Mapping_2D mapping(Abs_Axis* domain_axis, Abs_Axis* value_axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
return Axis_Mapping_2D{snapshot(domain_axis, frame_snapshot), snapshot(value_axis, frame_snapshot)};
|
||||
}
|
||||
static bool orientations_orthogonal(Abs_Axis* domain_axis, Abs_Axis* value_axis) {
|
||||
return domain_axis && value_axis && orientation(domain_axis) != orientation(value_axis);
|
||||
}
|
||||
@@ -252,15 +294,42 @@ struct Axis_Render_Access final {
|
||||
static Range coord_range(Abs_Axis* axis) {
|
||||
return axis->d()->render_coord_range();
|
||||
}
|
||||
static Range coord_range(Abs_Axis* axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
Axis_Frame_Snapshot s = snapshot(axis, frame_snapshot);
|
||||
return s.coord_range;
|
||||
}
|
||||
static int pixel_size(Abs_Axis* axis) {
|
||||
return axis->d()->render_pixel_size();
|
||||
}
|
||||
static int pixel_size(Abs_Axis* axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
return snapshot(axis, frame_snapshot).pixel_size();
|
||||
}
|
||||
static Orientation orientation(Abs_Axis* axis) {
|
||||
return axis->d()->render_axis_state()->orientation;
|
||||
}
|
||||
static Orientation orientation(Abs_Axis* axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
return snapshot(axis, frame_snapshot).orientation;
|
||||
}
|
||||
static std::string tick_label(Abs_Axis* axis, double tick) {
|
||||
return axis->d()->render_tick_label(tick);
|
||||
}
|
||||
static std::string tick_label(Abs_Axis* axis, double tick, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
if (axis) {
|
||||
if (const auto* node = frame_snapshot.frame_node_for(axis))
|
||||
return axis->d()->frame_tick_label(tick, frame_snapshot, node->frame_view);
|
||||
}
|
||||
return tick_label(axis, tick);
|
||||
}
|
||||
static std::string unit_text(Abs_Axis* axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
if (const auto* s = frame_state(axis, frame_snapshot))
|
||||
return s->unit_text;
|
||||
return axis ? axis->unit_text() : std::string{};
|
||||
}
|
||||
static Font unit_text_font(Abs_Axis* axis, const Render_Frame_Snapshot& frame_snapshot) {
|
||||
if (const auto* s = frame_state(axis, frame_snapshot))
|
||||
return s->unit_text_font;
|
||||
return axis ? axis->unit_text_font() : Font{};
|
||||
}
|
||||
};
|
||||
template <typename That>
|
||||
void Abs_Axis::Builder_T<That>::set(Abs_Axis* ret) {
|
||||
|
||||
Reference in New Issue
Block a user