Files
Renderive/Core/Axis/Time_Axis_p.h
T
2026-08-02 12:15:48 +08:00

81 lines
3.6 KiB
C++

#pragma once
#include <algorithm>
#include <memory_resource>
#include <string>
#include <vector>
#include "../architecture/Plot_Render_Context.h"
#include "../architecture/Timeline_Stream.h"
#include "../base/Memory.h"
#include "../base/String_Format.h"
#include "../base/Time_Of_Day.h"
#include "../render/Canvas.h"
#include "Abs_Axis_p.h"
#include "Time_Axis.h"
namespace renderive {
struct Time_Axis_Input_Data : Abs_Axis_Input_Data {};
struct Time_Axis_Render_State : Abs_Axis_Render_State, Time_Axis_Prop {
int label_tick_interval_hint() const {
double rate = (double)visible_time_point_count / (double)pixel_length;
double ret = rate * (tick_label_spacing_px + (double)(orientation == Orientation::Horizontal ? 80 : 20));
return std::max(1, (int)ret);
}
};
struct Time_Axis_Private : Typed_Render_Data_Base<Abs_Axis_Private, Time_Axis, Time_Axis_Render_State, Time_Axis_Input_Data> {
std::shared_ptr<const Timeline_Stream_Snapshot> timeline_snapshot;
std::vector<double> ticks;
Time_Of_Day time_by_tick(int tick) const {
return timeline_snapshot ? timeline_snapshot->time_by_tick(tick) : Time_Of_Day{};
}
std::shared_ptr<const Timeline_Stream_Snapshot> capture_timeline(const Plot_Render_Snapshot& snapshot, const Time_Axis_Render_State* state) const {
if (!state || !state->timeline_stream)
return {};
return snapshot.timeline_snapshot(state->timeline_stream, state->visible_time_point_count, state->label_tick_interval_hint(), state->newest_at_axis_start);
}
std::shared_ptr<const Timeline_Stream_Snapshot> capture_timeline(const Plot_Render_Snapshot& snapshot) {
sync_state_pipeline();
return capture_timeline(snapshot, render_state());
}
void prepare_data(const Plot_Render_Snapshot& snapshot) override {
sync_state_pipeline();
auto s = render_state();
auto captured = capture_timeline(snapshot, s);
if (captured)
timeline_snapshot = std::move(captured);
if (!timeline_snapshot)
return;
s->coord_start = timeline_snapshot->coordinate_begin;
s->coord_length = timeline_snapshot->visible_time_point_count;
ticks.clear();
for (const Timeline_Label_Tick& tick : timeline_snapshot->ticks) {
ticks.push_back(tick.coordinate);
}
}
std::vector<std::string> create_label_vector(const std::vector<double>& ticks, State_Role src) override {
auto s = reinterpret_cast<Time_Axis_Render_State*>(state(src));
std::vector<std::string> result;
result.reserve(ticks.size());
for (double tick : ticks)
result.push_back(format_time(time_by_tick((int)tick), s->time_format));
return result;
}
std::vector<double> create_tick_vector(double tick_step, const Range& range) override {
return ticks;
}
std::vector<double> create_sub_tick_vector(int sub_tick_count, const std::vector<double>& ticks, const Range& range) override {
return {};
}
void draw(Canvas& canvas, const Plot_Render_Snapshot& snapshot) override {
Abs_Axis_Private::draw(canvas, snapshot);
}
std::string get_tick_label(double tick, State_Role src) override {
auto render_state = reinterpret_cast<Time_Axis_Render_State*>(state(src));
return format_time(time_by_tick((int)tick), render_state->time_format);
}
};
struct Time_Axis_Render_Access final {
static std::shared_ptr<const Timeline_Stream_Snapshot> capture_timeline(Time_Axis* axis, const Plot_Render_Snapshot& snapshot) {
return axis ? axis->d()->capture_timeline(snapshot) : std::shared_ptr<const Timeline_Stream_Snapshot>{};
}
};
}