From 537c66dba8123f5736dd45d36862452b9c25212e Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 31 Dec 2024 22:27:50 +0800 Subject: [PATCH] `WindowConfig`: add `min_size` and `max_size` --- examples/window-size/src/main.rs | 74 +++++++++++--------------------- src/app_handle.rs | 10 +++++ src/window.rs | 18 ++++++++ 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/examples/window-size/src/main.rs b/examples/window-size/src/main.rs index 3e4f58bb..4e62a67c 100644 --- a/examples/window-size/src/main.rs +++ b/examples/window-size/src/main.rs @@ -2,48 +2,24 @@ use floem::{ event::{Event, EventListener}, keyboard::{Key, NamedKey}, kurbo::Size, - views::{button, label, v_stack, Decorators}, - window::{close_window, new_window, WindowConfig, WindowId}, + prelude::{create_signal, SignalGet, SignalUpdate}, + views::{label, v_stack, Decorators}, + window::WindowConfig, Application, IntoView, View, }; -fn sub_window_view(id: WindowId) -> impl IntoView { - v_stack(( - label(move || String::from("Hello world")).style(|s| s.font_size(30.0)), - button("Close this window").action(move || close_window(id)), - )) - .style(|s| { - s.flex_col() - .items_center() - .justify_center() - .width_full() - .height_full() - .column_gap(10.0) - }) -} - fn app_view() -> impl IntoView { - let view = v_stack(( - label(move || String::from("Hello world")).style(|s| s.font_size(30.0)), - button("Open another window").action(|| { - new_window( - sub_window_view, - Some( - WindowConfig::default() - .size(Size::new(600.0, 150.0)) - .title("Window Size Sub Example"), - ), - ); - }), - )) - .style(|s| { - s.flex_col() - .items_center() - .justify_center() - .width_full() - .height_full() - .column_gap(10.0) - }); + let (size, set_size) = create_signal(Size::default()); + + let view = v_stack((label(move || format!("{}", size.get())).style(|s| s.font_size(30.0)),)) + .style(|s| { + s.flex_col() + .items_center() + .justify_center() + .width_full() + .height_full() + .column_gap(10.0) + }); let id = view.id(); view.on_event_stop(EventListener::KeyUp, move |e| { @@ -53,17 +29,19 @@ fn app_view() -> impl IntoView { } } }) + .on_resize(move |r| set_size.update(|value| *value = r.size())) } fn main() { - Application::new() - .window( - |_| app_view(), - Some( - WindowConfig::default() - .size(Size::new(800.0, 250.0)) - .title("Window Size Example"), - ), - ) - .run(); + let app = Application::new().window( + |_| app_view(), + Some( + WindowConfig::default() + .size(Size::new(800.0, 600.0)) + .min_size(Size::new(400.0, 300.0)) + .max_size(Size::new(1200.0, 900.0)) + .title("Window Size Example"), + ), + ); + app.run(); } diff --git a/src/app_handle.rs b/src/app_handle.rs index bc5d9a4f..e79bc9bc 100644 --- a/src/app_handle.rs +++ b/src/app_handle.rs @@ -283,6 +283,8 @@ impl ApplicationHandle { view_fn: Box Box>, #[allow(unused_variables)] WindowConfig { size, + min_size, + max_size, position, show_titlebar, transparent, @@ -301,6 +303,8 @@ impl ApplicationHandle { }: WindowConfig, ) { let logical_size = size.map(|size| LogicalSize::new(size.width, size.height)); + let logical_min_size = min_size.map(|size| LogicalSize::new(size.width, size.height)); + let logical_max_size = max_size.map(|size| LogicalSize::new(size.width, size.height)); let mut window_builder = floem_winit::window::WindowBuilder::new() .with_visible(false) @@ -344,6 +348,12 @@ impl ApplicationHandle { if let Some(logical_size) = logical_size { window_builder = window_builder.with_inner_size(logical_size); } + if let Some(logical_min_size) = logical_min_size { + window_builder = window_builder.with_min_inner_size(logical_min_size); + } + if let Some(logical_max_size) = logical_max_size { + window_builder = window_builder.with_max_inner_size(logical_max_size); + } #[cfg(not(target_os = "macos"))] if !show_titlebar { diff --git a/src/window.rs b/src/window.rs index f8c5fd5a..8799dc5c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -14,6 +14,8 @@ use crate::view::IntoView; #[derive(Debug)] pub struct WindowConfig { pub(crate) size: Option, + pub(crate) min_size: Option, + pub(crate) max_size: Option, pub(crate) position: Option, pub(crate) show_titlebar: bool, pub(crate) transparent: bool, @@ -36,6 +38,8 @@ impl Default for WindowConfig { fn default() -> Self { Self { size: None, + min_size: None, + max_size: None, position: None, show_titlebar: true, transparent: false, @@ -65,6 +69,20 @@ impl WindowConfig { self } + /// Requests the window to be of specific min dimensions. + #[inline] + pub fn min_size(mut self, size: impl Into) -> Self { + self.min_size = Some(size.into()); + self + } + + /// Requests the window to be of specific max dimensions. + #[inline] + pub fn max_size(mut self, size: impl Into) -> Self { + self.max_size = Some(size.into()); + self + } + /// Sets a desired initial position for the window. /// /// If this is not set, some platform-specific position will be chosen.