platform_windows.rs

  1use gpui::{Hsla, Rgba, WindowControlArea, prelude::*};
  2
  3use ui::prelude::*;
  4
  5#[derive(IntoElement)]
  6pub struct WindowsWindowControls {
  7    button_height: Pixels,
  8}
  9
 10impl WindowsWindowControls {
 11    pub fn new(button_height: Pixels) -> Self {
 12        Self { button_height }
 13    }
 14
 15    #[cfg(not(target_os = "windows"))]
 16    fn get_font() -> &'static str {
 17        "Segoe Fluent Icons"
 18    }
 19
 20    #[cfg(target_os = "windows")]
 21    fn get_font() -> &'static str {
 22        use windows::Wdk::System::SystemServices::RtlGetVersion;
 23
 24        let mut version = unsafe { std::mem::zeroed() };
 25        let status = unsafe { RtlGetVersion(&mut version) };
 26
 27        if status.is_ok() && version.dwBuildNumber >= 22000 {
 28            "Segoe Fluent Icons"
 29        } else {
 30            "Segoe MDL2 Assets"
 31        }
 32    }
 33}
 34
 35impl RenderOnce for WindowsWindowControls {
 36    fn render(self, window: &mut Window, _: &mut App) -> impl IntoElement {
 37        div()
 38            .id("windows-window-controls")
 39            .font_family(Self::get_font())
 40            .flex()
 41            .flex_row()
 42            .justify_center()
 43            .content_stretch()
 44            .max_h(self.button_height)
 45            .min_h(self.button_height)
 46            .child(WindowsCaptionButton::Minimize)
 47            .map(|this| {
 48                this.child(if window.is_maximized() {
 49                    WindowsCaptionButton::Restore
 50                } else {
 51                    WindowsCaptionButton::Maximize
 52                })
 53            })
 54            .child(WindowsCaptionButton::Close)
 55    }
 56}
 57
 58#[derive(IntoElement)]
 59enum WindowsCaptionButton {
 60    Minimize,
 61    Restore,
 62    Maximize,
 63    Close,
 64}
 65
 66impl WindowsCaptionButton {
 67    #[inline]
 68    fn id(&self) -> &'static str {
 69        match self {
 70            Self::Minimize => "minimize",
 71            Self::Restore => "restore",
 72            Self::Maximize => "maximize",
 73            Self::Close => "close",
 74        }
 75    }
 76
 77    #[inline]
 78    fn icon(&self) -> &'static str {
 79        match self {
 80            Self::Minimize => "\u{e921}",
 81            Self::Restore => "\u{e923}",
 82            Self::Maximize => "\u{e922}",
 83            Self::Close => "\u{e8bb}",
 84        }
 85    }
 86
 87    #[inline]
 88    fn control_area(&self) -> WindowControlArea {
 89        match self {
 90            Self::Close => WindowControlArea::Close,
 91            Self::Maximize | Self::Restore => WindowControlArea::Max,
 92            Self::Minimize => WindowControlArea::Min,
 93        }
 94    }
 95}
 96
 97impl RenderOnce for WindowsCaptionButton {
 98    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
 99        let (hover_bg, hover_fg, active_bg, active_fg) = match self {
100            Self::Close => {
101                let color: Hsla = Rgba {
102                    r: 232.0 / 255.0,
103                    g: 17.0 / 255.0,
104                    b: 32.0 / 255.0,
105                    a: 1.0,
106                }
107                .into();
108
109                (
110                    color,
111                    gpui::white(),
112                    color.opacity(0.8),
113                    gpui::white().opacity(0.8),
114                )
115            }
116            _ => (
117                cx.theme().colors().ghost_element_hover,
118                cx.theme().colors().text,
119                cx.theme().colors().ghost_element_active,
120                cx.theme().colors().text,
121            ),
122        };
123
124        h_flex()
125            .id(self.id())
126            .justify_center()
127            .content_center()
128            .occlude()
129            .w(px(36.))
130            .h_full()
131            .text_size(px(10.0))
132            .hover(|style| style.bg(hover_bg).text_color(hover_fg))
133            .active(|style| style.bg(active_bg).text_color(active_fg))
134            .window_control_area(self.control_area())
135            .child(self.icon())
136    }
137}