diff options
| author | pml68 <contact@pml68.me> | 2024-11-06 14:22:41 +0100 |
|---|---|---|
| committer | pml68 <contact@pml68.me> | 2024-11-06 16:26:36 +0100 |
| commit | 65d3c249c9da370e26521a5ff409b6e6fdad4779 (patch) | |
| tree | ac8f2a1d05e481da6d3f82cce6081b853a71269c /iced_builder/src | |
| parent | fix: error when dropping new element on element list (diff) | |
| download | iced-builder-65d3c249c9da370e26521a5ff409b6e6fdad4779.tar.gz | |
feat: animated theme switching with `iced_anim` crate
c
c
Diffstat (limited to 'iced_builder/src')
| -rw-r--r-- | iced_builder/src/error.rs | 4 | ||||
| -rw-r--r-- | iced_builder/src/lib.rs | 3 | ||||
| -rw-r--r-- | iced_builder/src/main.rs | 49 | ||||
| -rw-r--r-- | iced_builder/src/types/element_name.rs | 4 | ||||
| -rw-r--r-- | iced_builder/src/types/mod.rs | 16 | ||||
| -rw-r--r-- | iced_builder/src/types/project.rs | 8 | ||||
| -rwxr-xr-x | iced_builder/src/types/rendered_element.rs | 4 | ||||
| -rw-r--r-- | iced_builder/src/views/code_view.rs | 8 |
8 files changed, 52 insertions, 44 deletions
diff --git a/iced_builder/src/error.rs b/iced_builder/src/error.rs index edb57b9..ab102a6 100644 --- a/iced_builder/src/error.rs +++ b/iced_builder/src/error.rs @@ -36,8 +36,8 @@ impl From<rust_format::Error> for Error { } } -impl From<&'static str> for Error { - fn from(value: &'static str) -> Self { +impl From<&str> for Error { + fn from(value: &str) -> Self { Self::Other(value.to_owned()) } } diff --git a/iced_builder/src/lib.rs b/iced_builder/src/lib.rs index 6af030f..a98a379 100644 --- a/iced_builder/src/lib.rs +++ b/iced_builder/src/lib.rs @@ -3,4 +3,5 @@ pub mod error; pub mod types; pub mod views; -pub type Result<T> = std::result::Result<T, error::Error>; +pub use error::Error; +pub type Result<T> = core::result::Result<T, Error>; diff --git a/iced_builder/src/main.rs b/iced_builder/src/main.rs index 287a466..c2ac7a5 100644 --- a/iced_builder/src/main.rs +++ b/iced_builder/src/main.rs @@ -4,12 +4,13 @@ use iced::{ advanced::widget::Id, clipboard, keyboard, widget::{ - button, container, + container, pane_grid::{self, Pane, PaneGrid}, - row, text_editor, Column, + pick_list, row, text_editor, Column, }, Alignment, Element, Length, Settings, Task, Theme, }; +use iced_anim::{Animation, Spring}; use iced_builder::{ dialogs::{error_dialog, unsaved_changes_dialog}, types::{Action, DesignerPage, ElementName, Message, Project}, @@ -17,13 +18,15 @@ use iced_builder::{ }; use rfd::MessageDialogResult; +const THEMES: &'static [Theme] = &[Theme::SolarizedDark, Theme::SolarizedLight]; + fn main() -> iced::Result { iced::application(App::title, App::update, App::view) .settings(Settings { fonts: vec![include_bytes!("../fonts/icons.ttf").as_slice().into()], ..Settings::default() }) - .theme(App::theme) + .theme(|state| state.theme.value().clone()) .subscription(App::subscription) .run_with(App::new) } @@ -33,7 +36,7 @@ struct App { is_loading: bool, project_path: Option<PathBuf>, project: Project, - dark_theme: bool, + theme: Spring<Theme>, pane_state: pane_grid::State<Panes>, focus: Option<Pane>, designer_page: DesignerPage, @@ -61,10 +64,10 @@ impl App { is_loading: false, project_path: None, project: Project::new(), - dark_theme: true, + theme: Spring::new(Theme::SolarizedDark), pane_state: state, focus: None, - designer_page: DesignerPage::Designer, + designer_page: DesignerPage::DesignerView, element_list: ElementName::ALL.to_vec(), editor_content: text_editor::Content::new(), }, @@ -92,17 +95,11 @@ impl App { format!("iced Builder{project_name}{saved_state}") } - fn theme(&self) -> iced::Theme { - if self.dark_theme { - Theme::SolarizedDark - } else { - Theme::SolarizedLight - } - } - fn update(&mut self, message: Message) -> Task<Message> { match message { - Message::ToggleDarkMode => self.dark_theme = !self.dark_theme, + Message::ToggleTheme(event) => { + self.theme.update(event); + } Message::CopyCode => return clipboard::write(self.editor_content.text()), Message::SwitchPage(page) => self.designer_page = page, Message::EditorAction(action) => { @@ -276,22 +273,26 @@ impl App { } fn view(&self) -> Element<Message> { - let header = row![button("Toggle Dark Mode") - .on_press(Message::ToggleDarkMode) - .padding(5)] + let header = row![pick_list( + THEMES, + Some(self.theme.target()).clone(), + |theme| { Message::ToggleTheme(theme.into()) } + )] .width(200); let pane_grid = PaneGrid::new(&self.pane_state, |id, pane, _is_maximized| { let is_focused = Some(id) == self.focus; match pane { Panes::Designer => match &self.designer_page { - DesignerPage::Designer => designer_view::view( + DesignerPage::DesignerView => designer_view::view( &self.project.element_tree, self.project.get_theme(), is_focused, ), - DesignerPage::CodeView => { - code_view::view(&self.editor_content, self.dark_theme, is_focused) - } + DesignerPage::CodeView => code_view::view( + &self.editor_content, + self.theme.value().clone(), + is_focused, + ), }, Panes::ElementList => element_list::view(&self.element_list, is_focused), } @@ -310,6 +311,8 @@ impl App { .align_x(Alignment::Center) .width(Length::Fill); - container(content).height(Length::Fill).into() + Animation::new(&self.theme, container(content).height(Length::Fill)) + .on_update(Message::ToggleTheme) + .into() } } diff --git a/iced_builder/src/types/element_name.rs b/iced_builder/src/types/element_name.rs index d71ae30..cdbdf8f 100644 --- a/iced_builder/src/types/element_name.rs +++ b/iced_builder/src/types/element_name.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::error::Error; +use crate::{Error, Result}; use super::rendered_element::{ button, column, container, image, row, svg, text, Action, RenderedElement, @@ -32,7 +32,7 @@ impl ElementName { &self, element_tree: Option<&mut RenderedElement>, action: Action, - ) -> Result<Option<RenderedElement>, Error> { + ) -> Result<Option<RenderedElement>> { let element = match self { Self::Text(_) => text(""), Self::Button(_) => button(""), diff --git a/iced_builder/src/types/mod.rs b/iced_builder/src/types/mod.rs index 841b255..02fab4a 100644 --- a/iced_builder/src/types/mod.rs +++ b/iced_builder/src/types/mod.rs @@ -8,12 +8,16 @@ pub use rendered_element::*; use std::path::PathBuf; -use crate::error::Error; -use iced::widget::{pane_grid, text_editor}; +use crate::Result; +use iced::{ + widget::{pane_grid, text_editor}, + Theme, +}; +use iced_anim::SpringEvent; #[derive(Debug, Clone)] pub enum Message { - ToggleDarkMode, + ToggleTheme(SpringEvent<Theme>), CopyCode, SwitchPage(DesignerPage), EditorAction(text_editor::Action), @@ -33,14 +37,14 @@ pub enum Message { PaneDragged(pane_grid::DragEvent), NewFile, OpenFile, - FileOpened(Result<(PathBuf, Project), Error>), + FileOpened(Result<(PathBuf, Project)>), SaveFile, SaveFileAs, - FileSaved(Result<PathBuf, Error>), + FileSaved(Result<PathBuf>), } #[derive(Debug, Clone)] pub enum DesignerPage { - Designer, + DesignerView, CodeView, } diff --git a/iced_builder/src/types/project.rs b/iced_builder/src/types/project.rs index 8d24a75..a33d3bb 100644 --- a/iced_builder/src/types/project.rs +++ b/iced_builder/src/types/project.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use iced::Theme; use serde::{Deserialize, Serialize}; -use crate::error::Error; +use crate::{Error, Result}; use super::rendered_element::RenderedElement; @@ -55,7 +55,7 @@ impl Project { } } - pub async fn from_path() -> Result<(PathBuf, Self), Error> { + pub async fn from_path() -> Result<(PathBuf, Self)> { let picked_file = rfd::AsyncFileDialog::new() .set_title("Open a JSON file...") .add_filter("*.json, *.JSON", &["json", "JSON"]) @@ -71,7 +71,7 @@ impl Project { Ok((path, element)) } - pub async fn write_to_file(self, path: Option<PathBuf>) -> Result<PathBuf, Error> { + pub async fn write_to_file(self, path: Option<PathBuf>) -> Result<PathBuf> { let path = if let Some(p) = path { p } else { @@ -92,7 +92,7 @@ impl Project { Ok(path) } - pub fn app_code(&self) -> Result<String, Error> { + pub fn app_code(&self) -> Result<String> { match self.element_tree { Some(ref element_tree) => { let (imports, view) = element_tree.codegen(); diff --git a/iced_builder/src/types/rendered_element.rs b/iced_builder/src/types/rendered_element.rs index 58fd18d..b1edb66 100755 --- a/iced_builder/src/types/rendered_element.rs +++ b/iced_builder/src/types/rendered_element.rs @@ -5,7 +5,7 @@ use iced::{widget, Element, Length}; use serde::{Deserialize, Serialize}; use unique_id::{string::StringGenerator, Generator}; -use crate::{error::Error, types::Message}; +use crate::{types::Message, Result}; use super::ElementName; @@ -121,7 +121,7 @@ impl RenderedElement { &self, element_tree: Option<&mut RenderedElement>, action: Action, - ) -> Result<(), Error> { + ) -> Result<()> { let element_tree = element_tree.unwrap(); match action { diff --git a/iced_builder/src/views/code_view.rs b/iced_builder/src/views/code_view.rs index e872e3d..98f0b48 100644 --- a/iced_builder/src/views/code_view.rs +++ b/iced_builder/src/views/code_view.rs @@ -3,12 +3,12 @@ use crate::types::{DesignerPage, Message}; use iced::{ highlighter, widget::{button, container, pane_grid, row, text, text_editor, tooltip, Space}, - Alignment, Font, Length, + Alignment, Font, Length, Theme, }; pub fn view<'a>( editor_content: &'a text_editor::Content, - dark_theme: bool, + theme: Theme, is_focused: bool, ) -> pane_grid::Content<'a, Message> { let title = row![ @@ -21,7 +21,7 @@ pub fn view<'a>( tooltip::Position::FollowCursor ), Space::with_width(20), - button("Switch to Designer view").on_press(Message::SwitchPage(DesignerPage::Designer)) + button("Switch to Designer view").on_press(Message::SwitchPage(DesignerPage::DesignerView)) ] .align_y(Alignment::Center); let title_bar = pane_grid::TitleBar::new(title) @@ -32,7 +32,7 @@ pub fn view<'a>( .on_action(Message::EditorAction) .highlight( "rs", - if dark_theme { + if theme.to_string().contains("Dark") { highlighter::Theme::SolarizedDark } else { highlighter::Theme::InspiredGitHub |
