diff --git a/egui/src/context.rs b/egui/src/context.rs index 6afa7903..bf749ed4 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -873,6 +873,11 @@ impl Context { ui.shrink_width_to_current(); // don't let the text below grow this window wider ui.label("NOTE: the position of this window cannot be reset from within itself."); + + ui.collapsing("Interaction", |ui| { + let interaction = self.memory().interaction.clone(); + interaction.ui(ui); + }); } } diff --git a/egui/src/introspection.rs b/egui/src/introspection.rs index cd02a449..12e14449 100644 --- a/egui/src/introspection.rs +++ b/egui/src/introspection.rs @@ -142,3 +142,16 @@ impl Widget for &mut epaint::TessellationOptions { .response } } + +impl Widget for &memory::Interaction { + fn ui(self, ui: &mut Ui) -> Response { + ui.vertical(|ui| { + ui.label(format!("click_id: {:?}", self.click_id)); + ui.label(format!("drag_id: {:?}", self.drag_id)); + ui.label(format!("drag_is_window: {:?}", self.drag_is_window)); + ui.label(format!("click_interest: {:?}", self.click_interest)); + ui.label(format!("drag_interest: {:?}", self.drag_interest)); + }) + .response + } +} diff --git a/egui_demo_lib/Cargo.toml b/egui_demo_lib/Cargo.toml index e4aa8a3f..01acf25c 100644 --- a/egui_demo_lib/Cargo.toml +++ b/egui_demo_lib/Cargo.toml @@ -20,7 +20,7 @@ epi = { version = "0.8.0", path = "../epi" } # feature "http": image = { version = "0.23", default_features = false, features = ["jpeg", "png"], optional = true } -syntect = { version = "4", default_features = false, features = ["default-fancy"], optional = true } +syntect = { version = "4", default_features = false, features = ["default-fancy"], optional = true } # optional syntax highlighting # feature "persistence": serde = { version = "1", features = ["derive"], optional = true } diff --git a/egui_demo_lib/src/apps/demo/demo_window.rs b/egui_demo_lib/src/apps/demo/demo_window.rs index b5bcc7f0..e2a77a15 100644 --- a/egui_demo_lib/src/apps/demo/demo_window.rs +++ b/egui_demo_lib/src/apps/demo/demo_window.rs @@ -26,8 +26,21 @@ impl Default for DemoWindow { } } -impl DemoWindow { - pub fn ui(&mut self, ui: &mut Ui) { +impl Demo for DemoWindow { + fn name(&self) -> &str { + "✨ Misc Demos" + } + + fn show(&mut self, ctx: &CtxRef, open: &mut bool) { + Window::new(self.name()) + .open(open) + .scroll(true) + .show(ctx, |ui| self.ui(ui)); + } +} + +impl View for DemoWindow { + fn ui(&mut self, ui: &mut Ui) { CollapsingHeader::new("Widgets") .default_open(true) .show(ui, |ui| { diff --git a/egui_demo_lib/src/apps/demo/demo_windows.rs b/egui_demo_lib/src/apps/demo/demo_windows.rs index 1696a212..fbc2045c 100644 --- a/egui_demo_lib/src/apps/demo/demo_windows.rs +++ b/egui_demo_lib/src/apps/demo/demo_windows.rs @@ -1,4 +1,4 @@ -use egui::{CtxRef, Resize, ScrollArea, Ui, Window}; +use egui::{CtxRef, ScrollArea, Ui, Window}; // ---------------------------------------------------------------------------- @@ -16,11 +16,13 @@ impl Default for Demos { Box::new(super::dancing_strings::DancingStrings::default()), Box::new(super::drag_and_drop::DragAndDropDemo::default()), Box::new(super::font_book::FontBook::default()), + Box::new(super::DemoWindow::default()), Box::new(super::painting::Painting::default()), Box::new(super::scrolling::Scrolling::default()), Box::new(super::sliders::Sliders::default()), Box::new(super::widget_gallery::WidgetGallery::default()), Box::new(super::window_options::WindowOptions::default()), + Box::new(super::tests::WindowResizeTest::default()), // Tests: Box::new(super::tests::IdTest::default()), Box::new(super::tests::InputTest::default()), @@ -70,7 +72,7 @@ impl DemoWindows { /// Show the app ui (menu bar and windows). /// `sidebar_ui` can be used to optionally show some things in the sidebar pub fn ui(&mut self, ctx: &CtxRef) { - egui::SidePanel::left("side_panel", 200.0).show(ctx, |ui| { + egui::SidePanel::left("side_panel", 185.0).show(ctx, |ui| { ui.heading("✒ egui demos"); ui.separator(); @@ -86,10 +88,8 @@ impl DemoWindows { ui.separator(); ui.heading("Windows:"); - ui.indent("windows", |ui| { - self.open_windows.checkboxes(ui); - self.demos.checkboxes(ui); - }); + self.demos.checkboxes(ui); + self.open_windows.checkboxes(ui); ui.separator(); @@ -117,18 +117,10 @@ impl DemoWindows { fn windows(&mut self, ctx: &CtxRef) { let Self { open_windows, - demo_window, demos, .. } = self; - Window::new("✨ Demo") - .open(&mut open_windows.demo) - .scroll(true) - .show(ctx, |ui| { - demo_window.ui(ui); - }); - Window::new("🔧 Settings") .open(&mut open_windows.settings) .scroll(true) @@ -151,61 +143,6 @@ impl DemoWindows { }); demos.show(ctx); - - self.resize_windows(ctx); - } - - fn resize_windows(&mut self, ctx: &CtxRef) { - let open = &mut self.open_windows.resize; - - Window::new("resizable") - .open(open) - .scroll(false) - .resizable(true) - .show(ctx, |ui| { - ui.label("scroll: NO"); - ui.label("resizable: YES"); - ui.label(crate::LOREM_IPSUM); - }); - - Window::new("resizable + embedded scroll") - .open(open) - .scroll(false) - .resizable(true) - .default_height(300.0) - .show(ctx, |ui| { - ui.label("scroll: NO"); - ui.label("resizable: YES"); - ui.heading("We have a sub-region with scroll bar:"); - ScrollArea::auto_sized().show(ui, |ui| { - ui.label(crate::LOREM_IPSUM_LONG); - ui.label(crate::LOREM_IPSUM_LONG); - }); - // ui.heading("Some additional text here, that should also be visible"); // this works, but messes with the resizing a bit - }); - - Window::new("resizable + scroll") - .open(open) - .scroll(true) - .resizable(true) - .default_height(300.0) - .show(ctx, |ui| { - ui.label("scroll: YES"); - ui.label("resizable: YES"); - ui.label(crate::LOREM_IPSUM_LONG); - }); - - Window::new("auto_sized") - .open(open) - .auto_sized() - .show(ctx, |ui| { - ui.label("This window will auto-size based on its contents."); - ui.heading("Resize this area:"); - Resize::default().show(ui, |ui| { - ui.label(crate::LOREM_IPSUM); - }); - ui.heading("Resize the above area!"); - }); } } @@ -213,54 +150,39 @@ impl DemoWindows { #[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] struct OpenWindows { - demo: bool, - // egui stuff: settings: bool, inspection: bool, memory: bool, - resize: bool, } impl Default for OpenWindows { fn default() -> Self { - Self { - demo: true, - ..OpenWindows::none() - } + OpenWindows::none() } } impl OpenWindows { fn none() -> Self { Self { - demo: false, - settings: false, inspection: false, memory: false, - resize: false, } } fn checkboxes(&mut self, ui: &mut Ui) { let Self { - demo, settings, inspection, memory, - resize, } = self; + + ui.separator(); ui.label("egui:"); ui.checkbox(settings, "🔧 Settings"); ui.checkbox(inspection, "🔍 Inspection"); ui.checkbox(memory, "📝 Memory"); - ui.separator(); - ui.checkbox(demo, "✨ Demo"); - ui.separator(); - ui.checkbox(resize, "↔ Resize examples"); - ui.separator(); - ui.label("Misc:"); } } diff --git a/egui_demo_lib/src/apps/demo/scrolling.rs b/egui_demo_lib/src/apps/demo/scrolling.rs index 80e65afa..71359f02 100644 --- a/egui_demo_lib/src/apps/demo/scrolling.rs +++ b/egui_demo_lib/src/apps/demo/scrolling.rs @@ -2,6 +2,7 @@ use egui::{color::*, *}; #[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "persistence", serde(default))] +#[derive(PartialEq)] pub struct Scrolling { track_item: usize, tack_item_align: Align, @@ -36,14 +37,6 @@ impl super::Demo for Scrolling { impl super::View for Scrolling { fn ui(&mut self, ui: &mut Ui) { - ScrollArea::from_max_height(200.0) - .id_source("lorem_ipsum_scroll_area") - .show(ui, |ui| { - ui.label(crate::LOREM_IPSUM_LONG); - ui.label(crate::LOREM_IPSUM_LONG); - }); - - ui.separator(); ui.label("This shows how you can scroll to a specific item or pixel offset"); let mut track_item = false; @@ -88,6 +81,7 @@ impl super::View for Scrolling { scroll_area = scroll_area.scroll_offset(self.offset); } + ui.separator(); let (current_scroll, max_scroll) = scroll_area.show(ui, |ui| { if scroll_top { ui.scroll_to_cursor(Align::TOP); @@ -95,10 +89,11 @@ impl super::View for Scrolling { ui.vertical(|ui| { for item in 1..=50 { if track_item && item == self.track_item { - let response = ui.colored_label(Color32::YELLOW, format!("Item {}", item)); + let response = + ui.colored_label(Color32::YELLOW, format!("This is item {}", item)); response.scroll_to_me(self.tack_item_align); } else { - ui.label(format!("Item {}", item)); + ui.label(format!("This is item {}", item)); } } }); @@ -113,10 +108,17 @@ impl super::View for Scrolling { let max_scroll = ui.min_rect().height() - ui.clip_rect().height() + 2.0 * margin; (current_scroll, max_scroll) }); + ui.separator(); - ui.colored_label( - Color32::WHITE, - format!("{:.0}/{:.0} px", current_scroll, max_scroll), - ); + ui.label(format!( + "Scroll offset: {:.0}/{:.0} px", + current_scroll, max_scroll + )); + + ui.separator(); + ui.vertical_centered(|ui| { + egui::reset_button(ui, self); + ui.add(crate::__egui_github_link_file!()); + }); } } diff --git a/egui_demo_lib/src/apps/demo/sliders.rs b/egui_demo_lib/src/apps/demo/sliders.rs index f9ee53a5..cc4d5386 100644 --- a/egui_demo_lib/src/apps/demo/sliders.rs +++ b/egui_demo_lib/src/apps/demo/sliders.rs @@ -138,6 +138,9 @@ impl super::View for Sliders { ui.label("Smart Aim will guide you towards round values when you drag the slider so you you are more likely to hit 250 than 247.23"); ui.advance_cursor(8.0); - egui::reset_button(ui, self); + ui.vertical_centered(|ui| { + egui::reset_button(ui, self); + ui.add(crate::__egui_github_link_file!()); + }); } } diff --git a/egui_demo_lib/src/apps/demo/tests.rs b/egui_demo_lib/src/apps/demo/tests.rs index a92590c6..59a00efd 100644 --- a/egui_demo_lib/src/apps/demo/tests.rs +++ b/egui_demo_lib/src/apps/demo/tests.rs @@ -266,3 +266,68 @@ impl super::View for InputTest { ui.label(&self.info); } } + +// ---------------------------------------------------------------------------- + +#[derive(Default)] +pub struct WindowResizeTest {} + +impl super::Demo for WindowResizeTest { + fn name(&self) -> &str { + "↔ Window Resize" + } + + fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool) { + use egui::*; + + Window::new("↔ resizable") + .open(open) + .scroll(false) + .resizable(true) + .show(ctx, |ui| { + assert!(ui.enabled()); // TODO: remove + ui.label("scroll: NO"); + ui.label("resizable: YES"); + ui.label(crate::LOREM_IPSUM); + }); + + Window::new("↔ resizable + embedded scroll") + .open(open) + .scroll(false) + .resizable(true) + .default_height(300.0) + .show(ctx, |ui| { + ui.label("scroll: NO"); + ui.label("resizable: YES"); + ui.heading("We have a sub-region with scroll bar:"); + ScrollArea::auto_sized().show(ui, |ui| { + ui.label(crate::LOREM_IPSUM_LONG); + ui.label(crate::LOREM_IPSUM_LONG); + }); + // ui.heading("Some additional text here, that should also be visible"); // this works, but messes with the resizing a bit + }); + + Window::new("↔ resizable + scroll") + .open(open) + .scroll(true) + .resizable(true) + .default_height(300.0) + .show(ctx, |ui| { + ui.label("scroll: YES"); + ui.label("resizable: YES"); + ui.label(crate::LOREM_IPSUM_LONG); + }); + + Window::new("↔ auto_sized") + .open(open) + .auto_sized() + .show(ctx, |ui| { + ui.label("This window will auto-size based on its contents."); + ui.heading("Resize this area:"); + Resize::default().show(ui, |ui| { + ui.label(crate::LOREM_IPSUM); + }); + ui.heading("Resize the above area!"); + }); + } +} diff --git a/egui_demo_lib/src/apps/demo/widgets.rs b/egui_demo_lib/src/apps/demo/widgets.rs index 562bba57..8c1773b2 100644 --- a/egui_demo_lib/src/apps/demo/widgets.rs +++ b/egui_demo_lib/src/apps/demo/widgets.rs @@ -17,7 +17,7 @@ impl Default for Enum { #[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "persistence", serde(default))] pub struct Widgets { - button_enabled: bool, + group_enabled: bool, count: usize, radio: Enum, angle: f32, @@ -30,7 +30,7 @@ pub struct Widgets { impl Default for Widgets { fn default() -> Self { Self { - button_enabled: true, + group_enabled: true, radio: Enum::First, count: 0, angle: std::f32::consts::TAU / 3.0, @@ -78,6 +78,8 @@ impl Widgets { .on_hover_ui(tooltip_ui); ui.group(|ui| { + ui.checkbox(&mut self.group_enabled, "Group enabled"); + ui.set_enabled(self.group_enabled); ui.horizontal(|ui| { ui.radio_value(&mut self.radio, Enum::First, "First"); ui.radio_value(&mut self.radio, Enum::Second, "Second"); @@ -91,11 +93,9 @@ impl Widgets { }); }); - ui.checkbox(&mut self.button_enabled, "Button enabled"); - ui.horizontal(|ui| { if ui - .add(Button::new("Click me").enabled(self.button_enabled)) + .button("Click me") .on_hover_text("This will just increase a counter.") .clicked() { diff --git a/egui_demo_lib/src/apps/demo/window_options.rs b/egui_demo_lib/src/apps/demo/window_options.rs index 5b089b84..8b32443d 100644 --- a/egui_demo_lib/src/apps/demo/window_options.rs +++ b/egui_demo_lib/src/apps/demo/window_options.rs @@ -63,8 +63,6 @@ impl super::Demo for WindowOptions { impl super::View for WindowOptions { fn ui(&mut self, ui: &mut egui::Ui) { - egui::reset_button(ui, self); - let Self { title, title_bar, @@ -84,12 +82,14 @@ impl super::View for WindowOptions { ui.checkbox(collapsible, "collapsible"); ui.checkbox(resizable, "resizable"); ui.checkbox(scroll, "scroll"); - ui.vertical_centered(|ui| { - ui.add(crate::__egui_github_link_file!()); - }); if ui.button("Disable for 2 seconds").clicked() { *disabled_time = ui.input().time; } + + ui.vertical_centered(|ui| { + egui::reset_button(ui, self); + ui.add(crate::__egui_github_link_file!()); + }); } } diff --git a/egui_demo_lib/src/wrap_app.rs b/egui_demo_lib/src/wrap_app.rs index 35f0bba1..b7fec40d 100644 --- a/egui_demo_lib/src/wrap_app.rs +++ b/egui_demo_lib/src/wrap_app.rs @@ -51,7 +51,15 @@ impl epi::App for WrapApp { } fn warm_up_enabled(&self) -> bool { - true // The example windows use a lot of emojis. Pre-cache them by running one frame where everything is open. + // The example windows use a lot of emojis. Pre-cache them by running one frame where everything is open + #[cfg(debug_assertions)] + { + false // debug + } + #[cfg(not(debug_assertions))] + { + true // release + } } fn update(&mut self, ctx: &egui::CtxRef, frame: &mut epi::Frame<'_>) {