From 191f5fdba95186f6ab94a1a09b16a8c12ff5596f Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:59:09 +0200 Subject: [PATCH] Add a hook for views to add additional UI in the tab title bar (#7438) ### What Add a hook so views can have additional buttons in the title bar. Unblocks #4466. Background: will be used for column show/hide UI of the dataframe UI. We had ample discussion on doing so, how different it is from other views, and on how we accept that (and eventually embrace that in other views). See eg this comment: https://github.com/rerun-io/rerun/issues/7067#issuecomment-2343699532 image ### 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 examples from latest `main` build: [rerun.io/viewer](https://rerun.io/viewer/pr/7438?manifest_url=https://app.rerun.io/version/main/examples_manifest.json) * Using full set of examples from `nightly` build: [rerun.io/viewer](https://rerun.io/viewer/pr/7438?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 * [x] If applicable, add a new check to the [release checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)! * [x] If have noted any breaking changes to the log API in `CHANGELOG.md` and the migration guide - [PR Build Summary](https://build.rerun.io/pr/7438) - [Recent benchmark results](https://build.rerun.io/graphs/crates.html) - [Wasm size tracking](https://build.rerun.io/graphs/sizes.html) To run all checks from `main`, comment on the PR with `@rerun-bot full-check`. --- .../src/space_view/space_view_class.rs | 15 ++++++++++ crates/viewer/re_viewport/src/viewport.rs | 29 ++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/crates/viewer/re_viewer_context/src/space_view/space_view_class.rs b/crates/viewer/re_viewer_context/src/space_view/space_view_class.rs index 71619bf40dd8..b62ca735abaf 100644 --- a/crates/viewer/re_viewer_context/src/space_view/space_view_class.rs +++ b/crates/viewer/re_viewer_context/src/space_view/space_view_class.rs @@ -1,4 +1,5 @@ use nohash_hasher::IntSet; + use re_entity_db::EntityDb; use re_log_types::EntityPath; use re_types::{ComponentName, SpaceViewClassIdentifier}; @@ -180,6 +181,20 @@ pub trait SpaceViewClass: Send + Sync { Ok(()) } + /// Additional UI displayed in the tab title bar, between the "maximize" and "help" buttons. + /// + /// Note: this is a right-to-left layout. + fn extra_title_bar_ui( + &self, + _ctx: &ViewerContext<'_>, + _ui: &mut egui::Ui, + _state: &mut dyn SpaceViewState, + _space_origin: &EntityPath, + _space_view_id: SpaceViewId, + ) -> Result<(), SpaceViewSystemExecutionError> { + Ok(()) + } + /// Draws the ui for this space view class and handles ui events. /// /// The passed state is kept frame-to-frame. diff --git a/crates/viewer/re_viewport/src/viewport.rs b/crates/viewer/re_viewport/src/viewport.rs index e00926df6c1f..2cdc2e8607b9 100644 --- a/crates/viewer/re_viewport/src/viewport.rs +++ b/crates/viewer/re_viewport/src/viewport.rs @@ -671,7 +671,8 @@ impl<'a, 'b> egui_tiles::Behavior for TabViewer<'a, 'b> { }; let space_view_id = *space_view_id; - let Some(space_view) = self.viewport_blueprint.space_views.get(&space_view_id) else { + let Some(space_view_blueprint) = self.viewport_blueprint.space_views.get(&space_view_id) + else { return; }; let num_space_views = tiles.tiles().filter(|tile| tile.is_pane()).count(); @@ -699,9 +700,29 @@ impl<'a, 'b> egui_tiles::Behavior for TabViewer<'a, 'b> { } } - let help_markdown = space_view - .class(self.ctx.space_view_class_registry) - .help_markdown(self.ctx.egui_ctx); + let space_view_class = space_view_blueprint.class(self.ctx.space_view_class_registry); + + // give the view a chance to display some extra UI in the top bar. + let view_state = self + .view_states + .get_mut_or_create(space_view_id, space_view_class); + space_view_class + .extra_title_bar_ui( + self.ctx, + ui, + view_state, + &space_view_blueprint.space_origin, + space_view_id, + ) + .unwrap_or_else(|err| { + re_log::error!( + "Error in view title bar UI (class: {}, display name: {}): {err}", + space_view_blueprint.class_identifier(), + space_view_class.display_name(), + ); + }); + + let help_markdown = space_view_class.help_markdown(self.ctx.egui_ctx); ui.help_hover_button().on_hover_ui(|ui| { ui.markdown_ui(&help_markdown); });