diff --git a/crates/ui2/src/components/status_bar.rs b/crates/ui2/src/components/status_bar.rs index 9f6c10f4eb..ce6ce623a5 100644 --- a/crates/ui2/src/components/status_bar.rs +++ b/crates/ui2/src/components/status_bar.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use crate::{get_workspace_state, Button, Icon, IconButton, IconColor, ToolDivider}; -use crate::{prelude::*, Workspace}; +use crate::prelude::*; +use crate::{Button, Icon, IconButton, IconColor, ToolDivider, Workspace}; #[derive(Default, PartialEq)] pub enum Tool { @@ -98,7 +98,7 @@ impl StatusBar { .w_full() .fill(theme.lowest.base.default.background) .child(self.left_tools(view, &theme)) - .child(self.right_tools(&theme)) + .child(self.right_tools(view, &theme)) } fn left_tools( @@ -106,7 +106,7 @@ impl StatusBar { workspace: &mut Workspace, theme: &Theme, ) -> impl Element { - div::() + div() .flex() .items_center() .gap_1() @@ -126,16 +126,17 @@ impl StatusBar { }) .on_click(|workspace, cx| { workspace.toggle_collab_panel(); - cx.notify(); }), ) .child(ToolDivider::new()) .child(IconButton::new(Icon::XCircle)) } - fn right_tools(&self, theme: &Theme) -> impl Element { - let workspace_state = get_workspace_state(); - + fn right_tools( + &self, + workspace: &mut Workspace, + theme: &Theme, + ) -> impl Element { div() .flex() .items_center() @@ -146,10 +147,11 @@ impl StatusBar { .items_center() .gap_1() .child(Button::new("116:25")) - .child(Button::new("Rust").on_click(Arc::new(|_, cx| { - workspace_state.toggle_language_selector(); - cx.notify(); - }))), + .child( + Button::::new("Rust").on_click(Arc::new(|workspace, cx| { + workspace.toggle_language_selector(cx); + })), + ), ) .child(ToolDivider::new()) .child( @@ -173,33 +175,30 @@ impl StatusBar { .items_center() .gap_1() .child( - IconButton::new(Icon::Terminal) - .when(workspace_state.is_terminal_open(), |this| { + IconButton::::new(Icon::Terminal) + .when(workspace.is_terminal_open(), |this| { this.color(IconColor::Accent) }) - .on_click(|_, cx| { - workspace_state.toggle_terminal(); - cx.notify(); + .on_click(|workspace, cx| { + workspace.toggle_terminal(cx); }), ) .child( - IconButton::new(Icon::MessageBubbles) - .when(workspace_state.is_chat_panel_open(), |this| { + IconButton::::new(Icon::MessageBubbles) + .when(workspace.is_chat_panel_open(), |this| { this.color(IconColor::Accent) }) - .on_click(|_, cx| { - workspace_state.toggle_chat_panel(); - cx.notify(); + .on_click(|workspace, cx| { + workspace.toggle_chat_panel(cx); }), ) .child( - IconButton::new(Icon::Ai) - .when(workspace_state.is_assistant_panel_open(), |this| { + IconButton::::new(Icon::Ai) + .when(workspace.is_assistant_panel_open(), |this| { this.color(IconColor::Accent) }) - .on_click(|_, cx| { - workspace_state.toggle_assistant_panel(); - cx.notify(); + .on_click(|workspace, cx| { + workspace.toggle_assistant_panel(cx); }), ), ) diff --git a/crates/ui2/src/components/workspace.rs b/crates/ui2/src/components/workspace.rs index 21feff873f..807ce215ae 100644 --- a/crates/ui2/src/components/workspace.rs +++ b/crates/ui2/src/components/workspace.rs @@ -1,6 +1,3 @@ -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, OnceLock}; - use chrono::DateTime; use gpui3::{px, relative, rems, view, Context, Size, View}; @@ -12,78 +9,14 @@ use crate::{ StatusBar, Terminal, TitleBar, Toast, ToastOrigin, }; -pub struct WorkspaceState { - pub show_chat_panel: Arc, - pub show_assistant_panel: Arc, - pub show_terminal: Arc, - pub show_language_selector: Arc, -} - -impl WorkspaceState { - fn toggle_value(current_value: &AtomicBool) { - let value = current_value.load(Ordering::SeqCst); - - current_value - .compare_exchange(value, !value, Ordering::SeqCst, Ordering::SeqCst) - .unwrap(); - } - - pub fn is_terminal_open(&self) -> bool { - self.show_terminal.load(Ordering::SeqCst) - } - - pub fn toggle_terminal(&self) { - Self::toggle_value(&self.show_terminal); - } - - pub fn is_chat_panel_open(&self) -> bool { - self.show_chat_panel.load(Ordering::SeqCst) - } - - pub fn toggle_chat_panel(&self) { - Self::toggle_value(&self.show_chat_panel); - - self.show_assistant_panel.store(false, Ordering::SeqCst); - } - - pub fn is_assistant_panel_open(&self) -> bool { - self.show_assistant_panel.load(Ordering::SeqCst) - } - - pub fn toggle_assistant_panel(&self) { - Self::toggle_value(&self.show_assistant_panel); - - self.show_chat_panel.store(false, Ordering::SeqCst); - } - - pub fn is_language_selector_open(&self) -> bool { - self.show_language_selector.load(Ordering::SeqCst) - } - - pub fn toggle_language_selector(&self) { - Self::toggle_value(&self.show_language_selector); - } -} - -/// HACK: This is just a temporary way to start hooking up interactivity until -/// I can get an explainer on how we should actually be managing state. -static WORKSPACE_STATE: OnceLock = OnceLock::new(); - -pub fn get_workspace_state() -> &'static WorkspaceState { - let state = WORKSPACE_STATE.get_or_init(|| WorkspaceState { - show_chat_panel: Arc::new(AtomicBool::new(true)), - show_assistant_panel: Arc::new(AtomicBool::new(false)), - show_terminal: Arc::new(AtomicBool::new(true)), - show_language_selector: Arc::new(AtomicBool::new(false)), - }); - - state -} - #[derive(Clone)] pub struct Workspace { show_project_panel: bool, show_collab_panel: bool, + show_chat_panel: bool, + show_assistant_panel: bool, + show_terminal: bool, + show_language_selector: bool, left_panel_scroll_state: ScrollState, right_panel_scroll_state: ScrollState, tab_bar_scroll_state: ScrollState, @@ -99,6 +32,10 @@ impl Workspace { Self { show_project_panel: true, show_collab_panel: false, + show_chat_panel: true, + show_assistant_panel: false, + show_terminal: true, + show_language_selector: false, left_panel_scroll_state: ScrollState::default(), right_panel_scroll_state: ScrollState::default(), tab_bar_scroll_state: ScrollState::default(), @@ -128,11 +65,53 @@ impl Workspace { self.show_project_panel = false; } + pub fn is_terminal_open(&self) -> bool { + self.show_terminal + } + + pub fn toggle_terminal(&mut self, cx: &mut ViewContext) { + self.show_terminal = !self.show_terminal; + + cx.notify(); + } + + pub fn is_chat_panel_open(&self) -> bool { + self.show_chat_panel + } + + pub fn toggle_chat_panel(&mut self, cx: &mut ViewContext) { + self.show_chat_panel = !self.show_chat_panel; + + self.show_assistant_panel = false; + + cx.notify(); + } + + pub fn is_assistant_panel_open(&self) -> bool { + self.show_assistant_panel + } + + pub fn toggle_assistant_panel(&mut self, cx: &mut ViewContext) { + self.show_assistant_panel = !self.show_assistant_panel; + + self.show_chat_panel = false; + + cx.notify(); + } + + pub fn is_language_selector_open(&self) -> bool { + self.show_language_selector + } + + pub fn toggle_language_selector(&mut self, cx: &mut ViewContext) { + self.show_language_selector = !self.show_language_selector; + + cx.notify(); + } + pub fn render(&mut self, cx: &mut ViewContext) -> impl Element { let theme = theme(cx).clone(); - let workspace_state = get_workspace_state(); - let temp_size = rems(36.).into(); let root_group = PaneGroup::new_groups( @@ -240,7 +219,7 @@ impl Workspace { .allowed_sides(PanelAllowedSides::BottomOnly) .side(PanelSide::Bottom), ) - .filter(|_| workspace_state.show_terminal.load(Ordering::SeqCst)), + .filter(|_| self.is_terminal_open()), ), ) .children( @@ -264,14 +243,14 @@ impl Workspace { ), ])), ) - .filter(|_| workspace_state.is_chat_panel_open()), + .filter(|_| self.is_chat_panel_open()), ) .children( Some( Panel::new(self.right_panel_scroll_state.clone()) .child(AssistantPanel::new()), ) - .filter(|_| workspace_state.is_assistant_panel_open()), + .filter(|_| self.is_assistant_panel_open()), ), ) .child(StatusBar::new()) @@ -284,7 +263,7 @@ impl Workspace { .z_index(999) .child(LanguageSelector::new()), ) - .filter(|_| workspace_state.is_language_selector_open()), + .filter(|_| self.is_language_selector_open()), ) .child(Toast::new(ToastOrigin::Bottom).child(Label::new("A toast"))) .child(Toast::new(ToastOrigin::BottomRight).child(Label::new("Another toast")))