Skip to content

Commit

Permalink
[pure refactor] Move item-ui to separate module, move AppOptions to r…
Browse files Browse the repository at this point in the history
…e_viewer_context (#2040)

* move out all "item ui" to its own module

* remove last gui dependency from ViewerContext (select_hovered_on_click)

* note on how to unify item button methods, but holding off of that

* move `AppOptions` to `re_viewer_context`

* todo note on what remains to move `ViewerContext` to `re_viewer_context`
  • Loading branch information
Wumpf authored May 4, 2023
1 parent cd4fa0f commit 181ed01
Show file tree
Hide file tree
Showing 17 changed files with 366 additions and 296 deletions.
3 changes: 2 additions & 1 deletion crates/re_viewer/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ use re_log_types::{ApplicationId, LogMsg, RecordingId};
use re_renderer::WgpuResourcePoolStatistics;
use re_smart_channel::Receiver;
use re_ui::{toasts, Command};
use re_viewer_context::AppOptions;

use crate::{
misc::{time_control::PlayState, AppOptions, Caches, RecordingConfig, ViewerContext},
misc::{time_control::PlayState, Caches, RecordingConfig, ViewerContext},
ui::{data_ui::ComponentUiRegistry, Blueprint},
viewer_analytics::ViewerAnalytics,
};
Expand Down
2 changes: 0 additions & 2 deletions crates/re_viewer/src/misc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
mod app_options;
pub mod caches;
pub mod format_time;
pub(crate) mod mesh_loader;
Expand Down Expand Up @@ -26,7 +25,6 @@ pub(crate) mod profiler;
#[cfg(not(target_arch = "wasm32"))]
pub mod clipboard;

pub use app_options::AppOptions;
pub use transform_cache::{TransformCache, UnreachableTransform};

pub use space_view_highlights::{
Expand Down
269 changes: 12 additions & 257 deletions crates/re_viewer/src/misc/viewer_context.rs
Original file line number Diff line number Diff line change
@@ -1,287 +1,42 @@
use re_data_store::{log_db::LogDb, InstancePath};
use re_log_types::{ComponentPath, EntityPath, TimeInt, Timeline};
use re_viewer_context::{
DataBlueprintGroupHandle, HoverHighlight, Item, ItemCollection, SelectionState, SpaceViewId,
};
use re_data_store::log_db::LogDb;
use re_viewer_context::{AppOptions, Item, ItemCollection, SelectionState};

use crate::ui::{
data_ui::{ComponentUiRegistry, DataUi},
UiVerbosity,
};
// TODO(andreas): Either viewer_context independent of these or move to re_viewer_context crate.
use super::{Caches, TimeControl};
use crate::ui::data_ui::ComponentUiRegistry;

/// Common things needed by many parts of the viewer.
pub struct ViewerContext<'a> {
/// Global options for the whole viewer.
pub app_options: &'a mut super::AppOptions,
pub app_options: &'a mut AppOptions,

/// Things that need caching.
pub cache: &'a mut super::Caches,
pub cache: &'a mut Caches,

/// How to display components
/// How to display components.
pub component_ui_registry: &'a ComponentUiRegistry,

/// The current recording
/// The current recording.
pub log_db: &'a LogDb,

/// UI config for the current recording (found in [`LogDb`]).
pub rec_cfg: &'a mut RecordingConfig,

/// The look and feel of the UI
/// The look and feel of the UI.
pub re_ui: &'a re_ui::ReUi,

/// The global `re_renderer` context, holds on to all GPU resources.
pub render_ctx: &'a mut re_renderer::RenderContext,
}

impl<'a> ViewerContext<'a> {
/// Show an entity path and make it selectable.
pub fn entity_path_button(
&mut self,
ui: &mut egui::Ui,
space_view_id: Option<SpaceViewId>,
entity_path: &EntityPath,
) -> egui::Response {
self.instance_path_button_to(
ui,
space_view_id,
&InstancePath::entity_splat(entity_path.clone()),
entity_path.to_string(),
)
}

/// Show an entity path and make it selectable.
pub fn entity_path_button_to(
&mut self,
ui: &mut egui::Ui,
space_view_id: Option<SpaceViewId>,
entity_path: &EntityPath,
text: impl Into<egui::WidgetText>,
) -> egui::Response {
self.instance_path_button_to(
ui,
space_view_id,
&InstancePath::entity_splat(entity_path.clone()),
text,
)
}

/// Show an instance id and make it selectable.
pub fn instance_path_button(
&mut self,
ui: &mut egui::Ui,
space_view_id: Option<SpaceViewId>,
instance_path: &InstancePath,
) -> egui::Response {
self.instance_path_button_to(ui, space_view_id, instance_path, instance_path.to_string())
}

/// Show an instance id and make it selectable.
pub fn instance_path_button_to(
&mut self,
ui: &mut egui::Ui,
space_view_id: Option<SpaceViewId>,
instance_path: &InstancePath,
text: impl Into<egui::WidgetText>,
) -> egui::Response {
let item = Item::InstancePath(space_view_id, instance_path.clone());
let subtype_string = if instance_path.instance_key.is_splat() {
"Entity"
} else {
"Entity Instance"
};

let response = ui
.selectable_label(self.selection().contains(&item), text)
.on_hover_ui(|ui| {
ui.strong(subtype_string);
ui.label(format!("Path: {instance_path}"));
instance_path.data_ui(
self,
ui,
crate::ui::UiVerbosity::Reduced,
&self.current_query(),
);
});

self.cursor_interact_with_selectable(response, item)
}

/// Show a component path and make it selectable.
pub fn component_path_button_to(
&mut self,
ui: &mut egui::Ui,
text: impl Into<egui::WidgetText>,
component_path: &ComponentPath,
) -> egui::Response {
let item = Item::ComponentPath(component_path.clone());
let response = ui.selectable_label(self.selection().contains(&item), text);
self.cursor_interact_with_selectable(response, item)
}

pub fn space_view_button(
&mut self,
ui: &mut egui::Ui,
space_view: &crate::ui::SpaceView,
) -> egui::Response {
self.space_view_button_to(
ui,
space_view.display_name.clone(),
space_view.id,
space_view.category,
)
}

pub fn space_view_button_to(
&mut self,
ui: &mut egui::Ui,
text: impl Into<egui::WidgetText>,
space_view_id: SpaceViewId,
space_view_category: crate::ui::ViewCategory,
) -> egui::Response {
let item = Item::SpaceView(space_view_id);
let is_selected = self.selection().contains(&item);

let response = self
.re_ui
.selectable_label_with_icon(ui, space_view_category.icon(), text, is_selected)
.on_hover_text("Space View");
self.cursor_interact_with_selectable(response, item)
}

pub fn data_blueprint_group_button_to(
&mut self,
ui: &mut egui::Ui,
text: impl Into<egui::WidgetText>,
space_view_id: SpaceViewId,
group_handle: DataBlueprintGroupHandle,
) -> egui::Response {
let item = Item::DataBlueprintGroup(space_view_id, group_handle);
let response = self
.re_ui
.selectable_label_with_icon(
ui,
&re_ui::icons::CONTAINER,
text,
self.selection().contains(&item),
)
.on_hover_text("Group");
self.cursor_interact_with_selectable(response, item)
}

pub fn data_blueprint_button_to(
&mut self,
ui: &mut egui::Ui,
text: impl Into<egui::WidgetText>,
space_view_id: SpaceViewId,
entity_path: &EntityPath,
) -> egui::Response {
let item = Item::InstancePath(
Some(space_view_id),
InstancePath::entity_splat(entity_path.clone()),
);
let response = ui
.selectable_label(self.selection().contains(&item), text)
.on_hover_ui(|ui| {
ui.strong("Space View Entity");
ui.label(format!("Path: {entity_path}"));
entity_path.data_ui(self, ui, UiVerbosity::Reduced, &self.current_query());
});
self.cursor_interact_with_selectable(response, item)
}

pub fn time_button(
&mut self,
ui: &mut egui::Ui,
timeline: &Timeline,
value: TimeInt,
) -> egui::Response {
let is_selected = self.rec_cfg.time_ctrl.is_time_selected(timeline, value);

let response = ui.selectable_label(is_selected, timeline.typ().format(value));
if response.clicked() {
self.rec_cfg
.time_ctrl
.set_timeline_and_time(*timeline, value);
self.rec_cfg.time_ctrl.pause();
}
response
}

pub fn timeline_button(&mut self, ui: &mut egui::Ui, timeline: &Timeline) -> egui::Response {
self.timeline_button_to(ui, timeline.name().to_string(), timeline)
}

pub fn timeline_button_to(
&mut self,
ui: &mut egui::Ui,
text: impl Into<egui::WidgetText>,
timeline: &Timeline,
) -> egui::Response {
let is_selected = self.rec_cfg.time_ctrl.timeline() == timeline;

let response = ui
.selectable_label(is_selected, text)
.on_hover_text("Click to switch to this timeline");
if response.clicked() {
self.rec_cfg.time_ctrl.set_timeline(*timeline);
self.rec_cfg.time_ctrl.pause();
}
response
}

// ---------------------------------------------------------
// shortcuts for common selection/hover manipulation

/// Sets a single selection, updating history as needed.
///
/// Returns the previous selection.
pub fn set_single_selection(&mut self, item: Item) -> ItemCollection {
self.rec_cfg.selection_state.set_single_selection(item)
}

/// Sets several objects to be selected, updating history as needed.
///
/// Returns the previous selection.
pub fn set_multi_selection(&mut self, items: impl Iterator<Item = Item>) -> ItemCollection {
self.rec_cfg.selection_state.set_multi_selection(items)
}

/// Selects (or toggles selection if modifier is clicked) currently hovered elements on click.
pub fn select_hovered_on_click(&mut self, response: &egui::Response) {
if response.clicked() {
let hovered = self.rec_cfg.selection_state.hovered().clone();
if response.ctx.input(|i| i.modifiers.command) {
self.rec_cfg
.selection_state
.toggle_selection(hovered.to_vec());
} else {
self.set_multi_selection(hovered.into_iter());
}
}
}

pub fn cursor_interact_with_selectable(
&mut self,
response: egui::Response,
item: Item,
) -> egui::Response {
let is_item_hovered =
self.selection_state().highlight_for_ui_element(&item) == HoverHighlight::Hovered;

if response.hovered() {
self.rec_cfg
.selection_state
.set_hovered(std::iter::once(item));
}
self.select_hovered_on_click(&response);
// TODO(andreas): How to deal with shift click for selecting ranges?

if is_item_hovered {
response.highlight()
} else {
response
}
}

/// Returns the current selection.
pub fn selection(&self) -> &ItemCollection {
self.rec_cfg.selection_state.current()
Expand Down Expand Up @@ -318,7 +73,7 @@ impl<'a> ViewerContext<'a> {
#[serde(default)]
pub struct RecordingConfig {
/// The current time of the time panel, how fast it is moving, etc.
pub time_ctrl: crate::TimeControl,
pub time_ctrl: TimeControl,

/// Selection & hovering state.
pub selection_state: SelectionState,
Expand Down
5 changes: 4 additions & 1 deletion crates/re_viewer/src/ui/data_ui/component.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use re_data_store::{ComponentName, EntityPath, InstancePath};
use re_query::ComponentWithInstances;

use crate::ui::item_ui;

use super::DataUi;

// We do NOT implement `DataUi` for just `ComponentWithInstances`
Expand Down Expand Up @@ -95,7 +97,8 @@ impl DataUi for EntityComponentWithInstances {
row.col(|ui| {
let instance_path =
InstancePath::instance(self.entity_path.clone(), instance_key);
ctx.instance_path_button_to(
item_ui::instance_path_button_to(
ctx,
ui,
None,
&instance_path,
Expand Down
8 changes: 6 additions & 2 deletions crates/re_viewer/src/ui/data_ui/instance_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use re_data_store::InstancePath;
use re_log_types::ComponentPath;
use re_query::{get_component_with_instances, QueryError};

use crate::{misc::ViewerContext, ui::UiVerbosity};
use crate::{
misc::ViewerContext,
ui::{item_ui, UiVerbosity},
};

use super::DataUi;

Expand Down Expand Up @@ -55,7 +58,8 @@ impl DataUi for InstancePath {
UiVerbosity::All => {}
}

ctx.component_path_button_to(
item_ui::component_path_button_to(
ctx,
ui,
component_name.short_name(),
&ComponentPath::new(self.entity_path.clone(), component_name),
Expand Down
7 changes: 5 additions & 2 deletions crates/re_viewer/src/ui/data_ui/log_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use re_log_types::{
ArrowMsg, BeginRecordingMsg, DataTable, EntityPathOpMsg, LogMsg, RecordingInfo,
};

use crate::{misc::ViewerContext, ui::UiVerbosity};
use crate::{
misc::ViewerContext,
ui::{item_ui, UiVerbosity},
};

use super::DataUi;

Expand Down Expand Up @@ -116,7 +119,7 @@ impl DataUi for ArrowMsg {
for row in table.to_rows() {
egui::Grid::new("fields").num_columns(2).show(ui, |ui| {
ui.monospace("entity_path:");
ctx.entity_path_button(ui, None, row.entity_path());
item_ui::entity_path_button(ctx, ui, None, row.entity_path());
ui.end_row();

ui.monospace("time_point:");
Expand Down
Loading

1 comment on commit 181ed01

@github-actions
Copy link

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Rust Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.25.

Benchmark suite Current: 181ed01 Previous: cd4fa0f Ratio
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at/default 370 ns/iter (± 3) 283 ns/iter (± 3) 1.31
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/primary/default 269 ns/iter (± 1) 205 ns/iter (± 0) 1.31
datastore/num_rows=1000/num_instances=1000/packed=false/latest_at_missing/secondaries/default 427 ns/iter (± 2) 329 ns/iter (± 0) 1.30
datastore/num_rows=1000/num_instances=1000/gc/default 2440332 ns/iter (± 7278) 1697042 ns/iter (± 7021) 1.44
mono_points_arrow/generate_message_bundles 28767824 ns/iter (± 1220405) 22049557 ns/iter (± 586452) 1.30
mono_points_arrow/decode_message_bundles 70032190 ns/iter (± 1541760) 51927704 ns/iter (± 495615) 1.35
mono_points_arrow_batched/generate_message_bundles 21163936 ns/iter (± 1849768) 15527089 ns/iter (± 34538) 1.36
mono_points_arrow_batched/generate_messages 4304332 ns/iter (± 224907) 3054151 ns/iter (± 16136) 1.41
mono_points_arrow_batched/encode_total 27585502 ns/iter (± 1360524) 19997120 ns/iter (± 65902) 1.38
mono_points_arrow_batched/decode_log_msg 743057 ns/iter (± 2156) 437523 ns/iter (± 1392) 1.70
mono_points_arrow_batched/decode_total 8419841 ns/iter (± 98586) 6575140 ns/iter (± 10828) 1.28
batch_points_arrow/encode_log_msg 313458 ns/iter (± 1273) 228470 ns/iter (± 642) 1.37
batch_points_arrow/encode_total 569104 ns/iter (± 3798) 439879 ns/iter (± 584) 1.29
arrow_mono_points/insert 2530527278 ns/iter (± 4982801) 1551822176 ns/iter (± 2862848) 1.63
arrow_mono_points/query 1181252 ns/iter (± 12880) 878309 ns/iter (± 6569) 1.34
arrow_batch_points/query 16832 ns/iter (± 75) 11961 ns/iter (± 6) 1.41
arrow_batch_vecs/query 387145 ns/iter (± 1311) 297384 ns/iter (± 921) 1.30

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

Please sign in to comment.