In theme, add an InputEditorSyle for styling small editors
Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
co-authored by
Antonio Scandurra
parent
f59e02cf25
commit
1c43121ae0
+1
-1
@@ -26,7 +26,7 @@ pub struct TextStyle {
|
||||
pub font_properties: Properties,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HighlightStyle {
|
||||
pub color: Color,
|
||||
pub font_properties: Properties,
|
||||
|
||||
@@ -65,6 +65,11 @@ corner_radius = 6
|
||||
border = { color = "#000000", width = 1 }
|
||||
background = "$surface.0"
|
||||
|
||||
[chat_panel.input_editor]
|
||||
text = "$text.1.color"
|
||||
background = "$surface.1"
|
||||
selection = "$selection.host"
|
||||
|
||||
[selector]
|
||||
background = "$surface.2"
|
||||
text = "$text.0"
|
||||
@@ -72,6 +77,7 @@ padding = 6
|
||||
margin.top = 12
|
||||
corner_radius = 6
|
||||
shadow = { offset = [0, 0], blur = 12, color = "#00000088" }
|
||||
input_editor = "$chat_panel.input_editor"
|
||||
|
||||
[selector.item]
|
||||
background = "#424344"
|
||||
@@ -85,15 +91,11 @@ extends = "$selector.item"
|
||||
background = "#094771"
|
||||
|
||||
[editor]
|
||||
text = "$text.1.color"
|
||||
background = "$surface.1"
|
||||
gutter_background = "$surface.1"
|
||||
active_line_background = "$surface.2"
|
||||
line_number = "$text.2.color"
|
||||
line_number_active = "$text.0.color"
|
||||
replicas = [
|
||||
{ selection = "#264f78", cursor = "$text.0.color" },
|
||||
{ selection = "#504f31", cursor = "#fcf154" },
|
||||
]
|
||||
|
||||
[syntax]
|
||||
default = "$text.1.color"
|
||||
selection = "$selection.host"
|
||||
guest_selections = "$selection.guests"
|
||||
|
||||
@@ -11,6 +11,10 @@ base = { family = "Helvetica", size = 14.0 }
|
||||
1 = { extends = "$text.base", color = "#b3b3b3" }
|
||||
2 = { extends = "$text.base", color = "#7b7d80" }
|
||||
|
||||
[selection]
|
||||
host = { selection = "#264f78", cursor = "$text.0.color" }
|
||||
guests = [{ selection = "#504f31", cursor = "#fcf154" }]
|
||||
|
||||
[status]
|
||||
good = "#4fac63"
|
||||
info = "#3c5dd4"
|
||||
|
||||
@@ -12,6 +12,10 @@ base = { family = "Helvetica", size = 14.0 }
|
||||
1 = { extends = "$text.base", color = "#111111" }
|
||||
2 = { extends = "$text.base", color = "#333333" }
|
||||
|
||||
[selection]
|
||||
host = { selection = "#264f78", cursor = "$text.0.color" }
|
||||
guests = [{ selection = "#504f31", cursor = "#fcf154" }]
|
||||
|
||||
[status]
|
||||
good = "#4fac63"
|
||||
info = "#3c5dd4"
|
||||
|
||||
@@ -46,7 +46,12 @@ impl ChatPanel {
|
||||
settings: watch::Receiver<Settings>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let input_editor = cx.add_view(|cx| Editor::auto_height(settings.clone(), cx));
|
||||
let input_editor = cx.add_view(|cx| {
|
||||
Editor::auto_height(settings.clone(), cx).with_style({
|
||||
let settings = settings.clone();
|
||||
move |_| settings.borrow().theme.chat_panel.input_editor.as_editor()
|
||||
})
|
||||
});
|
||||
let channel_select = cx.add_view(|cx| {
|
||||
let channel_list = channel_list.clone();
|
||||
Select::new(0, cx, {
|
||||
|
||||
+6
-1
@@ -2397,6 +2397,7 @@ impl Snapshot {
|
||||
pub fn layout_lines(
|
||||
&mut self,
|
||||
mut rows: Range<u32>,
|
||||
style: &EditorStyle,
|
||||
font_cache: &FontCache,
|
||||
layout_cache: &TextLayoutCache,
|
||||
) -> Result<Vec<text_layout::Line>> {
|
||||
@@ -2433,7 +2434,11 @@ impl Snapshot {
|
||||
}
|
||||
|
||||
if !line_chunk.is_empty() && !line_exceeded_max_len {
|
||||
let style = self.theme.syntax.highlight_style(style_ix);
|
||||
let style = self
|
||||
.theme
|
||||
.syntax
|
||||
.highlight_style(style_ix)
|
||||
.unwrap_or(style.text.clone());
|
||||
// Avoid a lookup if the font properties match the previous ones.
|
||||
let font_id = if style.font_properties == prev_font_properties {
|
||||
prev_font_id
|
||||
|
||||
@@ -661,13 +661,10 @@ mod tests {
|
||||
(function_item name: (identifier) @fn.name)"#,
|
||||
)
|
||||
.unwrap();
|
||||
let theme = SyntaxTheme::new(
|
||||
Default::default(),
|
||||
vec![
|
||||
("mod.body".to_string(), Color::from_u32(0xff0000ff).into()),
|
||||
("fn.name".to_string(), Color::from_u32(0x00ff00ff).into()),
|
||||
],
|
||||
);
|
||||
let theme = SyntaxTheme::new(vec![
|
||||
("mod.body".to_string(), Color::from_u32(0xff0000ff).into()),
|
||||
("fn.name".to_string(), Color::from_u32(0x00ff00ff).into()),
|
||||
]);
|
||||
let lang = Arc::new(Language {
|
||||
config: LanguageConfig {
|
||||
name: "Test".to_string(),
|
||||
@@ -754,13 +751,10 @@ mod tests {
|
||||
(function_item name: (identifier) @fn.name)"#,
|
||||
)
|
||||
.unwrap();
|
||||
let theme = SyntaxTheme::new(
|
||||
Default::default(),
|
||||
vec![
|
||||
("mod.body".to_string(), Color::from_u32(0xff0000ff).into()),
|
||||
("fn.name".to_string(), Color::from_u32(0x00ff00ff).into()),
|
||||
],
|
||||
);
|
||||
let theme = SyntaxTheme::new(vec![
|
||||
("mod.body".to_string(), Color::from_u32(0xff0000ff).into()),
|
||||
("fn.name".to_string(), Color::from_u32(0x00ff00ff).into()),
|
||||
]);
|
||||
let lang = Arc::new(Language {
|
||||
config: LanguageConfig {
|
||||
name: "Test".to_string(),
|
||||
|
||||
@@ -280,7 +280,12 @@ impl EditorElement {
|
||||
let content_origin = bounds.origin() + layout.text_offset;
|
||||
|
||||
for (replica_id, selections) in &layout.selections {
|
||||
let replica_theme = theme.replicas[*replica_id as usize % theme.replicas.len()];
|
||||
let style_ix = *replica_id as usize % (theme.guest_selections.len() + 1);
|
||||
let style = if style_ix == 0 {
|
||||
&theme.selection
|
||||
} else {
|
||||
&theme.guest_selections[style_ix - 1]
|
||||
};
|
||||
|
||||
for selection in selections {
|
||||
if selection.start != selection.end {
|
||||
@@ -294,7 +299,7 @@ impl EditorElement {
|
||||
};
|
||||
|
||||
let selection = Selection {
|
||||
color: replica_theme.selection,
|
||||
color: style.selection,
|
||||
line_height: layout.line_height,
|
||||
start_y: content_origin.y() + row_range.start as f32 * layout.line_height
|
||||
- scroll_top,
|
||||
@@ -337,7 +342,7 @@ impl EditorElement {
|
||||
- scroll_left;
|
||||
let y = selection.end.row() as f32 * layout.line_height - scroll_top;
|
||||
cursors.push(Cursor {
|
||||
color: replica_theme.cursor,
|
||||
color: style.cursor,
|
||||
origin: content_origin + vec2f(x, y),
|
||||
line_height: layout.line_height,
|
||||
});
|
||||
@@ -507,8 +512,12 @@ impl Element for EditorElement {
|
||||
};
|
||||
|
||||
let mut max_visible_line_width = 0.0;
|
||||
let line_layouts = match snapshot.layout_lines(start_row..end_row, font_cache, layout_cache)
|
||||
{
|
||||
let line_layouts = match snapshot.layout_lines(
|
||||
start_row..end_row,
|
||||
&self.style,
|
||||
font_cache,
|
||||
layout_cache,
|
||||
) {
|
||||
Err(error) => {
|
||||
log::error!("error laying out lines: {}", error);
|
||||
return (size, None);
|
||||
|
||||
+14
-9
@@ -30,7 +30,7 @@ pub struct FileFinder {
|
||||
handle: WeakViewHandle<Self>,
|
||||
settings: watch::Receiver<Settings>,
|
||||
workspace: WeakViewHandle<Workspace>,
|
||||
query_buffer: ViewHandle<Editor>,
|
||||
query_editor: ViewHandle<Editor>,
|
||||
search_count: usize,
|
||||
latest_search_id: usize,
|
||||
latest_search_did_cancel: bool,
|
||||
@@ -86,7 +86,7 @@ impl View for FileFinder {
|
||||
ConstrainedBox::new(
|
||||
Container::new(
|
||||
Flex::new(Axis::Vertical)
|
||||
.with_child(ChildView::new(self.query_buffer.id()).boxed())
|
||||
.with_child(ChildView::new(self.query_editor.id()).boxed())
|
||||
.with_child(Expanded::new(1.0, self.render_matches()).boxed())
|
||||
.boxed(),
|
||||
)
|
||||
@@ -102,7 +102,7 @@ impl View for FileFinder {
|
||||
}
|
||||
|
||||
fn on_focus(&mut self, cx: &mut ViewContext<Self>) {
|
||||
cx.focus(&self.query_buffer);
|
||||
cx.focus(&self.query_editor);
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> keymap::Context {
|
||||
@@ -266,15 +266,20 @@ impl FileFinder {
|
||||
) -> Self {
|
||||
cx.observe(&workspace, Self::workspace_updated).detach();
|
||||
|
||||
let query_buffer = cx.add_view(|cx| Editor::single_line(settings.clone(), cx));
|
||||
cx.subscribe(&query_buffer, Self::on_query_editor_event)
|
||||
let query_editor = cx.add_view(|cx| {
|
||||
Editor::single_line(settings.clone(), cx).with_style({
|
||||
let settings = settings.clone();
|
||||
move |_| settings.borrow().theme.selector.input_editor.as_editor()
|
||||
})
|
||||
});
|
||||
cx.subscribe(&query_editor, Self::on_query_editor_event)
|
||||
.detach();
|
||||
|
||||
Self {
|
||||
handle: cx.handle().downgrade(),
|
||||
settings,
|
||||
workspace: workspace.downgrade(),
|
||||
query_buffer,
|
||||
query_editor,
|
||||
search_count: 0,
|
||||
latest_search_id: 0,
|
||||
latest_search_did_cancel: false,
|
||||
@@ -287,7 +292,7 @@ impl FileFinder {
|
||||
}
|
||||
|
||||
fn workspace_updated(&mut self, _: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) {
|
||||
let query = self.query_buffer.update(cx, |buffer, cx| buffer.text(cx));
|
||||
let query = self.query_editor.update(cx, |buffer, cx| buffer.text(cx));
|
||||
if let Some(task) = self.spawn_search(query, cx) {
|
||||
task.detach();
|
||||
}
|
||||
@@ -301,7 +306,7 @@ impl FileFinder {
|
||||
) {
|
||||
match event {
|
||||
editor::Event::Edited => {
|
||||
let query = self.query_buffer.update(cx, |buffer, cx| buffer.text(cx));
|
||||
let query = self.query_editor.update(cx, |buffer, cx| buffer.text(cx));
|
||||
if query.is_empty() {
|
||||
self.latest_search_id = util::post_inc(&mut self.search_count);
|
||||
self.matches.clear();
|
||||
@@ -460,7 +465,7 @@ mod tests {
|
||||
.downcast::<FileFinder>()
|
||||
.unwrap()
|
||||
});
|
||||
let query_buffer = cx.read(|cx| finder.read(cx).query_buffer.clone());
|
||||
let query_buffer = cx.read(|cx| finder.read(cx).query_editor.clone());
|
||||
|
||||
let chain = vec![finder.id(), query_buffer.id()];
|
||||
cx.dispatch_action(window_id, chain.clone(), Insert("b".into()));
|
||||
|
||||
+36
-21
@@ -7,7 +7,7 @@ use gpui::{
|
||||
elements::{ContainerStyle, LabelStyle},
|
||||
fonts::{HighlightStyle, TextStyle},
|
||||
};
|
||||
use serde::{de, Deserialize};
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub use highlight_map::*;
|
||||
@@ -28,7 +28,6 @@ pub struct Theme {
|
||||
|
||||
pub struct SyntaxTheme {
|
||||
highlights: Vec<(String, HighlightStyle)>,
|
||||
default_style: HighlightStyle,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -69,6 +68,7 @@ pub struct ChatPanel {
|
||||
pub container: ContainerStyle,
|
||||
pub message: ChatMessage,
|
||||
pub channel_select: ChannelSelect,
|
||||
pub input_editor: InputEditorStyle,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -107,6 +107,7 @@ pub struct Selector {
|
||||
#[serde(flatten)]
|
||||
pub label: LabelStyle,
|
||||
|
||||
pub input_editor: InputEditorStyle,
|
||||
pub item: ContainedLabel,
|
||||
pub active_item: ContainedLabel,
|
||||
}
|
||||
@@ -129,33 +130,38 @@ pub struct ContainedLabel {
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
pub struct EditorStyle {
|
||||
pub text: HighlightStyle,
|
||||
pub background: Color,
|
||||
pub selection: SelectionStyle,
|
||||
pub gutter_background: Color,
|
||||
pub active_line_background: Color,
|
||||
pub line_number: Color,
|
||||
pub line_number_active: Color,
|
||||
pub replicas: Vec<Replica>,
|
||||
pub guest_selections: Vec<SelectionStyle>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
pub struct InputEditorStyle {
|
||||
pub text: HighlightStyle,
|
||||
pub background: Color,
|
||||
pub selection: SelectionStyle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default, Deserialize)]
|
||||
pub struct Replica {
|
||||
pub struct SelectionStyle {
|
||||
pub cursor: Color,
|
||||
pub selection: Color,
|
||||
}
|
||||
|
||||
impl SyntaxTheme {
|
||||
pub fn new(default_style: HighlightStyle, highlights: Vec<(String, HighlightStyle)>) -> Self {
|
||||
Self {
|
||||
default_style,
|
||||
highlights,
|
||||
}
|
||||
pub fn new(highlights: Vec<(String, HighlightStyle)>) -> Self {
|
||||
Self { highlights }
|
||||
}
|
||||
|
||||
pub fn highlight_style(&self, id: HighlightId) -> HighlightStyle {
|
||||
pub fn highlight_style(&self, id: HighlightId) -> Option<HighlightStyle> {
|
||||
self.highlights
|
||||
.get(id.0 as usize)
|
||||
.map(|entry| entry.1.clone())
|
||||
.unwrap_or_else(|| self.default_style.clone())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -167,12 +173,28 @@ impl SyntaxTheme {
|
||||
impl Default for EditorStyle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
text: HighlightStyle {
|
||||
color: Color::from_u32(0xff0000ff),
|
||||
font_properties: Default::default(),
|
||||
},
|
||||
background: Default::default(),
|
||||
gutter_background: Default::default(),
|
||||
active_line_background: Default::default(),
|
||||
line_number: Default::default(),
|
||||
line_number_active: Default::default(),
|
||||
replicas: vec![Default::default()],
|
||||
selection: Default::default(),
|
||||
guest_selections: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InputEditorStyle {
|
||||
pub fn as_editor(&self) -> EditorStyle {
|
||||
EditorStyle {
|
||||
text: self.text.clone(),
|
||||
background: self.background,
|
||||
selection: self.selection,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,16 +204,9 @@ impl<'de> Deserialize<'de> for SyntaxTheme {
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let mut syntax_data: HashMap<String, HighlightStyle> =
|
||||
Deserialize::deserialize(deserializer)?;
|
||||
|
||||
let mut result = Self {
|
||||
highlights: Vec::<(String, HighlightStyle)>::new(),
|
||||
default_style: syntax_data
|
||||
.remove("default")
|
||||
.ok_or_else(|| de::Error::custom("must specify a default color in syntax theme"))?,
|
||||
};
|
||||
let syntax_data: HashMap<String, HighlightStyle> = Deserialize::deserialize(deserializer)?;
|
||||
|
||||
let mut result = Self::new(Vec::new());
|
||||
for (key, style) in syntax_data {
|
||||
match result
|
||||
.highlights
|
||||
|
||||
@@ -69,7 +69,6 @@ mod tests {
|
||||
#[test]
|
||||
fn test_highlight_map() {
|
||||
let theme = SyntaxTheme::new(
|
||||
Default::default(),
|
||||
[
|
||||
("function", Color::from_u32(0x100000ff)),
|
||||
("function.method", Color::from_u32(0x200000ff)),
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct ThemeSelector {
|
||||
settings: watch::Receiver<Settings>,
|
||||
registry: Arc<ThemeRegistry>,
|
||||
matches: Vec<StringMatch>,
|
||||
query_buffer: ViewHandle<Editor>,
|
||||
query_editor: ViewHandle<Editor>,
|
||||
list_state: UniformListState,
|
||||
selected_index: usize,
|
||||
}
|
||||
@@ -60,15 +60,21 @@ impl ThemeSelector {
|
||||
registry: Arc<ThemeRegistry>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let query_buffer = cx.add_view(|cx| Editor::single_line(settings.clone(), cx));
|
||||
cx.subscribe(&query_buffer, Self::on_query_editor_event)
|
||||
let query_editor = cx.add_view(|cx| {
|
||||
Editor::single_line(settings.clone(), cx).with_style({
|
||||
let settings = settings.clone();
|
||||
move |_| settings.borrow().theme.selector.input_editor.as_editor()
|
||||
})
|
||||
});
|
||||
|
||||
cx.subscribe(&query_editor, Self::on_query_editor_event)
|
||||
.detach();
|
||||
|
||||
let mut this = Self {
|
||||
settings,
|
||||
settings_tx,
|
||||
registry,
|
||||
query_buffer,
|
||||
query_editor,
|
||||
matches: Vec::new(),
|
||||
list_state: Default::default(),
|
||||
selected_index: 0,
|
||||
@@ -151,7 +157,7 @@ impl ThemeSelector {
|
||||
string: name,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let query = self.query_buffer.update(cx, |buffer, cx| buffer.text(cx));
|
||||
let query = self.query_editor.update(cx, |buffer, cx| buffer.text(cx));
|
||||
|
||||
self.matches = if query.is_empty() {
|
||||
candidates
|
||||
@@ -276,7 +282,7 @@ impl View for ThemeSelector {
|
||||
ConstrainedBox::new(
|
||||
Container::new(
|
||||
Flex::new(Axis::Vertical)
|
||||
.with_child(ChildView::new(self.query_buffer.id()).boxed())
|
||||
.with_child(ChildView::new(self.query_editor.id()).boxed())
|
||||
.with_child(Expanded::new(1.0, self.render_matches(cx)).boxed())
|
||||
.boxed(),
|
||||
)
|
||||
@@ -292,7 +298,7 @@ impl View for ThemeSelector {
|
||||
}
|
||||
|
||||
fn on_focus(&mut self, cx: &mut ViewContext<Self>) {
|
||||
cx.focus(&self.query_buffer);
|
||||
cx.focus(&self.query_editor);
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> keymap::Context {
|
||||
|
||||
Reference in New Issue
Block a user