summaryrefslogtreecommitdiffstats
path: root/examples/editor
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-09-18 14:38:54 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-09-18 14:38:54 +0200
commit8446fe6de52fa68077d23d39f728f79a29b52f00 (patch)
tree937c0c1817afb1ab6cc95499f253938549cda68b /examples/editor
parent61ef8f3249218b301d434d04c483ba70562c1df4 (diff)
downloadiced-8446fe6de52fa68077d23d39f728f79a29b52f00.tar.gz
iced-8446fe6de52fa68077d23d39f728f79a29b52f00.tar.bz2
iced-8446fe6de52fa68077d23d39f728f79a29b52f00.zip
Implement theme selector in `editor` example
Diffstat (limited to 'examples/editor')
-rw-r--r--examples/editor/src/main.rs101
1 files changed, 82 insertions, 19 deletions
diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs
index 74649676..fa35ba0f 100644
--- a/examples/editor/src/main.rs
+++ b/examples/editor/src/main.rs
@@ -1,5 +1,5 @@
-use iced::widget::{container, text_editor};
-use iced::{Element, Font, Sandbox, Settings, Theme};
+use iced::widget::{column, horizontal_space, pick_list, row, text_editor};
+use iced::{Element, Font, Length, Sandbox, Settings, Theme};
use highlighter::Highlighter;
@@ -9,11 +9,13 @@ pub fn main() -> iced::Result {
struct Editor {
content: text_editor::Content,
+ theme: highlighter::Theme,
}
#[derive(Debug, Clone)]
enum Message {
Edit(text_editor::Action),
+ ThemeSelected(highlighter::Theme),
}
impl Sandbox for Editor {
@@ -21,9 +23,8 @@ impl Sandbox for Editor {
fn new() -> Self {
Self {
- content: text_editor::Content::with(include_str!(
- "../../../README.md"
- )),
+ content: text_editor::Content::with(include_str!("main.rs")),
+ theme: highlighter::Theme::SolarizedDark,
}
}
@@ -36,18 +37,33 @@ impl Sandbox for Editor {
Message::Edit(action) => {
self.content.edit(action);
}
+ Message::ThemeSelected(theme) => {
+ self.theme = theme;
+ }
}
}
fn view(&self) -> Element<Message> {
- container(
+ column![
+ row![
+ horizontal_space(Length::Fill),
+ pick_list(
+ highlighter::Theme::ALL,
+ Some(self.theme),
+ Message::ThemeSelected
+ )
+ .padding([5, 10])
+ ]
+ .spacing(10),
text_editor(&self.content)
.on_edit(Message::Edit)
.font(Font::with_name("Hasklug Nerd Font Mono"))
.highlight::<Highlighter>(highlighter::Settings {
- token: String::from("md"),
+ theme: self.theme,
+ extension: String::from("rs"),
}),
- )
+ ]
+ .spacing(10)
.padding(20)
.into()
}
@@ -60,21 +76,52 @@ impl Sandbox for Editor {
mod highlighter {
use iced::advanced::text::highlighter;
use iced::widget::text_editor;
- use iced::{Color, Font, Theme};
+ use iced::{Color, Font};
use std::ops::Range;
use syntect::highlighting;
use syntect::parsing::{self, SyntaxReference};
- #[derive(Debug, Clone, Hash)]
+ #[derive(Debug, Clone, PartialEq)]
pub struct Settings {
- pub token: String,
+ pub theme: Theme,
+ pub extension: String,
+ }
+
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ pub enum Theme {
+ SolarizedDark,
+ InspiredGitHub,
+ Base16Mocha,
+ }
+
+ impl Theme {
+ pub const ALL: &[Self] =
+ &[Self::SolarizedDark, Self::InspiredGitHub, Self::Base16Mocha];
+
+ fn key(&self) -> &'static str {
+ match self {
+ Theme::InspiredGitHub => "InspiredGitHub",
+ Theme::Base16Mocha => "base16-mocha.dark",
+ Theme::SolarizedDark => "Solarized (dark)",
+ }
+ }
+ }
+
+ impl std::fmt::Display for Theme {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Theme::InspiredGitHub => write!(f, "Inspired GitHub"),
+ Theme::Base16Mocha => write!(f, "Mocha"),
+ Theme::SolarizedDark => write!(f, "Solarized Dark"),
+ }
+ }
}
pub struct Highlight(highlighting::StyleModifier);
impl text_editor::Highlight for Highlight {
- fn format(&self, _theme: &Theme) -> highlighter::Format<Font> {
+ fn format(&self, _theme: &iced::Theme) -> highlighter::Format<Font> {
highlighter::Format {
color: self.0.foreground.map(|color| {
Color::from_rgba8(
@@ -92,8 +139,8 @@ mod highlighter {
pub struct Highlighter {
syntaxes: parsing::SyntaxSet,
syntax: SyntaxReference,
- caches: Vec<(parsing::ParseState, parsing::ScopeStack)>,
theme: highlighting::Theme,
+ caches: Vec<(parsing::ParseState, parsing::ScopeStack)>,
current_line: usize,
}
@@ -110,26 +157,42 @@ mod highlighter {
let syntaxes = parsing::SyntaxSet::load_defaults_nonewlines();
let syntax = syntaxes
- .find_syntax_by_token(&settings.token)
+ .find_syntax_by_token(&settings.extension)
.unwrap_or_else(|| syntaxes.find_syntax_plain_text());
- let parser = parsing::ParseState::new(syntax);
- let stack = parsing::ScopeStack::new();
-
let theme = highlighting::ThemeSet::load_defaults()
.themes
- .remove("base16-mocha.dark")
+ .remove(settings.theme.key())
.unwrap();
+ let parser = parsing::ParseState::new(syntax);
+ let stack = parsing::ScopeStack::new();
+
Highlighter {
syntax: syntax.clone(),
syntaxes,
- caches: vec![(parser, stack)],
theme,
+ caches: vec![(parser, stack)],
current_line: 0,
}
}
+ fn update(&mut self, new_settings: &Self::Settings) {
+ self.syntax = self
+ .syntaxes
+ .find_syntax_by_token(&new_settings.extension)
+ .unwrap_or_else(|| self.syntaxes.find_syntax_plain_text())
+ .clone();
+
+ self.theme = highlighting::ThemeSet::load_defaults()
+ .themes
+ .remove(new_settings.theme.key())
+ .unwrap();
+
+ // Restart the highlighter
+ self.change_line(0);
+ }
+
fn change_line(&mut self, line: usize) {
let snapshot = line / LINES_PER_SNAPSHOT;