Unified · Split
| @@ -4,10 +4,10 @@ use std::sync::Arc; · 3 unmodified lines | |||
| 4 | use gpui3::{Interactive, MouseButton}; | 4 | use gpui3::{Interactive, MouseButton}; |
| 5 | 5 | ||
| 6 | use crate::prelude::*; | 6 | use crate::prelude::*; |
| 7 | use crate::{theme, Icon, IconColor, IconElement}; | 7 | use crate::{theme, ClickHandler, Icon, IconColor, IconElement}; |
| 8 | 8 | ||
| 9 | struct IconButtonHandlers<S: 'static + Send + Sync> { | 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 | impl<S: 'static + Send + Sync> Default for IconButtonHandlers<S> { | 13 | impl<S: 'static + Send + Sync> Default for IconButtonHandlers<S> { |
| @@ -1,7 +1,7 @@ | |||
| 1 | use std::marker::PhantomData; | 1 | use std::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use crate::prelude::*; | 3 | use crate::prelude::*; |
| 4 | use crate::{Button, Icon, IconButton, IconColor, ToolDivider}; | 4 | use crate::{Button, ClickHandler, Icon, IconButton, IconColor, ToolDivider}; |
| 5 | 5 | ||
| 6 | #[derive(Default, PartialEq)] | 6 | #[derive(Default, PartialEq)] |
| 7 | pub enum Tool { | 7 | pub enum Tool { |
| @@ -34,15 +34,17 @@ pub struct StatusBar<S: 'static + Send + Sync + Clone> { · 26 unmodified lines | |||
| 34 | left_tools: Option<ToolGroup>, | 34 | left_tools: Option<ToolGroup>, |
| 35 | right_tools: Option<ToolGroup>, | 35 | right_tools: Option<ToolGroup>, |
| 36 | bottom_tools: Option<ToolGroup>, | 36 | bottom_tools: Option<ToolGroup>, |
| 37 | on_select_language: ClickHandler<S>, | ||
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | impl<S: 'static + Send + Sync + Clone> StatusBar<S> { | 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 | Self { | 42 | Self { |
| 42 | state_type: PhantomData, | 43 | state_type: PhantomData, |
| 43 | left_tools: None, | 44 | left_tools: None, |
| 44 | right_tools: None, | 45 | right_tools: None, |
| 45 | bottom_tools: None, | 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 | .items_center() | 121 | .items_center() |
| 120 | .gap_1() | 122 | .gap_1() |
| 121 | .child(Button::new("116:25")) | 123 | .child(Button::new("116:25")) |
| 122 | .child( | 124 | .child(Button::new("Rust").on_click(self.on_select_language.clone())), |
| 123 | Button::new("Rust").on_click(|_, _| println!("Select Language clicked.")), | ||
| 124 | ), | ||
| 125 | ) | 125 | ) |
| 126 | .child(ToolDivider::new()) | 126 | .child(ToolDivider::new()) |
| 127 | .child( | 127 | .child( |
| @@ -1,4 +1,5 @@ | |||
| 1 | use std::marker::PhantomData; | 1 | use std::marker::PhantomData; |
| 2 | use std::sync::atomic::{AtomicBool, Ordering}; | ||
| 2 | use std::sync::Arc; | 3 | use std::sync::Arc; |
| 3 | 4 | ||
| 4 | use chrono::DateTime; | 5 | use chrono::DateTime; |
| @@ -7,9 +8,9 @@ use gpui3::{relative, rems, Size}; · 2 unmodified lines | |||
| 7 | use crate::prelude::*; | 8 | use crate::prelude::*; |
| 8 | use crate::{ | 9 | use crate::{ |
| 9 | hello_world_rust_editor_with_status_example, random_players_with_call_status, theme, v_stack, | 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 | ChatMessage, ChatPanel, EditorPane, Label, LanguageSelector, Livestream, Pane, PaneGroup, |
| 11 | PanelAllowedSides, PanelSide, ProjectPanel, SplitDirection, StatusBar, Terminal, TitleBar, | 12 | Panel, PanelAllowedSides, PanelSide, ProjectPanel, SplitDirection, StatusBar, Terminal, |
| 12 | Toast, ToastOrigin, | 13 | TitleBar, Toast, ToastOrigin, |
| 13 | }; | 14 | }; |
| 14 | 15 | ||
| 15 | #[derive(Element)] | 16 | #[derive(Element)] |
| @@ -19,6 +20,7 @@ pub struct WorkspaceElement<S: 'static + Send + Sync + Clone> { · 3 unmodified lines | |||
| 19 | right_panel_scroll_state: ScrollState, | 20 | right_panel_scroll_state: ScrollState, |
| 20 | tab_bar_scroll_state: ScrollState, | 21 | tab_bar_scroll_state: ScrollState, |
| 21 | bottom_panel_scroll_state: ScrollState, | 22 | bottom_panel_scroll_state: ScrollState, |
| 23 | show_language_selector: Arc<AtomicBool>, | ||
| 22 | } | 24 | } |
| 23 | 25 | ||
| 24 | impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> { | 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 | right_panel_scroll_state: ScrollState::default(), | 31 | right_panel_scroll_state: ScrollState::default(), |
| 30 | tab_bar_scroll_state: ScrollState::default(), | 32 | tab_bar_scroll_state: ScrollState::default(), |
| 31 | bottom_panel_scroll_state: ScrollState::default(), | 33 | bottom_panel_scroll_state: ScrollState::default(), |
| 34 | show_language_selector: Arc::new(AtomicBool::new(false)), | ||
| 32 | } | 35 | } |
| 33 | } | 36 | } |
| 34 | 37 | ||
| 35 | pub fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> { | 38 | pub fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> { |
| 36 | let theme = theme(cx).clone(); | 39 | let theme = theme(cx).clone(); |
| 37 | 40 | ||
| 41 | let show_language_selector = self.show_language_selector.clone(); | ||
| 42 | |||
| 38 | let temp_size = rems(36.).into(); | 43 | let temp_size = rems(36.).into(); |
| 39 | 44 | ||
| 40 | let root_group = PaneGroup::new_groups( | 45 | let root_group = PaneGroup::new_groups( |
| @@ -182,7 +187,31 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> { · 141 unmodified lines | |||
| 182 | .side(PanelSide::Right), | 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 | .child(Toast::new( | 215 | .child(Toast::new( |
| 187 | ToastOrigin::Bottom, | 216 | ToastOrigin::Bottom, |
| 188 | |_, _| vec![Label::new("A toast").into_any()], | 217 | |_, _| vec![Label::new("A toast").into_any()], |
| @@ -20,8 +20,10 @@ pub enum ButtonVariant { · 19 unmodified lines | |||
| 20 | Filled, | 20 | Filled, |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | pub type ClickHandler<S> = Arc<dyn Fn(&mut S, &mut ViewContext<S>) + 'static + Send + Sync>; | ||
| 24 | |||
| 23 | struct ButtonHandlers<S: 'static + Send + Sync> { | 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 | impl<S: 'static + Send + Sync> Default for ButtonHandlers<S> { | 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 | self | 96 | self |
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | pub fn on_click( | 99 | pub fn on_click(mut self, handler: ClickHandler<S>) -> Self { |
| 98 | mut self, | 100 | self.handlers.click = Some(handler); |
| 99 | handler: impl Fn(&mut S, &mut ViewContext<S>) + 'static + Send + Sync, | ||
| 100 | ) -> Self { | ||
| 101 | self.handlers.click = Some(Arc::new(handler)); | ||
| 102 | self | 101 | self |
| 103 | } | 102 | } |
| 104 | 103 | ||
| @@ -403,7 +402,7 @@ mod stories { · 298 unmodified lines | |||
| 403 | .child( | 402 | .child( |
| 404 | Button::new("Label") | 403 | Button::new("Label") |
| 405 | .variant(ButtonVariant::Ghost) | 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 | } |