Skip to content

Commit

Permalink
Removed requirement to return an Option<Response> from `ListItemCon…
Browse files Browse the repository at this point in the history
…tent::ui()`
  • Loading branch information
abey79 committed May 2, 2024
1 parent c185d80 commit 6228024
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 87 deletions.
2 changes: 0 additions & 2 deletions crates/re_ui/examples/re_ui_example/right_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ impl RightPanel {
egui::Color32::LIGHT_RED,
"CustomContent delegates to a closure",
);

None
}),
)
},
Expand Down
9 changes: 1 addition & 8 deletions crates/re_ui/src/list_item2/label_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,7 @@ impl<'a> LabelContent<'a> {
}

impl ListItemContent for LabelContent<'_> {
fn ui(
self: Box<Self>,
re_ui: &ReUi,
ui: &mut Ui,
context: &ContentContext<'_>,
) -> Option<egui::Response> {
fn ui(self: Box<Self>, re_ui: &ReUi, ui: &mut Ui, context: &ContentContext<'_>) {
let Self {
mut text,
subdued,
Expand Down Expand Up @@ -226,8 +221,6 @@ impl ListItemContent for LabelContent<'_> {
.min;

ui.painter().galley(text_pos, galley, visuals.text_color());

button_response
}

fn desired_width(&self, _re_ui: &ReUi, ui: &Ui) -> DesiredWidth {
Expand Down
4 changes: 2 additions & 2 deletions crates/re_ui/src/list_item2/list_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ impl<'a> ListItem<'a> {
response: &style_response,
list_item: &self,
};
let content_response = content.ui(re_ui, ui, &content_ctx);
content.ui(re_ui, ui, &content_ctx);

// Draw background on interaction.
if drag_target {
Expand All @@ -293,7 +293,7 @@ impl<'a> ListItem<'a> {
Shape::rect_stroke(bg_rect, 0.0, (1.0, ui.visuals().selection.bg_fill)),
);
} else {
let bg_fill = if content_response.map_or(false, |r| r.hovered()) {
let bg_fill = if !response.hovered() && ui.rect_contains_pointer(bg_rect) {
// if some part of the content is active and hovered, our background should
// become dimmer
Some(visuals.bg_fill)
Expand Down
7 changes: 1 addition & 6 deletions crates/re_ui/src/list_item2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,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,
ui: &mut egui::Ui,
context: &ContentContext<'_>,
) -> Option<egui::Response>;
fn ui(self: Box<Self>, re_ui: &crate::ReUi, ui: &mut egui::Ui, context: &ContentContext<'_>);

/// The desired width of the content.
fn desired_width(&self, _re_ui: &crate::ReUi, _ui: &egui::Ui) -> DesiredWidth {
Expand Down
34 changes: 9 additions & 25 deletions crates/re_ui/src/list_item2/other_contents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,25 @@ impl ListItemContent for EmptyContent {
_re_ui: &crate::ReUi,
_ui: &mut egui::Ui,
_context: &ContentContext<'_>,
) -> Option<egui::Response> {
None
) {
}
}

/// [`ListItemContent`] that delegates to a closure.
#[allow(clippy::type_complexity)]
pub struct CustomContent {
ui: Box<dyn FnOnce(&crate::ReUi, &mut egui::Ui, &ContentContext<'_>) -> Option<egui::Response>>,
pub struct CustomContent<'a> {
ui: Box<dyn FnOnce(&crate::ReUi, &mut egui::Ui, &ContentContext<'_>) + 'a>,
}

impl CustomContent {
pub fn new(
ui: impl FnOnce(&crate::ReUi, &mut egui::Ui, &ContentContext<'_>) -> Option<egui::Response>
+ 'static,
) -> Self {
impl<'a> CustomContent<'a> {
pub fn new(ui: impl FnOnce(&crate::ReUi, &mut egui::Ui, &ContentContext<'_>) + 'a) -> Self {
Self { ui: Box::new(ui) }
}
}

impl ListItemContent for CustomContent {
fn ui(
self: Box<Self>,
re_ui: &crate::ReUi,
ui: &mut egui::Ui,
context: &ContentContext<'_>,
) -> Option<egui::Response> {
(self.ui)(re_ui, ui, context)
impl ListItemContent for CustomContent<'_> {
fn ui(self: Box<Self>, re_ui: &crate::ReUi, ui: &mut egui::Ui, context: &ContentContext<'_>) {
(self.ui)(re_ui, ui, context);
}
}

Expand All @@ -64,17 +55,10 @@ impl DebugContent {
}

impl ListItemContent for DebugContent {
fn ui(
self: Box<Self>,
_re_ui: &crate::ReUi,
ui: &mut egui::Ui,
context: &ContentContext<'_>,
) -> Option<egui::Response> {
fn ui(self: Box<Self>, _re_ui: &crate::ReUi, ui: &mut egui::Ui, context: &ContentContext<'_>) {
ui.ctx()
.debug_painter()
.debug_rect(context.rect, egui::Color32::DARK_GREEN, self.label);

None
}

fn desired_width(&self, _re_ui: &ReUi, _ui: &Ui) -> DesiredWidth {
Expand Down
70 changes: 27 additions & 43 deletions crates/re_ui/src/list_item2/property_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ use crate::list_item2::{ContentContext, DesiredWidth, ListItemContent};
use crate::{Icon, ReUi};
use eframe::emath::{Align, Align2};
use eframe::epaint::text::TextWrapping;
use egui::{NumExt, Response, Ui};
use egui::{NumExt, Ui};

/// Closure to draw an icon left of the label.
type IconFn<'a> = dyn FnOnce(&ReUi, &mut egui::Ui, egui::Rect, egui::style::WidgetVisuals) + 'a;

/// Closure to draw the right column of the property.
type PropertyValueFn<'a> =
dyn FnOnce(&ReUi, &mut egui::Ui, egui::style::WidgetVisuals) -> Option<egui::Response> + 'a;
type PropertyValueFn<'a> = dyn FnOnce(&ReUi, &mut egui::Ui, egui::style::WidgetVisuals) + 'a;

struct PropertyActionButton<'a> {
icon: &'static crate::icons::Icon,
Expand Down Expand Up @@ -99,7 +98,7 @@ impl<'a> PropertyContent<'a> {
#[inline]
pub fn value_fn<F>(mut self, value_fn: F) -> Self
where
F: FnOnce(&ReUi, &mut egui::Ui, egui::style::WidgetVisuals) -> Option<egui::Response> + 'a,
F: FnOnce(&ReUi, &mut egui::Ui, egui::style::WidgetVisuals) + 'a,
{
self.value_fn = Some(Box::new(value_fn));
self
Expand All @@ -113,7 +112,7 @@ impl<'a> PropertyContent<'a> {
#[inline]
pub fn value_bool(self, mut b: bool) -> Self {
self.value_fn(move |_, ui: &mut Ui, _| {
Some(ui.add_enabled(false, crate::toggle_switch(15.0, &mut b)))
ui.add_enabled(false, crate::toggle_switch(15.0, &mut b));
})
}

Expand All @@ -124,20 +123,24 @@ impl<'a> PropertyContent<'a> {
ui.visuals_mut().widgets.hovered.expansion = 0.0;
ui.visuals_mut().widgets.active.expansion = 0.0;

Some(ui.add(crate::toggle_switch(15.0, b)))
ui.add(crate::toggle_switch(15.0, b));
})
}

/// Show a static text in the value column.
#[inline]
pub fn value_text(self, text: impl Into<egui::WidgetText> + 'a) -> Self {
self.value_fn(move |_, ui, _| Some(ui.label(text.into())))
self.value_fn(move |_, ui, _| {
ui.label(text.into());
})
}

/// Show an editable text in the value column.
#[inline]
pub fn value_text_mut(self, text: &'a mut String) -> Self {
self.value_fn(|_, ui, _| Some(ui.text_edit_singleline(text)))
self.value_fn(|_, ui, _| {
ui.text_edit_singleline(text);
})
}

/// Show a read-only color in the value column.
Expand All @@ -148,7 +151,6 @@ impl<'a> PropertyContent<'a> {
let color = egui::Color32::from_rgba_unmultiplied(*r, *g, *b, *a);
let response = egui::color_picker::show_color(ui, color, ui.spacing().interact_size);
response.on_hover_text(format!("Color #{r:02x}{g:02x}{b:02x}{a:02x}"));
None
})
}

Expand All @@ -158,18 +160,13 @@ impl<'a> PropertyContent<'a> {
self.value_fn(|_, ui: &mut egui::Ui, _| {
ui.visuals_mut().widgets.hovered.expansion = 0.0;
ui.visuals_mut().widgets.active.expansion = 0.0;
Some(ui.color_edit_button_srgba_unmultiplied(color))
ui.color_edit_button_srgba_unmultiplied(color);
})
}
}

impl ListItemContent for PropertyContent<'_> {
fn ui(
self: Box<Self>,
re_ui: &ReUi,
ui: &mut Ui,
context: &ContentContext<'_>,
) -> Option<Response> {
fn ui(self: Box<Self>, re_ui: &ReUi, ui: &mut Ui, context: &ContentContext<'_>) {
let Self {
label,
icon_fn,
Expand Down Expand Up @@ -250,20 +247,6 @@ impl ListItemContent for PropertyContent<'_> {
icon_fn(re_ui, ui, icon_rect, visuals);
}

let button_response = if let Some(action_button) = action_buttons {
let mut child_ui = ui.child_ui(
action_button_rect.expand(2.0),
egui::Layout::centered_and_justified(egui::Direction::LeftToRight),
);
let button_response = re_ui.small_icon_button(&mut child_ui, action_button.icon);
if button_response.clicked() {
(action_button.on_click)();
}
Some(button_response)
} else {
None
};

// Prepare the label galley. We first go for an un-truncated version to register our desired
// column width. If it doesn't fit the available space, we recreate it with truncation.
let mut layout_job =
Expand All @@ -274,7 +257,7 @@ impl ListItemContent for PropertyContent<'_> {
.ceil();

super::StateStack::top_mut(ui.ctx(), |state| {
state.register_desired_left_column_width(desired_width)
state.register_desired_left_column_width(desired_width);
});

let galley = if desired_galley.size().x <= label_rect.width() {
Expand Down Expand Up @@ -305,23 +288,24 @@ impl ListItemContent for PropertyContent<'_> {
.collapse_openness
.map_or(true, |o| o == 0.0)
|| !summary_only;
let value_response = if let Some(value_fn) = value_fn {
if let Some(value_fn) = value_fn {
if should_show_value {
let mut child_ui =
ui.child_ui(value_rect, egui::Layout::left_to_right(egui::Align::Center));
value_fn(re_ui, &mut child_ui, visuals)
} else {
None
value_fn(re_ui, &mut child_ui, visuals);
}
} else {
None
};
}

// Make a union of all (possibly) interactive elements
match (value_response, button_response) {
(Some(a), Some(b)) => Some(a | b),
(Some(a), None) | (None, Some(a)) => Some(a),
(None, None) => None,
// Draw action button
if let Some(action_button) = action_buttons {
let mut child_ui = ui.child_ui(
action_button_rect.expand(2.0),
egui::Layout::centered_and_justified(egui::Direction::LeftToRight),
);
let button_response = re_ui.small_icon_button(&mut child_ui, action_button.icon);
if button_response.clicked() {
(action_button.on_click)();
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/re_ui/src/list_item2/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl StateStack {
`list_item_scope`."
);
}
})
});
}

fn peek(ctx: &egui::Context) -> Option<State> {
Expand Down

0 comments on commit 6228024

Please sign in to comment.