Skip to content

Commit

Permalink
Fix lagging time cursor when panning a time series plot (#4972)
Browse files Browse the repository at this point in the history
* Closes [#4564](#4564)

Also removes frame-delay when dragging said time cursor (see commits).

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using newly built examples:
[app.rerun.io](https://app.rerun.io/pr/4972/index.html)
* Using examples from latest `main` build:
[app.rerun.io](https://app.rerun.io/pr/4972/index.html?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[app.rerun.io](https://app.rerun.io/pr/4972/index.html?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG

- [PR Build Summary](https://build.rerun.io/pr/4972)
- [Docs
preview](https://rerun.io/preview/5332e5019ba61e4deb9b61478005487293d1c4ab/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/5332e5019ba61e4deb9b61478005487293d1c4ab/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)
  • Loading branch information
emilk authored Jan 30, 2024
1 parent fb8d5d9 commit 19f5382
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 37 deletions.
50 changes: 26 additions & 24 deletions crates/re_space_view_time_series/src/space_view_class.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use egui::ahash::HashSet;
use egui_plot::{Legend, Line, Plot, Points};
use egui_plot::{Legend, Line, Plot, PlotPoint, Points};

use re_data_store::TimeType;
use re_format::next_grid_tick_magnitude_ns;
Expand Down Expand Up @@ -354,7 +354,7 @@ impl SpaceViewClass for TimeSeriesSpaceView {
}

let egui_plot::PlotResponse {
inner: time_x,
inner: _,
response,
transform,
} = plot.show(ui, |plot_ui| {
Expand Down Expand Up @@ -407,18 +407,18 @@ impl SpaceViewClass for TimeSeriesSpaceView {
}

state.was_dragging_time_cursor = state.is_dragging_time_cursor;

// decide if the time cursor should be displayed, and if where
current_time
.map(|current_time| (current_time - time_offset) as f64)
.filter(|&x| {
// only display the time cursor when it's actually above the plot area
plot_ui.plot_bounds().min()[0] <= x && x <= plot_ui.plot_bounds().max()[0]
})
.map(|x| plot_ui.screen_from_plot([x, 0.0].into()).x)
});

if let Some(time_x) = time_x {
// Decide if the time cursor should be displayed, and if so where:
let time_x = current_time
.map(|current_time| (current_time - time_offset) as f64)
.filter(|&x| {
// only display the time cursor when it's actually above the plot area
transform.bounds().min()[0] <= x && x <= transform.bounds().max()[0]
})
.map(|x| transform.position_from_point(&PlotPoint::new(x, 0.0)).x);

if let Some(mut time_x) = time_x {
let interact_radius = ui.style().interaction.resize_grab_radius_side;
let line_rect = egui::Rect::from_x_y_ranges(time_x..=time_x, response.rect.y_range())
.expand(interact_radius);
Expand All @@ -431,27 +431,29 @@ impl SpaceViewClass for TimeSeriesSpaceView {
state.is_dragging_time_cursor = false;
if response.dragged() {
if let Some(pointer_pos) = ui.input(|i| i.pointer.hover_pos()) {
let time =
time_offset + transform.value_from_position(pointer_pos).x.round() as i64;
let new_offset_time = transform.value_from_position(pointer_pos).x;
let new_time = time_offset + new_offset_time.round() as i64;

// Avoid frame-delay:
time_x = pointer_pos.x;

let mut time_ctrl = ctx.rec_cfg.time_ctrl.write();
time_ctrl.set_time(time);
time_ctrl.set_time(new_time);
time_ctrl.pause();

state.is_dragging_time_cursor = true;
}
}

let stroke = if response.dragged() {
ui.style().visuals.widgets.active.fg_stroke
} else if response.hovered() {
ui.style().visuals.widgets.hovered.fg_stroke
} else {
ui.visuals().widgets.inactive.fg_stroke
};
ctx.re_ui
.paint_time_cursor(ui.painter(), time_x, response.rect.y_range(), stroke);
ctx.re_ui.paint_time_cursor(
ui,
ui.painter(),
&response,
time_x,
response.rect.y_range(),
);
}

Ok(())
}
}
Expand Down
20 changes: 8 additions & 12 deletions crates/re_time_panel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1281,11 +1281,11 @@ fn time_marker_ui(
let is_anything_being_dragged = ui.memory(|mem| mem.is_anything_being_dragged());
let interact_radius = ui.style().interaction.resize_grab_radius_side;

let mut is_hovering = false;
let mut is_hovering_time_cursor = false;

// show current time as a line:
if let Some(time) = time_ctrl.time() {
if let Some(x) = time_ranges_ui.x_from_time_f32(time) {
if let Some(mut x) = time_ranges_ui.x_from_time_f32(time) {
if timeline_rect.x_range().contains(x) {
let line_rect =
Rect::from_x_y_ranges(x..=x, timeline_rect.top()..=ui.max_rect().bottom())
Expand All @@ -1295,30 +1295,26 @@ fn time_marker_ui(
.interact(line_rect, time_drag_id, egui::Sense::drag())
.on_hover_and_drag_cursor(timeline_cursor_icon);

is_hovering = !is_anything_being_dragged && response.hovered();
is_hovering_time_cursor = response.hovered();

if response.dragged() {
if let Some(pointer_pos) = pointer_pos {
if let Some(time) = time_ranges_ui.time_from_x_f32(pointer_pos.x) {
let time = time_ranges_ui.clamp_time(time);
time_ctrl.set_time(time);
time_ctrl.pause();

x = pointer_pos.x; // avoid frame-delay
}
}
}

let stroke = if response.dragged() {
ui.style().visuals.widgets.active.fg_stroke
} else if is_hovering {
ui.style().visuals.widgets.hovered.fg_stroke
} else {
ui.visuals().widgets.inactive.fg_stroke
};
re_ui.paint_time_cursor(
ui,
time_area_painter,
&response,
x,
Rangef::new(timeline_rect.top(), ui.max_rect().bottom()),
stroke,
);
}
}
Expand All @@ -1329,7 +1325,7 @@ fn time_marker_ui(
let is_pointer_in_timeline_rect = timeline_rect.contains(pointer_pos);

// Show preview?
if !is_hovering
if !is_hovering_time_cursor
&& is_pointer_in_timeline_rect
&& !is_anything_being_dragged
&& !is_hovering_the_loop_selection
Expand Down
11 changes: 10 additions & 1 deletion crates/re_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,11 +1073,20 @@ impl ReUi {
#[allow(clippy::unused_self)]
pub fn paint_time_cursor(
&self,
ui: &egui::Ui,
painter: &egui::Painter,
response: &egui::Response,
x: f32,
y: Rangef,
stroke: egui::Stroke,
) {
let stroke = if response.dragged() {
ui.style().visuals.widgets.active.fg_stroke
} else if response.hovered() {
ui.style().visuals.widgets.hovered.fg_stroke
} else {
ui.visuals().widgets.inactive.fg_stroke
};

let Rangef {
min: y_min,
max: y_max,
Expand Down

0 comments on commit 19f5382

Please sign in to comment.