From f9d0203ff5a89caaa25a10d1190c5f9c6706bd44 Mon Sep 17 00:00:00 2001 From: Marli Frost Date: Tue, 19 Dec 2023 13:51:28 +0000 Subject: [PATCH] Add API for tracking checked to the inner_size of a window This matched the apis used for focused and occluded properties. I've added an example to demonstrate usage. --- examples/window-properties.rs | 22 +++++++++++++++ src/window.rs | 52 ++++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 examples/window-properties.rs diff --git a/examples/window-properties.rs b/examples/window-properties.rs new file mode 100644 index 0000000..e0fd174 --- /dev/null +++ b/examples/window-properties.rs @@ -0,0 +1,22 @@ +use gooey::value::Dynamic; +use gooey::widget::{MakeWidget, WidgetInstance}; +use gooey::Run; +use kludgine::figures::Size; + +fn main() -> gooey::Result { + let focused = Dynamic::new(false); + let occluded = Dynamic::new(false); + let inner_size = Dynamic::new(Size::default()); + + let widgets = focused.map_each(|v| format!("focused: {:?}", v)) + .and(occluded.map_each(|v| format!("occluded: {:?}", v))) + .and(inner_size.map_each(|v| format!("inner_size: {:?}", v))) + .into_rows() + .centered(); + + gooey::window::Window::::for_widget(widgets) + .focused(focused) + .occluded(occluded) + .inner_size(inner_size) + .run() +} diff --git a/src/window.rs b/src/window.rs index e669b01..ad5e06b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -49,6 +49,7 @@ pub struct RunningWindow<'window> { gooey: Gooey, focused: Dynamic, occluded: Dynamic, + inner_size: Dynamic>, } impl<'window> RunningWindow<'window> { @@ -57,12 +58,14 @@ impl<'window> RunningWindow<'window> { gooey: &Gooey, focused: &Dynamic, occluded: &Dynamic, + inner_size: &Dynamic>, ) -> Self { Self { window, gooey: gooey.clone(), focused: focused.clone(), occluded: occluded.clone(), + inner_size: inner_size.clone(), } } @@ -80,6 +83,13 @@ impl<'window> RunningWindow<'window> { &self.occluded } + /// Returns a dynamic that is updated whenever this window's inner size + /// changes. + #[must_use] + pub const fn inner_size(&self) -> &Dynamic> { + &self.inner_size + } + /// Returns a locked mutex guard to the OS's clipboard, if one was able to be /// initialized when the window opened. #[must_use] @@ -139,6 +149,7 @@ where /// during drawing operations. pub font_data_to_load: Vec>, + inner_size: Option>>, occluded: Option>, focused: Option>, theme_mode: Option>, @@ -194,6 +205,17 @@ impl Window { self } + /// Sets `inner_size` to be the dynamic updated when this window's inner size + /// is changed. + /// + /// When the window is resized, the dynamic will contain its new size. + /// `true`. + pub fn inner_size(mut self, inner_size: impl IntoDynamic>) -> Self { + let inner_size = inner_size.into_dynamic(); + self.inner_size = Some(inner_size); + self + } + /// Sets the [`ThemeMode`] for this window. /// /// If a [`ThemeMode`] is provided, the window will be set to this theme @@ -262,6 +284,7 @@ where occluded: None, focused: None, theme_mode: None, + inner_size: None, serif_font_family: FontFamilyList::default(), sans_serif_font_family: FontFamilyList::default(), fantasy_font_family: FontFamilyList::default(), @@ -289,6 +312,7 @@ where attributes: Some(self.attributes), occluded: self.occluded, focused: self.focused, + inner_size: self.inner_size, theme: Some(self.theme), theme_mode: self.theme_mode, font_data_to_load: self.font_data_to_load, @@ -346,6 +370,7 @@ struct GooeyWindow { initial_frame: bool, occluded: Dynamic, focused: Dynamic, + inner_size: Dynamic>, keyboard_activated: Option, min_inner_size: Option>, max_inner_size: Option>, @@ -548,6 +573,7 @@ where let gooey = settings.gooey.clone(); let occluded = settings.occluded.take().unwrap_or_default(); let focused = settings.focused.take().unwrap_or_default(); + let inner_size = settings.inner_size.take().unwrap_or_default(); let theme = settings.theme.take().expect("theme always present"); let fontdb = graphics.font_system().db_mut(); @@ -616,7 +642,7 @@ where }; let transparent = settings.transparent; let mut behavior = T::initialize( - &mut RunningWindow::new(window, &gooey, &focused, &occluded), + &mut RunningWindow::new(window, &gooey, &focused, &occluded, &inner_size), context.user, ); let root = Tree::default().push_boxed(behavior.make_root(), None); @@ -640,6 +666,7 @@ where initial_frame: true, occluded, focused, + inner_size, keyboard_activated: None, min_inner_size: None, max_inner_size: None, @@ -671,7 +698,7 @@ where .new_frame(self.redraw_status.invalidations().drain()); let resizable = window.winit().is_resizable(); - let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded); + let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size); let root_mode = self.constrain_window_resizing(resizable, &mut window, graphics); self.fonts.next_frame(); @@ -798,7 +825,7 @@ where Self::request_close( &mut self.should_close, &mut self.behavior, - &mut RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded), + &mut RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size), ) } @@ -834,9 +861,10 @@ where fn resized( &mut self, - _window: kludgine::app::Window<'_, WindowCommand>, + window: kludgine::app::Window<'_, WindowCommand>, _kludgine: &mut Kludgine, ) { + self.inner_size.set(window.inner_size()); self.root.invalidate(); } @@ -862,7 +890,7 @@ where let Some(target) = self.root.tree.widget_from_node(target) else { return; }; - let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded); + let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size); let mut target = EventContext::new( WidgetContext::new( target, @@ -972,7 +1000,7 @@ where .expect("missing widget") }); - let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded); + let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size); let mut widget = EventContext::new( WidgetContext::new( widget, @@ -1008,7 +1036,7 @@ where .widget(self.root.id()) .expect("missing widget") }); - let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded); + let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size); let mut target = EventContext::new( WidgetContext::new( widget, @@ -1035,7 +1063,7 @@ where let location = Point::::from(position); self.cursor.location = Some(location); - let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded); + let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size); EventContext::new( WidgetContext::new( @@ -1082,7 +1110,7 @@ where _device_id: DeviceId, ) { if self.cursor.widget.take().is_some() { - let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded); + let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size); let mut context = EventContext::new( WidgetContext::new( self.root.clone(), @@ -1106,7 +1134,7 @@ where state: ElementState, button: MouseButton, ) { - let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded); + let mut window = RunningWindow::new(window, &self.gooey, &self.focused, &self.occluded, &self.inner_size); match state { ElementState::Pressed => { EventContext::new( @@ -1238,6 +1266,9 @@ pub(crate) struct CursorState { pub(crate) mod sealed { use std::cell::RefCell; + use kludgine::figures::Size; + use kludgine::figures::units::UPx; + use crate::styles::{FontFamilyList, ThemePair}; use crate::value::{Dynamic, Value}; use crate::window::{ThemeMode, WindowAttributes}; @@ -1253,6 +1284,7 @@ pub(crate) mod sealed { pub attributes: Option, pub occluded: Option>, pub focused: Option>, + pub inner_size: Option>>, pub theme: Option>, pub theme_mode: Option>, pub transparent: bool,