Add a with_style method to Editor

This commit is contained in:
Max Brunsfeld 2021-09-01 17:13:48 -07:00
parent 6821c47e3d
commit 007d6f5eca
4 changed files with 51 additions and 22 deletions

View file

@ -4,7 +4,8 @@ mod element;
pub mod movement; pub mod movement;
use crate::{ use crate::{
settings::{HighlightId, Settings, Theme}, settings::{HighlightId, Settings},
theme::{EditorStyle, Theme},
time::ReplicaId, time::ReplicaId,
util::{post_inc, Bias}, util::{post_inc, Bias},
workspace, workspace,
@ -287,6 +288,7 @@ pub struct Editor {
scroll_position: Vector2F, scroll_position: Vector2F,
scroll_top_anchor: Anchor, scroll_top_anchor: Anchor,
autoscroll_requested: bool, autoscroll_requested: bool,
build_style: Option<Box<dyn FnMut(&mut MutableAppContext) -> EditorStyle>>,
settings: watch::Receiver<Settings>, settings: watch::Receiver<Settings>,
focused: bool, focused: bool,
cursors_visible: bool, cursors_visible: bool,
@ -366,6 +368,7 @@ impl Editor {
next_selection_id, next_selection_id,
add_selections_state: None, add_selections_state: None,
select_larger_syntax_node_stack: Vec::new(), select_larger_syntax_node_stack: Vec::new(),
build_style: None,
scroll_position: Vector2F::zero(), scroll_position: Vector2F::zero(),
scroll_top_anchor: Anchor::min(), scroll_top_anchor: Anchor::min(),
autoscroll_requested: false, autoscroll_requested: false,
@ -378,6 +381,14 @@ impl Editor {
} }
} }
pub fn with_style(
mut self,
f: impl 'static + FnMut(&mut MutableAppContext) -> EditorStyle,
) -> Self {
self.build_style = Some(Box::new(f));
self
}
pub fn replica_id(&self, cx: &AppContext) -> ReplicaId { pub fn replica_id(&self, cx: &AppContext) -> ReplicaId {
self.buffer.read(cx).replica_id() self.buffer.read(cx).replica_id()
} }
@ -2522,8 +2533,12 @@ impl Entity for Editor {
} }
impl View for Editor { impl View for Editor {
fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
EditorElement::new(self.handle.clone()).boxed() let style = self
.build_style
.as_mut()
.map_or(Default::default(), |build| build(cx));
EditorElement::new(self.handle.clone(), style).boxed()
} }
fn ui_name() -> &'static str { fn ui_name() -> &'static str {
@ -2563,7 +2578,8 @@ impl workspace::Item for Buffer {
settings: watch::Receiver<Settings>, settings: watch::Receiver<Settings>,
cx: &mut ViewContext<Self::View>, cx: &mut ViewContext<Self::View>,
) -> Self::View { ) -> Self::View {
Editor::for_buffer(handle, settings, cx) Editor::for_buffer(handle, settings.clone(), cx)
.with_style(move |_| settings.borrow().theme.editor.clone())
} }
} }

View file

@ -1,5 +1,5 @@
use super::{DisplayPoint, Editor, EditorMode, Insert, Scroll, Select, SelectPhase, Snapshot}; use super::{DisplayPoint, Editor, EditorMode, Insert, Scroll, Select, SelectPhase, Snapshot};
use crate::time::ReplicaId; use crate::{theme::EditorStyle, time::ReplicaId};
use gpui::{ use gpui::{
color::Color, color::Color,
geometry::{ geometry::{
@ -22,11 +22,12 @@ use std::{
pub struct EditorElement { pub struct EditorElement {
view: WeakViewHandle<Editor>, view: WeakViewHandle<Editor>,
style: EditorStyle,
} }
impl EditorElement { impl EditorElement {
pub fn new(view: WeakViewHandle<Editor>) -> Self { pub fn new(view: WeakViewHandle<Editor>, style: EditorStyle) -> Self {
Self { view } Self { view, style }
} }
fn view<'a>(&self, cx: &'a AppContext) -> &'a Editor { fn view<'a>(&self, cx: &'a AppContext) -> &'a Editor {
@ -189,17 +190,15 @@ impl EditorElement {
let bounds = gutter_bounds.union_rect(text_bounds); let bounds = gutter_bounds.union_rect(text_bounds);
let scroll_top = layout.snapshot.scroll_position().y() * layout.line_height; let scroll_top = layout.snapshot.scroll_position().y() * layout.line_height;
let editor = self.view(cx.app); let editor = self.view(cx.app);
let settings = editor.settings.borrow();
let theme = &settings.theme;
cx.scene.push_quad(Quad { cx.scene.push_quad(Quad {
bounds: gutter_bounds, bounds: gutter_bounds,
background: Some(theme.editor.gutter_background), background: Some(self.style.gutter_background),
border: Border::new(0., Color::transparent_black()), border: Border::new(0., Color::transparent_black()),
corner_radius: 0., corner_radius: 0.,
}); });
cx.scene.push_quad(Quad { cx.scene.push_quad(Quad {
bounds: text_bounds, bounds: text_bounds,
background: Some(theme.editor.background), background: Some(self.style.background),
border: Border::new(0., Color::transparent_black()), border: Border::new(0., Color::transparent_black()),
corner_radius: 0., corner_radius: 0.,
}); });
@ -226,7 +225,7 @@ impl EditorElement {
); );
cx.scene.push_quad(Quad { cx.scene.push_quad(Quad {
bounds: RectF::new(origin, size), bounds: RectF::new(origin, size),
background: Some(theme.editor.active_line_background), background: Some(self.style.active_line_background),
border: Border::default(), border: Border::default(),
corner_radius: 0., corner_radius: 0.,
}); });

View file

@ -22,7 +22,7 @@ pub struct Theme {
pub workspace: Workspace, pub workspace: Workspace,
pub chat_panel: ChatPanel, pub chat_panel: ChatPanel,
pub selector: Selector, pub selector: Selector,
pub editor: Editor, pub editor: EditorStyle,
pub syntax: SyntaxTheme, pub syntax: SyntaxTheme,
} }
@ -127,8 +127,8 @@ pub struct ContainedLabel {
pub label: LabelStyle, pub label: LabelStyle,
} }
#[derive(Deserialize)] #[derive(Clone, Deserialize)]
pub struct Editor { pub struct EditorStyle {
pub background: Color, pub background: Color,
pub gutter_background: Color, pub gutter_background: Color,
pub active_line_background: Color, pub active_line_background: Color,
@ -137,7 +137,7 @@ pub struct Editor {
pub replicas: Vec<Replica>, pub replicas: Vec<Replica>,
} }
#[derive(Clone, Copy, Deserialize)] #[derive(Clone, Copy, Default, Deserialize)]
pub struct Replica { pub struct Replica {
pub cursor: Color, pub cursor: Color,
pub selection: Color, pub selection: Color,
@ -164,6 +164,19 @@ impl SyntaxTheme {
} }
} }
impl Default for EditorStyle {
fn default() -> Self {
Self {
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()],
}
}
}
impl<'de> Deserialize<'de> for SyntaxTheme { impl<'de> Deserialize<'de> for SyntaxTheme {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where

View file

@ -4,7 +4,7 @@ pub mod sidebar;
use crate::{ use crate::{
chat_panel::ChatPanel, chat_panel::ChatPanel,
editor::{Buffer, Editor}, editor::Buffer,
fs::Fs, fs::Fs,
language::LanguageRegistry, language::LanguageRegistry,
project_browser::ProjectBrowser, project_browser::ProjectBrowser,
@ -565,11 +565,12 @@ impl Workspace {
pub fn open_new_file(&mut self, _: &OpenNew, cx: &mut ViewContext<Self>) { pub fn open_new_file(&mut self, _: &OpenNew, cx: &mut ViewContext<Self>) {
let buffer = cx.add_model(|cx| Buffer::new(0, "", cx)); let buffer = cx.add_model(|cx| Buffer::new(0, "", cx));
let buffer_view = let item_handle = ItemHandle::downgrade(&buffer);
cx.add_view(|cx| Editor::for_buffer(buffer.clone(), self.settings.clone(), cx)); let view = item_handle
self.items.push(ItemHandle::downgrade(&buffer)); .add_view(cx.window_id(), self.settings.clone(), cx)
self.active_pane() .unwrap();
.add_item_view(Box::new(buffer_view), cx.as_mut()); self.items.push(item_handle);
self.active_pane().add_item_view(view, cx.as_mut());
} }
#[must_use] #[must_use]