81 lines
3.6 KiB
C++
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>{};
|
|
}
|
|
};
|
|
}
|