diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 552c7f41315c78e1b800a4eba63a2cc9a3560dcd..9e1a6d479c46e705ee5ed36c8689a80fe3f1f4cb 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -76,7 +76,8 @@ impl View for FileFinder { Container::new( Flex::new(Axis::Vertical) .with_child( - Container::new(ChildView::new(&self.query_editor).boxed()) + ChildView::new(&self.query_editor) + .contained() .with_style(settings.theme.selector.input_editor.container) .boxed(), ) diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 3607f1af87b4b95fb0222ecaad0c35d4a49c2010..dc8ba002a38e9490e2e8980a42a24883277b92d3 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -144,7 +144,7 @@ impl OutlineView { let view = cx.add_view(|cx| OutlineView::new(outline, editor, settings, cx)); cx.subscribe(&view, Self::on_event).detach(); view - }) + }); } } } diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 9ac35339abe5b1951e85899fbf4e240059092a15..8483fa4e8a25ae2d6c53b8872b45d04ae0b4b4e3 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -10,7 +10,7 @@ use gpui::{ use parking_lot::Mutex; use postage::watch; use std::{cmp, sync::Arc}; -use theme::ThemeRegistry; +use theme::{Theme, ThemeRegistry}; use workspace::{ menu::{Confirm, SelectNext, SelectPrev}, AppState, Settings, Workspace, @@ -31,6 +31,8 @@ pub struct ThemeSelector { query_editor: ViewHandle, list_state: UniformListState, selected_index: usize, + original_theme: Arc, + selection_completed: bool, } action!(Toggle, ThemeSelectorParams); @@ -72,6 +74,8 @@ impl ThemeSelector { cx.subscribe(&query_editor, Self::on_query_editor_event) .detach(); + let original_theme = settings.borrow().theme.clone(); + let mut this = Self { settings, settings_tx, @@ -79,9 +83,15 @@ impl ThemeSelector { query_editor, matches: Vec::new(), list_state: Default::default(), - selected_index: 0, + selected_index: 0, // Default index for now + original_theme: original_theme.clone(), + selection_completed: false, }; this.update_matches(cx); + + // Set selected index to current theme + this.select_if_matching(&original_theme.name); + this } @@ -105,8 +115,8 @@ impl ThemeSelector { action.0.themes.clear(); match action.0.themes.get(¤t_theme_name) { Ok(theme) => { - cx.refresh_windows(); action.0.settings_tx.lock().borrow_mut().theme = theme; + cx.refresh_windows(); log::info!("reloaded theme {}", current_theme_name); } Err(error) => { @@ -116,16 +126,8 @@ impl ThemeSelector { } fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext) { - if let Some(mat) = self.matches.get(self.selected_index) { - match self.themes.get(&mat.string) { - Ok(theme) => { - self.settings_tx.lock().borrow_mut().theme = theme; - cx.refresh_windows(); - cx.emit(Event::Dismissed); - } - Err(error) => log::error!("error loading theme {}: {}", mat.string, error), - } - } + self.selection_completed = true; + cx.emit(Event::Dismissed); } fn select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext) { @@ -134,6 +136,8 @@ impl ThemeSelector { } self.list_state .scroll_to(ScrollTarget::Show(self.selected_index)); + + self.show_selected_theme(cx); cx.notify(); } @@ -143,9 +147,41 @@ impl ThemeSelector { } self.list_state .scroll_to(ScrollTarget::Show(self.selected_index)); + + self.show_selected_theme(cx); cx.notify(); } + fn show_selected_theme(&mut self, cx: &mut MutableAppContext) { + if let Some(mat) = self.matches.get(self.selected_index) { + match self.themes.get(&mat.string) { + Ok(theme) => { + self.set_theme(theme, cx); + } + Err(error) => { + log::error!("error loading theme {}: {}", mat.string, error) + } + } + } + } + + fn select_if_matching(&mut self, theme_name: &str) { + self.selected_index = self + .matches + .iter() + .position(|mat| mat.string == theme_name) + .unwrap_or(self.selected_index); + } + + fn current_theme(&self) -> Arc { + self.settings_tx.lock().borrow().theme.clone() + } + + fn set_theme(&self, theme: Arc, cx: &mut MutableAppContext) { + self.settings_tx.lock().borrow_mut().theme = theme; + cx.refresh_windows(); + } + fn update_matches(&mut self, cx: &mut ViewContext) { let background = cx.background().clone(); let candidates = self @@ -181,6 +217,11 @@ impl ThemeSelector { background, )) }; + + self.selected_index = self + .selected_index + .min(self.matches.len().saturating_sub(1)); + cx.notify(); } @@ -204,7 +245,11 @@ impl ThemeSelector { cx: &mut ViewContext, ) { match event { - editor::Event::Edited => self.update_matches(cx), + editor::Event::Edited => { + self.update_matches(cx); + self.select_if_matching(&self.current_theme().name); + self.show_selected_theme(cx); + } editor::Event::Blurred => cx.emit(Event::Dismissed), _ => {} } @@ -276,6 +321,12 @@ impl ThemeSelector { impl Entity for ThemeSelector { type Event = Event; + + fn release(&mut self, cx: &mut MutableAppContext) { + if !self.selection_completed { + self.set_theme(self.original_theme.clone(), cx); + } + } } impl View for ThemeSelector { @@ -290,7 +341,12 @@ impl View for ThemeSelector { ConstrainedBox::new( Container::new( Flex::new(Axis::Vertical) - .with_child(ChildView::new(&self.query_editor).boxed()) + .with_child( + ChildView::new(&self.query_editor) + .contained() + .with_style(settings.theme.selector.input_editor.container) + .boxed(), + ) .with_child(Flexible::new(1.0, false, self.render_matches(cx)).boxed()) .boxed(), ) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index dee138b0aeec0ca2243c5146f08057f377e1921c..f06a244c0580fe9bf31ad2a387e9622322308daa 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -754,20 +754,29 @@ impl Workspace { }) } - pub fn toggle_modal(&mut self, cx: &mut ViewContext, add_view: F) + // Returns the model that was toggled closed if it was open + pub fn toggle_modal( + &mut self, + cx: &mut ViewContext, + add_view: F, + ) -> Option> where V: 'static + View, F: FnOnce(&mut ViewContext, &mut Self) -> ViewHandle, { - if self.modal.as_ref().map_or(false, |modal| modal.is::()) { - self.modal.take(); + cx.notify(); + // Whatever modal was visible is getting clobbered. If its the same type as V, then return + // it. Otherwise, create a new modal and set it as active. + let already_open_modal = self.modal.take().and_then(|modal| modal.downcast::()); + if let Some(already_open_modal) = already_open_modal { cx.focus_self(); + Some(already_open_modal) } else { let modal = add_view(cx, self); cx.focus(&modal); self.modal = Some(modal.into()); + None } - cx.notify(); } pub fn modal(&self) -> Option<&AnyViewHandle> {