diff --git a/src/app.rs b/src/app.rs index c30058c4..902c49d9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -118,8 +118,13 @@ impl Application { self } - /// create a new window for the application, if you want multiple windows, - /// just chain more window method to the builder + /// Create a new window for the application, if you want multiple windows, + /// just chain more window method to the builder. + /// + /// # Note + /// + /// Using `None` as a configuration argument is equivalent to using + /// `WindowConfig::default()`. pub fn window( mut self, app_view: impl FnOnce(WindowId) -> V + 'static, @@ -128,7 +133,7 @@ impl Application { self.handle.as_mut().unwrap().new_window( &self.event_loop, Box::new(|window_id| app_view(window_id).into_any()), - config, + config.unwrap_or_default(), ); self } diff --git a/src/app_handle.rs b/src/app_handle.rs index 56c7c2e2..1f0d6ea0 100644 --- a/src/app_handle.rs +++ b/src/app_handle.rs @@ -59,7 +59,7 @@ impl ApplicationHandle { for event in events { match event { AppUpdateEvent::NewWindow { view_fn, config } => { - self.new_window(event_loop, view_fn, config) + self.new_window(event_loop, view_fn, config.unwrap_or_default()) } AppUpdateEvent::CloseWindow { window_id } => { self.close_window(window_id, event_loop); @@ -248,113 +248,107 @@ impl ApplicationHandle { &mut self, event_loop: &EventLoopWindowTarget, view_fn: Box Box>, - config: Option, + #[allow(unused_variables)] WindowConfig { + size, + position, + show_titlebar, + transparent, + fullscreen, + window_icon, + title, + enabled_buttons, + resizable, + undecorated, + window_level, + apply_default_theme, + mac_os_config, + }: WindowConfig, ) { - let mut window_builder = floem_winit::window::WindowBuilder::new(); - let transparent = config.as_ref().and_then(|c| c.transparent).unwrap_or(false); - let apply_default_theme = if let Some(config) = config { - if let Some(size) = config.size { - let size = if size.width == 0.0 || size.height == 0.0 { - Size::new(800.0, 600.0) - } else { - size - }; - window_builder = - window_builder.with_inner_size(LogicalSize::new(size.width, size.height)); - } - if let Some(pos) = config.position { - window_builder = window_builder.with_position(LogicalPosition::new(pos.x, pos.y)); - } - if let Some(show_titlebar) = config.show_titlebar { - #[cfg(target_os = "macos")] - if !show_titlebar { - use floem_winit::platform::macos::WindowBuilderExtMacOS; - window_builder = window_builder - .with_movable(false) - .with_title_hidden(true) - .with_titlebar_transparent(true) - .with_fullsize_content_view(true) - .with_traffic_lights_offset(11.0, 16.0); - } - #[cfg(not(target_os = "macos"))] - if !show_titlebar { - window_builder = window_builder.with_decorations(false); - } + let mut window_builder = floem_winit::window::WindowBuilder::new() + .with_decorations(!undecorated) + .with_transparent(transparent) + .with_fullscreen(fullscreen) + .with_window_level(window_level) + .with_window_icon(window_icon) + .with_resizable(resizable) + .with_enabled_buttons(enabled_buttons) + .with_inner_size(LogicalSize::new(size.width, size.height)); + + if let Some(pos) = position { + window_builder = window_builder.with_position(LogicalPosition::new(pos.x, pos.y)); + } + + if let Some(title) = title { + window_builder = window_builder.with_title(title); + } + + #[cfg(not(target_os = "macos"))] + if !show_titlebar { + window_builder = window_builder.with_decorations(false); + } + + #[cfg(target_os = "macos")] + if !show_titlebar { + use floem_winit::platform::macos::WindowBuilderExtMacOS; + window_builder = window_builder + .with_movable(false) + .with_title_hidden(true) + .with_titlebar_transparent(true) + .with_fullsize_content_view(true) + .with_traffic_lights_offset(11.0, 16.0); + } + + #[cfg(target_os = "macos")] + if undecorated { + use floem_winit::platform::macos::WindowBuilderExtMacOS; + // A palette-style window that will only obtain window focus but + // not actually propagate the first mouse click it receives is + // very unlikely to be expected behavior - these typically are + // used for something that offers a quick choice and are closed + // in a single pointer gesture. + window_builder = window_builder.with_accepts_first_mouse(true); + } + + #[cfg(target_os = "macos")] + if let Some(mac) = mac_os_config { + use floem_winit::platform::macos::WindowBuilderExtMacOS; + if let Some(val) = mac.movable_by_window_background { + window_builder = window_builder.with_movable_by_window_background(val); } - if let Some(undecorated) = config.undecorated { - window_builder = window_builder.with_decorations(!undecorated); - #[cfg(target_os = "macos")] - if undecorated { - use floem_winit::platform::macos::WindowBuilderExtMacOS; - // A palette-style window that will only obtain window focus but - // not actually propagate the first mouse click it receives is - // very unlikely to be expected behavior - these typically are - // used for something that offers a quick choice and are closed - // in a single pointer gesture. - window_builder = window_builder.with_accepts_first_mouse(true); - } + if let Some(val) = mac.titlebar_transparent { + window_builder = window_builder.with_titlebar_transparent(val); } - if let Some(transparent) = config.transparent { - window_builder = window_builder.with_transparent(transparent); + if let Some(val) = mac.titlebar_hidden { + window_builder = window_builder.with_titlebar_hidden(val); } - if let Some(fullscreen) = config.fullscreen { - window_builder = window_builder.with_fullscreen(Some(fullscreen)); + if let Some(val) = mac.full_size_content_view { + window_builder = window_builder.with_fullsize_content_view(val); } - if let Some(window_level) = config.window_level { - window_builder = window_builder.with_window_level(window_level); + if let Some(val) = mac.movable { + window_builder = window_builder.with_movable(val); } - if let Some(title) = config.title { - window_builder = window_builder.with_title(title); + if let Some((x, y)) = mac.traffic_lights_offset { + window_builder = window_builder.with_traffic_lights_offset(x, y); } - if let Some(window_icon) = config.window_icon { - window_builder = window_builder.with_window_icon(Some(window_icon)); + if let Some(val) = mac.accepts_first_mouse { + window_builder = window_builder.with_accepts_first_mouse(val); } - #[cfg(target_os = "macos")] - if let Some(mac) = config.mac_os_config { - use floem_winit::platform::macos::WindowBuilderExtMacOS; - if let Some(val) = mac.movable_by_window_background { - window_builder = window_builder.with_movable_by_window_background(val); - } - if let Some(val) = mac.titlebar_transparent { - window_builder = window_builder.with_titlebar_transparent(val); - } - if let Some(val) = mac.titlebar_hidden { - window_builder = window_builder.with_titlebar_hidden(val); - } - if let Some(val) = mac.full_size_content_view { - window_builder = window_builder.with_fullsize_content_view(val); - } - if let Some(val) = mac.movable { - window_builder = window_builder.with_movable(val); - } - if let Some((x, y)) = mac.traffic_lights_offset { - window_builder = window_builder.with_traffic_lights_offset(x, y); - } - if let Some(val) = mac.accepts_first_mouse { - window_builder = window_builder.with_accepts_first_mouse(val); - } - if let Some(val) = mac.option_as_alt { - window_builder = window_builder.with_option_as_alt(val.into()); - } - if let Some(title) = mac.tabbing_identifier { - window_builder = window_builder.with_tabbing_identifier(title.as_str()); - } - if let Some(disallow_hidpi) = mac.disallow_high_dpi { - window_builder = window_builder.with_disallow_hidpi(disallow_hidpi); - } - if let Some(shadow) = mac.has_shadow { - window_builder = window_builder.with_has_shadow(shadow); - } + if let Some(val) = mac.option_as_alt { + window_builder = window_builder.with_option_as_alt(val.into()); } - config.apply_default_theme.unwrap_or(true) - } else { - true - }; + if let Some(title) = mac.tabbing_identifier { + window_builder = window_builder.with_tabbing_identifier(title.as_str()); + } + if let Some(disallow_hidpi) = mac.disallow_high_dpi { + window_builder = window_builder.with_disallow_hidpi(disallow_hidpi); + } + if let Some(shadow) = mac.has_shadow { + window_builder = window_builder.with_has_shadow(shadow); + } + } - let result = window_builder.build(event_loop); - let window = match result { - Ok(window) => window, - Err(_) => return, + let Ok(window) = window_builder.build(event_loop) else { + return; }; let window_id = window.id(); let window_handle = WindowHandle::new(window, view_fn, transparent, apply_default_theme); diff --git a/src/inspector.rs b/src/inspector.rs index 044b7799..00ae0640 100644 --- a/src/inspector.rs +++ b/src/inspector.rs @@ -967,13 +967,7 @@ pub fn capture(window_id: WindowId) { EventPropagation::Continue }) }, - Some(WindowConfig { - size: Some(Size { - width: 1200.0, - height: 800.0, - }), - ..Default::default() - }), + Some(WindowConfig::default().size((1200.0, 800.0))), ); } diff --git a/src/window.rs b/src/window.rs index 9f9d27e3..5085d862 100644 --- a/src/window.rs +++ b/src/window.rs @@ -10,85 +10,121 @@ use peniko::kurbo::{Point, Size}; use crate::app::{add_app_update_event, AppUpdateEvent}; use crate::view::IntoView; -#[derive(Default, Debug)] +#[derive(Debug)] pub struct WindowConfig { - pub(crate) size: Option, + pub(crate) size: Size, pub(crate) position: Option, - pub(crate) show_titlebar: Option, - pub(crate) transparent: Option, + pub(crate) show_titlebar: bool, + pub(crate) transparent: bool, pub(crate) fullscreen: Option, pub(crate) window_icon: Option, pub(crate) title: Option, - pub(crate) enabled_buttons: Option, - pub(crate) resizable: Option, - pub(crate) undecorated: Option, - pub(crate) window_level: Option, - pub(crate) apply_default_theme: Option, + pub(crate) enabled_buttons: WindowButtons, + pub(crate) resizable: bool, + pub(crate) undecorated: bool, + pub(crate) window_level: WindowLevel, + pub(crate) apply_default_theme: bool, #[allow(dead_code)] pub(crate) mac_os_config: Option, } +impl Default for WindowConfig { + fn default() -> Self { + Self { + size: Size::new(800.0, 600.0), + position: None, + show_titlebar: true, + transparent: false, + fullscreen: None, + window_icon: None, + title: None, + enabled_buttons: WindowButtons::all(), + resizable: true, + undecorated: false, + window_level: WindowLevel::Normal, + apply_default_theme: true, + mac_os_config: None, + } + } +} + impl WindowConfig { + /// Sets new window size. + /// + /// # Panics + /// + /// Panics if either width or height of new size is zero. pub fn size(mut self, size: impl Into) -> Self { - self.size = Some(size.into()); + self.size = size.into(); self } + #[inline] pub fn position(mut self, position: Point) -> Self { self.position = Some(position); self } + #[inline] pub fn show_titlebar(mut self, show_titlebar: bool) -> Self { - self.show_titlebar = Some(show_titlebar); + self.show_titlebar = show_titlebar; self } + #[inline] pub fn undecorated(mut self, undecorated: bool) -> Self { - self.undecorated = Some(undecorated); + self.undecorated = undecorated; self } + #[inline] pub fn with_transparent(mut self, transparent: bool) -> Self { - self.transparent = Some(transparent); + self.transparent = transparent; self } + #[inline] pub fn fullscreen(mut self, fullscreen: Fullscreen) -> Self { self.fullscreen = Some(fullscreen); self } + #[inline] pub fn window_icon(mut self, window_icon: Icon) -> Self { self.window_icon = Some(window_icon); self } + #[inline] pub fn title(mut self, title: impl Into) -> Self { self.title = Some(title.into()); self } + #[inline] pub fn enabled_buttons(mut self, enabled_buttons: WindowButtons) -> Self { - self.enabled_buttons = Some(enabled_buttons); + self.enabled_buttons = enabled_buttons; self } + #[inline] pub fn resizable(mut self, resizable: bool) -> Self { - self.resizable = Some(resizable); + self.resizable = resizable; self } + #[inline] pub fn window_level(mut self, window_level: WindowLevel) -> Self { - self.window_level = Some(window_level); + self.window_level = window_level; self } /// If set to true, the stylesheet for Floem's default theme will be /// injected into your window. You may want to disable this when using a /// completely custom theme. + #[inline] pub fn apply_default_theme(mut self, apply_default_theme: bool) -> Self { - self.apply_default_theme = Some(apply_default_theme); + self.apply_default_theme = apply_default_theme; self }