code-editor: Improve CodeEditor to has default themes. (#900)
This commit is contained in:
parent
ebe10e20c7
commit
1cbbf6ef18
11 changed files with 94 additions and 91 deletions
|
|
@ -5,7 +5,7 @@ use gpui_component::{
|
||||||
h_flex,
|
h_flex,
|
||||||
highlighter::{HighlightTheme, Highlighter},
|
highlighter::{HighlightTheme, Highlighter},
|
||||||
input::{InputEvent, InputState, TabSize, TextInput},
|
input::{InputEvent, InputState, TabSize, TextInput},
|
||||||
v_flex, ActiveTheme as _,
|
v_flex,
|
||||||
};
|
};
|
||||||
use story::Assets;
|
use story::Assets;
|
||||||
|
|
||||||
|
|
@ -13,7 +13,6 @@ pub struct Example {
|
||||||
input_state: Entity<InputState>,
|
input_state: Entity<InputState>,
|
||||||
language_state: Entity<DropdownState<Vec<SharedString>>>,
|
language_state: Entity<DropdownState<Vec<SharedString>>>,
|
||||||
language: SharedString,
|
language: SharedString,
|
||||||
is_dark: bool,
|
|
||||||
line_number: bool,
|
line_number: bool,
|
||||||
_subscribes: Vec<Subscription>,
|
_subscribes: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +25,7 @@ impl Example {
|
||||||
let default_language: SharedString = LANGUAGES[0].into();
|
let default_language: SharedString = LANGUAGES[0].into();
|
||||||
let input_state = cx.new(|cx| {
|
let input_state = cx.new(|cx| {
|
||||||
InputState::new(window, cx)
|
InputState::new(window, cx)
|
||||||
.code_editor(Some(&default_language), &HighlightTheme::default_light())
|
.code_editor(Some(&default_language))
|
||||||
.line_number(true)
|
.line_number(true)
|
||||||
.tab_size(TabSize {
|
.tab_size(TabSize {
|
||||||
tab_size: 4,
|
tab_size: 4,
|
||||||
|
|
@ -63,7 +62,6 @@ impl Example {
|
||||||
input_state,
|
input_state,
|
||||||
language_state,
|
language_state,
|
||||||
language: default_language,
|
language: default_language,
|
||||||
is_dark: false,
|
|
||||||
line_number: true,
|
line_number: true,
|
||||||
_subscribes,
|
_subscribes,
|
||||||
}
|
}
|
||||||
|
|
@ -74,26 +72,21 @@ impl Example {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_highlighter(&mut self, new_language: Option<SharedString>, cx: &mut Context<Self>) {
|
fn update_highlighter(&mut self, new_language: Option<SharedString>, cx: &mut Context<Self>) {
|
||||||
let is_dark = cx.theme().mode.is_dark();
|
|
||||||
let is_language_changed = new_language.is_some();
|
let is_language_changed = new_language.is_some();
|
||||||
if new_language.is_some() {
|
if new_language.is_some() {
|
||||||
self.language = new_language.unwrap();
|
self.language = new_language.unwrap();
|
||||||
}
|
}
|
||||||
let language = self.language.as_ref();
|
let language = self.language.as_ref();
|
||||||
if self.is_dark != is_dark || is_language_changed {
|
if is_language_changed {
|
||||||
self.is_dark = is_dark;
|
|
||||||
self.input_state.update(cx, |state, cx| {
|
self.input_state.update(cx, |state, cx| {
|
||||||
if is_dark {
|
state.set_highlighter(
|
||||||
state.set_highlighter(
|
Highlighter::new(
|
||||||
Highlighter::new(Some(language), &HighlightTheme::default_dark()),
|
Some(language),
|
||||||
cx,
|
&HighlightTheme::default_light(),
|
||||||
);
|
&HighlightTheme::default_dark(),
|
||||||
} else {
|
),
|
||||||
state.set_highlighter(
|
cx,
|
||||||
Highlighter::new(Some(language), &HighlightTheme::default_dark()),
|
);
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,14 @@
|
||||||
use gpui::*;
|
use gpui::*;
|
||||||
use gpui_component::{
|
use gpui_component::{
|
||||||
highlighter::{HighlightTheme, Highlighter},
|
|
||||||
input::{InputState, TabSize, TextInput},
|
input::{InputState, TabSize, TextInput},
|
||||||
resizable::{h_resizable, resizable_panel, ResizableState},
|
resizable::{h_resizable, resizable_panel, ResizableState},
|
||||||
text::TextView,
|
text::TextView,
|
||||||
ActiveTheme as _,
|
|
||||||
};
|
};
|
||||||
use story::Assets;
|
use story::Assets;
|
||||||
|
|
||||||
pub struct Example {
|
pub struct Example {
|
||||||
input_state: Entity<InputState>,
|
input_state: Entity<InputState>,
|
||||||
resizable_state: Entity<ResizableState>,
|
resizable_state: Entity<ResizableState>,
|
||||||
is_dark: bool,
|
|
||||||
_subscribe: Subscription,
|
_subscribe: Subscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,7 +19,7 @@ impl Example {
|
||||||
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
let input_state = cx.new(|cx| {
|
let input_state = cx.new(|cx| {
|
||||||
InputState::new(window, cx)
|
InputState::new(window, cx)
|
||||||
.code_editor(Some(LANG), &HighlightTheme::default_light())
|
.code_editor(Some(LANG))
|
||||||
.tab_size(TabSize {
|
.tab_size(TabSize {
|
||||||
tab_size: 4,
|
tab_size: 4,
|
||||||
hard_tabs: false,
|
hard_tabs: false,
|
||||||
|
|
@ -43,7 +40,6 @@ impl Example {
|
||||||
Self {
|
Self {
|
||||||
input_state,
|
input_state,
|
||||||
resizable_state,
|
resizable_state,
|
||||||
is_dark: false,
|
|
||||||
_subscribe,
|
_subscribe,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -55,24 +51,6 @@ impl Example {
|
||||||
|
|
||||||
impl Render for Example {
|
impl Render for Example {
|
||||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let is_dark = cx.theme().mode.is_dark();
|
|
||||||
if self.is_dark != is_dark {
|
|
||||||
self.is_dark = is_dark;
|
|
||||||
self.input_state.update(cx, |state, cx| {
|
|
||||||
if is_dark {
|
|
||||||
state.set_highlighter(
|
|
||||||
Highlighter::new(Some(LANG), &HighlightTheme::default_dark()),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
state.set_highlighter(
|
|
||||||
Highlighter::new(Some(LANG), &HighlightTheme::default_light()),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
h_resizable("container", self.resizable_state.clone())
|
h_resizable("container", self.resizable_state.clone())
|
||||||
.child(
|
.child(
|
||||||
resizable_panel().child(
|
resizable_panel().child(
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::rc::Rc;
|
||||||
|
|
||||||
use gpui::*;
|
use gpui::*;
|
||||||
use gpui_component::{
|
use gpui_component::{
|
||||||
highlighter::{HighlightTheme, Highlighter},
|
highlighter::HighlightTheme,
|
||||||
input::{InputEvent, InputState, TabSize, TextInput},
|
input::{InputEvent, InputState, TabSize, TextInput},
|
||||||
resizable::{h_resizable, resizable_panel, ResizableState},
|
resizable::{h_resizable, resizable_panel, ResizableState},
|
||||||
text::{TextView, TextViewStyle},
|
text::{TextView, TextViewStyle},
|
||||||
|
|
@ -15,7 +15,6 @@ const LANG: &str = "markdown";
|
||||||
pub struct Example {
|
pub struct Example {
|
||||||
input_state: Entity<InputState>,
|
input_state: Entity<InputState>,
|
||||||
resizable_state: Entity<ResizableState>,
|
resizable_state: Entity<ResizableState>,
|
||||||
is_dark: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EXAMPLE: &str = include_str!("./markdown.md");
|
const EXAMPLE: &str = include_str!("./markdown.md");
|
||||||
|
|
@ -24,7 +23,7 @@ impl Example {
|
||||||
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
let input_state = cx.new(|cx| {
|
let input_state = cx.new(|cx| {
|
||||||
InputState::new(window, cx)
|
InputState::new(window, cx)
|
||||||
.code_editor(Some(LANG), &HighlightTheme::default_light())
|
.code_editor(Some(LANG))
|
||||||
.line_number(false)
|
.line_number(false)
|
||||||
.tab_size(TabSize {
|
.tab_size(TabSize {
|
||||||
tab_size: 2,
|
tab_size: 2,
|
||||||
|
|
@ -42,7 +41,6 @@ impl Example {
|
||||||
Self {
|
Self {
|
||||||
resizable_state,
|
resizable_state,
|
||||||
input_state,
|
input_state,
|
||||||
is_dark: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,22 +58,6 @@ impl Render for Example {
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_dark = cx.theme().mode.is_dark();
|
let is_dark = cx.theme().mode.is_dark();
|
||||||
if self.is_dark != is_dark {
|
|
||||||
self.is_dark = is_dark;
|
|
||||||
self.input_state.update(cx, |state, cx| {
|
|
||||||
if is_dark {
|
|
||||||
state.set_highlighter(
|
|
||||||
Highlighter::new(Some(LANG), &HighlightTheme::default_dark()),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
state.set_highlighter(
|
|
||||||
Highlighter::new(Some(LANG), &HighlightTheme::default_light()),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
h_resizable("container", self.resizable_state.clone())
|
h_resizable("container", self.resizable_state.clone())
|
||||||
.child(
|
.child(
|
||||||
|
|
@ -97,6 +79,7 @@ impl Render for Example {
|
||||||
TextView::markdown("preview", self.input_state.read(cx).value()).style(
|
TextView::markdown("preview", self.input_state.read(cx).value()).style(
|
||||||
TextViewStyle {
|
TextViewStyle {
|
||||||
highlight_theme: Rc::new(theme.clone()),
|
highlight_theme: Rc::new(theme.clone()),
|
||||||
|
is_dark,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -66,26 +66,51 @@ impl HighlightTheme {
|
||||||
/// https://github.com/iced-rs/iced/blob/master/highlighter/src/lib.rs#L24
|
/// https://github.com/iced-rs/iced/blob/master/highlighter/src/lib.rs#L24
|
||||||
pub struct Highlighter<'a> {
|
pub struct Highlighter<'a> {
|
||||||
syntax: &'static parsing::SyntaxReference,
|
syntax: &'static parsing::SyntaxReference,
|
||||||
pub(crate) theme: &'a HighlightTheme,
|
pub(crate) light_theme: &'a HighlightTheme,
|
||||||
highlighter: highlighting::Highlighter<'a>,
|
pub(crate) dark_theme: &'a HighlightTheme,
|
||||||
|
light_highlighter: highlighting::Highlighter<'a>,
|
||||||
|
dark_highlighter: highlighting::Highlighter<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Highlighter<'a> {
|
impl<'a> Highlighter<'a> {
|
||||||
pub fn new(lang: Option<&str>, theme: &'a HighlightTheme) -> Self {
|
pub fn new(
|
||||||
|
lang: Option<&str>,
|
||||||
|
light_theme: &'a HighlightTheme,
|
||||||
|
dark_theme: &'a HighlightTheme,
|
||||||
|
) -> Self {
|
||||||
let syntax = lang
|
let syntax = lang
|
||||||
.and_then(|lang| SYNTAXES.find_syntax_by_token(&lang))
|
.and_then(|lang| SYNTAXES.find_syntax_by_token(&lang))
|
||||||
.unwrap_or_else(|| SYNTAXES.find_syntax_plain_text());
|
.unwrap_or_else(|| SYNTAXES.find_syntax_plain_text());
|
||||||
let highlighter = highlighting::Highlighter::new(&theme.inner);
|
let light_highlighter = highlighting::Highlighter::new(&light_theme.inner);
|
||||||
|
let dark_highlighter = highlighting::Highlighter::new(&dark_theme.inner);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
syntax,
|
syntax,
|
||||||
theme,
|
light_theme,
|
||||||
highlighter,
|
dark_theme,
|
||||||
|
light_highlighter,
|
||||||
|
dark_highlighter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn theme(&self, is_dark: bool) -> &HighlightTheme {
|
||||||
|
if is_dark {
|
||||||
|
self.dark_theme
|
||||||
|
} else {
|
||||||
|
self.light_theme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn highlighter(&self, is_dark: bool) -> &highlighting::Highlighter<'a> {
|
||||||
|
if is_dark {
|
||||||
|
&self.dark_highlighter
|
||||||
|
} else {
|
||||||
|
&self.light_highlighter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Highlight a line and returns a vector of ranges and highlight styles
|
/// Highlight a line and returns a vector of ranges and highlight styles
|
||||||
pub fn highlight(&self, line: &str) -> Vec<(Range<usize>, HighlightStyle)> {
|
pub fn highlight(&self, line: &str, is_dark: bool) -> Vec<(Range<usize>, HighlightStyle)> {
|
||||||
let mut parser = parsing::ParseState::new(self.syntax);
|
let mut parser = parsing::ParseState::new(self.syntax);
|
||||||
let mut stack = parsing::ScopeStack::new();
|
let mut stack = parsing::ScopeStack::new();
|
||||||
|
|
||||||
|
|
@ -102,7 +127,7 @@ impl<'a> Highlighter<'a> {
|
||||||
if range.is_empty() {
|
if range.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
} else {
|
} else {
|
||||||
let style_mod = self.highlighter.style_mod_for_stack(&stack.scopes);
|
let style_mod = self.highlighter(is_dark).style_mod_for_stack(&stack.scopes);
|
||||||
let mut style = HighlightStyle::default();
|
let mut style = HighlightStyle::default();
|
||||||
style.color = style_mod.foreground.map(color_to_hsla);
|
style.color = style_mod.foreground.map(color_to_hsla);
|
||||||
style.background_color = style_mod.background.map(color_to_hsla);
|
style.background_color = style_mod.background.map(color_to_hsla);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::{collections::HashMap, ops::Range, rc::Rc};
|
||||||
|
|
||||||
use gpui::{App, HighlightStyle, SharedString, TextRun, TextStyle};
|
use gpui::{App, HighlightStyle, SharedString, TextRun, TextStyle};
|
||||||
|
|
||||||
use crate::highlighter::Highlighter;
|
use crate::{highlighter::Highlighter, ActiveTheme, ThemeMode};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct LineHighlightStyle {
|
pub(crate) struct LineHighlightStyle {
|
||||||
|
|
@ -44,6 +44,7 @@ pub(super) struct CodeHighlighter {
|
||||||
pub(super) text: SharedString,
|
pub(super) text: SharedString,
|
||||||
/// The lines by split \n
|
/// The lines by split \n
|
||||||
pub(super) lines: Vec<LineHighlightStyle>,
|
pub(super) lines: Vec<LineHighlightStyle>,
|
||||||
|
pub(super) cache_theme_mode: ThemeMode,
|
||||||
pub(super) cache: HashMap<u64, LineHighlightStyle>,
|
pub(super) cache: HashMap<u64, LineHighlightStyle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,6 +54,7 @@ impl CodeHighlighter {
|
||||||
highlighter,
|
highlighter,
|
||||||
text: SharedString::default(),
|
text: SharedString::default(),
|
||||||
lines: vec![],
|
lines: vec![],
|
||||||
|
cache_theme_mode: ThemeMode::default(),
|
||||||
cache: HashMap::new(),
|
cache: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,11 +66,16 @@ impl CodeHighlighter {
|
||||||
self.update(self.text.clone(), true, cx);
|
self.update(self.text.clone(), true, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, text: SharedString, force: bool, _: &mut App) {
|
pub fn update(&mut self, text: SharedString, force: bool, cx: &mut App) {
|
||||||
if self.text == text && !force {
|
if self.text == text && self.cache_theme_mode == cx.theme().mode && !force {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear if mode is changed
|
||||||
|
if self.cache_theme_mode != cx.theme().mode {
|
||||||
|
self.cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
let mut lines = vec![];
|
let mut lines = vec![];
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
let mut new_cache = HashMap::new();
|
let mut new_cache = HashMap::new();
|
||||||
|
|
@ -85,7 +92,7 @@ impl CodeHighlighter {
|
||||||
lines.push(new_style);
|
lines.push(new_style);
|
||||||
} else {
|
} else {
|
||||||
// cache miss
|
// cache miss
|
||||||
let styles = Rc::new(self.highlighter.highlight(line));
|
let styles = Rc::new(self.highlighter.highlight(line, cx.theme().is_dark()));
|
||||||
let line_style = LineHighlightStyle { offset, styles };
|
let line_style = LineHighlightStyle { offset, styles };
|
||||||
new_cache.insert(cache_key, line_style.clone());
|
new_cache.insert(cache_key, line_style.clone());
|
||||||
lines.push(line_style);
|
lines.push(line_style);
|
||||||
|
|
@ -96,6 +103,7 @@ impl CodeHighlighter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure to recreate cache to remove unused caches.
|
// Ensure to recreate cache to remove unused caches.
|
||||||
|
self.cache_theme_mode = cx.theme().mode;
|
||||||
self.cache = new_cache;
|
self.cache = new_cache;
|
||||||
self.lines = lines;
|
self.lines = lines;
|
||||||
self.text = text;
|
self.text = text;
|
||||||
|
|
|
||||||
|
|
@ -709,7 +709,7 @@ impl Element for TextElement {
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.mode
|
.mode
|
||||||
.highlighter()
|
.highlighter()
|
||||||
.and_then(|h| h.theme.settings().line_highlight)
|
.and_then(|h| h.theme(cx.theme().is_dark()).settings().line_highlight)
|
||||||
.map(crate::highlighter::color_to_hsla)
|
.map(crate::highlighter::color_to_hsla)
|
||||||
{
|
{
|
||||||
window.paint_quad(fill(
|
window.paint_quad(fill(
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,8 @@ impl InputState {
|
||||||
/// - hard_tabs: false
|
/// - hard_tabs: false
|
||||||
/// - height: full
|
/// - height: full
|
||||||
///
|
///
|
||||||
|
/// If `highlighter` is None, will use the default highlighter.
|
||||||
|
///
|
||||||
/// Code Editor aim for help used to simple code editing or display, not a full-featured code editor.
|
/// Code Editor aim for help used to simple code editing or display, not a full-featured code editor.
|
||||||
///
|
///
|
||||||
/// ## Features
|
/// ## Features
|
||||||
|
|
@ -366,12 +368,15 @@ impl InputState {
|
||||||
/// - Syntax Highlighting
|
/// - Syntax Highlighting
|
||||||
/// - Auto Indent
|
/// - Auto Indent
|
||||||
/// - Line Number
|
/// - Line Number
|
||||||
pub fn code_editor(mut self, language: Option<&str>, theme: &'static HighlightTheme) -> Self {
|
pub fn code_editor(mut self, language: Option<&str>) -> Self {
|
||||||
let highlighter = Rc::new(Highlighter::new(language, theme));
|
|
||||||
self.mode = InputMode::CodeEditor {
|
self.mode = InputMode::CodeEditor {
|
||||||
rows: 2,
|
rows: 2,
|
||||||
tab: TabSize::default(),
|
tab: TabSize::default(),
|
||||||
highlighter: CodeHighlighter::new(highlighter),
|
highlighter: CodeHighlighter::new(Rc::new(Highlighter::new(
|
||||||
|
language,
|
||||||
|
&HighlightTheme::default_light(),
|
||||||
|
&HighlightTheme::default_dark(),
|
||||||
|
))),
|
||||||
line_number: true,
|
line_number: true,
|
||||||
height: Some(relative(1.)),
|
height: Some(relative(1.)),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ pub struct TextInput {
|
||||||
cleanable: bool,
|
cleanable: bool,
|
||||||
mask_toggle: bool,
|
mask_toggle: bool,
|
||||||
disabled: bool,
|
disabled: bool,
|
||||||
|
bordered: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sizable for TextInput {
|
impl Sizable for TextInput {
|
||||||
|
|
@ -47,6 +48,7 @@ impl TextInput {
|
||||||
suffix: None,
|
suffix: None,
|
||||||
height: None,
|
height: None,
|
||||||
appearance: true,
|
appearance: true,
|
||||||
|
bordered: true,
|
||||||
cleanable: false,
|
cleanable: false,
|
||||||
mask_toggle: false,
|
mask_toggle: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
|
@ -81,6 +83,12 @@ impl TextInput {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the bordered for the input field, default: true
|
||||||
|
pub fn bordered(mut self, bordered: bool) -> Self {
|
||||||
|
self.bordered = bordered;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set true to show the clear button when the input field is not empty.
|
/// Set true to show the clear button when the input field is not empty.
|
||||||
pub fn cleanable(mut self) -> Self {
|
pub fn cleanable(mut self) -> Self {
|
||||||
self.cleanable = true;
|
self.cleanable = true;
|
||||||
|
|
@ -234,11 +242,13 @@ impl RenderOnce for TextInput {
|
||||||
})
|
})
|
||||||
.when(self.appearance, |this| {
|
.when(self.appearance, |this| {
|
||||||
this.bg(bg)
|
this.bg(bg)
|
||||||
.border_color(cx.theme().input)
|
|
||||||
.border_1()
|
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.when(cx.theme().shadow, |this| this.shadow_sm())
|
.when(self.bordered, |this| {
|
||||||
.when(focused, |this| this.focused_border(cx))
|
this.border_color(cx.theme().input)
|
||||||
|
.border_1()
|
||||||
|
.when(cx.theme().shadow, |this| this.shadow_sm())
|
||||||
|
.when(focused, |this| this.focused_border(cx))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.when(prefix.is_none(), |this| this.input_pl(self.size))
|
.when(prefix.is_none(), |this| this.input_pl(self.size))
|
||||||
.input_pr(self.size)
|
.input_pr(self.size)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ use crate::{
|
||||||
clipboard::Clipboard,
|
clipboard::Clipboard,
|
||||||
description_list::DescriptionList,
|
description_list::DescriptionList,
|
||||||
h_flex,
|
h_flex,
|
||||||
highlighter::HighlightTheme,
|
|
||||||
input::{InputState, TextInput},
|
input::{InputState, TextInput},
|
||||||
link::Link,
|
link::Link,
|
||||||
v_flex, ActiveTheme, IconName, Selectable, Sizable, TITLE_BAR_HEIGHT,
|
v_flex, ActiveTheme, IconName, Selectable, Sizable, TITLE_BAR_HEIGHT,
|
||||||
|
|
@ -60,15 +59,9 @@ pub struct DivInspector {
|
||||||
|
|
||||||
impl DivInspector {
|
impl DivInspector {
|
||||||
pub fn new(window: &mut Window, cx: &mut App) -> Self {
|
pub fn new(window: &mut Window, cx: &mut App) -> Self {
|
||||||
let theme = if cx.theme().is_dark() {
|
|
||||||
HighlightTheme::default_dark()
|
|
||||||
} else {
|
|
||||||
HighlightTheme::default_light()
|
|
||||||
};
|
|
||||||
|
|
||||||
let input_state = cx.new(|cx| {
|
let input_state = cx.new(|cx| {
|
||||||
InputState::new(window, cx)
|
InputState::new(window, cx)
|
||||||
.code_editor(Some("json"), theme)
|
.code_editor(Some("json"))
|
||||||
.line_number(false)
|
.line_number(false)
|
||||||
.disabled(true)
|
.disabled(true)
|
||||||
});
|
});
|
||||||
|
|
@ -134,7 +127,9 @@ impl Render for DivInspector {
|
||||||
.w_full()
|
.w_full()
|
||||||
.font_family("Monaco")
|
.font_family("Monaco")
|
||||||
.text_size(px(12.))
|
.text_size(px(12.))
|
||||||
.child(TextInput::new(&input_state).h_full()),
|
.border_1()
|
||||||
|
.border_color(cx.theme().border)
|
||||||
|
.child(TextInput::new(&input_state).h_full().appearance(false)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -150,6 +145,7 @@ fn render_inspector(
|
||||||
let inspector_element_id = inspector.active_element_id();
|
let inspector_element_id = inspector.active_element_id();
|
||||||
let source_location =
|
let source_location =
|
||||||
inspector_element_id.map(|id| SharedString::new(format!("{}", id.path.source_location)));
|
inspector_element_id.map(|id| SharedString::new(format!("{}", id.path.source_location)));
|
||||||
|
let element_global_id = inspector_element_id.map(|id| format!("{}", id.path.global_id));
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.id("inspector")
|
.id("inspector")
|
||||||
|
|
@ -202,6 +198,7 @@ fn render_inspector(
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.p_3()
|
.p_3()
|
||||||
.gap_3()
|
.gap_3()
|
||||||
|
.text_sm()
|
||||||
.when_some(source_location, |this, source_location| {
|
.when_some(source_location, |this, source_location| {
|
||||||
this.child(
|
this.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
|
|
@ -215,6 +212,7 @@ fn render_inspector(
|
||||||
.child(Clipboard::new("copy-source-location").value(source_location)),
|
.child(Clipboard::new("copy-source-location").value(source_location)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
.children(element_global_id)
|
||||||
.children(inspector.render_inspector_states(window, cx)),
|
.children(inspector.render_inspector_states(window, cx)),
|
||||||
)
|
)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
|
|
|
||||||
|
|
@ -215,8 +215,9 @@ impl CodeBlock {
|
||||||
let highlight = Highlighter::new(
|
let highlight = Highlighter::new(
|
||||||
lang.as_ref().map(|v| v.as_ref()),
|
lang.as_ref().map(|v| v.as_ref()),
|
||||||
text_view_style.highlight_theme.as_ref(),
|
text_view_style.highlight_theme.as_ref(),
|
||||||
|
text_view_style.highlight_theme.as_ref(),
|
||||||
);
|
);
|
||||||
let styles = highlight.highlight(code.as_ref());
|
let styles = highlight.highlight(code.as_ref(), text_view_style.is_dark);
|
||||||
Self { code, lang, styles }
|
Self { code, lang, styles }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ pub struct TextViewStyle {
|
||||||
pub heading_base_font_size: Pixels,
|
pub heading_base_font_size: Pixels,
|
||||||
/// Highlight theme for code blocks. Default: [`HighlightTheme::default_light()`]
|
/// Highlight theme for code blocks. Default: [`HighlightTheme::default_light()`]
|
||||||
pub highlight_theme: Rc<HighlightTheme>,
|
pub highlight_theme: Rc<HighlightTheme>,
|
||||||
|
pub is_dark: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TextViewStyle {
|
impl Default for TextViewStyle {
|
||||||
|
|
@ -85,6 +86,7 @@ impl Default for TextViewStyle {
|
||||||
paragraph_gap: rems(1.),
|
paragraph_gap: rems(1.),
|
||||||
heading_base_font_size: px(14.),
|
heading_base_font_size: px(14.),
|
||||||
highlight_theme: Rc::new(HighlightTheme::default_light().clone()),
|
highlight_theme: Rc::new(HighlightTheme::default_light().clone()),
|
||||||
|
is_dark: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue