summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/appearance.rs50
-rw-r--r--src/config.rs2
-rw-r--r--src/dialog.rs4
-rw-r--r--src/main.rs99
-rw-r--r--src/panes/designer_view.rs2
-rw-r--r--src/types.rs4
-rw-r--r--src/types/project.rs16
7 files changed, 117 insertions, 60 deletions
diff --git a/src/appearance.rs b/src/appearance.rs
index 4d73ec5..0af9879 100644
--- a/src/appearance.rs
+++ b/src/appearance.rs
@@ -2,31 +2,31 @@ use std::sync::Arc;
use iced_material::Theme;
-pub fn iced_theme_from_str(theme_name: &str) -> iced::Theme {
+pub fn iced_theme_from_str(theme_name: &str) -> Option<iced::Theme> {
match theme_name {
- "Light" => iced::Theme::Light,
- "Dark" => iced::Theme::Dark,
- "Dracula" => iced::Theme::Dracula,
- "Nord" => iced::Theme::Nord,
- "Solarized Light" => iced::Theme::SolarizedLight,
- "Solarized Dark" => iced::Theme::SolarizedDark,
- "Gruvbox Light" => iced::Theme::GruvboxLight,
- "Gruvbox Dark" => iced::Theme::GruvboxDark,
- "Catppuccin Latte" => iced::Theme::CatppuccinLatte,
- "Catppuccin Frappé" => iced::Theme::CatppuccinFrappe,
- "Catppuccin Macchiato" => iced::Theme::CatppuccinMacchiato,
- "Catppuccin Mocha" => iced::Theme::CatppuccinMocha,
- "Tokyo Night" => iced::Theme::TokyoNight,
- "Tokyo Night Storm" => iced::Theme::TokyoNightStorm,
- "Tokyo Night Light" => iced::Theme::TokyoNightLight,
- "Kanagawa Wave" => iced::Theme::KanagawaWave,
- "Kanagawa Dragon" => iced::Theme::KanagawaDragon,
- "Kanagawa Lotus" => iced::Theme::KanagawaLotus,
- "Moonfly" => iced::Theme::Moonfly,
- "Nightfly" => iced::Theme::Nightfly,
- "Oxocarbon" => iced::Theme::Oxocarbon,
- "Ferra" => iced::Theme::Ferra,
- _ => iced::Theme::default(),
+ "Light" => Some(iced::Theme::Light),
+ "Dark" => Some(iced::Theme::Dark),
+ "Dracula" => Some(iced::Theme::Dracula),
+ "Nord" => Some(iced::Theme::Nord),
+ "Solarized Light" => Some(iced::Theme::SolarizedLight),
+ "Solarized Dark" => Some(iced::Theme::SolarizedDark),
+ "Gruvbox Light" => Some(iced::Theme::GruvboxLight),
+ "Gruvbox Dark" => Some(iced::Theme::GruvboxDark),
+ "Catppuccin Latte" => Some(iced::Theme::CatppuccinLatte),
+ "Catppuccin Frappé" => Some(iced::Theme::CatppuccinFrappe),
+ "Catppuccin Macchiato" => Some(iced::Theme::CatppuccinMacchiato),
+ "Catppuccin Mocha" => Some(iced::Theme::CatppuccinMocha),
+ "Tokyo Night" => Some(iced::Theme::TokyoNight),
+ "Tokyo Night Storm" => Some(iced::Theme::TokyoNightStorm),
+ "Tokyo Night Light" => Some(iced::Theme::TokyoNightLight),
+ "Kanagawa Wave" => Some(iced::Theme::KanagawaWave),
+ "Kanagawa Dragon" => Some(iced::Theme::KanagawaDragon),
+ "Kanagawa Lotus" => Some(iced::Theme::KanagawaLotus),
+ "Moonfly" => Some(iced::Theme::Moonfly),
+ "Nightfly" => Some(iced::Theme::Nightfly),
+ "Oxocarbon" => Some(iced::Theme::Oxocarbon),
+ "Ferra" => Some(iced::Theme::Ferra),
+ _ => None,
}
}
@@ -39,7 +39,7 @@ pub struct Appearance {
impl Default for Appearance {
fn default() -> Self {
Self {
- selected: Theme::default(),
+ selected: Theme::Dark,
all: Theme::ALL.into(),
}
}
diff --git a/src/config.rs b/src/config.rs
index 0ef094c..98140e6 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -104,7 +104,7 @@ impl Config {
Some(theme)
};
- let mut selected = Theme::default();
+ let mut selected = Theme::Dark;
let mut all = Theme::ALL.to_owned();
if let Some(index) =
diff --git a/src/dialog.rs b/src/dialog.rs
index c5e008c..2aefb50 100644
--- a/src/dialog.rs
+++ b/src/dialog.rs
@@ -1,6 +1,6 @@
use std::borrow::Cow;
-use iced::widget::{Space, text};
+use iced::widget::{space, text};
use iced_dialog::button;
use iced_material::button::filled_tonal;
@@ -34,7 +34,7 @@ impl From<Action> for Vec<Element<'_, Message>> {
Action::Close => vec![button("Close", Message::DialogYes).into()],
Action::UnsavedChanges(_) => vec![
button("Don't Save", Message::DialogNo).style(danger).into(),
- Space::with_width(20).into(),
+ space().width(20).into(),
button("Save", Message::DialogYes)
.style(filled_tonal)
.into(),
diff --git a/src/main.rs b/src/main.rs
index d04183a..add73ec 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,13 +20,19 @@ use config::Config;
use dialog::{Dialog, UnsavedChanges};
use error::Error;
use iced::advanced::widget::Id;
-use iced::widget::{column, container, pane_grid, pick_list, row, text_editor};
+use iced::system::theme_changes;
+use iced::theme::{self, Base};
+use iced::time::Duration;
+use iced::widget::{
+ checkbox, column, container, pane_grid, pick_list, row, text, text_editor,
+};
use iced::{
- Alignment, Length, Subscription, Task, clipboard, keyboard, window,
+ Alignment, Length, Subscription, Task, border, clipboard, keyboard, window,
};
use iced_anim::transition::Easing;
use iced_anim::{Animated, Animation};
use iced_material::Theme;
+use iced_material::utils::{disabled_container, disabled_text};
use panes::{code_view, designer_view, element_list};
use types::{
Action, ConfigChangeType, DesignerPane, Element, Message, Panes, Project,
@@ -79,6 +85,8 @@ struct IcedBuilder {
project: Project,
config: Config,
theme: Animated<Theme>,
+ theme_mode: theme::Mode,
+ use_system_theme: bool,
pane_state: pane_grid::State<Panes>,
focus: Option<pane_grid::Pane>,
designer_page: DesignerPane,
@@ -119,7 +127,10 @@ impl IcedBuilder {
project_path,
project: Project::new(),
config,
- theme: Animated::new(theme, Easing::EASE_IN),
+ theme: Animated::new(theme, Easing::EASE_IN)
+ .with_duration(Duration::from_millis(300)),
+ theme_mode: theme::Mode::Dark,
+ use_system_theme: false,
pane_state: state,
focus: None,
designer_page: DesignerPane::DesignerView,
@@ -203,10 +214,25 @@ impl IcedBuilder {
Message::SwitchTheme(event) => {
self.theme.update(event);
- return self.update(ConfigChangeType::SelectedTheme.into());
+ if !self.use_system_theme {
+ return self.update(ConfigChangeType::SelectedTheme.into());
+ }
}
- Message::SystemThemeChanged(theme) => {
- Theme::update_system_theme(theme);
+ Message::SystemThemeChanged(mode) => {
+ self.theme_mode = mode;
+
+ if self.use_system_theme {
+ self.theme.set_target(Theme::default(mode));
+ }
+ }
+ Message::UseSystemTheme(use_system_theme) => {
+ self.use_system_theme = use_system_theme;
+
+ self.theme.set_target(if use_system_theme {
+ Theme::default(self.theme_mode)
+ } else {
+ self.config.selected_theme()
+ });
}
Message::CopyCode => {
return clipboard::write(self.editor_content.text());
@@ -217,13 +243,15 @@ impl IcedBuilder {
self.editor_content.perform(action);
}
}
- Message::RefreshEditorContent => match self.project.app_code() {
- Ok(code) => {
- self.editor_content =
- text_editor::Content::with_text(&code);
+ Message::RefreshEditorContent => {
+ match self.project.app_code(self.theme_mode) {
+ Ok(code) => {
+ self.editor_content =
+ text_editor::Content::with_text(&code);
+ }
+ Err(error) => self.dialog = Dialog::error(error),
}
- Err(error) => self.dialog = Dialog::error(error),
- },
+ }
Message::DropNewElement(name, point, _) => {
return iced_drop::zones_on_point(
move |zones| Message::HandleNew(name.clone(), zones),
@@ -434,7 +462,7 @@ impl IcedBuilder {
}
}
Message::CloseApp => {
- return window::get_latest().and_then(window::close);
+ return iced::exit();
}
Message::EscapePressed
if self.dialog.action() == dialog::Action::Close =>
@@ -485,19 +513,46 @@ impl IcedBuilder {
let window_events =
window::events().map(|(_id, event)| Message::WindowEvent(event));
- let system_theme =
- Theme::subscription().map(Message::SystemThemeChanged);
+ let system_theme = theme_changes().map(Message::SystemThemeChanged);
Subscription::batch([keyboard, window_events, system_theme])
}
fn view(&self) -> Element<'_, Message> {
- let header = row![pick_list(
- self.config.themes(),
- Some(self.theme.target()),
- |theme| Message::SwitchTheme(theme.into())
- )]
- .width(200);
+ let header = row![
+ if self.use_system_theme {
+ Element::from(
+ container(text(self.config.selected_theme().to_string()))
+ .padding([5, 10])
+ .width(Length::Fill)
+ .style(|theme: &Theme| {
+ let color = theme.colors().surface.on_surface;
+ container::Style {
+ background: Some(
+ disabled_container(color).into(),
+ ),
+ text_color: Some(disabled_text(color)),
+ border: border::rounded(4),
+ ..Default::default()
+ }
+ }),
+ )
+ } else {
+ Element::from(
+ pick_list(
+ self.config.themes(),
+ Some(self.theme.target()),
+ |theme| Message::SwitchTheme(theme.into()),
+ )
+ .width(Length::Fill),
+ )
+ },
+ checkbox("Use system theme", self.use_system_theme)
+ .on_toggle(Message::UseSystemTheme)
+ ]
+ .spacing(10)
+ .align_y(Alignment::Center)
+ .width(500);
let pane_grid =
pane_grid(&self.pane_state, |id, pane, _is_maximized| {
let is_focused = Some(id) == self.focus;
@@ -505,7 +560,7 @@ impl IcedBuilder {
Panes::Designer => match &self.designer_page {
DesignerPane::DesignerView => designer_view::view(
self.project.element_tree.as_ref(),
- self.project.get_theme(),
+ self.project.get_theme(self.theme_mode),
is_focused,
),
DesignerPane::CodeView => {
diff --git a/src/panes/designer_view.rs b/src/panes/designer_view.rs
index 92364bf..48a8304 100644
--- a/src/panes/designer_view.rs
+++ b/src/panes/designer_view.rs
@@ -29,7 +29,7 @@ pub fn view<'a>(
None => center("Open a project or begin creating one").into(),
};
- let content = container(themer(designer_theme, el_tree))
+ let content = container(themer(Some(designer_theme), el_tree))
.id("drop_zone")
.height(Length::Fill)
.width(Length::Fill);
diff --git a/src/types.rs b/src/types.rs
index d998d61..0014090 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -6,6 +6,7 @@ use std::path::PathBuf;
pub use element_name::ElementName;
use iced::advanced::widget::Id;
+use iced::theme::Mode;
use iced::widget::{pane_grid, text_editor};
use iced::window;
use iced_anim::Event;
@@ -25,7 +26,8 @@ pub enum Message {
ConfigWrite(Result<(), Error>),
SaveConfigChanges(ConfigChangeType),
SwitchTheme(Event<Theme>),
- SystemThemeChanged(Theme),
+ SystemThemeChanged(Mode),
+ UseSystemTheme(bool),
CopyCode,
SwitchPane(DesignerPane),
EditorAction(text_editor::Action),
diff --git a/src/types/project.rs b/src/types/project.rs
index ceb4f84..aac9bca 100644
--- a/src/types/project.rs
+++ b/src/types/project.rs
@@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};
extern crate fxhash;
-use iced::Theme;
+use iced::theme::{Base, Mode, Theme};
use rust_format::{Formatter, PostProcess, PrettyPlease};
use serde::{Deserialize, Serialize};
@@ -31,11 +31,11 @@ impl Project {
}
}
- pub fn get_theme(&self) -> Theme {
- match &self.theme {
- Some(theme) => iced_theme_from_str(theme),
- None => iced::Theme::default(),
- }
+ pub fn get_theme(&self, mode: Mode) -> Theme {
+ self.theme
+ .as_ref()
+ .and_then(|theme| iced_theme_from_str(theme))
+ .unwrap_or_else(|| Theme::default(mode))
}
pub async fn from_path(path: PathBuf) -> Result<(PathBuf, Self), Error> {
@@ -90,14 +90,14 @@ impl Project {
Ok(path)
}
- pub fn app_code(&mut self) -> Result<String, Error> {
+ pub fn app_code(&mut self, theme_mode: Mode) -> Result<String, Error> {
use iced::debug;
let codegen = debug::time("Code Generation");
let result = match self.element_tree {
Some(ref element_tree) => {
let (imports, view) = element_tree.codegen();
- let theme = self.get_theme();
+ let theme = self.get_theme(theme_mode);
let app_code = format!(
r#"// Automatically generated by iced Builder