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

Allow naming space view containers #5626

Merged
merged 8 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/re_space_view/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod visualizable;
pub use data_query::{DataQuery, EntityOverrideContext, PropertyResolver};
pub use heuristics::suggest_space_view_for_each_entity;
pub use screenshot::ScreenshotMode;
pub use space_view::{SpaceViewBlueprint, SpaceViewName};
pub use space_view::SpaceViewBlueprint;
pub use space_view_contents::SpaceViewContents;
pub use sub_archetypes::{
entity_path_for_space_view_sub_archetype, query_space_view_sub_archetype,
Expand Down
41 changes: 8 additions & 33 deletions crates/re_space_view/src/space_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,12 @@ use re_types::{
use re_types_core::archetypes::Clear;
use re_types_core::Archetype as _;
use re_viewer_context::{
DataResult, OverridePath, PerSystemEntities, PropertyOverrides, RecommendedSpaceView,
SpaceViewClass, SpaceViewClassIdentifier, SpaceViewId, SpaceViewState, StoreContext,
SystemCommand, SystemCommandSender as _, SystemExecutionOutput, ViewQuery, ViewerContext,
ContentsName, DataResult, OverridePath, PerSystemEntities, PropertyOverrides,
RecommendedSpaceView, SpaceViewClass, SpaceViewClassIdentifier, SpaceViewId, SpaceViewState,
StoreContext, SystemCommand, SystemCommandSender as _, SystemExecutionOutput, ViewQuery,
ViewerContext,
};

// ----------------------------------------------------------------------------

/// The name of a space view.
///
/// Space views are unnamed by default, but have a placeholder name to be used in the UI.
#[derive(Clone, Debug)]
pub enum SpaceViewName {
/// This space view has been given a name by the user.
Named(String),

/// This space view is unnamed and should be displayed with this placeholder name.
Placeholder(String),
}

impl AsRef<str> for SpaceViewName {
#[inline]
fn as_ref(&self) -> &str {
match self {
SpaceViewName::Named(name) | SpaceViewName::Placeholder(name) => name,
}
}
}

// ----------------------------------------------------------------------------

/// A view of a space.
///
/// Note: [`SpaceViewBlueprint`] doesn't implement Clone because it stores an internal
Expand Down Expand Up @@ -96,7 +72,6 @@ impl SpaceViewBlueprint {
}

/// Placeholder name displayed in the UI if the user hasn't explicitly named the space view.
#[allow(clippy::unused_self)]
pub fn missing_name_placeholder(&self) -> String {
let entity_path = self
.space_origin
Expand Down Expand Up @@ -125,12 +100,12 @@ impl SpaceViewBlueprint {

/// Returns this space view's display name
///
/// When returning [`SpaceViewName::Placeholder`], the UI should display the resulting name using
/// When returning [`ContentsName::Placeholder`], the UI should display the resulting name using
/// `re_ui::LabelStyle::Unnamed`.
pub fn display_name_or_default(&self) -> SpaceViewName {
pub fn display_name_or_default(&self) -> ContentsName {
self.display_name.clone().map_or_else(
|| SpaceViewName::Placeholder(self.missing_name_placeholder()),
SpaceViewName::Named,
|| ContentsName::Placeholder(self.missing_name_placeholder()),
ContentsName::Named,
)
}

Expand Down
3 changes: 2 additions & 1 deletion crates/re_viewer/src/ui/selection_history_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,9 @@ fn item_to_string(blueprint: &ViewportBlueprint, item: &Item) -> String {
format!("{}:{}", path.entity_path, path.component_name.short_name(),)
}
Item::Container(container_id) => {
// TODO(#4678): unnamed container should have their label formatted accordingly (subdued)
if let Some(container) = blueprint.container(container_id) {
format!("{:?}", container.container_kind)
container.display_name_or_default().as_ref().to_owned()
} else {
"<removed Container>".to_owned()
}
Expand Down
55 changes: 39 additions & 16 deletions crates/re_viewer/src/ui/selection_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ use re_types::{
use re_ui::list_item::ListItem;
use re_ui::{ReUi, SyntaxHighlighting as _};
use re_viewer_context::{
gpu_bridge::colormap_dropdown_button_ui, ContainerId, DataQueryResult, HoverHighlight, Item,
SpaceViewClass, SpaceViewClassIdentifier, SpaceViewId, UiVerbosity, ViewerContext,
gpu_bridge::colormap_dropdown_button_ui, ContainerId, Contents, DataQueryResult,
HoverHighlight, Item, SpaceViewClass, SpaceViewClassIdentifier, SpaceViewId, UiVerbosity,
ViewerContext,
};
use re_viewport::{
context_menu_ui_for_item, icon_for_container_kind, space_view_name_style, Contents,
contents_name_style, context_menu_ui_for_item, icon_for_container_kind,
SelectionUpdateBehavior, Viewport, ViewportBlueprint,
};

Expand Down Expand Up @@ -280,7 +281,7 @@ fn space_view_button(
space_view.class(ctx.space_view_class_registry).icon(),
space_view_name.as_ref(),
is_selected,
space_view_name_style(&space_view_name),
contents_name_style(&space_view_name),
)
.on_hover_text("Space View");
item_ui::cursor_interact_with_selectable(ctx, response, item)
Expand Down Expand Up @@ -319,15 +320,26 @@ fn what_is_selected_ui(

Item::Container(container_id) => {
if let Some(container_blueprint) = viewport.container(container_id) {
item_title_ui(
ctx.re_ui,
ui,
&format!("{:?}", container_blueprint.container_kind),
Some(re_viewport::icon_for_container_kind(
let hover_text =
if let Some(display_name) = container_blueprint.display_name.as_ref() {
format!(
"{:?} Container {display_name:?}",
container_blueprint.container_kind,
)
} else {
format!("Unnamed {:?} Container", container_blueprint.container_kind,)
};

let container_name = container_blueprint.display_name_or_default();
ListItem::new(ctx.re_ui, container_name.as_ref())
.label_style(contents_name_style(&container_name))
.with_icon(re_viewport::icon_for_container_kind(
&container_blueprint.container_kind,
)),
&format!("{:?} container", container_blueprint.container_kind),
);
))
.with_height(ReUi::title_bar_height())
.selected(true)
.show_flat(ui)
.on_hover_text(hover_text);
}
}

Expand Down Expand Up @@ -376,7 +388,7 @@ fn what_is_selected_ui(

let space_view_name = space_view.display_name_or_default();
ListItem::new(ctx.re_ui, space_view_name.as_ref())
.label_style(space_view_name_style(&space_view_name))
.label_style(contents_name_style(&space_view_name))
.with_icon(space_view.class(ctx.space_view_class_registry).icon())
.with_height(ReUi::title_bar_height())
.selected(true)
Expand Down Expand Up @@ -586,6 +598,15 @@ fn container_top_level_properties(
egui::Grid::new("container_top_level_properties")
.num_columns(2)
.show(ui, |ui| {
let mut name = container.display_name.clone().unwrap_or_default();
ui.label("Name").on_hover_text(
"The name of the Container used for display purposes. This can be any text string.",
);
ui.text_edit_singleline(&mut name);
container.set_display_name(ctx, if name.is_empty() { None } else { Some(name) });

ui.end_row();

ui.label("Kind");

let mut container_kind = container.container_kind;
Expand Down Expand Up @@ -701,7 +722,7 @@ fn show_list_item_for_container_child(
(
Item::SpaceView(*space_view_id),
ListItem::new(ctx.re_ui, space_view_name.as_ref())
.label_style(space_view_name_style(&space_view_name))
.label_style(contents_name_style(&space_view_name))
.with_icon(space_view.class(ctx.space_view_class_registry).icon())
.with_buttons(|re_ui, ui| {
let response = re_ui
Expand All @@ -722,10 +743,12 @@ fn show_list_item_for_container_child(
return false;
};

let container_name = container.display_name_or_default();

(
Item::Container(*container_id),
ListItem::new(ctx.re_ui, format!("{:?}", container.container_kind))
.label_style(re_ui::LabelStyle::Unnamed)
ListItem::new(ctx.re_ui, container_name.as_ref())
.label_style(contents_name_style(&container_name))
.with_icon(icon_for_container_kind(&container.container_kind))
.with_buttons(|re_ui, ui| {
let response = re_ui
Expand Down
124 changes: 124 additions & 0 deletions crates/re_viewer_context/src/contents.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use std::convert::{TryFrom, TryInto};

use egui_tiles::TileId;

use re_log_types::EntityPath;

use crate::item::Item;
use crate::{BlueprintId, BlueprintIdRegistry, ContainerId, SpaceViewId};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Contents {
Container(ContainerId),
SpaceView(SpaceViewId),
}

impl Contents {
pub fn try_from(path: &EntityPath) -> Option<Self> {
if path.starts_with(SpaceViewId::registry()) {
Some(Self::SpaceView(SpaceViewId::from_entity_path(path)))
} else if path.starts_with(ContainerId::registry()) {
Some(Self::Container(ContainerId::from_entity_path(path)))
} else {
None
}
}

#[inline]
pub fn as_entity_path(&self) -> EntityPath {
match self {
Self::Container(id) => id.as_entity_path(),
Self::SpaceView(id) => id.as_entity_path(),
}
}

#[inline]
pub fn as_tile_id(&self) -> TileId {
match self {
Self::Container(id) => blueprint_id_to_tile_id(id),
Self::SpaceView(id) => blueprint_id_to_tile_id(id),
}
}

#[inline]
pub fn as_item(&self) -> Item {
match self {
Contents::Container(container_id) => Item::Container(*container_id),
Contents::SpaceView(space_view_id) => Item::SpaceView(*space_view_id),
}
}

#[inline]
pub fn as_container_id(&self) -> Option<ContainerId> {
match self {
Self::Container(id) => Some(*id),
Self::SpaceView(_) => None,
}
}

#[inline]
pub fn as_space_view_id(&self) -> Option<SpaceViewId> {
match self {
Self::SpaceView(id) => Some(*id),
Self::Container(_) => None,
}
}
}

impl TryFrom<Item> for Contents {
type Error = ();

fn try_from(item: Item) -> Result<Self, Self::Error> {
(&item).try_into()
}
}

impl TryFrom<&Item> for Contents {
type Error = ();

fn try_from(item: &Item) -> Result<Self, Self::Error> {
match item {
Item::Container(id) => Ok(Self::Container(*id)),
Item::SpaceView(id) => Ok(Self::SpaceView(*id)),
_ => Err(()),
}
}
}

impl From<SpaceViewId> for Contents {
#[inline]
fn from(id: SpaceViewId) -> Self {
Self::SpaceView(id)
}
}

impl From<ContainerId> for Contents {
#[inline]
fn from(id: ContainerId) -> Self {
Self::Container(id)
}
}

/// The name of a [`Contents`].
#[derive(Clone, Debug)]
pub enum ContentsName {
/// This [`Contents`] has been given a name by the user.
Named(String),

/// This [`Contents`] is unnamed and should be displayed with this placeholder name.
Placeholder(String),
}

impl AsRef<str> for ContentsName {
#[inline]
fn as_ref(&self) -> &str {
match self {
ContentsName::Named(name) | ContentsName::Placeholder(name) => name,
}
}
}

#[inline]
pub fn blueprint_id_to_tile_id<T: BlueprintIdRegistry>(id: &BlueprintId<T>) -> TileId {
TileId::from_u64(id.hash())
}
3 changes: 3 additions & 0 deletions crates/re_viewer_context/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod caches;
mod collapsed_id;
mod command_sender;
mod component_ui_registry;
mod contents;
mod item;
mod query_context;
mod selection_history;
Expand Down Expand Up @@ -37,6 +38,7 @@ pub use command_sender::{
command_channel, CommandReceiver, CommandSender, SystemCommand, SystemCommandSender,
};
pub use component_ui_registry::{ComponentUiRegistry, UiVerbosity};
pub use contents::{blueprint_id_to_tile_id, Contents, ContentsName};
pub use item::Item;
pub use query_context::{DataQueryResult, DataResultHandle, DataResultNode, DataResultTree};
pub use selection_history::SelectionHistory;
Expand Down Expand Up @@ -66,6 +68,7 @@ pub use viewer_context::{RecordingConfig, ViewerContext};

#[cfg(not(target_arch = "wasm32"))]
mod clipboard;

#[cfg(not(target_arch = "wasm32"))]
pub use clipboard::Clipboard;

Expand Down
5 changes: 3 additions & 2 deletions crates/re_viewport/src/add_space_view_or_container_modal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

use itertools::Itertools;

use crate::container::blueprint_id_to_tile_id;
use crate::{icon_for_container_kind, ViewportBlueprint};
use re_space_view::SpaceViewBlueprint;
use re_ui::ReUi;
use re_viewer_context::{ContainerId, RecommendedSpaceView, ViewerContext};
use re_viewer_context::{
blueprint_id_to_tile_id, ContainerId, RecommendedSpaceView, ViewerContext,
};

#[derive(Default)]
pub struct AddSpaceViewOrContainerModal {
Expand Down
Loading
Loading