wip(plot): region layout, hot handles and draggable handles (build restored)
This commit is contained in:
1 parent
7d2349555d
commit
e4d48cc6c3
9 files changed
+915
-37
No files matched your search
+52
-1
@@ -348,6 +348,9 @@ void Renderer::draw(Plot& plot) {
|
||||
draw_tick_labels(plot, layout);
|
||||
draw_titles(plot, layout);
|
||||
draw_traces(plot, layout);
|
||||
// Regions over the traces and under the cursors: an area of interest the data is
|
||||
// still legible through, with the markers that bound it on top of it.
|
||||
draw_regions(plot, layout);
|
||||
draw_cursors(plot, layout);
|
||||
draw_measures(plot, layout);
|
||||
draw_annotations(plot);
|
||||
@@ -764,10 +767,17 @@ void Renderer::draw_traces(const Plot& plot, const PlotLayout& layout) {
|
||||
void Renderer::draw_cursors(const Plot& plot, const PlotLayout& layout) {
|
||||
const Range y_range = plot.y_range(0);
|
||||
const bool log_y = plot.y_axis(0).log;
|
||||
// The handles the input layer last found under the pointer: a marker hovered or
|
||||
// being dragged is drawn in the style's cursor colour and as a *tab*, so the cue
|
||||
// does not depend on the marker's own colour differing from the accent -- a cursor
|
||||
// created in the accent colour is otherwise indistinguishable from an idle one.
|
||||
const HotHandles hot = plot.hot_handles();
|
||||
|
||||
for (u32 i = 0; i < plot.cursor_count(); ++i) {
|
||||
const Cursor& cursor = plot.cursor(i);
|
||||
if (!cursor.visible) continue;
|
||||
const u64 id = static_cast<u64>(i);
|
||||
const bool on = id == hot.cursor || id == hot.grabbed_cursor;
|
||||
const Transform transform = plot.x_transform(cursor.axis_x);
|
||||
const f32 px = static_cast<f32>(transform.to_screen_x(cursor.x));
|
||||
// A cursor scrolled out of the visible x range is off the plot: drawing it
|
||||
@@ -776,13 +786,54 @@ void Renderer::draw_cursors(const Plot& plot, const PlotLayout& layout) {
|
||||
|
||||
stage_segment(cursor.x, y_range.min, cursor.x, y_range.max, plot.x_axis(cursor.axis_x).log,
|
||||
log_y);
|
||||
flush_lines(mapping(plot, cursor.axis_x, 0), cursor.color, style_.device(style_.line_width_px));
|
||||
flush_lines(mapping(plot, cursor.axis_x, 0),
|
||||
on ? style_.cursor : cursor.color,
|
||||
style_.device(on ? style_.handle_width_px : style_.line_width_px));
|
||||
if (!cursor.label.empty()) {
|
||||
stage_text({px + style_.device(3.0f), layout.axes.y + style_.device(2.0f)}, cursor.label.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::draw_regions(const Plot& plot, const PlotLayout& layout) {
|
||||
const HotHandles hot = plot.hot_handles();
|
||||
const f32 edge_w = style_.device(style_.line_width_px);
|
||||
|
||||
for (const RegionLayout& region : layout.regions) {
|
||||
const Region& config = plot.region(region.region);
|
||||
// The fill first, so both bounds are drawn on top of it: one instance of the
|
||||
// line pipeline (see fill_pixels), which blends at the region's own alpha and
|
||||
// therefore leaves the trace under it readable.
|
||||
if (region.fill.w > 0.0f) fill_pixels(region.fill, config.fill);
|
||||
|
||||
// A bound is emphasized only when that bound is the hot zone: a body hover draws
|
||||
// no edge highlight -- the fill is the body, and the host's own cursor says what
|
||||
// a drag there would do (Controller::region_grab()).
|
||||
const bool hot_region = static_cast<u64>(region.region) == hot.region;
|
||||
const bool hot_left = hot_region && hot.zone == RegionGrab::Left;
|
||||
const bool hot_right = hot_region && hot.zone == RegionGrab::Right;
|
||||
// A hot bound is drawn in the cursor colour and at its tab's own width: the tab is
|
||||
// the target the controller hit-tested, so the highlight a grab or a hover lights up
|
||||
// is exactly the thing a drag was aimed at, and the grab column and the drawn column
|
||||
// are one number rather than two that would have to be kept in step.
|
||||
draw_region_edge(region.left_handle, layout.axes, hot_left ? style_.cursor : config.edge,
|
||||
hot_left ? region.left_handle.w : edge_w);
|
||||
draw_region_edge(region.right_handle, layout.axes, hot_right ? style_.cursor : config.edge,
|
||||
hot_right ? region.right_handle.w : edge_w);
|
||||
|
||||
if (!config.label.empty() && region.label.w > 0.0f) {
|
||||
stage_text({region.label.x, region.label.y}, config.label.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::draw_region_edge(const Rect& tab, const Rect& axes, Color color, f32 width) {
|
||||
const f32 x = handle_column(tab);
|
||||
if (x < axes.x || x >= axes.right()) return; // scrolled out: the strip is not ours
|
||||
lines_.add_segment({x, tab.y}, {x, tab.bottom()});
|
||||
flush_lines(pixel_mapping(), color, width);
|
||||
}
|
||||
|
||||
void Renderer::draw_measures(const Plot& plot, const PlotLayout& layout) {
|
||||
const Rect& axes = layout.axes;
|
||||
const Range y_range = plot.y_range(0);
|
||||
|
||||
Reference in new issue
Block a user