Files
Renderive/Core/Axis/Time_Axis_p.h
T
2026-08-02 18:58:35 +08:00

102 lines
5.5 KiB
C++

#pragma once
#include <algorithm>
#include <memory_resource>
#include <string>
#include <vector>
#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 "../render/Render_Frame_Snapshot.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> capture_timeline(const Render_Frame_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 Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view) {
return capture_timeline(snapshot, render_state(frame_view));
}
void prepare_data(const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view) override {
(void)capture_timeline(snapshot, frame_view);
}
Axis_Frame_Snapshot frame_snapshot(const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view) override {
auto s = render_state(frame_view);
Axis_Frame_Snapshot result = axis_frame_snapshot(s);
auto captured = capture_timeline(snapshot, s);
if (captured)
result.coord_range = Range{static_cast<double>(captured->coordinate_begin), static_cast<double>(captured->coordinate_begin + captured->visible_time_point_count)};
return result;
}
std::vector<std::string> create_label_vector(const std::vector<double>& ticks, Abs_Axis_Render_State* state) override {
auto s = static_cast<Time_Axis_Render_State*>(state);
std::vector<std::string> result;
result.reserve(ticks.size());
for (double tick : ticks)
result.push_back(format_time(Time_Of_Day{}, s->time_format));
return result;
}
std::vector<double> create_tick_vector(double tick_step, const Range& range) override {
return Abs_Axis_Private::create_tick_vector(tick_step, range);
}
std::vector<double> create_sub_tick_vector(int sub_tick_count, const std::vector<double>& ticks, const Range& range) override {
return {};
}
std::vector<double> create_frame_tick_vector(double, const Range&, Abs_Axis_Render_State* state, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View&) override {
std::vector<double> result;
auto captured = capture_timeline(snapshot, static_cast<Time_Axis_Render_State*>(state));
if (!captured)
return result;
result.reserve(captured->ticks.size());
for (const Timeline_Label_Tick& tick : captured->ticks)
result.push_back(tick.coordinate);
return result;
}
std::vector<double> create_frame_sub_tick_vector(int, const std::vector<double>&, const Range&, Abs_Axis_Render_State*, const Render_Frame_Snapshot&, const Renderable_Frame_View&) override {
return {};
}
std::vector<std::string> create_frame_label_vector(const std::vector<double>& ticks, Abs_Axis_Render_State* state, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View&) override {
auto s = static_cast<Time_Axis_Render_State*>(state);
auto captured = capture_timeline(snapshot, s);
std::vector<std::string> result;
result.reserve(ticks.size());
for (double tick : ticks) {
Time_Of_Day time = captured ? captured->time_by_tick(static_cast<int>(tick)) : Time_Of_Day{};
result.push_back(format_time(time, s->time_format));
}
return result;
}
void draw(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view) override {
Abs_Axis_Private::draw(canvas, snapshot, frame_view);
}
std::string get_tick_label(double tick, Abs_Axis_Render_State* state) override {
auto render_state = static_cast<Time_Axis_Render_State*>(state);
return format_time(Time_Of_Day{}, render_state->time_format);
}
std::string frame_tick_label(double tick, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view) override {
auto s = render_state(frame_view);
auto captured = capture_timeline(snapshot, s);
Time_Of_Day time = captured ? captured->time_by_tick(static_cast<int>(tick)) : Time_Of_Day{};
return format_time(time, s ? s->time_format : std::string{});
}
};
struct Time_Axis_Render_Access final {
static std::shared_ptr<const Timeline_Stream_Snapshot> capture_timeline(Time_Axis* axis, const Render_Frame_Snapshot& snapshot) {
const auto* node = axis ? snapshot.frame_node_for(axis) : nullptr;
return axis && node ? axis->d()->capture_timeline(snapshot, node->frame_view) : std::shared_ptr<const Timeline_Stream_Snapshot>{};
}
};
}