mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-23 18:32:17 +00:00
Give hover state to picker items, keystrokes in command palette
This commit is contained in:
parent
a60c75e343
commit
8481834847
20 changed files with 269 additions and 288 deletions
|
@ -21,29 +21,19 @@
|
|||
"color": "#576ddb",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#5852607a",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#e2dfe7",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#58526052"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#e2dfe7",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#576ddb",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#5852607a"
|
||||
},
|
||||
"border": {
|
||||
"color": "#19171c",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#efecf4",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -21,29 +21,19 @@
|
|||
"color": "#576ddb",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#8b87922e",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#26232a",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#8b87921f"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#26232a",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#576ddb",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#8b87922e"
|
||||
},
|
||||
"border": {
|
||||
"color": "#efecf4",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#19171c",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -21,29 +21,19 @@
|
|||
"color": "#4f8ff7",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#2b2b2b",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#f1f1f1",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#232323"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#f1f1f1",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#4f8ff7",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#2b2b2b"
|
||||
},
|
||||
"border": {
|
||||
"color": "#070707",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#ffffff",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -21,29 +21,19 @@
|
|||
"color": "#484bed",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#e3e3e3",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#2b2b2b",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#eaeaea"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#2b2b2b",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#484bed",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#e3e3e3"
|
||||
},
|
||||
"border": {
|
||||
"color": "#d5d5d5",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#000000",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -21,29 +21,19 @@
|
|||
"color": "#268bd2",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#586e757a",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#eee8d5",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#586e7552"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#eee8d5",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#268bd2",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#586e757a"
|
||||
},
|
||||
"border": {
|
||||
"color": "#002b36",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#fdf6e3",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -21,29 +21,19 @@
|
|||
"color": "#268bd2",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#93a1a12e",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#073642",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#93a1a11f"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#073642",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#268bd2",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#93a1a12e"
|
||||
},
|
||||
"border": {
|
||||
"color": "#fdf6e3",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#002b36",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -21,29 +21,19 @@
|
|||
"color": "#3d8fd1",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#5e66877a",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#dfe2f1",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#5e668752"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#dfe2f1",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#3d8fd1",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#5e66877a"
|
||||
},
|
||||
"border": {
|
||||
"color": "#202746",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#f5f7ff",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -21,29 +21,19 @@
|
|||
"color": "#3d8fd1",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"active": {
|
||||
"background": "#979db42e",
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#293256",
|
||||
"size": 14
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"background": "#979db41f"
|
||||
}
|
||||
},
|
||||
"active_item": {
|
||||
"padding": {
|
||||
"bottom": 4,
|
||||
"left": 12,
|
||||
"right": 12,
|
||||
"top": 4
|
||||
},
|
||||
"corner_radius": 8,
|
||||
"text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#293256",
|
||||
"size": 14
|
||||
},
|
||||
"highlight_text": {
|
||||
"family": "Zed Sans",
|
||||
"color": "#3d8fd1",
|
||||
"weight": "bold",
|
||||
"size": 14
|
||||
},
|
||||
"background": "#979db42e"
|
||||
},
|
||||
"border": {
|
||||
"color": "#f5f7ff",
|
||||
"width": 1
|
||||
|
@ -906,6 +896,13 @@
|
|||
},
|
||||
"margin": {
|
||||
"left": 2
|
||||
},
|
||||
"active": {
|
||||
"text": {
|
||||
"family": "Zed Mono",
|
||||
"color": "#202746",
|
||||
"size": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
actions,
|
||||
elements::{ChildView, Flex, Label, ParentElement},
|
||||
elements::{ChildView, Flex, Label, MouseState, ParentElement},
|
||||
keymap::Keystroke,
|
||||
Action, Element, Entity, MutableAppContext, View, ViewContext, ViewHandle,
|
||||
};
|
||||
|
@ -200,17 +200,19 @@ impl PickerDelegate for CommandPalette {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_match(&self, ix: usize, selected: bool, cx: &gpui::AppContext) -> gpui::ElementBox {
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
mouse_state: &MouseState,
|
||||
selected: bool,
|
||||
cx: &gpui::AppContext,
|
||||
) -> gpui::ElementBox {
|
||||
let mat = &self.matches[ix];
|
||||
let command = &self.actions[mat.candidate_id];
|
||||
let settings = cx.global::<Settings>();
|
||||
let theme = &settings.theme;
|
||||
let style = if selected {
|
||||
&theme.picker.active_item
|
||||
} else {
|
||||
&theme.picker.item
|
||||
};
|
||||
let key_style = &theme.command_palette.key;
|
||||
let style = theme.picker.item.style_for(mouse_state, selected);
|
||||
let key_style = &theme.command_palette.key.style_for(mouse_state, selected);
|
||||
let keystroke_spacing = theme.command_palette.keystroke_spacing;
|
||||
|
||||
Flex::row()
|
||||
|
|
|
@ -95,12 +95,8 @@ impl View for DiagnosticIndicator {
|
|||
.theme
|
||||
.workspace
|
||||
.status_bar
|
||||
.diagnostic_summary;
|
||||
let style = if state.hovered {
|
||||
style.hover()
|
||||
} else {
|
||||
&style.default
|
||||
};
|
||||
.diagnostic_summary
|
||||
.style_for(state, false);
|
||||
|
||||
let mut summary_row = Flex::row();
|
||||
if self.summary.error_count > 0 {
|
||||
|
@ -190,11 +186,7 @@ impl View for DiagnosticIndicator {
|
|||
MouseEventHandler::new::<Message, _, _>(1, cx, |state, _| {
|
||||
Label::new(
|
||||
diagnostic.message.split('\n').next().unwrap().to_string(),
|
||||
if state.hovered {
|
||||
message_style.hover().text.clone()
|
||||
} else {
|
||||
message_style.default.text.clone()
|
||||
},
|
||||
message_style.style_for(state, false).text.clone(),
|
||||
)
|
||||
.aligned()
|
||||
.contained()
|
||||
|
|
|
@ -223,14 +223,16 @@ impl PickerDelegate for FileFinder {
|
|||
cx.emit(Event::Dismissed);
|
||||
}
|
||||
|
||||
fn render_match(&self, ix: usize, selected: bool, cx: &AppContext) -> ElementBox {
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
mouse_state: &MouseState,
|
||||
selected: bool,
|
||||
cx: &AppContext,
|
||||
) -> ElementBox {
|
||||
let path_match = &self.matches[ix];
|
||||
let settings = cx.global::<Settings>();
|
||||
let style = if selected {
|
||||
&settings.theme.picker.active_item
|
||||
} else {
|
||||
&settings.theme.picker.item
|
||||
};
|
||||
let style = settings.theme.picker.item.style_for(mouse_state, selected);
|
||||
let (file_name, file_name_positions, full_path, full_path_positions) =
|
||||
self.labels_for_match(path_match);
|
||||
Flex::column()
|
||||
|
|
|
@ -228,14 +228,16 @@ impl PickerDelegate for OutlineView {
|
|||
cx.emit(Event::Dismissed);
|
||||
}
|
||||
|
||||
fn render_match(&self, ix: usize, selected: bool, cx: &AppContext) -> ElementBox {
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
mouse_state: &MouseState,
|
||||
selected: bool,
|
||||
cx: &AppContext,
|
||||
) -> ElementBox {
|
||||
let settings = cx.global::<Settings>();
|
||||
let string_match = &self.matches[ix];
|
||||
let style = if selected {
|
||||
&settings.theme.picker.active_item
|
||||
} else {
|
||||
&settings.theme.picker.item
|
||||
};
|
||||
let style = settings.theme.picker.item.style_for(mouse_state, selected);
|
||||
let outline_item = &self.outline.items[string_match.candidate_id];
|
||||
|
||||
Text::new(outline_item.text.clone(), style.label.text.clone())
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use editor::Editor;
|
||||
use gpui::{
|
||||
elements::{
|
||||
ChildView, EventHandler, Flex, Label, ParentElement, ScrollTarget, UniformList,
|
||||
UniformListState,
|
||||
ChildView, Flex, Label, MouseEventHandler, MouseState, ParentElement, ScrollTarget,
|
||||
UniformList, UniformListState,
|
||||
},
|
||||
geometry::vector::{vec2f, Vector2F},
|
||||
keymap, AppContext, Axis, Element, ElementBox, Entity, MutableAppContext, RenderContext, Task,
|
||||
View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
keymap,
|
||||
platform::CursorStyle,
|
||||
AppContext, Axis, Element, ElementBox, Entity, MutableAppContext, RenderContext, Task, View,
|
||||
ViewContext, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use settings::Settings;
|
||||
use std::cmp;
|
||||
|
@ -29,7 +31,13 @@ pub trait PickerDelegate: View {
|
|||
fn update_matches(&mut self, query: String, cx: &mut ViewContext<Self>) -> Task<()>;
|
||||
fn confirm(&mut self, cx: &mut ViewContext<Self>);
|
||||
fn dismiss(&mut self, cx: &mut ViewContext<Self>);
|
||||
fn render_match(&self, ix: usize, selected: bool, cx: &AppContext) -> ElementBox;
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
state: &MouseState,
|
||||
selected: bool,
|
||||
cx: &AppContext,
|
||||
) -> ElementBox;
|
||||
fn center_selection_after_match_updates(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -73,18 +81,18 @@ impl<D: PickerDelegate> View for Picker<D> {
|
|||
self.list_state.clone(),
|
||||
match_count,
|
||||
move |mut range, items, cx| {
|
||||
let cx = cx.as_ref();
|
||||
let delegate = delegate.upgrade(cx).unwrap();
|
||||
let delegate = delegate.read(cx);
|
||||
let selected_ix = delegate.selected_index();
|
||||
range.end = cmp::min(range.end, delegate.match_count());
|
||||
let selected_ix = delegate.read(cx).selected_index();
|
||||
range.end = cmp::min(range.end, delegate.read(cx).match_count());
|
||||
items.extend(range.map(move |ix| {
|
||||
EventHandler::new(delegate.render_match(ix, ix == selected_ix, cx))
|
||||
.on_mouse_down(move |cx| {
|
||||
cx.dispatch_action(SelectIndex(ix));
|
||||
true
|
||||
})
|
||||
.boxed()
|
||||
MouseEventHandler::new::<D, _, _>(ix, cx, |state, cx| {
|
||||
delegate
|
||||
.read(cx)
|
||||
.render_match(ix, state, ix == selected_ix, cx)
|
||||
})
|
||||
.on_mouse_down(move |cx| cx.dispatch_action(SelectIndex(ix)))
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.boxed()
|
||||
}));
|
||||
},
|
||||
)
|
||||
|
|
|
@ -220,14 +220,17 @@ impl PickerDelegate for ProjectSymbolsView {
|
|||
Task::ready(())
|
||||
}
|
||||
|
||||
fn render_match(&self, ix: usize, selected: bool, cx: &AppContext) -> ElementBox {
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
mouse_state: &MouseState,
|
||||
selected: bool,
|
||||
cx: &AppContext,
|
||||
) -> ElementBox {
|
||||
let string_match = &self.matches[ix];
|
||||
let settings = cx.global::<Settings>();
|
||||
let style = if selected {
|
||||
&settings.theme.picker.active_item
|
||||
} else {
|
||||
&settings.theme.picker.item
|
||||
};
|
||||
let style = &settings.theme.picker.item;
|
||||
let current_style = style.style_for(mouse_state, selected);
|
||||
let symbol = &self.symbols[string_match.candidate_id];
|
||||
let syntax_runs = styled_runs_for_code_label(&symbol.label, &settings.theme.editor.syntax);
|
||||
|
||||
|
@ -246,11 +249,11 @@ impl PickerDelegate for ProjectSymbolsView {
|
|||
|
||||
Flex::column()
|
||||
.with_child(
|
||||
Text::new(symbol.label.text.clone(), style.label.text.clone())
|
||||
Text::new(symbol.label.text.clone(), current_style.label.text.clone())
|
||||
.with_soft_wrap(false)
|
||||
.with_highlights(combine_syntax_and_fuzzy_match_highlights(
|
||||
&symbol.label.text,
|
||||
style.label.text.clone().into(),
|
||||
current_style.label.text.clone().into(),
|
||||
syntax_runs,
|
||||
&string_match.positions,
|
||||
))
|
||||
|
@ -259,10 +262,10 @@ impl PickerDelegate for ProjectSymbolsView {
|
|||
.with_child(
|
||||
// Avoid styling the path differently when it is selected, since
|
||||
// the symbol's syntax highlighting doesn't change when selected.
|
||||
Label::new(path.to_string(), settings.theme.picker.item.label.clone()).boxed(),
|
||||
Label::new(path.to_string(), style.default.label.clone()).boxed(),
|
||||
)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.with_style(current_style.container)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ mod theme_registry;
|
|||
|
||||
use gpui::{
|
||||
color::Color,
|
||||
elements::{ContainerStyle, ImageStyle, LabelStyle},
|
||||
elements::{ContainerStyle, ImageStyle, LabelStyle, MouseState},
|
||||
fonts::{HighlightStyle, TextStyle},
|
||||
Border,
|
||||
};
|
||||
|
@ -229,7 +229,7 @@ pub struct ProjectPanelEntry {
|
|||
|
||||
#[derive(Debug, Deserialize, Default)]
|
||||
pub struct CommandPalette {
|
||||
pub key: ContainedLabel,
|
||||
pub key: Interactive<ContainedLabel>,
|
||||
pub keystroke_spacing: f32,
|
||||
}
|
||||
|
||||
|
@ -293,8 +293,7 @@ pub struct Picker {
|
|||
pub container: ContainerStyle,
|
||||
pub empty: ContainedLabel,
|
||||
pub input_editor: FieldEditor,
|
||||
pub item: ContainedLabel,
|
||||
pub active_item: ContainedLabel,
|
||||
pub item: Interactive<ContainedLabel>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
|
@ -419,16 +418,23 @@ pub struct Interactive<T> {
|
|||
}
|
||||
|
||||
impl<T> Interactive<T> {
|
||||
pub fn active(&self) -> &T {
|
||||
self.active.as_ref().unwrap_or(&self.default)
|
||||
}
|
||||
|
||||
pub fn hover(&self) -> &T {
|
||||
self.hover.as_ref().unwrap_or(&self.default)
|
||||
}
|
||||
|
||||
pub fn active_hover(&self) -> &T {
|
||||
self.active_hover.as_ref().unwrap_or(self.active())
|
||||
pub fn style_for(&self, state: &MouseState, active: bool) -> &T {
|
||||
if active {
|
||||
if state.hovered {
|
||||
self.active_hover
|
||||
.as_ref()
|
||||
.or(self.active.as_ref())
|
||||
.unwrap_or(&self.default)
|
||||
} else {
|
||||
self.active.as_ref().unwrap_or(&self.default)
|
||||
}
|
||||
} else {
|
||||
if state.hovered {
|
||||
self.hover.as_ref().unwrap_or(&self.default)
|
||||
} else {
|
||||
&self.default
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -203,15 +203,17 @@ impl PickerDelegate for ThemeSelector {
|
|||
})
|
||||
}
|
||||
|
||||
fn render_match(&self, ix: usize, selected: bool, cx: &AppContext) -> ElementBox {
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
mouse_state: &MouseState,
|
||||
selected: bool,
|
||||
cx: &AppContext,
|
||||
) -> ElementBox {
|
||||
let settings = cx.global::<Settings>();
|
||||
let theme = &settings.theme;
|
||||
let theme_match = &self.matches[ix];
|
||||
let style = if selected {
|
||||
&theme.picker.active_item
|
||||
} else {
|
||||
&theme.picker.item
|
||||
};
|
||||
let style = theme.picker.item.style_for(mouse_state, selected);
|
||||
|
||||
Label::new(theme_match.string.clone(), style.label.clone())
|
||||
.with_highlights(theme_match.positions.clone())
|
||||
|
|
|
@ -193,13 +193,7 @@ impl View for SidebarButtons {
|
|||
Flex::row()
|
||||
.with_children(items.iter().enumerate().map(|(ix, item)| {
|
||||
MouseEventHandler::new::<Self, _, _>(ix, cx, move |state, _| {
|
||||
let style = if Some(ix) == active_ix {
|
||||
item_style.active()
|
||||
} else if state.hovered {
|
||||
item_style.hover()
|
||||
} else {
|
||||
&item_style.default
|
||||
};
|
||||
let style = item_style.style_for(state, Some(ix) == active_ix);
|
||||
Svg::new(item.icon_path)
|
||||
.with_color(style.icon_color)
|
||||
.constrained()
|
||||
|
|
|
@ -1574,11 +1574,11 @@ impl Workspace {
|
|||
} else {
|
||||
Some(
|
||||
MouseEventHandler::new::<Authenticate, _, _>(0, cx, |state, _| {
|
||||
let style = if state.hovered {
|
||||
&theme.workspace.titlebar.sign_in_prompt.hover()
|
||||
} else {
|
||||
&theme.workspace.titlebar.sign_in_prompt.default
|
||||
};
|
||||
let style = theme
|
||||
.workspace
|
||||
.titlebar
|
||||
.sign_in_prompt
|
||||
.style_for(state, false);
|
||||
Label::new("Sign in".to_string(), style.text.clone())
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
|
@ -1649,18 +1649,11 @@ impl Workspace {
|
|||
{
|
||||
Some(
|
||||
MouseEventHandler::new::<ToggleShare, _, _>(0, cx, |state, cx| {
|
||||
let style = &theme.workspace.titlebar.share_icon;
|
||||
let style = if self.project().read(cx).is_shared() {
|
||||
if state.hovered {
|
||||
style.active_hover()
|
||||
} else {
|
||||
&style.active()
|
||||
}
|
||||
} else if state.hovered {
|
||||
&style.active()
|
||||
} else {
|
||||
&style.default
|
||||
};
|
||||
let style = &theme
|
||||
.workspace
|
||||
.titlebar
|
||||
.share_icon
|
||||
.style_for(state, self.project().read(cx).is_shared());
|
||||
Svg::new("icons/share.svg")
|
||||
.with_color(style.color)
|
||||
.constrained()
|
||||
|
|
|
@ -18,6 +18,9 @@ export default function commandPalette(theme: Theme) {
|
|||
margin: {
|
||||
left: 2
|
||||
},
|
||||
active: {
|
||||
text: text(theme, "mono", "active", { size: "xs" }),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,30 +2,28 @@ import Theme from "../themes/theme";
|
|||
import { backgroundColor, border, player, shadow, text } from "./components";
|
||||
|
||||
export default function picker(theme: Theme) {
|
||||
const item = {
|
||||
padding: {
|
||||
bottom: 4,
|
||||
left: 12,
|
||||
right: 12,
|
||||
top: 4,
|
||||
},
|
||||
cornerRadius: 8,
|
||||
text: text(theme, "sans", "secondary"),
|
||||
highlightText: text(theme, "sans", "feature", { weight: "bold" }),
|
||||
};
|
||||
|
||||
const activeItem = {
|
||||
...item,
|
||||
background: backgroundColor(theme, 300, "active"),
|
||||
text: text(theme, "sans", "primary"),
|
||||
};
|
||||
|
||||
return {
|
||||
background: backgroundColor(theme, 300),
|
||||
cornerRadius: 8,
|
||||
padding: 8,
|
||||
item,
|
||||
activeItem,
|
||||
item: {
|
||||
padding: {
|
||||
bottom: 4,
|
||||
left: 12,
|
||||
right: 12,
|
||||
top: 4,
|
||||
},
|
||||
cornerRadius: 8,
|
||||
text: text(theme, "sans", "secondary"),
|
||||
highlightText: text(theme, "sans", "feature", { weight: "bold" }),
|
||||
active: {
|
||||
background: backgroundColor(theme, 300, "active"),
|
||||
text: text(theme, "sans", "primary"),
|
||||
},
|
||||
hover: {
|
||||
background: backgroundColor(theme, 300, "hovered"),
|
||||
}
|
||||
},
|
||||
border: border(theme, "primary"),
|
||||
empty: {
|
||||
text: text(theme, "sans", "placeholder"),
|
||||
|
|
Loading…
Reference in a new issue