Skip to content

Commit

Permalink
Improve UI of various components in the selection panel (#6297)
Browse files Browse the repository at this point in the history
### What

- Follow up to #6291 
- Fixes #6245 
- Unblocks #4161
- Limitation #6315

This PR fixes the `UiLayout::List` implementations of `DataUi` such that
they all fit on a single line and are deal with potentially narrow space
(mostly via truncation).

This PR unearthed quite some inconsistencies in how we're using
monospace font for data. For now, `text_ui` (which uses monospace) has
been renamed `data_label_for_ui_layout` to parallel the new
`label_for_ui_layout` (which uses proportional). In the future (#6315),
we must unify both with a better, flexible API that also allows mixed
styles.

TODO:
- [x] blob: check with large binaries -> OK (could certainly be improved
but it truncates correct 🤷🏻)
- [x] tensor data: fix ui for `size(shape) > 3`
- [x] range2d: improve label

### Screenshots

<img width="488" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/e82c83c1-0f2b-4d64-9e76-71d28e3cba5c">
<img width="501" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/da811427-cad2-463e-8285-9ae096441fc5">
<img width="369" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/987af231-43c6-44e5-babb-52efdf110e30">
<img width="314" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/2a4174bf-8117-46e5-9734-5e3ac05dd209">
<img width="231" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/4fdc4e02-f6ff-43fc-8a68-163985ee0186">
<br/><br/>

When truncated:

<img width="228" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/cbfbbb79-df18-48e9-be82-0401feec9d93">


### 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/6297?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/6297?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)!

- [PR Build Summary](https://build.rerun.io/pr/6297)
- [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`.
  • Loading branch information
abey79 committed May 14, 2024
1 parent 55cf671 commit 3ad7245
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 138 deletions.
35 changes: 21 additions & 14 deletions crates/re_data_ui/src/annotation_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use re_types::datatypes::{
};
use re_viewer_context::{auto_color, UiLayout, ViewerContext};

use super::{table_for_ui_layout, DataUi};
use super::{data_label_for_ui_layout, label_for_ui_layout, table_for_ui_layout, DataUi};

impl crate::EntityDataUi for re_types::components::ClassId {
fn entity_data_ui(
Expand All @@ -27,10 +27,12 @@ impl crate::EntityDataUi for re_types::components::ClassId {
let response = ui.horizontal(|ui| {
// Color first, to keep subsequent rows of the same things aligned
small_color_ui(ui, &class.info);
ui.label(format!("{}", self.0));
let mut text = format!("{}", self.0);
if let Some(label) = &class.info.label {
ui.label(label.as_str());
text.push(' ');
text.push_str(label.as_str());
}
label_for_ui_layout(ui, ui_layout, text);
});

let id = self.0;
Expand All @@ -40,7 +42,7 @@ impl crate::EntityDataUi for re_types::components::ClassId {
|| !class.keypoint_annotations.is_empty()
{
response.response.on_hover_ui(|ui| {
class_description_ui(ctx, ui, ui_layout, class, id);
class_description_ui(ctx, ui, UiLayout::Tooltip, class, id);
});
}
}
Expand All @@ -52,7 +54,7 @@ impl crate::EntityDataUi for re_types::components::ClassId {
}
}
} else {
ui.label(format!("{}", self.0));
label_for_ui_layout(ui, ui_layout, format!("{}", self.0));
}
}
}
Expand All @@ -62,7 +64,7 @@ impl crate::EntityDataUi for re_types::components::KeypointId {
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_ui_layout: UiLayout,
ui_layout: UiLayout,
entity_path: &re_log_types::EntityPath,
query: &re_data_store::LatestAtQuery,
_db: &re_entity_db::EntityDb,
Expand All @@ -71,13 +73,16 @@ impl crate::EntityDataUi for re_types::components::KeypointId {
ui.horizontal(|ui| {
// Color first, to keep subsequent rows of the same things aligned
small_color_ui(ui, &info);
ui.label(format!("{}", self.0));
let mut text = format!("{}", self.0);
if let Some(label) = &info.label {
ui.label(label.as_str());
text.push(' ');
text.push_str(label.as_str());
}

data_label_for_ui_layout(ui, ui_layout, text);
});
} else {
ui.label(format!("{}", self.0));
data_label_for_ui_layout(ui, ui_layout, format!("{}", self.0));
}
}
}
Expand Down Expand Up @@ -108,16 +113,18 @@ impl DataUi for AnnotationContext {
) {
match ui_layout {
UiLayout::List | UiLayout::Tooltip => {
if self.0.len() == 1 {
let text = if self.0.len() == 1 {
let descr = &self.0[0].class_description;
ui.label(format!(

format!(
"One class containing {} keypoints and {} connections",
descr.keypoint_annotations.len(),
descr.keypoint_connections.len()
));
)
} else {
ui.label(format!("{} classes", self.0.len()));
}
format!("{} classes", self.0.len())
};
label_for_ui_layout(ui, ui_layout, text);
}
UiLayout::SelectionPanelLimitHeight | UiLayout::SelectionPanelFull => {
ui.vertical(|ui| {
Expand Down
50 changes: 7 additions & 43 deletions crates/re_data_ui/src/component_ui_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use re_viewer_context::{ComponentUiRegistry, UiLayout, ViewerContext};

use crate::editors::register_editors;

use super::EntityDataUi;
use super::{data_label_for_ui_layout, EntityDataUi};

pub fn create_component_ui_registry() -> ComponentUiRegistry {
re_tracing::profile_function!();
Expand All @@ -20,6 +20,8 @@ pub fn create_component_ui_registry() -> ComponentUiRegistry {
add_to_registry::<re_types::components::KeypointId>(&mut registry);
add_to_registry::<re_types::components::LineStrip2D>(&mut registry);
add_to_registry::<re_types::components::LineStrip3D>(&mut registry);
add_to_registry::<re_types::components::Range1D>(&mut registry);
add_to_registry::<re_types::components::Range2D>(&mut registry);
add_to_registry::<re_types::components::Resolution>(&mut registry);
add_to_registry::<re_types::components::Rotation3D>(&mut registry);
add_to_registry::<re_types::components::Material>(&mut registry);
Expand Down Expand Up @@ -88,14 +90,14 @@ fn arrow_ui(ui: &mut egui::Ui, ui_layout: UiLayout, array: &dyn arrow2::array::A
if let Some(utf8) = array.as_any().downcast_ref::<Utf8Array<i32>>() {
if utf8.len() == 1 {
let string = utf8.value(0);
text_ui(ui, ui_layout, string);
data_label_for_ui_layout(ui, ui_layout, string);
return;
}
}
if let Some(utf8) = array.as_any().downcast_ref::<Utf8Array<i64>>() {
if utf8.len() == 1 {
let string = utf8.value(0);
text_ui(ui, ui_layout, string);
data_label_for_ui_layout(ui, ui_layout, string);
return;
}
}
Expand All @@ -106,7 +108,7 @@ fn arrow_ui(ui: &mut egui::Ui, ui_layout: UiLayout, array: &dyn arrow2::array::A
let mut string = String::new();
let display = arrow2::array::get_display(array, "null");
if display(&mut string, 0).is_ok() {
text_ui(ui, ui_layout, &string);
data_label_for_ui_layout(ui, ui_layout, &string);
return;
}
}
Expand All @@ -119,47 +121,9 @@ fn arrow_ui(ui: &mut egui::Ui, ui_layout: UiLayout, array: &dyn arrow2::array::A

if data_type_formatted.len() < 20 {
// e.g. "4.2 KiB of Float32"
text_ui(ui, ui_layout, &format!("{bytes} of {data_type_formatted}"));
data_label_for_ui_layout(ui, ui_layout, &format!("{bytes} of {data_type_formatted}"));
} else {
// Huge datatype, probably a union horror show
ui.label(format!("{bytes} of data"));
}
}

fn text_ui(ui: &mut egui::Ui, ui_layout: UiLayout, string: &str) {
let font_id = egui::TextStyle::Monospace.resolve(ui.style());
let color = ui.visuals().text_color();
let wrap_width = ui.available_width();
let mut layout_job =
egui::text::LayoutJob::simple(string.to_owned(), font_id, color, wrap_width);

let mut needs_scroll_area = false;

match ui_layout {
UiLayout::List => {
// Elide
layout_job.wrap.max_rows = 1;
layout_job.wrap.break_anywhere = true;
}
UiLayout::Tooltip => {
layout_job.wrap.max_rows = 3;
}
UiLayout::SelectionPanelLimitHeight => {
let num_newlines = string.chars().filter(|&c| c == '\n').count();
needs_scroll_area = 10 < num_newlines || 300 < string.len();
}
UiLayout::SelectionPanelFull => {
needs_scroll_area = false;
}
}

let galley = ui.fonts(|f| f.layout_job(layout_job)); // We control the text layout; not the label

if needs_scroll_area {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.label(galley);
});
} else {
ui.label(galley);
}
}
66 changes: 47 additions & 19 deletions crates/re_data_ui/src/data.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use egui::Vec2;
use egui::{Ui, Vec2};
use re_data_store::LatestAtQuery;
use re_entity_db::EntityDb;

use re_format::format_f32;
use re_types::components::{Color, LineStrip2D, LineStrip3D, ViewCoordinates};
use re_types::components::{Color, LineStrip2D, LineStrip3D, Range1D, Range2D, ViewCoordinates};
use re_viewer_context::{UiLayout, ViewerContext};

use super::{table_for_ui_layout, DataUi};
use super::{data_label_for_ui_layout, label_for_ui_layout, table_for_ui_layout, DataUi};

/// Default number of ui points to show a number.
const DEFAULT_NUMBER_WIDTH: f32 = 52.0;
Expand Down Expand Up @@ -62,13 +64,13 @@ impl DataUi for ViewCoordinates {
) {
match ui_layout {
UiLayout::List => {
ui.label(self.describe_short())
label_for_ui_layout(ui, ui_layout, self.describe_short())
.on_hover_text(self.describe());
}
UiLayout::SelectionPanelFull
| UiLayout::SelectionPanelLimitHeight
| UiLayout::Tooltip => {
ui.label(self.describe());
label_for_ui_layout(ui, ui_layout, self.describe());
}
}
}
Expand Down Expand Up @@ -107,11 +109,11 @@ impl DataUi for re_types::datatypes::Vec2D {
&self,
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_ui_layout: UiLayout,
ui_layout: UiLayout,
_query: &re_data_store::LatestAtQuery,
_db: &re_entity_db::EntityDb,
) {
ui.label(self.to_string());
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

Expand All @@ -120,11 +122,11 @@ impl DataUi for re_types::datatypes::Vec3D {
&self,
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_ui_layout: UiLayout,
ui_layout: UiLayout,
_query: &re_data_store::LatestAtQuery,
_db: &re_entity_db::EntityDb,
) {
ui.label(self.to_string());
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

Expand All @@ -133,11 +135,11 @@ impl DataUi for re_types::datatypes::Vec4D {
&self,
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_ui_layout: UiLayout,
ui_layout: UiLayout,
_query: &re_data_store::LatestAtQuery,
_db: &re_entity_db::EntityDb,
) {
ui.label(self.to_string());
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

Expand All @@ -146,11 +148,11 @@ impl DataUi for re_types::datatypes::UVec2D {
&self,
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_ui_layout: UiLayout,
ui_layout: UiLayout,
_query: &re_data_store::LatestAtQuery,
_db: &re_entity_db::EntityDb,
) {
ui.label(self.to_string());
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

Expand All @@ -159,11 +161,11 @@ impl DataUi for re_types::datatypes::UVec3D {
&self,
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_ui_layout: UiLayout,
ui_layout: UiLayout,
_query: &re_data_store::LatestAtQuery,
_db: &re_entity_db::EntityDb,
) {
ui.label(self.to_string());
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

Expand All @@ -172,11 +174,37 @@ impl DataUi for re_types::datatypes::UVec4D {
&self,
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_ui_layout: UiLayout,
ui_layout: UiLayout,
_query: &re_data_store::LatestAtQuery,
_db: &re_entity_db::EntityDb,
) {
ui.label(self.to_string());
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

impl DataUi for Range1D {
fn data_ui(
&self,
_ctx: &ViewerContext<'_>,
ui: &mut Ui,
ui_layout: UiLayout,
_query: &LatestAtQuery,
_db: &EntityDb,
) {
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

impl DataUi for Range2D {
fn data_ui(
&self,
_ctx: &ViewerContext<'_>,
ui: &mut Ui,
ui_layout: UiLayout,
_query: &LatestAtQuery,
_db: &EntityDb,
) {
data_label_for_ui_layout(ui, ui_layout, self.to_string());
}
}

Expand All @@ -191,7 +219,7 @@ impl DataUi for LineStrip2D {
) {
match ui_layout {
UiLayout::List | UiLayout::Tooltip => {
ui.label(format!("{} positions", self.0.len()));
label_for_ui_layout(ui, ui_layout, format!("{} positions", self.0.len()));
}
UiLayout::SelectionPanelLimitHeight | UiLayout::SelectionPanelFull => {
use egui_extras::Column;
Expand Down Expand Up @@ -238,7 +266,7 @@ impl DataUi for LineStrip3D {
) {
match ui_layout {
UiLayout::List | UiLayout::Tooltip => {
ui.label(format!("{} positions", self.0.len()));
label_for_ui_layout(ui, ui_layout, format!("{} positions", self.0.len()));
}
UiLayout::SelectionPanelFull | UiLayout::SelectionPanelLimitHeight => {
use egui_extras::Column;
Expand Down
Loading

0 comments on commit 3ad7245

Please sign in to comment.