Skip to content

Commit

Permalink
ListItem 2.0 (part 2): introduce PropertyContent for two-column, …
Browse files Browse the repository at this point in the history
…property-like list items (#6174)

### What

This PR introduced the `PropertyContent`, an implementation of
`ListItemContent` for two-column list item, with a label and flexible
"values". Currently only demonstrated in `re_ui_example`.

What the "value" displays is delegated to a user-provided closure.
However, `PropertyContent` provides helper for a few basic types: bool,
text, color (both read-only and editable).

- Part of #6075
- Follow-up to #6161 


https://github.com/rerun-io/rerun/assets/49431240/bf94871a-63d5-46fa-94fe-a9adf720cdb8


### Limitations and todo

- Columns are fixed size at 50%. They will be made smart in [the next
PR.](#6182)
- More helpers are needed for various kinds of values.
- There can be only 0 or 1 action button. This should be extended by
using a `…` button with some kind of popup with all available actions in
a future PR.
- Right gutter space is reserved for the action button even if no list
item in scope use them. The `list_item_scope` could track this and skip
reserving that space if it's never used (e.g. component list in entity
path selection panel): #6179

### 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/6174?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/6174?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/6174)
- [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 authored May 2, 2024
1 parent 0c14528 commit 9f6add2
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 23 deletions.
3 changes: 2 additions & 1 deletion crates/re_ui/examples/re_ui_example/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl eframe::App for ExampleApp {
.show(ui, |ui| {
ui.horizontal(|ui| {
ui.label("Toggle switch:");
ui.add(re_ui::toggle_switch(&mut self.dummy_bool));
ui.add(re_ui::toggle_switch(8.0, &mut self.dummy_bool));
});
ui.label(format!("Latest command: {}", self.latest_cmd));

Expand Down Expand Up @@ -310,6 +310,7 @@ impl eframe::App for ExampleApp {

egui::SidePanel::right("right_panel")
.frame(panel_frame)
.min_width(0.0)
.show_animated(egui_ctx, self.show_right_panel, |ui| {
// TODO(#6156): this is still needed for some full-span widgets
ui.set_clip_rect(ui.max_rect());
Expand Down
66 changes: 63 additions & 3 deletions crates/re_ui/examples/re_ui_example/right_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ pub struct RightPanel {
drag_and_drop: drag_and_drop::ExampleDragAndDrop,
hierarchical_drag_and_drop: hierarchical_drag_and_drop::HierarchicalDragAndDrop,
selected_list_item: Option<usize>,

// dummy data
text: String,
color: [u8; 4],
boolean: bool,
}

impl Default for RightPanel {
Expand All @@ -17,6 +22,10 @@ impl Default for RightPanel {
hierarchical_drag_and_drop:
hierarchical_drag_and_drop::HierarchicalDragAndDrop::default(),
selected_list_item: None,
// dummy data
text: "Hello world".to_owned(),
color: [128, 0, 0, 255],
boolean: false,
}
}
}
Expand All @@ -32,7 +41,7 @@ impl RightPanel {

re_ui.panel_content(ui, |re_ui, ui| {
re_ui.panel_title_bar_with_buttons(ui, "Demo: drag-and-drop", None, |ui| {
ui.add(re_ui::toggle_switch(&mut self.show_hierarchical_demo));
ui.add(re_ui::toggle_switch(8.0, &mut self.show_hierarchical_demo));
ui.label("Hierarchical:");
});

Expand All @@ -51,7 +60,7 @@ impl RightPanel {

re_ui.panel_content(ui, |re_ui, ui| {
re_ui.panel_title_bar(ui, "Demo: ListItem APIs", None);
Self::list_item_api_demo(re_ui, ui);
self.list_item_api_demo(re_ui, ui);
});

ui.add_space(20.0);
Expand Down Expand Up @@ -93,7 +102,7 @@ impl RightPanel {
});
}

fn list_item_api_demo(re_ui: &ReUi, ui: &mut Ui) {
fn list_item_api_demo(&mut self, re_ui: &ReUi, ui: &mut Ui) {
re_ui
.list_item2()
.show_hierarchical(ui, list_item2::LabelContent::new("Default"));
Expand Down Expand Up @@ -170,6 +179,57 @@ impl RightPanel {
},
);

re_ui.list_item2().show_hierarchical_with_children(
ui,
"property content features",
true,
list_item2::PropertyContent::new("PropertyContent features:")
.value_text("bunch of properties"),
|re_ui, ui| {
re_ui.list_item2().show_hierarchical(
ui,
list_item2::PropertyContent::new("Bool").value_bool(self.boolean),
);

re_ui.list_item2().show_hierarchical(
ui,
list_item2::PropertyContent::new("Bool (editable)")
.value_bool_mut(&mut self.boolean),
);

re_ui.list_item2().show_hierarchical(
ui,
list_item2::PropertyContent::new("Text").value_text(&self.text),
);

re_ui.list_item2().show_hierarchical(
ui,
list_item2::PropertyContent::new("Text (editable)")
.value_text_mut(&mut self.text),
);

re_ui.list_item2().show_hierarchical(
ui,
list_item2::PropertyContent::new("Color")
.with_icon(&re_ui::icons::SPACE_VIEW_TEXT)
.action_button(&re_ui::icons::ADD, || {
re_log::warn!("Add button clicked");
})
.value_color(&self.color),
);

re_ui.list_item2().show_hierarchical(
ui,
list_item2::PropertyContent::new("Color (editable)")
.with_icon(&re_ui::icons::SPACE_VIEW_TEXT)
.action_button(&re_ui::icons::ADD, || {
re_log::warn!("Add button clicked");
})
.value_color_mut(&mut self.color),
);
},
);

re_ui.list_item2().show_hierarchical_with_children(
ui,
"other features",
Expand Down
12 changes: 4 additions & 8 deletions crates/re_ui/src/list_item2/list_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,15 @@ impl<'a> ListItem<'a> {
}

/// Draw the item as part of a flat list.
pub fn show_flat(self, ui: &mut Ui, content: impl ListItemContent + 'static) -> Response {
pub fn show_flat(self, ui: &mut Ui, content: impl ListItemContent + 'a) -> Response {
// Note: the purpose of the scope is to minimise interferences on subsequent items' id
ui.scope(|ui| self.ui(ui, None, 0.0, Box::new(content)))
.inner
.response
}

/// Draw the item as a leaf node from a hierarchical list.
pub fn show_hierarchical(
self,
ui: &mut Ui,
content: impl ListItemContent + 'static,
) -> Response {
pub fn show_hierarchical(self, ui: &mut Ui, content: impl ListItemContent + 'a) -> Response {
// Note: the purpose of the scope is to minimise interferences on subsequent items' id
ui.scope(|ui| {
self.ui(
Expand All @@ -138,7 +134,7 @@ impl<'a> ListItem<'a> {
ui: &mut Ui,
id: impl Into<egui::Id>,
default_open: bool,
content: impl ListItemContent + 'static,
content: impl ListItemContent + 'a,
add_childrens: impl FnOnce(&ReUi, &mut egui::Ui) -> R,
) -> ShowCollapsingResponse<R> {
let id = id.into();
Expand Down Expand Up @@ -185,7 +181,7 @@ impl<'a> ListItem<'a> {
ui: &mut Ui,
id: Option<egui::Id>,
extra_indent: f32,
content: Box<dyn ListItemContent>,
content: Box<dyn ListItemContent + 'a>,
) -> ListItemResponse {
let Self {
re_ui,
Expand Down
3 changes: 3 additions & 0 deletions crates/re_ui/src/list_item2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
mod label_content;
mod list_item;
mod other_contents;
mod property_content;
mod scope;

pub use label_content::*;
pub use list_item::*;
pub use other_contents::*;
pub use property_content::*;
pub use scope::*;

/// Context provided to [`ListItemContent`] implementations
Expand Down Expand Up @@ -62,6 +64,7 @@ pub trait ListItemContent {
///
/// If the content has some interactive elements, it should return its response. In particular,
/// if the response is hovered, the list item will show a dimmer background highlight.
//TODO(ab): could the return type be just a bool meaning "inner interactive widget was hovered"?
fn ui(
self: Box<Self>,
re_ui: &crate::ReUi,
Expand Down
Loading

0 comments on commit 9f6add2

Please sign in to comment.