Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New auto-layout of space views #2558

Merged
merged 15 commits into from
Jun 29, 2023
4 changes: 4 additions & 0 deletions crates/re_space_view_bar_chart/src/space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ impl SpaceViewClass for BarChartSpaceView {
None
}

fn layout_priority(&self) -> re_viewer_context::SpaceViewClassLayoutPriority {
re_viewer_context::SpaceViewClassLayoutPriority::Low
}

fn selection_ui(
&self,
_ctx: &mut ViewerContext<'_>,
Expand Down
4 changes: 4 additions & 0 deletions crates/re_space_view_spatial/src/space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ impl SpaceViewClass for SpatialSpaceView {
}
}

fn layout_priority(&self) -> re_viewer_context::SpaceViewClassLayoutPriority {
re_viewer_context::SpaceViewClassLayoutPriority::High
}

fn prepare_populate(
&self,
ctx: &mut re_viewer_context::ViewerContext<'_>,
Expand Down
4 changes: 4 additions & 0 deletions crates/re_space_view_tensor/src/space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ impl SpaceViewClass for TensorSpaceView {
None
}

fn layout_priority(&self) -> re_viewer_context::SpaceViewClassLayoutPriority {
re_viewer_context::SpaceViewClassLayoutPriority::Medium
}

fn selection_ui(
&self,
ctx: &mut ViewerContext<'_>,
Expand Down
4 changes: 4 additions & 0 deletions crates/re_space_view_text/src/space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ impl SpaceViewClass for TextSpaceView {
Some(2.0) // Make text logs wide
}

fn layout_priority(&self) -> re_viewer_context::SpaceViewClassLayoutPriority {
re_viewer_context::SpaceViewClassLayoutPriority::Low
}

fn selection_ui(
&self,
ctx: &mut ViewerContext<'_>,
Expand Down
4 changes: 4 additions & 0 deletions crates/re_space_view_text_box/src/space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ impl SpaceViewClass for TextBoxSpaceView {
"Displays text from a text entry components.".into()
}

fn layout_priority(&self) -> re_viewer_context::SpaceViewClassLayoutPriority {
re_viewer_context::SpaceViewClassLayoutPriority::Low
}

fn selection_ui(
&self,
ctx: &mut ViewerContext<'_>,
Expand Down
4 changes: 4 additions & 0 deletions crates/re_space_view_time_series/src/space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ impl SpaceViewClass for TimeSeriesSpaceView {
None
}

fn layout_priority(&self) -> re_viewer_context::SpaceViewClassLayoutPriority {
re_viewer_context::SpaceViewClassLayoutPriority::Low
}

fn selection_ui(
&self,
_ctx: &mut ViewerContext<'_>,
Expand Down
16 changes: 9 additions & 7 deletions crates/re_viewer/src/ui/selection_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,15 @@ fn blueprint_ui(
space_view.class_name(),
);

space_view.class(ctx).selection_ui(
ctx,
ui,
space_view_state,
&space_view.space_origin,
space_view.id,
);
space_view
.class(ctx.space_view_class_registry)
.selection_ui(
ctx,
ui,
space_view_state,
&space_view.space_origin,
space_view.id,
);
}
}

Expand Down
7 changes: 4 additions & 3 deletions crates/re_viewer_context/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ pub use selection_state::{
};
pub use space_view::{
ArchetypeDefinition, DynSpaceViewClass, Scene, SceneContext, SceneContextPart, ScenePart,
ScenePartCollection, SceneQuery, SpaceViewClass, SpaceViewClassName, SpaceViewClassRegistry,
SpaceViewClassRegistryError, SpaceViewEntityHighlight, SpaceViewHighlights,
SpaceViewOutlineMasks, SpaceViewState, TypedScene,
ScenePartCollection, SceneQuery, SpaceViewClass, SpaceViewClassLayoutPriority,
SpaceViewClassName, SpaceViewClassRegistry, SpaceViewClassRegistryError,
SpaceViewEntityHighlight, SpaceViewHighlights, SpaceViewOutlineMasks, SpaceViewState,
TypedScene,
};
pub use store_context::StoreContext;
pub use tensor::{TensorDecodeCache, TensorStats, TensorStatsCache};
Expand Down
18 changes: 18 additions & 0 deletions crates/re_viewer_context/src/space_view/dyn_space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ re_string_interner::declare_new_type!(
pub struct SpaceViewClassName;
);

#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Ord, Eq)]
pub enum SpaceViewClassLayoutPriority {
/// This space view can share space with others
///
/// Used for boring things like text and plots.
Copy link
Member

Choose a reason for hiding this comment

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

I didn't think of our plots as boring :P

Low,

#[default]
Medium,

/// Give this space view lots of space.
/// Used for spatial views (2D/3D).
High,
}

/// Defines a class of space view without any concrete types making it suitable for storage and interfacing.
///
/// Implemented by [`crate::SpaceViewClass`].
Expand Down Expand Up @@ -56,6 +71,9 @@ pub trait DynSpaceViewClass {
/// Preferred aspect ratio for the ui tiles of this space view.
fn preferred_tile_aspect_ratio(&self, state: &dyn SpaceViewState) -> Option<f32>;

/// Controls how likely this space view will get a large tile in the ui.
fn layout_priority(&self) -> SpaceViewClassLayoutPriority;

/// Executed before the scene is populated, can be use for heuristic & state updates before populating the scene.
///
/// Is only allowed to access archetypes defined by [`Self::blueprint_archetype`]
Expand Down
3 changes: 2 additions & 1 deletion crates/re_viewer_context/src/space_view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ mod space_view_class_placeholder;
mod space_view_class_registry;

pub use dyn_space_view_class::{
ArchetypeDefinition, DynSpaceViewClass, SpaceViewClassName, SpaceViewState,
ArchetypeDefinition, DynSpaceViewClass, SpaceViewClassLayoutPriority, SpaceViewClassName,
SpaceViewState,
};
pub use highlights::{SpaceViewEntityHighlight, SpaceViewHighlights, SpaceViewOutlineMasks};
pub use scene::{Scene, TypedScene};
Expand Down
8 changes: 8 additions & 0 deletions crates/re_viewer_context/src/space_view/space_view_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub trait SpaceViewClass: std::marker::Sized {
None
}

/// Controls how likely this space view will get a large tile in the ui.
fn layout_priority(&self) -> crate::SpaceViewClassLayoutPriority;

/// Optional archetype of the Space View's blueprint properties.
///
/// Blueprint components that only apply to the space view itself, not to the entities it displays.
Expand Down Expand Up @@ -125,6 +128,11 @@ impl<T: SpaceViewClass + 'static> DynSpaceViewClass for T {
typed_state_wrapper(state, |state| self.preferred_tile_aspect_ratio(state))
}

#[inline]
fn layout_priority(&self) -> crate::SpaceViewClassLayoutPriority {
self.layout_priority()
}

fn blueprint_archetype(&self) -> Option<ArchetypeDefinition> {
self.blueprint_archetype()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ impl SpaceViewClass for SpaceViewClassPlaceholder {
"The Space View Class was not recognized.\nThis happens if either the Blueprint specifies an invalid Space View Class or this version of the Viewer does not know about this type.".into()
}

fn layout_priority(&self) -> crate::SpaceViewClassLayoutPriority {
crate::SpaceViewClassLayoutPriority::Low
}

fn selection_ui(
&self,
_ctx: &mut crate::ViewerContext<'_>,
Expand Down
32 changes: 13 additions & 19 deletions crates/re_viewport/src/auto_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ use itertools::Itertools as _;

use re_viewer_context::SpaceViewId;

use super::{space_view::SpaceViewBlueprint, view_category::ViewCategory};
use super::space_view::SpaceViewBlueprint;

#[derive(Clone, Debug)]
struct SpaceMakeInfo {
id: SpaceViewId,
category: ViewCategory,
layout_priority: re_viewer_context::SpaceViewClassLayoutPriority,
}

pub(crate) fn tree_from_space_views(
space_view_class_registry: &re_viewer_context::SpaceViewClassRegistry,
space_views: &BTreeMap<SpaceViewId, SpaceViewBlueprint>,
) -> egui_tiles::Tree<SpaceViewId> {
if space_views.is_empty() {
Expand All @@ -33,9 +34,14 @@ pub(crate) fn tree_from_space_views(
*space_view_id,
)
})
.map(|(space_view_id, space_view)| SpaceMakeInfo {
id: *space_view_id,
category: space_view.category,
.map(|(space_view_id, space_view)| {
let layout_priority = space_view
.class(space_view_class_registry)
.layout_priority();
SpaceMakeInfo {
id: *space_view_id,
layout_priority,
}
})
.collect_vec();

Expand Down Expand Up @@ -92,21 +98,9 @@ fn arrange_three(
// +----------+------------+
//
// But which space gets a full side, and which doesn't?
// Answer: we prioritize them by category:
// Answer: we prioritize them based on a class-specific layout priority:

/// lower is better
fn category_priority(category: ViewCategory) -> usize {
match category {
ViewCategory::Spatial => 0,
ViewCategory::Tensor => 1,
ViewCategory::TimeSeries => 2,
ViewCategory::BarChart => 3,
ViewCategory::TextBox => 4,
ViewCategory::Text => 5,
}
}

spaces.sort_by_key(|smi| category_priority(smi.category));
spaces.sort_by_key(|smi| -(smi.layout_priority as isize));

let pane_ids = spaces
.into_iter()
Expand Down
2 changes: 1 addition & 1 deletion crates/re_viewport/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub mod item_ui {
.re_ui
.selectable_label_with_icon(
ui,
space_view.class(ctx).icon(),
space_view.class(ctx.space_view_class_registry).icon(),
space_view.display_name.clone(),
is_selected,
)
Expand Down
10 changes: 6 additions & 4 deletions crates/re_viewport/src/space_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ impl SpaceViewBlueprint {
&self.class_name
}

pub fn class<'a>(&self, ctx: &ViewerContext<'a>) -> &'a dyn DynSpaceViewClass {
ctx.space_view_class_registry
.get_or_log_error(&self.class_name)
pub fn class<'a>(
&self,
space_view_class_registry: &'a re_viewer_context::SpaceViewClassRegistry,
) -> &'a dyn DynSpaceViewClass {
space_view_class_registry.get_or_log_error(&self.class_name)
}

pub fn on_frame_start(
Expand Down Expand Up @@ -164,7 +166,7 @@ impl SpaceViewBlueprint {
return;
}

let class = self.class(ctx);
let class = self.class(ctx.space_view_class_registry);

class.prepare_populate(
ctx,
Expand Down
9 changes: 6 additions & 3 deletions crates/re_viewport/src/viewport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,10 @@ impl Viewport {
&mut maximized_tree
} else {
if self.tree.is_empty() {
self.tree = super::auto_layout::tree_from_space_views(&self.space_views);
self.tree = super::auto_layout::tree_from_space_views(
ctx.space_view_class_registry,
&self.space_views,
);
}
&mut self.tree
};
Expand Down Expand Up @@ -576,7 +579,7 @@ impl Viewport {
.re_ui
.selectable_label_with_icon(
ui,
space_view.class(ctx).icon(),
space_view.class(ctx.space_view_class_registry).icon(),
if space_view.space_origin.is_root() {
space_view.display_name.clone()
} else {
Expand Down Expand Up @@ -871,7 +874,7 @@ impl<'a, 'b> egui_tiles::Behavior<SpaceViewId> for TabViewer<'a, 'b> {
}

let help_text = space_view
.class(self.ctx)
.class(self.ctx.space_view_class_registry)
.help_text(self.ctx.re_ui, space_view_state);
re_ui::help_hover_button(ui).on_hover_text(help_text);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use re_viewer::external::{
re_log_types::EntityPath,
re_ui,
re_viewer_context::{
HoverHighlight, Item, SelectionHighlight, SpaceViewClass, SpaceViewClassName, SpaceViewId,
SpaceViewState, TypedScene, UiVerbosity, ViewerContext,
HoverHighlight, Item, SelectionHighlight, SpaceViewClass, SpaceViewClassLayoutPriority,
SpaceViewClassName, SpaceViewId, SpaceViewState, TypedScene, UiVerbosity, ViewerContext,
},
};

Expand Down Expand Up @@ -95,6 +95,10 @@ impl SpaceViewClass for ColorCoordinatesSpaceView {
Some(1.0)
}

fn layout_priority(&self) -> SpaceViewClassLayoutPriority {
Default::default()
}

/// Additional UI displayed when the space view is selected.
///
/// In this sample we show a combo box to select the color coordinates mode.
Expand Down