use gpui::{prelude::*, Rgba, WindowAppearance}; use ui::prelude::*; #[derive(IntoElement)]pub struct WindowsWindowControls { button_height: Pixels,} impl WindowsWindowControls { pub fn new(button_height: Pixels) -> Self { Self { button_height } } #[cfg(not(target_os = "windows"))] fn get_font() -> &'static str { "Segoe Fluent Icons" } #[cfg(target_os = "windows")] fn get_font() -> &'static str { use windows::Wdk::System::SystemServices::RtlGetVersion; let mut version = unsafe { std::mem::zeroed() }; let status = unsafe { RtlGetVersion(&mut version) }; if status.is_ok() && version.dwBuildNumber >= 22000 { "Segoe Fluent Icons" } else { "Segoe MDL2 Assets" } }} impl RenderOnce for WindowsWindowControls { fn render(self, window: &mut Window, _: &mut App) -> impl IntoElement { let close_button_hover_color = Rgba { r: 232.0 / 255.0, g: 17.0 / 255.0, b: 32.0 / 255.0, a: 1.0, }; let button_hover_color = match window.appearance() { WindowAppearance::Light | WindowAppearance::VibrantLight => Rgba { r: 0.1, g: 0.1, b: 0.1, a: 0.2, }, WindowAppearance::Dark | WindowAppearance::VibrantDark => Rgba { r: 0.9, g: 0.9, b: 0.9, a: 0.1, }, }; div() .id("windows-window-controls") .font_family(Self::get_font()) .flex() .flex_row() .justify_center() .content_stretch() .max_h(self.button_height) .min_h(self.button_height) .child(WindowsCaptionButton::new( "minimize", WindowsCaptionButtonIcon::Minimize, button_hover_color, )) .child(WindowsCaptionButton::new( "maximize-or-restore", if window.is_maximized() { WindowsCaptionButtonIcon::Restore } else { WindowsCaptionButtonIcon::Maximize }, button_hover_color, )) .child(WindowsCaptionButton::new( "close", WindowsCaptionButtonIcon::Close, close_button_hover_color, )) }} #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]enum WindowsCaptionButtonIcon { Minimize, Restore, Maximize, Close,} #[derive(IntoElement)]struct WindowsCaptionButton { id: ElementId, icon: WindowsCaptionButtonIcon, hover_background_color: Rgba,} impl WindowsCaptionButton { pub fn new( id: impl Into<ElementId>, icon: WindowsCaptionButtonIcon, hover_background_color: Rgba, ) -> Self { Self { id: id.into(), icon, hover_background_color, } }} impl RenderOnce for WindowsCaptionButton { fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement { // todo(windows) report this width to the Windows platform API // NOTE: this is intentionally hard coded. An option to use the 'native' size // could be added when the width is reported to the Windows platform API // as this could change between future Windows versions. let width = px(36.); h_flex() .id(self.id) .justify_center() .content_center() .w(width) .h_full() .text_size(px(10.0)) .hover(|style| style.bg(self.hover_background_color)) .active(|style| { let mut active_color = self.hover_background_color; active_color.a *= 0.2; style.bg(active_color) }) .child(match self.icon { WindowsCaptionButtonIcon::Minimize => "\u{e921}", WindowsCaptionButtonIcon::Restore => "\u{e923}", WindowsCaptionButtonIcon::Maximize => "\u{e922}", WindowsCaptionButtonIcon::Close => "\u{e8bb}", }) }}
use gpui::{prelude::*, Rgba, WindowAppearance};
use ui::prelude::*;
#[derive(IntoElement)]
pub struct WindowsWindowControls {
button_height: Pixels,
}
impl WindowsWindowControls {
pub fn new(button_height: Pixels) -> Self {
Self { button_height }
}
#[cfg(not(target_os = "windows"))]
fn get_font() -> &'static str {
"Segoe Fluent Icons"
}
#[cfg(target_os = "windows")]
fn get_font() -> &'static str {
use windows::Wdk::System::SystemServices::RtlGetVersion;
let mut version = unsafe { std::mem::zeroed() };
let status = unsafe { RtlGetVersion(&mut version) };
if status.is_ok() && version.dwBuildNumber >= 22000 {
"Segoe Fluent Icons"
} else {
"Segoe MDL2 Assets"
}
}
}
impl RenderOnce for WindowsWindowControls {
fn render(self, window: &mut Window, _: &mut App) -> impl IntoElement {
let close_button_hover_color = Rgba {
r: 232.0 / 255.0,
g: 17.0 / 255.0,
b: 32.0 / 255.0,
a: 1.0,
};
let button_hover_color = match window.appearance() {
WindowAppearance::Light | WindowAppearance::VibrantLight => Rgba {
r: 0.1,
g: 0.1,
b: 0.1,
a: 0.2,
},
WindowAppearance::Dark | WindowAppearance::VibrantDark => Rgba {
r: 0.9,
g: 0.9,
b: 0.9,
a: 0.1,
},
};
div()
.id("windows-window-controls")
.font_family(Self::get_font())
.flex()
.flex_row()
.justify_center()
.content_stretch()
.max_h(self.button_height)
.min_h(self.button_height)
.child(WindowsCaptionButton::new(
"minimize",
WindowsCaptionButtonIcon::Minimize,
button_hover_color,
))
.child(WindowsCaptionButton::new(
"maximize-or-restore",
if window.is_maximized() {
WindowsCaptionButtonIcon::Restore
} else {
WindowsCaptionButtonIcon::Maximize
},
button_hover_color,
))
.child(WindowsCaptionButton::new(
"close",
WindowsCaptionButtonIcon::Close,
close_button_hover_color,
))
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
enum WindowsCaptionButtonIcon {
Minimize,
Restore,
Maximize,
Close,
}
#[derive(IntoElement)]
struct WindowsCaptionButton {
id: ElementId,
icon: WindowsCaptionButtonIcon,
hover_background_color: Rgba,
}
impl WindowsCaptionButton {
pub fn new(
id: impl Into<ElementId>,
icon: WindowsCaptionButtonIcon,
hover_background_color: Rgba,
) -> Self {
Self {
id: id.into(),
icon,
hover_background_color,
}
}
}
impl RenderOnce for WindowsCaptionButton {
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
// todo(windows) report this width to the Windows platform API
// NOTE: this is intentionally hard coded. An option to use the 'native' size
// could be added when the width is reported to the Windows platform API
// as this could change between future Windows versions.
let width = px(36.);
h_flex()
.id(self.id)
.justify_center()
.content_center()
.w(width)
.h_full()
.text_size(px(10.0))
.hover(|style| style.bg(self.hover_background_color))
.active(|style| {
let mut active_color = self.hover_background_color;
active_color.a *= 0.2;
style.bg(active_color)
})
.child(match self.icon {
WindowsCaptionButtonIcon::Minimize => "\u{e921}",
WindowsCaptionButtonIcon::Restore => "\u{e923}",
WindowsCaptionButtonIcon::Maximize => "\u{e922}",
WindowsCaptionButtonIcon::Close => "\u{e8bb}",
})
}
}