Skip to content

Commit

Permalink
Add ComboBox::icon() (#1405)
Browse files Browse the repository at this point in the history
  • Loading branch information
4JX authored Mar 23, 2022
1 parent 8272b08 commit dd96990
Showing 1 changed file with 57 additions and 3 deletions.
60 changes: 57 additions & 3 deletions egui/src/containers/combo_box.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{style::WidgetVisuals, *};
use epaint::Shape;

/// A function that paints the `ComboBox` icon
pub type IconPainter = Box<dyn FnOnce(&Ui, Rect, &WidgetVisuals, bool)>;

/// A drop-down selection menu with a descriptive label.
///
/// ```
Expand All @@ -24,6 +27,7 @@ pub struct ComboBox {
label: Option<WidgetText>,
selected_text: WidgetText,
width: Option<f32>,
icon: Option<IconPainter>,
}

impl ComboBox {
Expand All @@ -34,6 +38,7 @@ impl ComboBox {
label: Some(label.into()),
selected_text: Default::default(),
width: None,
icon: None,
}
}

Expand All @@ -45,6 +50,7 @@ impl ComboBox {
label: Some(label),
selected_text: Default::default(),
width: None,
icon: None,
}
}

Expand All @@ -55,6 +61,7 @@ impl ComboBox {
label: Default::default(),
selected_text: Default::default(),
width: None,
icon: None,
}
}

Expand All @@ -70,6 +77,41 @@ impl ComboBox {
self
}

/// Use the provided function to render a different `ComboBox` icon.
/// Defaults to a triangle that expands when the cursor is hovering over the `ComboBox`.
///
/// For example:
/// ```
/// # egui::__run_test_ui(|ui| {
/// # let text = "Selected text";
/// pub fn filled_triangle(
/// ui: &egui::Ui,
/// rect: egui::Rect,
/// visuals: &egui::style::WidgetVisuals,
/// _is_open: bool,
/// ) {
/// let rect = egui::Rect::from_center_size(
/// rect.center(),
/// egui::Vec2::new(rect.width() * 0.6, rect.height() * 0.4),
/// );
/// ui.painter().add(egui::Shape::convex_polygon(
/// vec![rect.left_top(), rect.right_top(), rect.center_bottom()],
/// visuals.fg_stroke.color,
/// visuals.fg_stroke,
/// ));
/// }
///
/// egui::ComboBox::from_id_source("my-combobox")
/// .selected_text(text)
/// .icon(filled_triangle)
/// .show_ui(ui, |_ui| {});
/// # });
/// ```
pub fn icon(mut self, icon_fn: impl FnOnce(&Ui, Rect, &WidgetVisuals, bool) + 'static) -> Self {
self.icon = Some(Box::new(icon_fn));
self
}

/// Show the combo box, with the given ui code for the menu contents.
///
/// Returns `InnerResponse { inner: None }` if the combo box is closed.
Expand All @@ -91,6 +133,7 @@ impl ComboBox {
label,
selected_text,
width,
icon,
} = self;

let button_id = ui.make_persistent_id(id_source);
Expand All @@ -99,7 +142,7 @@ impl ComboBox {
if let Some(width) = width {
ui.spacing_mut().slider_width = width; // yes, this is ugly. Will remove later.
}
let mut ir = combo_box_dyn(ui, button_id, selected_text, menu_contents);
let mut ir = combo_box_dyn(ui, button_id, selected_text, menu_contents, icon);
if let Some(label) = label {
ir.response
.widget_info(|| WidgetInfo::labeled(WidgetType::ComboBox, label.text()));
Expand Down Expand Up @@ -165,6 +208,7 @@ fn combo_box_dyn<'c, R>(
button_id: Id,
selected_text: WidgetText,
menu_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
icon: Option<IconPainter>,
) -> InnerResponse<Option<R>> {
let popup_id = button_id.with("popup");

Expand Down Expand Up @@ -192,7 +236,17 @@ fn combo_box_dyn<'c, R>(
} else {
ui.style().interact(&response)
};
paint_icon(ui.painter(), icon_rect.expand(visuals.expansion), visuals);

if let Some(icon) = icon {
icon(
ui,
icon_rect.expand(visuals.expansion),
visuals,
is_popup_open,
);
} else {
paint_default_icon(ui.painter(), icon_rect.expand(visuals.expansion), visuals);
}

let text_rect = Align2::LEFT_CENTER.align_size_within_rect(galley.size(), rect);
galley.paint_with_visuals(ui.painter(), text_rect.min, visuals);
Expand Down Expand Up @@ -262,7 +316,7 @@ fn button_frame(
response
}

fn paint_icon(painter: &Painter, rect: Rect, visuals: &WidgetVisuals) {
fn paint_default_icon(painter: &Painter, rect: Rect, visuals: &WidgetVisuals) {
let rect = Rect::from_center_size(
rect.center(),
vec2(rect.width() * 0.7, rect.height() * 0.45),
Expand Down

0 comments on commit dd96990

Please sign in to comment.