Add color picker menu item example (#5755)

* To be merged after #5756 



https://github.com/user-attachments/assets/ad40c172-cad2-4cc5-a3ef-3284b6545e94
This commit is contained in:
Lucas Meurer 2025-03-19 09:33:17 +01:00 committed by GitHub
parent a2afc8d092
commit 93c06c3405
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 82 additions and 52 deletions

View File

@ -295,6 +295,14 @@ impl Color32 {
pub fn blend(self, on_top: Self) -> Self {
self.gamma_multiply_u8(255 - on_top.a()) + on_top
}
/// Intensity of the color.
///
/// Returns a value in the range 0-1.
/// The brighter the color, the closer to 1.
pub fn intensity(&self) -> f32 {
(self.r() as f32 * 0.299 + self.g() as f32 * 0.587 + self.b() as f32 * 0.114) / 255.0
}
}
impl std::ops::Mul for Color32 {

View File

@ -1,8 +1,9 @@
use crate::rust_view_ui;
use egui::color_picker::{color_picker_color32, Alpha};
use egui::containers::menu::{MenuConfig, SubMenuButton};
use egui::{
include_image, Align, Align2, ComboBox, Frame, Id, Layout, Popup, PopupCloseBehavior,
RectAlign, Tooltip, Ui, UiBuilder,
RectAlign, RichText, Tooltip, Ui, UiBuilder,
};
/// Showcase [`Popup`].
@ -16,6 +17,7 @@ pub struct PopupsDemo {
close_behavior: PopupCloseBehavior,
popup_open: bool,
checked: bool,
color: egui::Color32,
}
impl PopupsDemo {
@ -25,6 +27,74 @@ impl PopupsDemo {
.gap(self.gap)
.close_behavior(self.close_behavior)
}
fn nested_menus(&mut self, ui: &mut Ui) {
ui.set_max_width(200.0); // To make sure we wrap long text
if ui.button("Open…").clicked() {
ui.close();
}
ui.menu_button("Popups can have submenus", |ui| {
ui.menu_button("SubMenu", |ui| {
if ui.button("Open…").clicked() {
ui.close();
}
let _ = ui.button("Item");
ui.menu_button("Recursive", |ui| self.nested_menus(ui));
});
ui.menu_button("SubMenu", |ui| {
if ui.button("Open…").clicked() {
ui.close();
}
let _ = ui.button("Item");
});
let _ = ui.button("Item");
if ui.button("Open…").clicked() {
ui.close();
}
});
ui.menu_image_text_button(
include_image!("../../data/icon.png"),
"I have an icon!",
|ui| {
let _ = ui.button("Item1");
let _ = ui.button("Item2");
let _ = ui.button("Item3");
let _ = ui.button("Item4");
if ui.button("Open…").clicked() {
ui.close();
}
},
);
let _ = ui.button("Very long text for this item that should be wrapped");
SubMenuButton::new("Always CloseOnClickOutside")
.config(MenuConfig::new().close_behavior(PopupCloseBehavior::CloseOnClickOutside))
.ui(ui, |ui| {
ui.checkbox(&mut self.checked, "Checkbox");
// Customized color SubMenuButton
let is_bright = self.color.intensity() > 0.5;
let text_color = if is_bright {
egui::Color32::BLACK
} else {
egui::Color32::WHITE
};
let mut color_button =
SubMenuButton::new(RichText::new("Background").color(text_color));
color_button.button = color_button.button.fill(self.color);
color_button.button = color_button
.button
.right_text(RichText::new(SubMenuButton::RIGHT_ARROW).color(text_color));
color_button.ui(ui, |ui| {
ui.spacing_mut().slider_width = 200.0;
color_picker_color32(ui, &mut self.color, Alpha::Opaque);
});
if ui.button("Open…").clicked() {
ui.close();
}
});
}
}
impl Default for PopupsDemo {
@ -35,6 +105,7 @@ impl Default for PopupsDemo {
close_behavior: PopupCloseBehavior::CloseOnClick,
popup_open: false,
checked: false,
color: egui::Color32::RED,
}
}
}
@ -57,55 +128,6 @@ impl crate::Demo for PopupsDemo {
}
}
fn nested_menus(ui: &mut egui::Ui, checked: &mut bool) {
ui.set_max_width(200.0); // To make sure we wrap long text
if ui.button("Open…").clicked() {
ui.close();
}
ui.menu_button("Popups can have submenus", |ui| {
ui.menu_button("SubMenu", |ui| {
if ui.button("Open…").clicked() {
ui.close();
}
let _ = ui.button("Item");
ui.menu_button("Recursive", |ui| nested_menus(ui, checked));
});
ui.menu_button("SubMenu", |ui| {
if ui.button("Open…").clicked() {
ui.close();
}
let _ = ui.button("Item");
});
let _ = ui.button("Item");
if ui.button("Open…").clicked() {
ui.close();
}
});
ui.menu_image_text_button(
include_image!("../../data/icon.png"),
"I have an icon!",
|ui| {
let _ = ui.button("Item1");
let _ = ui.button("Item2");
let _ = ui.button("Item3");
let _ = ui.button("Item4");
if ui.button("Open…").clicked() {
ui.close();
}
},
);
let _ = ui.button("Very long text for this item that should be wrapped");
SubMenuButton::new("Always CloseOnClickOutside")
.config(MenuConfig::new().close_behavior(PopupCloseBehavior::CloseOnClickOutside))
.ui(ui, |ui| {
ui.checkbox(checked, "Checkbox");
if ui.button("Open…").clicked() {
ui.close();
}
});
}
impl crate::View for PopupsDemo {
fn ui(&mut self, ui: &mut egui::Ui) {
let response = Frame::group(ui.style())
@ -117,10 +139,10 @@ impl crate::View for PopupsDemo {
.inner;
self.apply_options(Popup::menu(&response).id(Id::new("menu")))
.show(|ui| nested_menus(ui, &mut self.checked));
.show(|ui| self.nested_menus(ui));
self.apply_options(Popup::context_menu(&response).id(Id::new("context_menu")))
.show(|ui| nested_menus(ui, &mut self.checked));
.show(|ui| self.nested_menus(ui));
if self.popup_open {
self.apply_options(Popup::from_response(&response).id(Id::new("popup")))