From d2e4f06df7f271190305ccf74f581f325943e82e Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Sun, 27 Oct 2024 12:02:58 -0500 Subject: [PATCH 01/12] Allow for percent in ternary --- internal/compiler/langtype.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/compiler/langtype.rs b/internal/compiler/langtype.rs index 58a940ffb86..eff720fae36 100644 --- a/internal/compiler/langtype.rs +++ b/internal/compiler/langtype.rs @@ -284,6 +284,7 @@ impl Type { | (Type::Rem, Type::PhysicalLength) | (Type::LogicalLength, Type::Rem) | (Type::PhysicalLength, Type::Rem) + | (Type::Percent, Type::LogicalLength) | (Type::Percent, Type::Float32) | (Type::Brush, Type::Color) | (Type::Color, Type::Brush) => true, From 7b9b57b86d8f722d82dfadbf35838b5f61dc1af4 Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Mon, 28 Oct 2024 10:10:34 -0500 Subject: [PATCH 02/12] Added window button styles --- internal/backends/winit/winitwindowadapter.rs | 22 +++++++++++++++- internal/core/api.rs | 11 +++++++- internal/core/items.rs | 2 +- internal/core/window.rs | 26 +++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index 19b56c6f91b..d56a252628f 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -10,6 +10,7 @@ use core::pin::Pin; use std::rc::Rc; use std::rc::Weak; +use i_slint_core::window::WindowStyle; #[cfg(target_arch = "wasm32")] use winit::platform::web::WindowExtWebSys; #[cfg(target_family = "windows")] @@ -39,7 +40,7 @@ use i_slint_core::{self as corelib, OpenGLAPI}; use once_cell::unsync::OnceCell; #[cfg(enable_accesskit)] use winit::event_loop::EventLoopProxy; -use winit::window::WindowAttributes; +use winit::window::{WindowAttributes, WindowButtons}; fn position_to_winit(pos: &corelib::api::WindowPosition) -> winit::dpi::Position { match pos { @@ -195,6 +196,23 @@ impl WinitWindowOrNone { } } + fn set_window_style(&self, window_style: WindowStyle) { + match self { + Self::HasWindow(window) => match window_style { + WindowStyle::None => window.set_enabled_buttons(WindowButtons::empty()), + WindowStyle::SingleBorderWindow => window.set_enabled_buttons( + WindowButtons::CLOSE | WindowButtons::MINIMIZE | WindowButtons::MAXIMIZE, + ), + WindowStyle::ToolWindow => { + window.set_enabled_buttons(WindowButtons::CLOSE); + } + }, + Self::None(attributes) => { + attributes.borrow_mut().enabled_buttons = WindowButtons::all() + } + } + } + fn set_minimized(&self, minimized: bool) { match self { Self::HasWindow(window) => window.set_minimized(minimized), @@ -764,6 +782,8 @@ impl WindowAdapter for WinitWindowAdapter { winit_window_or_none.set_window_level(new_window_level); } + winit_window_or_none.set_window_style(properties.window_style()); + // Use our scale factor instead of winit's logical size to take a scale factor override into account. let sf = self.window().scale_factor(); diff --git a/internal/core/api.rs b/internal/core/api.rs index 1cf79f6b43c..85e7bc30dee 100644 --- a/internal/core/api.rs +++ b/internal/core/api.rs @@ -12,7 +12,7 @@ pub use crate::future::*; use crate::graphics::{Rgba8Pixel, SharedPixelBuffer}; use crate::input::{KeyEventType, MouseEvent}; use crate::item_tree::ItemTreeVTable; -use crate::window::{WindowAdapter, WindowInner}; +use crate::window::{WindowAdapter, WindowInner, WindowStyle as WindowStyleInner}; #[cfg(not(feature = "std"))] use alloc::boxed::Box; #[cfg(not(feature = "std"))] @@ -429,6 +429,10 @@ impl raw_window_handle_06::HasDisplayHandle for WindowHandle { #[repr(transparent)] pub struct Window(pub(crate) WindowInner); +/// This enum describes the different window styles that can be set on a window. +/// The window style is a hint to the windowing system how the window should be displayed. +pub type WindowStyle = WindowStyleInner; + /// This enum describes whether a Window is allowed to be hidden when the user tries to close the window. /// It is the return type of the callback provided to [Window::on_close_requested]. #[derive(Copy, Clone, Debug, PartialEq, Default)] @@ -567,6 +571,11 @@ impl Window { self.0.set_maximized(maximized); } + /// Sets the window style for the window. + pub fn set_window_style(&self, window_style: WindowStyle) { + self.0.set_window_style(window_style); + } + /// Returns if the window is currently minimized pub fn is_minimized(&self) -> bool { self.0.is_minimized() diff --git a/internal/core/items.rs b/internal/core/items.rs index 21b16cc4233..82ce1e90d80 100644 --- a/internal/core/items.rs +++ b/internal/core/items.rs @@ -264,7 +264,7 @@ impl Item for Rectangle { _orientation: Orientation, _window_adapter: &Rc, ) -> LayoutInfo { - LayoutInfo { stretch: 1., ..LayoutInfo::default() } + LayoutInfo { stretch: 1., min: 250.0, ..LayoutInfo::default() } } fn input_event_filter_before_children( diff --git a/internal/core/window.rs b/internal/core/window.rs index b7c04201f8d..dd909a2f63c 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -343,6 +343,11 @@ impl<'a> WindowProperties<'a> { pub fn is_minimized(&self) -> bool { self.0.minimized.get() } + + /// The widow style + pub fn window_style(&self) -> WindowStyle { + self.0.window_style.get() + } } struct WindowPropertiesTracker { @@ -406,6 +411,18 @@ struct WindowPinnedFields { text_input_focused: Property, } +/// The style of the window. +/// Values taken from Microsoft's [Window.WindowStyle](https://learn.microsoft.com/en-us/dotnet/api/system.windows.window.windowstyle?view=windowsdesktop-8.0). +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum WindowStyle { + /// Only the client area is visible - the title bar and border are not shown. + None, + /// A window with a single border. This is the default value. + SingleBorderWindow, + /// A fixed tool window. + ToolWindow, +} + /// Inner datastructure for the [`crate::api::Window`] pub struct WindowInner { window_adapter_weak: Weak, @@ -431,6 +448,8 @@ pub struct WindowInner { maximized: Cell, minimized: Cell, + window_style: Cell, + active_popup: RefCell>, had_popup_on_press: Cell, close_requested: Callback<(), CloseRequestResponse>, @@ -489,6 +508,7 @@ impl WindowInner { fullscreen: Cell::new(false), maximized: Cell::new(false), minimized: Cell::new(false), + window_style: Cell::new(WindowStyle::SingleBorderWindow), focus_item: Default::default(), last_ime_text: Default::default(), cursor_blinker: Default::default(), @@ -1166,6 +1186,12 @@ impl WindowInner { self.update_window_properties() } + /// Set the window style + pub fn set_window_style(&self, window_style: WindowStyle) { + self.window_style.set(window_style); + self.update_window_properties() + } + /// Returns if the window is currently minimized pub fn is_minimized(&self) -> bool { self.minimized.get() From 99d8cda241f2ff8e6b34d9b77513e2e34f4141bc Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Mon, 28 Oct 2024 10:28:26 -0500 Subject: [PATCH 03/12] removed some changes --- internal/compiler/langtype.rs | 1 - internal/core/items.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/compiler/langtype.rs b/internal/compiler/langtype.rs index eff720fae36..58a940ffb86 100644 --- a/internal/compiler/langtype.rs +++ b/internal/compiler/langtype.rs @@ -284,7 +284,6 @@ impl Type { | (Type::Rem, Type::PhysicalLength) | (Type::LogicalLength, Type::Rem) | (Type::PhysicalLength, Type::Rem) - | (Type::Percent, Type::LogicalLength) | (Type::Percent, Type::Float32) | (Type::Brush, Type::Color) | (Type::Color, Type::Brush) => true, diff --git a/internal/core/items.rs b/internal/core/items.rs index 82ce1e90d80..21b16cc4233 100644 --- a/internal/core/items.rs +++ b/internal/core/items.rs @@ -264,7 +264,7 @@ impl Item for Rectangle { _orientation: Orientation, _window_adapter: &Rc, ) -> LayoutInfo { - LayoutInfo { stretch: 1., min: 250.0, ..LayoutInfo::default() } + LayoutInfo { stretch: 1., ..LayoutInfo::default() } } fn input_event_filter_before_children( From 6467fb30fa2475591e6b8ca783b0a29302d755be Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Mon, 28 Oct 2024 11:34:21 -0500 Subject: [PATCH 04/12] renamed functions --- internal/backends/winit/winitwindowadapter.rs | 13 ++++++------- internal/core/api.rs | 8 ++++---- internal/core/window.rs | 16 ++++++++-------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index d56a252628f..f7e53670fd1 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -10,7 +10,7 @@ use core::pin::Pin; use std::rc::Rc; use std::rc::Weak; -use i_slint_core::window::WindowStyle; +use i_slint_core::window::WindowButtonStyle; #[cfg(target_arch = "wasm32")] use winit::platform::web::WindowExtWebSys; #[cfg(target_family = "windows")] @@ -196,14 +196,14 @@ impl WinitWindowOrNone { } } - fn set_window_style(&self, window_style: WindowStyle) { + fn set_window_button_style(&self, window_style: WindowButtonStyle) { match self { Self::HasWindow(window) => match window_style { - WindowStyle::None => window.set_enabled_buttons(WindowButtons::empty()), - WindowStyle::SingleBorderWindow => window.set_enabled_buttons( + WindowButtonStyle::None => window.set_enabled_buttons(WindowButtons::empty()), + WindowButtonStyle::SingleBorderWindow => window.set_enabled_buttons( WindowButtons::CLOSE | WindowButtons::MINIMIZE | WindowButtons::MAXIMIZE, ), - WindowStyle::ToolWindow => { + WindowButtonStyle::ToolWindow => { window.set_enabled_buttons(WindowButtons::CLOSE); } }, @@ -768,6 +768,7 @@ impl WindowAdapter for WinitWindowAdapter { winit_window_or_none.set_window_icon(icon_to_winit(window_item.icon())); winit_window_or_none.set_title(&properties.title()); + winit_window_or_none.set_window_button_style(properties.window_style()); winit_window_or_none.set_decorations( !window_item.no_frame() || winit_window_or_none.fullscreen().is_some(), ); @@ -782,8 +783,6 @@ impl WindowAdapter for WinitWindowAdapter { winit_window_or_none.set_window_level(new_window_level); } - winit_window_or_none.set_window_style(properties.window_style()); - // Use our scale factor instead of winit's logical size to take a scale factor override into account. let sf = self.window().scale_factor(); diff --git a/internal/core/api.rs b/internal/core/api.rs index 85e7bc30dee..4c8e32c6d99 100644 --- a/internal/core/api.rs +++ b/internal/core/api.rs @@ -12,7 +12,7 @@ pub use crate::future::*; use crate::graphics::{Rgba8Pixel, SharedPixelBuffer}; use crate::input::{KeyEventType, MouseEvent}; use crate::item_tree::ItemTreeVTable; -use crate::window::{WindowAdapter, WindowInner, WindowStyle as WindowStyleInner}; +use crate::window::{WindowAdapter, WindowButtonStyle as WindowButtonStyleInner, WindowInner}; #[cfg(not(feature = "std"))] use alloc::boxed::Box; #[cfg(not(feature = "std"))] @@ -431,7 +431,7 @@ pub struct Window(pub(crate) WindowInner); /// This enum describes the different window styles that can be set on a window. /// The window style is a hint to the windowing system how the window should be displayed. -pub type WindowStyle = WindowStyleInner; +pub type WindowButtonStyle = WindowButtonStyleInner; /// This enum describes whether a Window is allowed to be hidden when the user tries to close the window. /// It is the return type of the callback provided to [Window::on_close_requested]. @@ -572,8 +572,8 @@ impl Window { } /// Sets the window style for the window. - pub fn set_window_style(&self, window_style: WindowStyle) { - self.0.set_window_style(window_style); + pub fn set_window_button_style(&self, window_button_style: WindowButtonStyle) { + self.0.set_window_button_style(window_button_style); } /// Returns if the window is currently minimized diff --git a/internal/core/window.rs b/internal/core/window.rs index dd909a2f63c..93a13c57490 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -345,8 +345,8 @@ impl<'a> WindowProperties<'a> { } /// The widow style - pub fn window_style(&self) -> WindowStyle { - self.0.window_style.get() + pub fn window_style(&self) -> WindowButtonStyle { + self.0.window_button_style.get() } } @@ -414,8 +414,8 @@ struct WindowPinnedFields { /// The style of the window. /// Values taken from Microsoft's [Window.WindowStyle](https://learn.microsoft.com/en-us/dotnet/api/system.windows.window.windowstyle?view=windowsdesktop-8.0). #[derive(Debug, Copy, Clone, PartialEq)] -pub enum WindowStyle { - /// Only the client area is visible - the title bar and border are not shown. +pub enum WindowButtonStyle { + /// No buttons are available. None, /// A window with a single border. This is the default value. SingleBorderWindow, @@ -448,7 +448,7 @@ pub struct WindowInner { maximized: Cell, minimized: Cell, - window_style: Cell, + window_button_style: Cell, active_popup: RefCell>, had_popup_on_press: Cell, @@ -508,7 +508,7 @@ impl WindowInner { fullscreen: Cell::new(false), maximized: Cell::new(false), minimized: Cell::new(false), - window_style: Cell::new(WindowStyle::SingleBorderWindow), + window_button_style: Cell::new(WindowButtonStyle::SingleBorderWindow), focus_item: Default::default(), last_ime_text: Default::default(), cursor_blinker: Default::default(), @@ -1187,8 +1187,8 @@ impl WindowInner { } /// Set the window style - pub fn set_window_style(&self, window_style: WindowStyle) { - self.window_style.set(window_style); + pub fn set_window_button_style(&self, window_button_style: WindowButtonStyle) { + self.window_button_style.set(window_button_style); self.update_window_properties() } From 6909d43e3f1ae5544791e82329e24834c17d4abd Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Mon, 28 Oct 2024 11:38:18 -0500 Subject: [PATCH 05/12] orginization --- internal/backends/winit/winitwindowadapter.rs | 3 +-- internal/core/api.rs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index f7e53670fd1..a53e819f1ef 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -10,7 +10,6 @@ use core::pin::Pin; use std::rc::Rc; use std::rc::Weak; -use i_slint_core::window::WindowButtonStyle; #[cfg(target_arch = "wasm32")] use winit::platform::web::WindowExtWebSys; #[cfg(target_family = "windows")] @@ -36,7 +35,7 @@ use corelib::platform::{PlatformError, WindowEvent}; use corelib::window::{WindowAdapter, WindowAdapterInternal, WindowInner}; use corelib::Property; use corelib::{graphics::*, Coord}; -use i_slint_core::{self as corelib, OpenGLAPI}; +use i_slint_core::{self as corelib, window::WindowButtonStyle, OpenGLAPI}; use once_cell::unsync::OnceCell; #[cfg(enable_accesskit)] use winit::event_loop::EventLoopProxy; diff --git a/internal/core/api.rs b/internal/core/api.rs index 4c8e32c6d99..d4828a4ca7b 100644 --- a/internal/core/api.rs +++ b/internal/core/api.rs @@ -429,8 +429,8 @@ impl raw_window_handle_06::HasDisplayHandle for WindowHandle { #[repr(transparent)] pub struct Window(pub(crate) WindowInner); -/// This enum describes the different window styles that can be set on a window. -/// The window style is a hint to the windowing system how the window should be displayed. +/// This enum describes the different window button styles that can be set on a window. +/// The window style is a hint to the windowing system how the window buttons should be displayed. pub type WindowButtonStyle = WindowButtonStyleInner; /// This enum describes whether a Window is allowed to be hidden when the user tries to close the window. From 609bae2f10c60edbc0767a00c2bb0ad28c49a59d Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Mon, 28 Oct 2024 11:45:25 -0500 Subject: [PATCH 06/12] modified how it works --- internal/backends/winit/winitwindowadapter.rs | 19 ++++++++++++++-- internal/core/window.rs | 22 ++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index a53e819f1ef..8b22d588ca2 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -199,12 +199,27 @@ impl WinitWindowOrNone { match self { Self::HasWindow(window) => match window_style { WindowButtonStyle::None => window.set_enabled_buttons(WindowButtons::empty()), - WindowButtonStyle::SingleBorderWindow => window.set_enabled_buttons( + WindowButtonStyle::Full => window.set_enabled_buttons( WindowButtons::CLOSE | WindowButtons::MINIMIZE | WindowButtons::MAXIMIZE, ), - WindowButtonStyle::ToolWindow => { + WindowButtonStyle::Close => { window.set_enabled_buttons(WindowButtons::CLOSE); } + WindowButtonStyle::Minimize => { + window.set_enabled_buttons(WindowButtons::MINIMIZE); + } + WindowButtonStyle::Maximize => { + window.set_enabled_buttons(WindowButtons::MAXIMIZE); + } + WindowButtonStyle::MaximizeClose => { + window.set_enabled_buttons(WindowButtons::MAXIMIZE | WindowButtons::CLOSE); + } + WindowButtonStyle::MinimizeClose => { + window.set_enabled_buttons(WindowButtons::MINIMIZE | WindowButtons::CLOSE); + } + WindowButtonStyle::MinimizeMaximize => { + window.set_enabled_buttons(WindowButtons::MINIMIZE | WindowButtons::MAXIMIZE); + } }, Self::None(attributes) => { attributes.borrow_mut().enabled_buttons = WindowButtons::all() diff --git a/internal/core/window.rs b/internal/core/window.rs index 93a13c57490..5e6fc52b67e 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -415,12 +415,22 @@ struct WindowPinnedFields { /// Values taken from Microsoft's [Window.WindowStyle](https://learn.microsoft.com/en-us/dotnet/api/system.windows.window.windowstyle?view=windowsdesktop-8.0). #[derive(Debug, Copy, Clone, PartialEq)] pub enum WindowButtonStyle { - /// No buttons are available. + /// A window with no buttons. None, - /// A window with a single border. This is the default value. - SingleBorderWindow, - /// A fixed tool window. - ToolWindow, + /// A window with all buttons. + Full, + /// A window with only a close button. + Close, + /// A window with only a minimize button. + Minimize, + /// A window with only a maximize button. + Maximize, + /// A window with only a minimize and close button. + MinimizeClose, + /// A window with only a maximize and close button. + MaximizeClose, + /// A window with only a minimize and maximize button. + MinimizeMaximize, } /// Inner datastructure for the [`crate::api::Window`] @@ -508,7 +518,7 @@ impl WindowInner { fullscreen: Cell::new(false), maximized: Cell::new(false), minimized: Cell::new(false), - window_button_style: Cell::new(WindowButtonStyle::SingleBorderWindow), + window_button_style: Cell::new(WindowButtonStyle::Full), focus_item: Default::default(), last_ime_text: Default::default(), cursor_blinker: Default::default(), From 6525654690a4f0def0a4de1ea34d77c13fc15c06 Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Mon, 28 Oct 2024 11:49:20 -0500 Subject: [PATCH 07/12] modified how it works --- internal/backends/winit/winitwindowadapter.rs | 2 +- internal/core/window.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index 8b22d588ca2..9e72c578291 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -199,7 +199,7 @@ impl WinitWindowOrNone { match self { Self::HasWindow(window) => match window_style { WindowButtonStyle::None => window.set_enabled_buttons(WindowButtons::empty()), - WindowButtonStyle::Full => window.set_enabled_buttons( + WindowButtonStyle::All => window.set_enabled_buttons( WindowButtons::CLOSE | WindowButtons::MINIMIZE | WindowButtons::MAXIMIZE, ), WindowButtonStyle::Close => { diff --git a/internal/core/window.rs b/internal/core/window.rs index 5e6fc52b67e..303e24e28a3 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -418,7 +418,7 @@ pub enum WindowButtonStyle { /// A window with no buttons. None, /// A window with all buttons. - Full, + All, /// A window with only a close button. Close, /// A window with only a minimize button. @@ -518,7 +518,7 @@ impl WindowInner { fullscreen: Cell::new(false), maximized: Cell::new(false), minimized: Cell::new(false), - window_button_style: Cell::new(WindowButtonStyle::Full), + window_button_style: Cell::new(WindowButtonStyle::All), focus_item: Default::default(), last_ime_text: Default::default(), cursor_blinker: Default::default(), From 65cbdbcccf7af71027f343b89ac760ad622f4bd6 Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Mon, 28 Oct 2024 11:51:04 -0500 Subject: [PATCH 08/12] modified how it works --- internal/core/window.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/core/window.rs b/internal/core/window.rs index 303e24e28a3..79099eade4e 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -412,7 +412,6 @@ struct WindowPinnedFields { } /// The style of the window. -/// Values taken from Microsoft's [Window.WindowStyle](https://learn.microsoft.com/en-us/dotnet/api/system.windows.window.windowstyle?view=windowsdesktop-8.0). #[derive(Debug, Copy, Clone, PartialEq)] pub enum WindowButtonStyle { /// A window with no buttons. From feac7dcc6763faca495894c78ac8f823f5cbfcdb Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Wed, 30 Oct 2024 09:05:17 -0500 Subject: [PATCH 09/12] Updated the windows buttons implementation --- internal/backends/winit/winitwindowadapter.rs | 38 +++++------- internal/core/api.rs | 10 ++-- internal/core/window.rs | 58 +++++++++++-------- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index 9e72c578291..f18f94a5829 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -10,6 +10,7 @@ use core::pin::Pin; use std::rc::Rc; use std::rc::Weak; +use i_slint_core::window::WindowButtonState; #[cfg(target_arch = "wasm32")] use winit::platform::web::WindowExtWebSys; #[cfg(target_family = "windows")] @@ -35,7 +36,7 @@ use corelib::platform::{PlatformError, WindowEvent}; use corelib::window::{WindowAdapter, WindowAdapterInternal, WindowInner}; use corelib::Property; use corelib::{graphics::*, Coord}; -use i_slint_core::{self as corelib, window::WindowButtonStyle, OpenGLAPI}; +use i_slint_core::{self as corelib, OpenGLAPI}; use once_cell::unsync::OnceCell; #[cfg(enable_accesskit)] use winit::event_loop::EventLoopProxy; @@ -195,32 +196,21 @@ impl WinitWindowOrNone { } } - fn set_window_button_style(&self, window_style: WindowButtonStyle) { + fn set_window_buttons_state(&self, window_buttons_state: WindowButtonState) { match self { - Self::HasWindow(window) => match window_style { - WindowButtonStyle::None => window.set_enabled_buttons(WindowButtons::empty()), - WindowButtonStyle::All => window.set_enabled_buttons( - WindowButtons::CLOSE | WindowButtons::MINIMIZE | WindowButtons::MAXIMIZE, - ), - WindowButtonStyle::Close => { - window.set_enabled_buttons(WindowButtons::CLOSE); - } - WindowButtonStyle::Minimize => { - window.set_enabled_buttons(WindowButtons::MINIMIZE); - } - WindowButtonStyle::Maximize => { - window.set_enabled_buttons(WindowButtons::MAXIMIZE); - } - WindowButtonStyle::MaximizeClose => { - window.set_enabled_buttons(WindowButtons::MAXIMIZE | WindowButtons::CLOSE); + Self::HasWindow(window) => { + let mut enabled_buttons = WindowButtons::empty(); + if window_buttons_state.minimize { + enabled_buttons |= WindowButtons::MINIMIZE; } - WindowButtonStyle::MinimizeClose => { - window.set_enabled_buttons(WindowButtons::MINIMIZE | WindowButtons::CLOSE); + if window_buttons_state.maximize { + enabled_buttons |= WindowButtons::MAXIMIZE; } - WindowButtonStyle::MinimizeMaximize => { - window.set_enabled_buttons(WindowButtons::MINIMIZE | WindowButtons::MAXIMIZE); + if window_buttons_state.close { + enabled_buttons |= WindowButtons::CLOSE; } - }, + window.set_enabled_buttons(enabled_buttons); + } Self::None(attributes) => { attributes.borrow_mut().enabled_buttons = WindowButtons::all() } @@ -782,7 +772,7 @@ impl WindowAdapter for WinitWindowAdapter { winit_window_or_none.set_window_icon(icon_to_winit(window_item.icon())); winit_window_or_none.set_title(&properties.title()); - winit_window_or_none.set_window_button_style(properties.window_style()); + winit_window_or_none.set_window_buttons_state(properties.window_buttons_enabled()); winit_window_or_none.set_decorations( !window_item.no_frame() || winit_window_or_none.fullscreen().is_some(), ); diff --git a/internal/core/api.rs b/internal/core/api.rs index d4828a4ca7b..435f5769402 100644 --- a/internal/core/api.rs +++ b/internal/core/api.rs @@ -12,7 +12,7 @@ pub use crate::future::*; use crate::graphics::{Rgba8Pixel, SharedPixelBuffer}; use crate::input::{KeyEventType, MouseEvent}; use crate::item_tree::ItemTreeVTable; -use crate::window::{WindowAdapter, WindowButtonStyle as WindowButtonStyleInner, WindowInner}; +use crate::window::{WindowAdapter, WindowButton as WindowButtonInner, WindowInner}; #[cfg(not(feature = "std"))] use alloc::boxed::Box; #[cfg(not(feature = "std"))] @@ -431,7 +431,7 @@ pub struct Window(pub(crate) WindowInner); /// This enum describes the different window button styles that can be set on a window. /// The window style is a hint to the windowing system how the window buttons should be displayed. -pub type WindowButtonStyle = WindowButtonStyleInner; +pub type WindowButton = WindowButtonInner; /// This enum describes whether a Window is allowed to be hidden when the user tries to close the window. /// It is the return type of the callback provided to [Window::on_close_requested]. @@ -571,9 +571,9 @@ impl Window { self.0.set_maximized(maximized); } - /// Sets the window style for the window. - pub fn set_window_button_style(&self, window_button_style: WindowButtonStyle) { - self.0.set_window_button_style(window_button_style); + /// Enable or disable a particular window button. + pub fn set_window_button_enabled(&self, window_button: WindowButton, enabled: bool) { + self.0.set_window_button_enabled(window_button, enabled); } /// Returns if the window is currently minimized diff --git a/internal/core/window.rs b/internal/core/window.rs index 79099eade4e..4d6c33f8fa6 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -345,8 +345,9 @@ impl<'a> WindowProperties<'a> { } /// The widow style - pub fn window_style(&self) -> WindowButtonStyle { - self.0.window_button_style.get() + /// Returns a tuple of three booleans: (minimize, maximize, close) + pub fn window_buttons_enabled(&self) -> WindowButtonState { + self.0.window_button_state.get() } } @@ -411,25 +412,26 @@ struct WindowPinnedFields { text_input_focused: Property, } -/// The style of the window. +/// A reference to the windows buttons #[derive(Debug, Copy, Clone, PartialEq)] -pub enum WindowButtonStyle { - /// A window with no buttons. - None, - /// A window with all buttons. - All, - /// A window with only a close button. - Close, - /// A window with only a minimize button. +pub enum WindowButton { + /// Refers to the window's minimize button Minimize, - /// A window with only a maximize button. + /// Refers to the window's maximize button Maximize, - /// A window with only a minimize and close button. - MinimizeClose, - /// A window with only a maximize and close button. - MaximizeClose, - /// A window with only a minimize and maximize button. - MinimizeMaximize, + /// Refers to the window's close button + Close, +} + +#[derive(Debug, Copy, Clone, PartialEq)] +/// The state of each window button +pub struct WindowButtonState { + /// The minimize button state + pub minimize: bool, + /// The maximize button state + pub maximize: bool, + /// The close button state + pub close: bool, } /// Inner datastructure for the [`crate::api::Window`] @@ -457,7 +459,7 @@ pub struct WindowInner { maximized: Cell, minimized: Cell, - window_button_style: Cell, + window_button_state: Cell, active_popup: RefCell>, had_popup_on_press: Cell, @@ -517,7 +519,11 @@ impl WindowInner { fullscreen: Cell::new(false), maximized: Cell::new(false), minimized: Cell::new(false), - window_button_style: Cell::new(WindowButtonStyle::All), + window_button_state: Cell::new(WindowButtonState { + minimize: true, + maximize: true, + close: true, + }), focus_item: Default::default(), last_ime_text: Default::default(), cursor_blinker: Default::default(), @@ -1195,9 +1201,15 @@ impl WindowInner { self.update_window_properties() } - /// Set the window style - pub fn set_window_button_style(&self, window_button_style: WindowButtonStyle) { - self.window_button_style.set(window_button_style); + /// Enable or disable a particular window button. + pub fn set_window_button_enabled(&self, window_button: WindowButton, enabled: bool) { + let mut state = self.window_button_state.get(); + match window_button { + WindowButton::Minimize => state.minimize = enabled, + WindowButton::Maximize => state.maximize = enabled, + WindowButton::Close => state.close = enabled, + } + self.window_button_state.set(state); self.update_window_properties() } From 4286819fa90c2f468f4aa74dbe2749b73a7e824c Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Thu, 31 Oct 2024 11:47:13 -0500 Subject: [PATCH 10/12] Removed from api and placed in .slint --- .../src/language/builtins/elements.md | 13 +++++++---- internal/backends/winit/winitwindowadapter.rs | 14 +++++++---- internal/compiler/builtins.slint | 3 +++ internal/core/api.rs | 11 +-------- internal/core/items.rs | 3 +++ internal/core/window.rs | 23 ------------------- 6 files changed, 25 insertions(+), 42 deletions(-) diff --git a/docs/reference/src/language/builtins/elements.md b/docs/reference/src/language/builtins/elements.md index fb4340a24b9..567a7c87e8c 100644 --- a/docs/reference/src/language/builtins/elements.md +++ b/docs/reference/src/language/builtins/elements.md @@ -371,11 +371,11 @@ An `Image` can be used to represent an image loaded from a file. - **`source`** (_in_ _image_): The image to load. Use the [`@image-url("...")` macro](../syntax/types.md#images) to specify the location of the image. - **`source-clip-x`**, **`source-clip-y`**, **`source-clip-width`**, **`source-clip-height`** (_in_ _int_): Properties in source image coordinates that define the region of the source image that is rendered. By default the entire source image is visible: - | Property | Default Binding | - |----------|---------------| - | `source-clip-x` | `0` | - | `source-clip-y` | `0` | - | `source-clip-width` | `source.width - source-clip-x` | + | Property | Default Binding | + | -------------------- | ------------------------------- | + | `source-clip-x` | `0` | + | `source-clip-y` | `0` | + | `source-clip-width` | `source.width - source-clip-x` | | `source-clip-height` | `source.height - source-clip-y` | - **`vertical-alignment`** (_in_ _enum [`ImageVerticalAlignment`](enums.md#imageverticalalignment)_): The vertical alignment of the image within the element. - **`vertical-tiling`** (_in_ _enum [`ImageTiling`](enums.md#imagetiling)_): Whether the image should be tiled on the vertical axis. @@ -1064,3 +1064,6 @@ or smaller. The initial width can be controlled with the `preferred-width` prope - **`no-frame`** (_in_ _bool_): Whether the window should be borderless/frameless or not. - **`resize-border-width`** (_in_ _length_): Size of the resize border in borderless/frameless windows (winit only for now). - **`title`** (_in_ _string_): The window title that is shown in the title bar. +- **`no-minimize-button`** (_in_ _bool_): Whether the window should have a minimize button in the title bar. Default is `false` to show the minimize button. +- **`no-maximize-button`** (_in_ _bool_): Whether the window should have a maximize button in the title bar. Default is `false` to show the maximize button. +- **`no-close-button`** (_in_ _bool_): Whether the window should have a close button in the title bar. Default is `false` to show the close button. diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index f18f94a5829..3119b5b2341 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -200,13 +200,13 @@ impl WinitWindowOrNone { match self { Self::HasWindow(window) => { let mut enabled_buttons = WindowButtons::empty(); - if window_buttons_state.minimize { + if !window_buttons_state.minimize { enabled_buttons |= WindowButtons::MINIMIZE; } - if window_buttons_state.maximize { + if !window_buttons_state.maximize { enabled_buttons |= WindowButtons::MAXIMIZE; } - if window_buttons_state.close { + if !window_buttons_state.close { enabled_buttons |= WindowButtons::CLOSE; } window.set_enabled_buttons(enabled_buttons); @@ -772,7 +772,6 @@ impl WindowAdapter for WinitWindowAdapter { winit_window_or_none.set_window_icon(icon_to_winit(window_item.icon())); winit_window_or_none.set_title(&properties.title()); - winit_window_or_none.set_window_buttons_state(properties.window_buttons_enabled()); winit_window_or_none.set_decorations( !window_item.no_frame() || winit_window_or_none.fullscreen().is_some(), ); @@ -787,6 +786,13 @@ impl WindowAdapter for WinitWindowAdapter { winit_window_or_none.set_window_level(new_window_level); } + // Get the associated window button states + let mut win_props = properties.window_buttons_enabled(); + win_props.close = window_item.no_close_button(); + win_props.minimize = window_item.no_minimize_button(); + win_props.maximize = window_item.no_maximize_button(); + winit_window_or_none.set_window_buttons_state(win_props); + // Use our scale factor instead of winit's logical size to take a scale factor override into account. let sf = self.window().scale_factor(); diff --git a/internal/compiler/builtins.slint b/internal/compiler/builtins.slint index fdec4a5453b..5ecc2e2246e 100644 --- a/internal/compiler/builtins.slint +++ b/internal/compiler/builtins.slint @@ -196,6 +196,9 @@ component WindowItem { in-out property default-font-size; // <=> StyleMetrics.default-font-size set in apply_default_properties_from_style in property default-font-weight; in property icon; + in property no-minimize-button; + in property no-maximize-button; + in property no-close-button; } export component Window inherits WindowItem { } diff --git a/internal/core/api.rs b/internal/core/api.rs index 435f5769402..1cf79f6b43c 100644 --- a/internal/core/api.rs +++ b/internal/core/api.rs @@ -12,7 +12,7 @@ pub use crate::future::*; use crate::graphics::{Rgba8Pixel, SharedPixelBuffer}; use crate::input::{KeyEventType, MouseEvent}; use crate::item_tree::ItemTreeVTable; -use crate::window::{WindowAdapter, WindowButton as WindowButtonInner, WindowInner}; +use crate::window::{WindowAdapter, WindowInner}; #[cfg(not(feature = "std"))] use alloc::boxed::Box; #[cfg(not(feature = "std"))] @@ -429,10 +429,6 @@ impl raw_window_handle_06::HasDisplayHandle for WindowHandle { #[repr(transparent)] pub struct Window(pub(crate) WindowInner); -/// This enum describes the different window button styles that can be set on a window. -/// The window style is a hint to the windowing system how the window buttons should be displayed. -pub type WindowButton = WindowButtonInner; - /// This enum describes whether a Window is allowed to be hidden when the user tries to close the window. /// It is the return type of the callback provided to [Window::on_close_requested]. #[derive(Copy, Clone, Debug, PartialEq, Default)] @@ -571,11 +567,6 @@ impl Window { self.0.set_maximized(maximized); } - /// Enable or disable a particular window button. - pub fn set_window_button_enabled(&self, window_button: WindowButton, enabled: bool) { - self.0.set_window_button_enabled(window_button, enabled); - } - /// Returns if the window is currently minimized pub fn is_minimized(&self) -> bool { self.0.is_minimized() diff --git a/internal/core/items.rs b/internal/core/items.rs index 21b16cc4233..4f93f28a31d 100644 --- a/internal/core/items.rs +++ b/internal/core/items.rs @@ -958,6 +958,9 @@ pub struct WindowItem { pub default_font_size: Property, pub default_font_weight: Property, pub cached_rendering_data: CachedRenderingData, + pub no_minimize_button: Property, + pub no_maximize_button: Property, + pub no_close_button: Property, } impl Item for WindowItem { diff --git a/internal/core/window.rs b/internal/core/window.rs index 4d6c33f8fa6..cfa530a6e49 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -412,17 +412,6 @@ struct WindowPinnedFields { text_input_focused: Property, } -/// A reference to the windows buttons -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum WindowButton { - /// Refers to the window's minimize button - Minimize, - /// Refers to the window's maximize button - Maximize, - /// Refers to the window's close button - Close, -} - #[derive(Debug, Copy, Clone, PartialEq)] /// The state of each window button pub struct WindowButtonState { @@ -1201,18 +1190,6 @@ impl WindowInner { self.update_window_properties() } - /// Enable or disable a particular window button. - pub fn set_window_button_enabled(&self, window_button: WindowButton, enabled: bool) { - let mut state = self.window_button_state.get(); - match window_button { - WindowButton::Minimize => state.minimize = enabled, - WindowButton::Maximize => state.maximize = enabled, - WindowButton::Close => state.close = enabled, - } - self.window_button_state.set(state); - self.update_window_properties() - } - /// Returns if the window is currently minimized pub fn is_minimized(&self) -> bool { self.minimized.get() From 9710748a46ad2e069da48946c60055d5820f9cde Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Thu, 31 Oct 2024 11:49:02 -0500 Subject: [PATCH 11/12] Removed from api and placed in .slint --- docs/reference/src/language/builtins/elements.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/reference/src/language/builtins/elements.md b/docs/reference/src/language/builtins/elements.md index 567a7c87e8c..361a576d9b5 100644 --- a/docs/reference/src/language/builtins/elements.md +++ b/docs/reference/src/language/builtins/elements.md @@ -371,11 +371,11 @@ An `Image` can be used to represent an image loaded from a file. - **`source`** (_in_ _image_): The image to load. Use the [`@image-url("...")` macro](../syntax/types.md#images) to specify the location of the image. - **`source-clip-x`**, **`source-clip-y`**, **`source-clip-width`**, **`source-clip-height`** (_in_ _int_): Properties in source image coordinates that define the region of the source image that is rendered. By default the entire source image is visible: - | Property | Default Binding | - | -------------------- | ------------------------------- | - | `source-clip-x` | `0` | - | `source-clip-y` | `0` | - | `source-clip-width` | `source.width - source-clip-x` | + | Property | Default Binding | + |----------|---------------| + | `source-clip-x` | `0` | + | `source-clip-y` | `0` | + | `source-clip-width` | `source.width - source-clip-x` | | `source-clip-height` | `source.height - source-clip-y` | - **`vertical-alignment`** (_in_ _enum [`ImageVerticalAlignment`](enums.md#imageverticalalignment)_): The vertical alignment of the image within the element. - **`vertical-tiling`** (_in_ _enum [`ImageTiling`](enums.md#imagetiling)_): Whether the image should be tiled on the vertical axis. From 9a818a7596ad4df930d34b0f58496cd6a2a42df5 Mon Sep 17 00:00:00 2001 From: Ryan Naddy Date: Thu, 31 Oct 2024 18:01:07 -0500 Subject: [PATCH 12/12] fixed conflicts --- internal/core/window.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/core/window.rs b/internal/core/window.rs index 7eee322f21b..33d39a0561a 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -448,6 +448,7 @@ pub struct WindowInner { fullscreen: Cell, maximized: Cell, minimized: Cell, + window_button_state: Cell, /// Stack of currently active popups active_popups: RefCell>,