diff --git a/crates/ecolor/src/color32.rs b/crates/ecolor/src/color32.rs index 87f4915c..e72a3b98 100644 --- a/crates/ecolor/src/color32.rs +++ b/crates/ecolor/src/color32.rs @@ -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 { diff --git a/crates/egui_demo_lib/src/demo/popups.rs b/crates/egui_demo_lib/src/demo/popups.rs index 4cf689d3..f9815a6b 100644 --- a/crates/egui_demo_lib/src/demo/popups.rs +++ b/crates/egui_demo_lib/src/demo/popups.rs @@ -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")))