Unified · Split
| @@ -4,10 +4,10 @@ use std::sync::Arc; · 3 unmodified lines | ||
| 4 | 4 | use gpui3::{Interactive, MouseButton}; |
| 5 | 5 | |
| 6 | 6 | use crate::prelude::*; |
| 7 | −use crate::{theme, Icon, IconColor, IconElement}; | |
| 7 | +use crate::{theme, ClickHandler, Icon, IconColor, IconElement}; | |
| 8 | 8 | |
| 9 | 9 | struct IconButtonHandlers<S: 'static + Send + Sync> { |
| 10 | − click: Option<Arc<dyn Fn(&mut S, &mut ViewContext<S>) + 'static + Send + Sync>>, | |
| 10 | + click: Option<ClickHandler<S>>, | |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | impl<S: 'static + Send + Sync> Default for IconButtonHandlers<S> { |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | use std::marker::PhantomData; |
| 2 | 2 | |
| 3 | 3 | use crate::prelude::*; |
| 4 | −use crate::{Button, Icon, IconButton, IconColor, ToolDivider}; | |
| 4 | +use crate::{Button, ClickHandler, Icon, IconButton, IconColor, ToolDivider}; | |
| 5 | 5 | |
| 6 | 6 | #[derive(Default, PartialEq)] |
| 7 | 7 | pub enum Tool { |
| @@ -34,15 +34,17 @@ pub struct StatusBar<S: 'static + Send + Sync + Clone> { · 26 unmodified lines | ||
| 34 | 34 | left_tools: Option<ToolGroup>, |
| 35 | 35 | right_tools: Option<ToolGroup>, |
| 36 | 36 | bottom_tools: Option<ToolGroup>, |
| 37 | + on_select_language: ClickHandler<S>, | |
| 37 | 38 | } |
| 38 | 39 | |
| 39 | 40 | impl<S: 'static + Send + Sync + Clone> StatusBar<S> { |
| 40 | − pub fn new() -> Self { | |
| 41 | + pub fn new(on_select_language: ClickHandler<S>) -> Self { | |
| 41 | 42 | Self { |
| 42 | 43 | state_type: PhantomData, |
| 43 | 44 | left_tools: None, |
| 44 | 45 | right_tools: None, |
| 45 | 46 | bottom_tools: None, |
| 47 | + on_select_language, | |
| 46 | 48 | } |
| 47 | 49 | } |
| 48 | 50 | |
| @@ -119,9 +121,7 @@ impl<S: 'static + Send + Sync + Clone> StatusBar<S> { · 70 unmodified lines | ||
| 119 | 121 | .items_center() |
| 120 | 122 | .gap_1() |
| 121 | 123 | .child(Button::new("116:25")) |
| 122 | − .child( | |
| 123 | − Button::new("Rust").on_click(|_, _| println!("Select Language clicked.")), | |
| 124 | − ), | |
| 124 | + .child(Button::new("Rust").on_click(self.on_select_language.clone())), | |
| 125 | 125 | ) |
| 126 | 126 | .child(ToolDivider::new()) |
| 127 | 127 | .child( |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | use std::marker::PhantomData; |
| 2 | +use std::sync::atomic::{AtomicBool, Ordering}; | |
| 2 | 3 | use std::sync::Arc; |
| 3 | 4 | |
| 4 | 5 | use chrono::DateTime; |
| @@ -7,9 +8,9 @@ use gpui3::{relative, rems, Size}; · 2 unmodified lines | ||
| 7 | 8 | use crate::prelude::*; |
| 8 | 9 | use crate::{ |
| 9 | 10 | hello_world_rust_editor_with_status_example, random_players_with_call_status, theme, v_stack, |
| 10 | − ChatMessage, ChatPanel, EditorPane, Label, Livestream, Pane, PaneGroup, Panel, | |
| 11 | − PanelAllowedSides, PanelSide, ProjectPanel, SplitDirection, StatusBar, Terminal, TitleBar, | |
| 12 | − Toast, ToastOrigin, | |
| 11 | + ChatMessage, ChatPanel, EditorPane, Label, LanguageSelector, Livestream, Pane, PaneGroup, | |
| 12 | + Panel, PanelAllowedSides, PanelSide, ProjectPanel, SplitDirection, StatusBar, Terminal, | |
| 13 | + TitleBar, Toast, ToastOrigin, | |
| 13 | 14 | }; |
| 14 | 15 | |
| 15 | 16 | #[derive(Element)] |
| @@ -19,6 +20,7 @@ pub struct WorkspaceElement<S: 'static + Send + Sync + Clone> { · 3 unmodified lines | ||
| 19 | 20 | right_panel_scroll_state: ScrollState, |
| 20 | 21 | tab_bar_scroll_state: ScrollState, |
| 21 | 22 | bottom_panel_scroll_state: ScrollState, |
| 23 | + show_language_selector: Arc<AtomicBool>, | |
| 22 | 24 | } |
| 23 | 25 | |
| 24 | 26 | impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> { |
| @@ -29,12 +31,15 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> { · 4 unmodified lines | ||
| 29 | 31 | right_panel_scroll_state: ScrollState::default(), |
| 30 | 32 | tab_bar_scroll_state: ScrollState::default(), |
| 31 | 33 | bottom_panel_scroll_state: ScrollState::default(), |
| 34 | + show_language_selector: Arc::new(AtomicBool::new(false)), | |
| 32 | 35 | } |
| 33 | 36 | } |
| 34 | 37 | |
| 35 | 38 | pub fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> { |
| 36 | 39 | let theme = theme(cx).clone(); |
| 37 | 40 | |
| 41 | + let show_language_selector = self.show_language_selector.clone(); | |
| 42 | + | |
| 38 | 43 | let temp_size = rems(36.).into(); |
| 39 | 44 | |
| 40 | 45 | let root_group = PaneGroup::new_groups( |
| @@ -182,7 +187,31 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> { · 141 unmodified lines | ||
| 182 | 187 | .side(PanelSide::Right), |
| 183 | 188 | ), |
| 184 | 189 | ) |
| 185 | − .child(StatusBar::new()) | |
| 190 | + .child(StatusBar::new(Arc::new(move |_, cx| { | |
| 191 | + let is_showing_language_selector = show_language_selector.load(Ordering::SeqCst); | |
| 192 | + | |
| 193 | + show_language_selector | |
| 194 | + .compare_exchange( | |
| 195 | + is_showing_language_selector, | |
| 196 | + !is_showing_language_selector, | |
| 197 | + Ordering::SeqCst, | |
| 198 | + Ordering::SeqCst, | |
| 199 | + ) | |
| 200 | + .unwrap(); | |
| 201 | + | |
| 202 | + cx.notify(); | |
| 203 | + }))) | |
| 204 | + .children( | |
| 205 | + Some( | |
| 206 | + div() | |
| 207 | + .absolute() | |
| 208 | + .top_0() | |
| 209 | + .left_0() | |
| 210 | + .z_index(999) | |
| 211 | + .child(LanguageSelector::new()), | |
| 212 | + ) | |
| 213 | + .filter(|_| self.show_language_selector.load(Ordering::SeqCst)), | |
| 214 | + ) | |
| 186 | 215 | .child(Toast::new( |
| 187 | 216 | ToastOrigin::Bottom, |
| 188 | 217 | |_, _| vec![Label::new("A toast").into_any()], |
| @@ -20,8 +20,10 @@ pub enum ButtonVariant { · 19 unmodified lines | ||
| 20 | 20 | Filled, |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | +pub type ClickHandler<S> = Arc<dyn Fn(&mut S, &mut ViewContext<S>) + 'static + Send + Sync>; | |
| 24 | + | |
| 23 | 25 | struct ButtonHandlers<S: 'static + Send + Sync> { |
| 24 | − click: Option<Arc<dyn Fn(&mut S, &mut ViewContext<S>) + 'static + Send + Sync>>, | |
| 26 | + click: Option<ClickHandler<S>>, | |
| 25 | 27 | } |
| 26 | 28 | |
| 27 | 29 | impl<S: 'static + Send + Sync> Default for ButtonHandlers<S> { |
| @@ -94,11 +96,8 @@ impl<S: 'static + Send + Sync + Clone> Button<S> { · 66 unmodified lines | ||
| 94 | 96 | self |
| 95 | 97 | } |
| 96 | 98 | |
| 97 | − pub fn on_click( | |
| 98 | − mut self, | |
| 99 | − handler: impl Fn(&mut S, &mut ViewContext<S>) + 'static + Send + Sync, | |
| 100 | − ) -> Self { | |
| 101 | − self.handlers.click = Some(Arc::new(handler)); | |
| 99 | + pub fn on_click(mut self, handler: ClickHandler<S>) -> Self { | |
| 100 | + self.handlers.click = Some(handler); | |
| 102 | 101 | self |
| 103 | 102 | } |
| 104 | 103 | |
| @@ -403,7 +402,7 @@ mod stories { · 298 unmodified lines | ||
| 403 | 402 | .child( |
| 404 | 403 | Button::new("Label") |
| 405 | 404 | .variant(ButtonVariant::Ghost) |
| 406 | − .on_click(|_view, _cx| println!("Button clicked.")), | |
| 405 | + .on_click(Arc::new(|_view, _cx| println!("Button clicked."))), | |
| 407 | 406 | ) |
| 408 | 407 | } |
| 409 | 408 | } |