Skip to content

Commit

Permalink
Good looking Blueprint View (#962)
Browse files Browse the repository at this point in the history
* Make the hover background color brighter to make it easier to see

* Add a nice hover-effect to the entire row in the blueprint view

* Tweak hover rect

* Fix hover going through menus

* Make room for visibility button, even when not visible

* Add a little comment

* More comments

* Don't leave room for the visibility button

* Draw hover-rect behind instead

* Clip button text instead of painting over it

* Log instead of unwrap

* Compilation fix

* Remove the indent vlines

* Tweak button spacing in the timeline view
  • Loading branch information
emilk authored Jan 27, 2023
1 parent f2c8542 commit 31e8d0f
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 60 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ arrow2_convert = { git = "https://github.com/rerun-io/arrow2-convert", rev = "7e
# arrow2 = { path = "../arrow2" }
# arrow2_convert = { path = "../arrow2-convert/arrow2_convert" }

# 2023-01-27 - wgpu update
ecolor = { git = "https://github.com/emilk/egui", rev = "ce62b61e15af391cc0da9963d5920bcbdc8a6704" }
eframe = { git = "https://github.com/emilk/egui", rev = "ce62b61e15af391cc0da9963d5920bcbdc8a6704" }
egui = { git = "https://github.com/emilk/egui", rev = "ce62b61e15af391cc0da9963d5920bcbdc8a6704" }
egui_extras = { git = "https://github.com/emilk/egui", rev = "ce62b61e15af391cc0da9963d5920bcbdc8a6704" }
egui-wgpu = { git = "https://github.com/emilk/egui", rev = "ce62b61e15af391cc0da9963d5920bcbdc8a6704" }
emath = { git = "https://github.com/emilk/egui", rev = "ce62b61e15af391cc0da9963d5920bcbdc8a6704" }
epaint = { git = "https://github.com/emilk/egui", rev = "ce62b61e15af391cc0da9963d5920bcbdc8a6704" }
# 2023-01-27 - add ability to disable the vertical line in indented blocks (e.g. our blurprint panel tree)
ecolor = { git = "https://github.com/emilk/egui", rev = "fe7ff6626652d2da6c1fa63b7b75131cd9d664ab" }
eframe = { git = "https://github.com/emilk/egui", rev = "fe7ff6626652d2da6c1fa63b7b75131cd9d664ab" }
egui = { git = "https://github.com/emilk/egui", rev = "fe7ff6626652d2da6c1fa63b7b75131cd9d664ab" }
egui_extras = { git = "https://github.com/emilk/egui", rev = "fe7ff6626652d2da6c1fa63b7b75131cd9d664ab" }
egui-wgpu = { git = "https://github.com/emilk/egui", rev = "fe7ff6626652d2da6c1fa63b7b75131cd9d664ab" }
emath = { git = "https://github.com/emilk/egui", rev = "fe7ff6626652d2da6c1fa63b7b75131cd9d664ab" }
epaint = { git = "https://github.com/emilk/egui", rev = "fe7ff6626652d2da6c1fa63b7b75131cd9d664ab" }
# ecolor = { path = "../../egui/crates/ecolor" }
# eframe = { path = "../../egui/crates/eframe" }
# egui = { path = "../../egui/crates/egui" }
Expand Down
7 changes: 4 additions & 3 deletions crates/re_ui/src/design_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ fn apply_design_tokens(ctx: &egui::Context) -> DesignTokens {
get_aliased_color(&json, "{Alias.Color.Action.Default.value}");

{
// Background colors for menu buttons etc:
// Background colors for buttons (menu buttons, blueprint buttons, etc) when hovered or clicked:
// let hovered_color = get_aliased_color(&json, "{Alias.Color.Action.Hovered.value}");
let hovered_color = Color32::from_gray(20); // TODO(emilk): change the content of the design_tokens.json origin instead
let hovered_color = Color32::from_gray(64); // TODO(emilk): change the content of the design_tokens.json origin instead
egui_style.visuals.widgets.hovered.weak_bg_fill = hovered_color;
egui_style.visuals.widgets.hovered.bg_fill = hovered_color;
egui_style.visuals.widgets.active.weak_bg_fill = hovered_color;
Expand Down Expand Up @@ -127,7 +127,8 @@ fn apply_design_tokens(ctx: &egui::Context) -> DesignTokens {

// Add stripes to grids and tables?
egui_style.visuals.striped = false;
egui_style.visuals.faint_bg_color = Color32::from_additive_luminance(8);
egui_style.visuals.indent_has_left_vline = false;
egui_style.spacing.indent = 14.0;

egui_style.debug.show_blocking_widget = false; // turn this on to debug interaction problems

Expand Down
13 changes: 8 additions & 5 deletions crates/re_viewer/src/misc/time_control_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,14 @@ impl TimeControl {
times_per_timeline: &TimesPerTimeline,
ui: &mut egui::Ui,
) {
self.play_button_ui(re_ui, ui, times_per_timeline);
self.follow_button_ui(re_ui, ui, times_per_timeline);
self.pause_button_ui(re_ui, ui);
self.step_time_button_ui(re_ui, ui, times_per_timeline);
self.loop_button_ui(re_ui, ui);
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 5.0; // from figma
self.play_button_ui(re_ui, ui, times_per_timeline);
self.follow_button_ui(re_ui, ui, times_per_timeline);
self.pause_button_ui(re_ui, ui);
self.step_time_button_ui(re_ui, ui, times_per_timeline);
self.loop_button_ui(re_ui, ui);
});
}

fn play_button_ui(
Expand Down
4 changes: 4 additions & 0 deletions crates/re_viewer/src/ui/time_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ impl TimePanel {

#[allow(clippy::unused_self)]
fn collapsed_ui(&mut self, ctx: &mut ViewerContext<'_>, ui: &mut egui::Ui) {
ui.spacing_mut().item_spacing.x = 18.0; // from figma

ctx.rec_cfg
.time_ctrl
.time_control_ui(ctx.re_ui, ctx.log_db.times_per_timeline(), ui);
Expand Down Expand Up @@ -520,6 +522,8 @@ impl TimePanel {
}

fn top_row_ui(ctx: &mut ViewerContext<'_>, ui: &mut egui::Ui) {
ui.spacing_mut().item_spacing.x = 18.0; // from figma

ctx.rec_cfg
.time_ctrl
.time_control_ui(ctx.re_ui, ctx.log_db.times_per_timeline(), ui);
Expand Down
106 changes: 71 additions & 35 deletions crates/re_viewer/src/ui/viewport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ impl Viewport {
ui: &mut egui::Ui,
space_view_id: &SpaceViewId,
) {
let space_view = self.space_views.get_mut(space_view_id).unwrap();
let Some(space_view) = self.space_views.get_mut(space_view_id) else {
re_log::warn_once!("Bug: asked to show a ui for a Space View that doesn't exist");
return;
};
debug_assert_eq!(space_view.id, *space_view_id);

let root_group = space_view.data_blueprint.root_group();
Expand Down Expand Up @@ -561,19 +564,16 @@ impl Viewport {
}
}

/// Returns true if visibility changed
/// Show a single button (`add_content`), justified,
/// and show a visibility button if the row is hovered.
///
/// Returns true if visibility changed.
fn blueprint_row_with_visibility_button(
ui: &mut egui::Ui,
enabled: bool,
visible: &mut bool,
add_content: impl FnOnce(&mut egui::Ui) -> egui::Response,
) -> bool {
let row_rect = ui.max_rect().expand2(ui.spacing().item_spacing * 0.5);

let hovered = ui
.input(|i| i.pointer.hover_pos())
.map_or(false, |pointer| row_rect.contains(pointer));

if !*visible || !enabled {
// Dim the appearance of things added by `add_content`:
let widget_visuals = &mut ui.visuals_mut().widgets;
Expand All @@ -584,44 +584,80 @@ fn blueprint_row_with_visibility_button(
dim_color(&mut widget_visuals.inactive.fg_stroke.color);
}

add_content(ui);
let where_to_add_hover_rect = ui.painter().add(egui::Shape::Noop);

// Make the main button span the whole width to make it easier to click:
let main_button_response = ui
.with_layout(egui::Layout::top_down_justified(egui::Align::LEFT), |ui| {
ui.style_mut().wrap = Some(false);

if hovered {
// TODO(emilk): enable the highlight once clicking the whole width
// is the same as clicking the button, i.e. the button in `add_content` is justified.
if false {
// Highlight the row:
let mut paint_rect = row_rect;
paint_rect.min.x = 0.0; // fill full panel width
// Turn off the background color of hovered buttons.
// Why? Because we add a manual hover-effect later.
// Why? Because we want that hover-effect even when only the visibility button is hovered.
let visuals = ui.visuals_mut();
visuals.widgets.hovered.weak_bg_fill = egui::Color32::TRANSPARENT;
visuals.widgets.hovered.bg_fill = egui::Color32::TRANSPARENT;
visuals.widgets.active.weak_bg_fill = egui::Color32::TRANSPARENT;
visuals.widgets.active.bg_fill = egui::Color32::TRANSPARENT;
visuals.widgets.open.weak_bg_fill = egui::Color32::TRANSPARENT;
visuals.widgets.open.bg_fill = egui::Color32::TRANSPARENT;

if ui
.interact(ui.max_rect(), ui.id(), egui::Sense::hover())
.hovered()
{
// Clip the main button so that the visibility button has room to cover it.
// Ideally we would only clip the button _text_, not the button background, but that's not possible.
let mut clip_rect = ui.max_rect();
let visibility_button_width = 16.0;
clip_rect.max.x -= visibility_button_width;
ui.set_clip_rect(clip_rect);
}

// TODO(emilk): paint behind when https://github.com/emilk/egui/issues/1516 is done
ui.painter()
.rect_filled(paint_rect, 2.0, egui::Color32::WHITE.gamma_multiply(0.1));
}
add_content(ui)
})
.inner;

visibility_button(ui, enabled, visible).changed()
let main_button_rect = main_button_response.rect;

let button_hovered = ui
.interact(main_button_rect, ui.id(), egui::Sense::hover())
.hovered();

if button_hovered {
let visibility_button_changed = visibility_button(ui, enabled, visible).changed();

// Highlight the row:
let visuals = ui.visuals().widgets.hovered;
let hover_rect = main_button_rect.expand(visuals.expansion);
ui.painter().set(
where_to_add_hover_rect,
egui::Shape::rect_filled(hover_rect, visuals.rounding, visuals.bg_fill),
);

visibility_button_changed
} else {
false
}
}

fn visibility_button(ui: &mut egui::Ui, enabled: bool, visible: &mut bool) -> egui::Response {
use re_ui::toggle_switch;
// Just put the button on top of the existing ui:
let mut ui = ui.child_ui(
ui.max_rect(),
egui::Layout::right_to_left(egui::Align::Center),
);

ui.add_space(16.0); // Make room for visibility button so the side bar don't become too narrow to fit it
ui.set_enabled(enabled);

ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
ui.set_enabled(enabled);
if enabled {
ui.add(toggle_switch(visible))
} else {
let mut always_false = false;
ui.add(toggle_switch(&mut always_false))
}
.on_hover_text("Toggle visibility")
.on_disabled_hover_text("A parent is invisible")
})
.inner
if enabled {
ui.add(re_ui::toggle_switch(visible))
} else {
let mut always_false = false;
ui.add(re_ui::toggle_switch(&mut always_false))
}
.on_hover_text("Toggle visibility")
.on_disabled_hover_text("A parent is invisible")
}

// ----------------------------------------------------------------------------
Expand Down

1 comment on commit 31e8d0f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rust Benchmark

Benchmark suite Current: 31e8d0f Previous: f2c8542 Ratio
datastore/insert/batch/rects/insert 572646 ns/iter (± 1788) 581932 ns/iter (± 3051) 0.98
datastore/latest_at/batch/rects/query 1868 ns/iter (± 5) 1827 ns/iter (± 1) 1.02
datastore/latest_at/missing_components/primary 317 ns/iter (± 0) 327 ns/iter (± 0) 0.97
datastore/latest_at/missing_components/secondaries 387 ns/iter (± 0) 385 ns/iter (± 0) 1.01
datastore/range/batch/rects/query 158739 ns/iter (± 1029) 156365 ns/iter (± 185) 1.02
obj_mono_points/insert 863783779 ns/iter (± 7500465) 868363935 ns/iter (± 3493901) 0.99
obj_mono_points/query 357096 ns/iter (± 2284) 364053 ns/iter (± 865) 0.98
obj_batch_points/insert 89498297 ns/iter (± 418844) 88330278 ns/iter (± 451112) 1.01
obj_batch_points/query 10985 ns/iter (± 53) 10943 ns/iter (± 30) 1.00
obj_batch_points_sequential/insert 23133147 ns/iter (± 172789) 22107935 ns/iter (± 275447) 1.05
obj_batch_points_sequential/query 6930 ns/iter (± 44) 6922 ns/iter (± 10) 1.00
mono_points_classic/generate_messages 4223441 ns/iter (± 139602) 4169200 ns/iter (± 89385) 1.01
mono_points_classic/encode_log_msg 12044152 ns/iter (± 716579) 11019202 ns/iter (± 304458) 1.09
mono_points_classic/encode_total 16342397 ns/iter (± 853380) 16491636 ns/iter (± 626183) 0.99
mono_points_classic/decode_total 38192717 ns/iter (± 585027) 36433434 ns/iter (± 706732) 1.05
mono_points_arrow/generate_message_bundles 49456001 ns/iter (± 654108) 47391038 ns/iter (± 1415710) 1.04
mono_points_arrow/generate_messages 126492580 ns/iter (± 1218219) 125135496 ns/iter (± 1196778) 1.01
mono_points_arrow/encode_log_msg 153299462 ns/iter (± 1549790) 149843615 ns/iter (± 1278725) 1.02
mono_points_arrow/encode_total 332720569 ns/iter (± 2182953) 322383583 ns/iter (± 1624391) 1.03
mono_points_arrow/decode_log_msg 180601094 ns/iter (± 890895) 176800396 ns/iter (± 920496) 1.02
mono_points_arrow/decode_message_bundles 70561567 ns/iter (± 1092742) 66643050 ns/iter (± 912325) 1.06
mono_points_arrow/decode_total 245702318 ns/iter (± 1563528) 240659198 ns/iter (± 1894849) 1.02
batch_points_classic/generate_messages 3415 ns/iter (± 39) 3534 ns/iter (± 26) 0.97
batch_points_classic/encode_log_msg 394212 ns/iter (± 687) 381050 ns/iter (± 667) 1.03
batch_points_classic/encode_total 400184 ns/iter (± 1418) 387332 ns/iter (± 353) 1.03
batch_points_classic/decode_total 746197 ns/iter (± 3059) 757243 ns/iter (± 1640) 0.99
batch_points_arrow/generate_message_bundles 332943 ns/iter (± 845) 331304 ns/iter (± 1161) 1.00
batch_points_arrow/generate_messages 6255 ns/iter (± 43) 6184 ns/iter (± 26) 1.01
batch_points_arrow/encode_log_msg 348606 ns/iter (± 1128) 348726 ns/iter (± 610) 1.00
batch_points_arrow/encode_total 710437 ns/iter (± 4190) 711321 ns/iter (± 1439) 1.00
batch_points_arrow/decode_log_msg 349564 ns/iter (± 1504) 347424 ns/iter (± 553) 1.01
batch_points_arrow/decode_message_bundles 2125 ns/iter (± 11) 2131 ns/iter (± 11) 1.00
batch_points_arrow/decode_total 355780 ns/iter (± 2017) 354264 ns/iter (± 5718) 1.00
arrow_mono_points/insert 6095095560 ns/iter (± 33364528) 6008886059 ns/iter (± 16133773) 1.01
arrow_mono_points/query 1691520 ns/iter (± 14248) 1695681 ns/iter (± 10068) 1.00
arrow_batch_points/insert 2650660 ns/iter (± 13995) 2605634 ns/iter (± 7203) 1.02
arrow_batch_points/query 15856 ns/iter (± 55) 15300 ns/iter (± 42) 1.04
obj_batch_points_sequential/Tuid::random 37 ns/iter (± 0) 37 ns/iter (± 0) 1

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.