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

Convert most remaining DataUI component implementations to component uis in re_component_ui #7247

Merged
merged 15 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4381,9 +4381,13 @@ name = "re_component_ui"
version = "0.19.0-alpha.1+dev"
dependencies = [
"egui",
"egui_extras",
"egui_plot",
"re_data_ui",
"re_format",
"re_tracing",
"re_types",
"re_types_blueprint",
"re_types_core",
"re_ui",
"re_viewer_context",
Expand Down
4 changes: 4 additions & 0 deletions crates/viewer/re_component_ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ workspace = true
all-features = true

[dependencies]
re_data_ui.workspace = true # Needed for `item_ui`.
re_format.workspace = true
re_tracing.workspace = true
re_types = { workspace = true, features = [
"egui_plot", # Needed to draw marker shapes.
] }
re_types_blueprint.workspace = true # Needed to give some of the components a custom ui. Could happen in any other crate as well.
re_types_core.workspace = true
re_ui.workspace = true
re_viewer_context.workspace = true

egui_extras.workspace = true
egui_plot.workspace = true
egui.workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod enum_combobox;
mod float_drag;
mod singleline_string;
mod vec;
mod view_id;

pub use bool_toggle::edit_bool;
pub use enum_combobox::edit_view_enum;
Expand All @@ -11,3 +12,4 @@ pub use singleline_string::{
display_name_ui, display_text_ui, edit_multiline_string, edit_singleline_string,
};
pub use vec::edit_or_view_vec3d;
pub use view_id::view_view_id;
21 changes: 21 additions & 0 deletions crates/viewer/re_component_ui/src/datatype_uis/view_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use re_data_ui::item_ui;
use re_types::datatypes::Uuid;
use re_viewer_context::{MaybeMutRef, SpaceViewId};

pub fn view_view_id(
ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
value: &mut MaybeMutRef<'_, impl std::ops::DerefMut<Target = Uuid>>,
) -> egui::Response {
// An edit ui could be a drop down with all known views! But that's for another day.
view_view_id_impl(ctx, ui, value.as_ref())
}

fn view_view_id_impl(
ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
value: &Uuid,
) -> egui::Response {
let view = SpaceViewId::from(*value);
item_ui::blueprint_entity_path_button_to(ctx, ui, &view.as_entity_path(), view.to_string())
}
69 changes: 69 additions & 0 deletions crates/viewer/re_component_ui/src/fallback_ui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use re_types::external::arrow2::{self, array::Utf8Array};
use re_viewer_context::{
external::{
re_chunk_store::{LatestAtQuery, RowId},
re_entity_db::EntityDb,
re_log_types::EntityPath,
},
UiLayout, ViewerContext,
};

#[allow(clippy::too_many_arguments)]
pub fn fallback_component_ui(
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
ui_layout: UiLayout,
_query: &LatestAtQuery,
_db: &EntityDb,
_entity_path: &EntityPath,
_row_id: Option<RowId>,
component: &dyn arrow2::array::Array,
) {
arrow_ui(ui, ui_layout, component);
}

fn arrow_ui(ui: &mut egui::Ui, ui_layout: UiLayout, array: &dyn arrow2::array::Array) {
use re_types::SizeBytes as _;

// Special-treat text.
// Note: we match on the raw data here, so this works for any component containing text.
if let Some(utf8) = array.as_any().downcast_ref::<Utf8Array<i32>>() {
if utf8.len() == 1 {
let string = utf8.value(0);
ui_layout.data_label(ui, string);
return;
}
}
if let Some(utf8) = array.as_any().downcast_ref::<Utf8Array<i64>>() {
if utf8.len() == 1 {
let string = utf8.value(0);
ui_layout.data_label(ui, string);
return;
}
}

let num_bytes = array.total_size_bytes();
if num_bytes < 3000 {
// Print small items:
let mut string = String::new();
let display = arrow2::array::get_display(array, "null");
if display(&mut string, 0).is_ok() {
ui_layout.data_label(ui, &string);
return;
}
}

// Fallback:
let bytes = re_format::format_bytes(num_bytes as _);

// TODO(emilk): pretty-print data type
let data_type_formatted = format!("{:?}", array.data_type());

if data_type_formatted.len() < 20 {
// e.g. "4.2 KiB of Float32"
ui_layout.data_label(ui, &format!("{bytes} of {data_type_formatted}"));
} else {
// Huge datatype, probably a union horror show
ui.label(format!("{bytes} of data"));
}
}
23 changes: 23 additions & 0 deletions crates/viewer/re_component_ui/src/image_format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use re_types::components::ImageFormat;
use re_viewer_context::{MaybeMutRef, UiLayout, ViewerContext};

pub fn edit_or_view_image_format(
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
value: &mut MaybeMutRef<'_, ImageFormat>,
) -> egui::Response {
// TODO(#7100): need a ui for editing this!
let value = value.as_ref();
let label = if let Some(pixel_format) = value.pixel_format {
format!("{} {}×{}", pixel_format, value.width, value.height)
} else {
format!(
"{} {} {}×{}",
value.color_model(),
value.datatype(),
value.width,
value.height
)
};
UiLayout::List.data_label(ui, label)
}
93 changes: 68 additions & 25 deletions crates/viewer/re_component_ui/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,61 @@
//! This crate implements various component editors.
//!
//! The only entry point is [`register_editors`], which registers all editors in the component UI registry.
//! The only entry point is [`create_component_ui_registry`], which registers all editors in the component UI registry.
//! This should be called by `re_viewer` on startup.

mod color;
mod datatype_editors;
mod datatype_uis;
mod fallback_ui;
mod image_format;
mod line_strip;
mod marker_shape;
mod pinhole;
mod radius;
mod range1d;
mod resolution;
mod response_utils;
mod timeline;
mod transforms;
mod view_coordinates;
mod visual_bounds2d;

use datatype_editors::{
use datatype_uis::{
display_name_ui, display_text_ui, edit_bool, edit_f32_min_to_max_float, edit_f32_zero_to_max,
edit_f32_zero_to_one, edit_multiline_string, edit_or_view_vec3d, edit_singleline_string,
edit_view_enum,
edit_view_enum, view_view_id,
};

use re_types::{
blueprint::components::{
BackgroundKind, Corner2D, LockRangeDuringZoom, SortKey, SortOrder, TimelineName, ViewFit,
Visible,
BackgroundKind, Corner2D, LockRangeDuringZoom, SortKey, SortOrder, ViewFit, Visible,
},
components::{
AggregationPolicy, AlbedoFactor, AxisLength, Color, Colormap, DepthMeter, DrawOrder,
FillMode, FillRatio, GammaCorrection, ImagePlaneDistance, MagnificationFilter, MarkerSize,
Name, Opacity, Scale3D, StrokeWidth, Text, TransformRelation, Translation3D,
AggregationPolicy, AlbedoFactor, AxisLength, Color, DepthMeter, DrawOrder, FillMode,
FillRatio, GammaCorrection, ImagePlaneDistance, MagnificationFilter, MarkerSize, Name,
Opacity, Scale3D, StrokeWidth, Text, TransformRelation, Translation3D,
},
Loggable as _,
};
use re_types_blueprint::blueprint::components::{IncludedSpaceView, SpaceViewMaximized};
use re_viewer_context::gpu_bridge::colormap_edit_or_view_ui;

// ----

/// Registers all editors of this crate in the component UI registry.
/// Crates a component ui registry and registers all editors of this crate to it.
///
/// ⚠️ This is supposed to be the only export of this crate.
/// This crate is meant to be a leaf crate in the viewer ecosystem and should only be used by the `re_viewer` crate itself.
pub fn register_editors(registry: &mut re_viewer_context::ComponentUiRegistry) {
registry.add_singleline_edit_or_view::<Color>(color::edit_rgba32);
pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry {
re_tracing::profile_function!();

registry.add_singleline_edit_or_view(radius::edit_radius_ui);
let mut registry =
re_viewer_context::ComponentUiRegistry::new(Box::new(&fallback_ui::fallback_component_ui));

registry.add_singleline_edit_or_view(marker_shape::edit_marker_shape_ui);
// Color components:
registry.add_singleline_edit_or_view::<Color>(color::edit_rgba32);
registry.add_singleline_edit_or_view::<AlbedoFactor>(color::edit_rgba32);
registry.add_singleline_edit_or_view(range1d::edit_range1d);

// 0-inf float components:
registry.add_singleline_edit_or_view::<AxisLength>(edit_f32_zero_to_max);
registry.add_singleline_edit_or_view::<DepthMeter>(edit_f32_zero_to_max);
registry.add_singleline_edit_or_view::<FillRatio>(edit_f32_zero_to_max);
Expand All @@ -54,25 +64,25 @@ pub fn register_editors(registry: &mut re_viewer_context::ComponentUiRegistry) {
registry.add_singleline_edit_or_view::<MarkerSize>(edit_f32_zero_to_max);
registry.add_singleline_edit_or_view::<StrokeWidth>(edit_f32_zero_to_max);

// float min-max components:
registry.add_singleline_edit_or_view::<DrawOrder>(edit_f32_min_to_max_float);

// float 0-1 components:
registry.add_singleline_edit_or_view::<Opacity>(edit_f32_zero_to_one);

// Bool components:
registry.add_singleline_edit_or_view::<Visible>(edit_bool);
registry.add_singleline_edit_or_view::<LockRangeDuringZoom>(edit_bool);

registry.add_singleline_edit_or_view::<TimelineName>(timeline::edit_timeline_name);

registry.add_display_ui(Text::name(), Box::new(display_text_ui));
// Text components:
registry.add_legacy_display_ui(Text::name(), Box::new(display_text_ui)); // TODO(andreas): Why is there a display ui?
registry.add_singleline_edit_or_view::<Text>(edit_singleline_string);
registry.add_multiline_edit_or_view::<Text>(edit_multiline_string);
registry.add_display_ui(Name::name(), Box::new(display_name_ui));
registry.add_legacy_display_ui(Name::name(), Box::new(display_name_ui)); // TODO(andreas): Why is there a display ui?
registry.add_singleline_edit_or_view::<Name>(edit_singleline_string);
registry.add_multiline_edit_or_view::<Name>(edit_multiline_string);

// `Colormap` _is_ an enum, but its custom editor is far better.
registry.add_singleline_edit_or_view::<Colormap>(colormap_edit_or_view_ui);

// Enums:
// TODO(#6974): Enums editors trivial and always the same, provide them automatically!
registry.add_singleline_edit_or_view::<AggregationPolicy>(edit_view_enum);
registry.add_singleline_edit_or_view::<BackgroundKind>(edit_view_enum);
Expand All @@ -83,14 +93,47 @@ pub fn register_editors(registry: &mut re_viewer_context::ComponentUiRegistry) {
registry.add_singleline_edit_or_view::<SortOrder>(edit_view_enum);
registry.add_singleline_edit_or_view::<TransformRelation>(edit_view_enum);
registry.add_singleline_edit_or_view::<ViewFit>(edit_view_enum);
// TODO(#7100): Editor for ImageFormat

// Vec3 components:
registry.add_singleline_edit_or_view::<Translation3D>(edit_or_view_vec3d);
registry.add_singleline_edit_or_view::<Scale3D>(edit_or_view_vec3d);

// Components that refer to views:
registry.add_singleline_edit_or_view::<IncludedSpaceView>(view_view_id);
registry.add_singleline_edit_or_view::<SpaceViewMaximized>(view_view_id);

// --------------------------------------------------------------------------------
// All other special components:
// --------------------------------------------------------------------------------

// `Colormap` _is_ an enum, but its custom editor is far better.
registry.add_singleline_edit_or_view(colormap_edit_or_view_ui);

registry.add_singleline_edit_or_view(timeline::edit_timeline_name);

registry.add_multiline_edit_or_view(visual_bounds2d::multiline_edit_visual_bounds2d);
registry.add_singleline_edit_or_view(visual_bounds2d::singleline_edit_visual_bounds2d);

registry.add_multiline_edit_or_view(transforms::multiline_view_transform_mat3x3);
registry.add_singleline_edit_or_view(transforms::singleline_view_transform_mat3x3);

registry.add_singleline_edit_or_view::<Translation3D>(edit_or_view_vec3d);
registry.add_singleline_edit_or_view::<Scale3D>(edit_or_view_vec3d);
registry.add_singleline_edit_or_view(image_format::edit_or_view_image_format);
registry.add_singleline_edit_or_view(resolution::edit_or_view_resolution);
registry.add_singleline_edit_or_view(view_coordinates::edit_or_view_view_coordinates);

registry.add_singleline_edit_or_view(radius::edit_radius_ui);
registry.add_singleline_edit_or_view(marker_shape::edit_marker_shape_ui);
registry.add_singleline_edit_or_view(range1d::edit_range1d);

registry.add_multiline_edit_or_view(visual_bounds2d::multiline_edit_visual_bounds2d);
registry.add_singleline_edit_or_view(visual_bounds2d::singleline_edit_visual_bounds2d);
registry.add_multiline_edit_or_view(visual_bounds2d::multiline_edit_visual_bounds2d);
registry.add_singleline_edit_or_view(visual_bounds2d::singleline_edit_visual_bounds2d);

registry.add_singleline_edit_or_view(pinhole::singleline_view_pinhole);
registry.add_multiline_edit_or_view(pinhole::multiline_view_pinhole);

line_strip::register_linestrip_component_ui(&mut registry);

registry
}
Loading
Loading