Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T05:53:53.060Z 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

anchor.rs

202 lines · 7.7 KB · rust
1#![cfg_attr(target_family = "wasm", no_main)]
2
3use gpui::{
4    Anchor, AnchoredPositionMode, App, Axis, Bounds, Context, Half as _, InteractiveElement,
5    ParentElement, Pixels, Point, Render, SharedString, Size, Window, WindowBounds, WindowOptions,
6    anchored, deferred, div, point, prelude::*, px, rgb, size,
7};
8use gpui_platform::application;
9
10struct AnchorDemo {
11    hovered_button: Option<usize>,
12}
13
14struct ButtonDemo {
15    label: SharedString,
16    corner: Option<Anchor>,
17}
18
19fn resolved_position(corner: Anchor, button_size: Size<Pixels>) -> Point<Pixels> {
20    let offset = Point {
21        x: px(0.),
22        y: -button_size.height,
23    };
24
25    offset
26        + match corner.other_side_along(Axis::Vertical) {
27            Anchor::TopLeft => point(px(0.0), px(0.0)),
28            Anchor::TopCenter => point(button_size.width.half(), px(0.0)),
29            Anchor::TopRight => point(button_size.width, px(0.0)),
30            Anchor::LeftCenter => point(button_size.width, button_size.height.half()),
31            Anchor::RightCenter => point(px(0.), button_size.height.half()),
32            Anchor::BottomLeft => point(px(0.0), button_size.height),
33            Anchor::BottomCenter => point(button_size.width / 2.0, button_size.height),
34            Anchor::BottomRight => point(button_size.width, button_size.height),
35        }
36}
37
38impl AnchorDemo {
39    fn buttons() -> Vec<ButtonDemo> {
40        vec![
41            ButtonDemo {
42                label: "TopLeft".into(),
43                corner: Some(Anchor::TopLeft),
44            },
45            ButtonDemo {
46                label: "TopCenter".into(),
47                corner: Some(Anchor::TopCenter),
48            },
49            ButtonDemo {
50                label: "TopRight".into(),
51                corner: Some(Anchor::TopRight),
52            },
53            ButtonDemo {
54                label: "LeftCenter".into(),
55                corner: Some(Anchor::LeftCenter),
56            },
57            ButtonDemo {
58                label: "Center".into(),
59                corner: None,
60            },
61            ButtonDemo {
62                label: "RightCenter".into(),
63                corner: Some(Anchor::RightCenter),
64            },
65            ButtonDemo {
66                label: "BottomLeft".into(),
67                corner: Some(Anchor::BottomLeft),
68            },
69            ButtonDemo {
70                label: "BottomCenter".into(),
71                corner: Some(Anchor::BottomCenter),
72            },
73            ButtonDemo {
74                label: "BottomRight".into(),
75                corner: Some(Anchor::BottomRight),
76            },
77        ]
78    }
79}
80
81impl Render for AnchorDemo {
82    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
83        let buttons = Self::buttons();
84        let button_size = size(px(120.0), px(65.0));
85
86        div()
87            .flex()
88            .flex_col()
89            .size_full()
90            .items_center()
91            .justify_center()
92            .bg(gpui::white())
93            .gap_4()
94            .p_10()
95            .child("Popover with Anchor")
96            .child(
97                div()
98                    .size_128()
99                    .grid()
100                    .grid_cols(3)
101                    .gap_6()
102                    .relative()
103                    .children(buttons.iter().enumerate().map(|(index, button)| {
104                        let is_hovered = self.hovered_button == Some(index);
105                        let is_hoverable = button.corner.is_some();
106                        div()
107                            .relative()
108                            .child(
109                                div()
110                                    .id(("button", index))
111                                    .w(button_size.width)
112                                    .h(button_size.height)
113                                    .flex()
114                                    .items_center()
115                                    .justify_center()
116                                    .bg(gpui::white())
117                                    .when(is_hoverable, |this| {
118                                        this.border_1()
119                                            .rounded_lg()
120                                            .border_color(gpui::black())
121                                            .hover(|style| {
122                                                style.bg(gpui::black()).text_color(gpui::white())
123                                            })
124                                            .on_hover(cx.listener(
125                                                move |this, hovered, _window, cx| {
126                                                    if *hovered {
127                                                        this.hovered_button = Some(index);
128                                                    } else if this.hovered_button == Some(index) {
129                                                        this.hovered_button = None;
130                                                    }
131                                                    cx.notify();
132                                                },
133                                            ))
134                                            .child(button.label.clone())
135                                    }),
136                            )
137                            .when_some(self.hovered_button.filter(|_| is_hovered), |this, index| {
138                                let button = &buttons[index];
139                                let Some(corner) = button.corner else {
140                                    return this;
141                                };
142
143                                let position = resolved_position(corner, button_size);
144                                this.child(deferred(
145                                    anchored()
146                                        .anchor(corner)
147                                        .position(position)
148                                        .position_mode(AnchoredPositionMode::Local)
149                                        .snap_to_window()
150                                        .child(
151                                            div()
152                                                .py_0p5()
153                                                .px_2()
154                                                .bg(gpui::black().opacity(0.75))
155                                                .text_color(rgb(0xffffff))
156                                                .rounded_sm()
157                                                .shadow_sm()
158                                                .min_w(px(100.0))
159                                                .text_sm()
160                                                .child(button.label.clone()),
161                                        ),
162                                ))
163                            })
164                    })),
165            )
166    }
167}
168
169fn run_example() {
170    application().run(|cx: &mut App| {
171        cx.open_window(
172            WindowOptions {
173                window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
174                    None,
175                    size(px(750.), px(600.)),
176                    cx,
177                ))),
178                ..Default::default()
179            },
180            |_, cx| {
181                cx.new(|_| AnchorDemo {
182                    hovered_button: None,
183                })
184            },
185        )
186        .unwrap();
187        cx.activate(true);
188    });
189}
190
191#[cfg(not(target_family = "wasm"))]
192fn main() {
193    run_example();
194}
195
196#[cfg(target_family = "wasm")]
197#[wasm_bindgen::prelude::wasm_bindgen(start)]
198pub fn start() {
199    gpui_platform::web_init();
200    run_example();
201}
202
Served at tenant.openagents/omega Member data and write actions are omitted.