diff options
Diffstat (limited to '')
| -rw-r--r-- | src/main.rs (renamed from iced_builder/src/main.rs) | 124 |
1 files changed, 80 insertions, 44 deletions
diff --git a/iced_builder/src/main.rs b/src/main.rs index a041c6f..5b95b94 100644 --- a/iced_builder/src/main.rs +++ b/src/main.rs @@ -1,26 +1,47 @@ +#![feature(test)] +mod config; +mod dialogs; +mod environment; +mod error; +mod icon; +mod panes; +mod theme; +mod types; +mod widget; + use std::path::PathBuf; +use config::Config; +use dialogs::{error_dialog, unsaved_changes_dialog, warning_dialog}; +use error::Error; use iced::advanced::widget::Id; use iced::widget::pane_grid::{self, Pane, PaneGrid}; use iced::widget::{container, pick_list, row, text_editor, Column}; use iced::{clipboard, keyboard, Alignment, Element, Length, Task, Theme}; -use iced_anim::{Animation, Spring}; -use iced_builder::dialogs::{error_dialog, unsaved_changes_dialog}; -use iced_builder::icon; -use iced_builder::panes::{code_view, designer_view, element_list}; -use iced_builder::types::{ - Action, DesignerPage, ElementName, Message, Project, -}; -use rfd::MessageDialogResult; +use iced_anim::transition::Easing; +use iced_anim::{Animated, Animation}; +use panes::{code_view, designer_view, element_list}; +use tokio::runtime; +use types::{Action, DesignerPage, ElementName, Message, Project}; + +//pub(crate) type Result<T> = core::result::Result<T, Error>; + +fn main() -> Result<(), Box<dyn std::error::Error>> { + let config_load = { + let rt = runtime::Builder::new_current_thread() + .enable_all() + .build()?; -const THEMES: &'static [Theme] = &[Theme::SolarizedDark, Theme::SolarizedLight]; + rt.block_on(Config::load()) + }; -fn main() -> iced::Result { iced::application(App::title, App::update, App::view) .font(icon::FONT) .theme(|state| state.theme.value().clone()) .subscription(App::subscription) - .run_with(App::new) + .run_with(move || App::new(config_load))?; + + Ok(()) } struct App { @@ -28,7 +49,8 @@ struct App { is_loading: bool, project_path: Option<PathBuf>, project: Project, - theme: Spring<Theme>, + config: Config, + theme: Animated<Theme>, pane_state: pane_grid::State<Panes>, focus: Option<Pane>, designer_page: DesignerPage, @@ -43,7 +65,7 @@ enum Panes { } impl App { - fn new() -> (Self, Task<Message>) { + fn new(config_load: Result<Config, Error>) -> (Self, Task<Message>) { let state = pane_grid::State::with_configuration( pane_grid::Configuration::Split { axis: pane_grid::Axis::Vertical, @@ -52,25 +74,46 @@ impl App { b: Box::new(pane_grid::Configuration::Pane(Panes::ElementList)), }, ); + + let config = config_load.unwrap_or_default(); + let theme = config.selected_theme(); + + let mut task = Task::none(); + + if let Some(path) = config.last_project.clone() { + if path.exists() && path.is_file() { + task = Task::perform( + Project::from_path(path, config.clone()), + Message::FileOpened, + ); + } else { + warning_dialog(format!( + "The file {} does not exist, or isn't a file.", + path.to_string_lossy() + )); + } + } + ( Self { is_dirty: false, is_loading: false, project_path: None, project: Project::new(), - theme: Spring::new(Theme::SolarizedDark), + config, + theme: Animated::new(theme, Easing::EASE_IN), pane_state: state, focus: None, designer_page: DesignerPage::DesignerView, element_list: ElementName::ALL, editor_content: text_editor::Content::new(), }, - Task::none(), + task, ) } fn title(&self) -> String { - let saved_state = if !self.is_dirty { "" } else { " *" }; + let saved_state = if self.is_dirty { " *" } else { "" }; let project_name = match &self.project.title { Some(n) => { @@ -83,7 +126,7 @@ impl App { } ) } - None => "".to_owned(), + None => String::new(), }; format!("iced Builder{project_name}{saved_state}") @@ -104,7 +147,7 @@ impl App { } } Message::RefreshEditorContent => { - match self.project.clone().app_code() { + match self.project.app_code(&self.config) { Ok(code) => { self.editor_content = text_editor::Content::with_text(&code); @@ -119,23 +162,19 @@ impl App { None, None, ) - .into() } Message::HandleNew(name, zones) => { let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect(); - if ids.len() > 0 { - let action = Action::new( - ids, - &mut self.project.element_tree.clone(), - None, - ); + if !ids.is_empty() { + let eltree_clone = self.project.element_tree.clone(); + let action = Action::new(&ids, &eltree_clone, None); let result = name.handle_action( self.project.element_tree.as_mut(), action, ); match result { Ok(Some(ref element)) => { - self.project.element_tree = Some(element.clone()) + self.project.element_tree = Some(element.clone()); } Err(error) => error_dialog(error.to_string()), _ => {} @@ -152,14 +191,14 @@ impl App { None, None, ) - .into() } Message::HandleMove(element, zones) => { let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect(); - if ids.len() > 0 { + if !ids.is_empty() { + let eltree_clone = self.project.element_tree.clone(); let action = Action::new( - ids, - &mut self.project.element_tree.clone(), + &ids, + &eltree_clone, Some(element.get_id()), ); let result = element.handle_action( @@ -193,13 +232,11 @@ impl App { self.project = Project::new(); self.project_path = None; self.editor_content = text_editor::Content::new(); - } else { - if let MessageDialogResult::Ok = unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and create a new project?") { + } else if unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and create a new project?") { self.is_dirty = false; self.project = Project::new(); self.project_path = None; self.editor_content = text_editor::Content::new(); - } } } } @@ -209,15 +246,13 @@ impl App { self.is_loading = true; return Task::perform( - Project::from_path(), + Project::from_file(self.config.clone()), Message::FileOpened, ); - } else { - if let MessageDialogResult::Ok = unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and open another project?") { + } else if unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and open another project?") { self.is_dirty = false; self.is_loading = true; - return Task::perform(Project::from_path(), Message::FileOpened); - } + return Task::perform(Project::from_file(self.config.clone()), Message::FileOpened); } } } @@ -227,11 +262,12 @@ impl App { match result { Ok((path, project)) => { - self.project = project.clone(); + self.project = project; self.project_path = Some(path); self.editor_content = text_editor::Content::with_text( - &project - .app_code() + &self + .project + .app_code(&self.config) .unwrap_or_else(|err| err.to_string()), ); } @@ -299,7 +335,7 @@ impl App { fn view(&self) -> Element<'_, Message> { let header = row![pick_list( - THEMES, + self.config.theme.all.clone(), Some(self.theme.target().clone()), |theme| { Message::ToggleTheme(theme.into()) } )] @@ -311,12 +347,12 @@ impl App { Panes::Designer => match &self.designer_page { DesignerPage::DesignerView => designer_view::view( &self.project.element_tree, - self.project.get_theme(), + self.project.get_theme(&self.config), is_focused, ), DesignerPage::CodeView => code_view::view( &self.editor_content, - self.theme.value().clone(), + self.theme.target().clone(), is_focused, ), }, |
