Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:02:41.414Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

platform_linux.rs

246 lines · 7.1 KB · rust
1use gpui::{
2    Action, AnyElement, Hsla, MAX_BUTTONS_PER_SIDE, MouseButton, WindowButton, prelude::*, svg,
3};
4use ui::prelude::*;
5
6#[derive(IntoElement)]
7pub struct LinuxWindowControls {
8    id: &'static str,
9    buttons: [Option<WindowButton>; MAX_BUTTONS_PER_SIDE],
10    close_action: Box<dyn Action>,
11}
12
13impl LinuxWindowControls {
14    pub fn new(
15        id: &'static str,
16        buttons: [Option<WindowButton>; MAX_BUTTONS_PER_SIDE],
17        close_action: Box<dyn Action>,
18    ) -> Self {
19        Self {
20            id,
21            buttons,
22            close_action,
23        }
24    }
25}
26
27impl RenderOnce for LinuxWindowControls {
28    fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
29        let is_maximized = window.is_maximized();
30        let supported_controls = window.window_controls();
31        let button_elements: Vec<AnyElement> = self
32            .buttons
33            .iter()
34            .filter_map(|b| *b)
35            .filter(|button| match button {
36                WindowButton::Minimize => supported_controls.minimize,
37                WindowButton::Maximize => supported_controls.maximize,
38                WindowButton::Close => true,
39            })
40            .map(|button| {
41                create_window_button(button, button.id(), is_maximized, &*self.close_action, cx)
42            })
43            .collect();
44
45        h_flex()
46            .id(self.id)
47            .when(!button_elements.is_empty(), |el| {
48                el.gap_3()
49                    .px_3()
50                    .on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation())
51                    .children(button_elements)
52            })
53    }
54}
55
56fn create_window_button(
57    button: WindowButton,
58    id: &'static str,
59    is_maximized: bool,
60    close_action: &dyn Action,
61    cx: &mut App,
62) -> AnyElement {
63    match button {
64        WindowButton::Minimize => {
65            WindowControl::new(id, WindowControlType::Minimize, cx).into_any_element()
66        }
67        WindowButton::Maximize => WindowControl::new(
68            id,
69            if is_maximized {
70                WindowControlType::Restore
71            } else {
72                WindowControlType::Maximize
73            },
74            cx,
75        )
76        .into_any_element(),
77        WindowButton::Close => {
78            WindowControl::new_close(id, WindowControlType::Close, close_action.boxed_clone(), cx)
79                .into_any_element()
80        }
81    }
82}
83
84#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
85pub enum WindowControlType {
86    Minimize,
87    Restore,
88    Maximize,
89    Close,
90}
91
92impl WindowControlType {
93    /// Returns the icon name for the window control type.
94    ///
95    /// Will take a [PlatformStyle] in the future to return a different
96    /// icon name based on the platform.
97    pub fn icon(&self) -> IconName {
98        match self {
99            WindowControlType::Minimize => IconName::GenericMinimize,
100            WindowControlType::Restore => IconName::GenericRestore,
101            WindowControlType::Maximize => IconName::GenericMaximize,
102            WindowControlType::Close => IconName::GenericClose,
103        }
104    }
105}
106
107#[allow(unused)]
108pub struct WindowControlStyle {
109    background: Hsla,
110    background_hover: Hsla,
111    icon: Hsla,
112    icon_hover: Hsla,
113}
114
115impl WindowControlStyle {
116    pub fn default(cx: &mut App) -> Self {
117        let colors = cx.theme().colors();
118
119        Self {
120            background: colors.ghost_element_background,
121            background_hover: colors.ghost_element_hover,
122            icon: colors.icon,
123            icon_hover: colors.icon_muted,
124        }
125    }
126
127    #[allow(unused)]
128    /// Sets the background color of the control.
129    pub fn background(mut self, color: impl Into<Hsla>) -> Self {
130        self.background = color.into();
131        self
132    }
133
134    #[allow(unused)]
135    /// Sets the background color of the control when hovered.
136    pub fn background_hover(mut self, color: impl Into<Hsla>) -> Self {
137        self.background_hover = color.into();
138        self
139    }
140
141    #[allow(unused)]
142    /// Sets the color of the icon.
143    pub fn icon(mut self, color: impl Into<Hsla>) -> Self {
144        self.icon = color.into();
145        self
146    }
147
148    #[allow(unused)]
149    /// Sets the color of the icon when hovered.
150    pub fn icon_hover(mut self, color: impl Into<Hsla>) -> Self {
151        self.icon_hover = color.into();
152        self
153    }
154}
155
156#[derive(IntoElement)]
157pub struct WindowControl {
158    id: ElementId,
159    icon: WindowControlType,
160    style: WindowControlStyle,
161    close_action: Option<Box<dyn Action>>,
162}
163
164impl WindowControl {
165    pub fn new(id: impl Into<ElementId>, icon: WindowControlType, cx: &mut App) -> Self {
166        let style = WindowControlStyle::default(cx);
167
168        Self {
169            id: id.into(),
170            icon,
171            style,
172            close_action: None,
173        }
174    }
175
176    pub fn new_close(
177        id: impl Into<ElementId>,
178        icon: WindowControlType,
179        close_action: Box<dyn Action>,
180        cx: &mut App,
181    ) -> Self {
182        let style = WindowControlStyle::default(cx);
183
184        Self {
185            id: id.into(),
186            icon,
187            style,
188            close_action: Some(close_action.boxed_clone()),
189        }
190    }
191
192    #[allow(unused)]
193    pub fn custom_style(
194        id: impl Into<ElementId>,
195        icon: WindowControlType,
196        style: WindowControlStyle,
197    ) -> Self {
198        Self {
199            id: id.into(),
200            icon,
201            style,
202            close_action: None,
203        }
204    }
205}
206
207impl RenderOnce for WindowControl {
208    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
209        let icon = svg()
210            .size_4()
211            .flex_none()
212            .path(self.icon.icon().path())
213            .text_color(self.style.icon)
214            .group_hover("", |this| this.text_color(self.style.icon_hover));
215
216        h_flex()
217            .id(self.id)
218            .group("")
219            .cursor_pointer()
220            .justify_center()
221            .content_center()
222            .rounded_2xl()
223            .w_5()
224            .h_5()
225            .hover(|this| this.bg(self.style.background_hover))
226            .active(|this| this.bg(self.style.background_hover))
227            .child(icon)
228            .on_mouse_move(|_, _, cx| cx.stop_propagation())
229            .on_click(move |_, window, cx| {
230                cx.stop_propagation();
231                match self.icon {
232                    WindowControlType::Minimize => window.minimize_window(),
233                    WindowControlType::Restore => window.zoom_window(),
234                    WindowControlType::Maximize => window.zoom_window(),
235                    WindowControlType::Close => window.dispatch_action(
236                        self.close_action
237                            .as_ref()
238                            .expect("Use WindowControl::new_close() for close control.")
239                            .boxed_clone(),
240                        cx,
241                    ),
242                }
243            })
244    }
245}
246
Served at tenant.openagents/omega Member data and write actions are omitted.