diff options
| author | Polesznyák Márk László <116908301+pml68@users.noreply.github.com> | 2025-03-23 02:49:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-23 02:49:57 +0100 |
| commit | 3076889c00116b22f022792471253e7188c6e93e (patch) | |
| tree | bff0cda7a9152e9f94d3176bbf5acaf879394f5f /src/main.rs | |
| parent | feat: update to Rust 2024 (diff) | |
| parent | feat: finish `ApplyOptions` impls (diff) | |
| download | iced-builder-3076889c00116b22f022792471253e7188c6e93e.tar.gz | |
Merge pull request #7 from pml68/feat/options-backend
Options backend done (for now)
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 147 |
1 files changed, 86 insertions, 61 deletions
diff --git a/src/main.rs b/src/main.rs index 13510b9..336378e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,19 +4,21 @@ mod environment; mod error; #[allow(clippy::all, dead_code)] mod icon; +mod options; mod panes; mod theme; mod types; +mod values; mod widget; use std::path::PathBuf; +use std::sync::Arc; 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::{Column, container, pick_list, row, text_editor}; +use iced::widget::{Column, container, pane_grid, pick_list, row, text_editor}; use iced::{Alignment, Element, Length, Task, Theme, clipboard, keyboard}; use iced_anim::transition::Easing; use iced_anim::{Animated, Animation}; @@ -25,13 +27,12 @@ use tokio::runtime; use types::{Action, DesignerPane, ElementName, Message, Project}; fn main() -> Result<(), Box<dyn std::error::Error>> { - let mut args = std::env::args(); - let _ = args.next(); - - let version = args.next().is_some_and(|s| s == "--version" || s == "-V"); + let version = std::env::args() + .nth(1) + .is_some_and(|s| s == "--version" || s == "-V"); if version { - println!("{}", env!("CARGO_PKG_VERSION")); + println!("iced-builder {}", environment::formatted_version()); println!("{}", env!("CARGO_PKG_REPOSITORY")); return Ok(()); @@ -59,10 +60,10 @@ struct App { is_loading: bool, project_path: Option<PathBuf>, project: Project, - config: Config, + config: Arc<Config>, theme: Animated<Theme>, pane_state: pane_grid::State<Panes>, - focus: Option<Pane>, + focus: Option<pane_grid::Pane>, designer_page: DesignerPane, element_list: &'static [ElementName], editor_content: text_editor::Content, @@ -85,24 +86,25 @@ impl App { }, ); - let config = config_load.unwrap_or_default(); + let config = Arc::new(config_load.unwrap_or_default()); let theme = config.selected_theme(); - let mut task = Task::none(); - - if let Some(path) = config.last_project.clone() { + let task = if let Some(path) = config.last_project.clone() { if path.exists() && path.is_file() { - task = Task::perform( + Task::perform( Project::from_path(path, config.clone()), Message::FileOpened, - ); + ) } else { - warning_dialog(format!( + Task::future(warning_dialog(format!( "The file {} does not exist, or isn't a file.", path.to_string_lossy() - )); + ))) + .discard() } - } + } else { + Task::none() + }; ( Self { @@ -146,32 +148,37 @@ impl App { match message { Message::SwitchTheme(event) => { self.theme.update(event); + + Task::none() } - Message::CopyCode => { - return clipboard::write(self.editor_content.text()); + Message::CopyCode => clipboard::write(self.editor_content.text()), + Message::SwitchPage(page) => { + self.designer_page = page; + Task::none() } - Message::SwitchPage(page) => self.designer_page = page, Message::EditorAction(action) => { if let text_editor::Action::Scroll { lines: _ } = action { self.editor_content.perform(action); } + Task::none() } Message::RefreshEditorContent => { match self.project.app_code(&self.config) { Ok(code) => { self.editor_content = text_editor::Content::with_text(&code); + Task::none() } - Err(error) => error_dialog(error), + Err(error) => Task::future(error_dialog(error)).discard(), } } Message::DropNewElement(name, point, _) => { - return iced_drop::zones_on_point( + iced_drop::zones_on_point( move |zones| Message::HandleNew(name.clone(), zones), point, None, None, - ); + ) } Message::HandleNew(name, zones) => { let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect(); @@ -182,25 +189,29 @@ impl App { self.project.element_tree.as_mut(), action, ); + self.is_dirty = true; match result { Ok(Some(ref element)) => { self.project.element_tree = Some(element.clone()); } - Err(error) => error_dialog(error), + Err(error) => { + return Task::future(error_dialog(error)) + .map(|_| Message::RefreshEditorContent); + } _ => {} } - - self.is_dirty = true; - return Task::done(Message::RefreshEditorContent); + Task::done(Message::RefreshEditorContent) + } else { + Task::none() } } Message::MoveElement(element, point, _) => { - return iced_drop::zones_on_point( + iced_drop::zones_on_point( move |zones| Message::HandleMove(element.clone(), zones), point, None, None, - ); + ) } Message::HandleMove(element, zones) => { let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect(); @@ -209,33 +220,38 @@ impl App { let action = Action::new( &ids, eltree_clone.as_ref(), - Some(element.get_id()), + Some(element.id()), ); let result = element.handle_action( self.project.element_tree.as_mut(), action, ); if let Err(error) = result { - error_dialog(error); + return Task::future(error_dialog(error)).discard(); } self.is_dirty = true; - return Task::done(Message::RefreshEditorContent); + Task::done(Message::RefreshEditorContent) + } else { + Task::none() } } Message::PaneResized(pane_grid::ResizeEvent { split, ratio }) => { self.pane_state.resize(split, ratio); + Task::none() } Message::PaneClicked(pane) => { self.focus = Some(pane); + Task::none() } Message::PaneDragged(pane_grid::DragEvent::Dropped { pane, target, }) => { self.pane_state.drop(pane, target); + Task::none() } - Message::PaneDragged(_) => {} + Message::PaneDragged(_) => Task::none(), Message::NewFile => { if !self.is_loading { if !self.is_dirty { @@ -251,26 +267,32 @@ impl App { self.editor_content = text_editor::Content::new(); } } + + Task::none() } Message::OpenFile => { if !self.is_loading { if !self.is_dirty { self.is_loading = true; - return Task::perform( + Task::perform( Project::from_file(self.config.clone()), Message::FileOpened, - ); + ) } 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( + Task::perform( Project::from_file(self.config.clone()), Message::FileOpened, - ); + ) + } else { + Task::none() } + } else { + Task::none() } } Message::FileOpened(result) => { @@ -281,31 +303,35 @@ impl App { Ok((path, project)) => { self.project = project; self.project_path = Some(path); - return Task::done(Message::RefreshEditorContent); + Task::done(Message::RefreshEditorContent) } - Err(error) => error_dialog(error), + Err(error) => Task::future(error_dialog(error)).discard(), } } Message::SaveFile => { if !self.is_loading { self.is_loading = true; - return Task::perform( + Task::perform( self.project .clone() .write_to_file(self.project_path.clone()), Message::FileSaved, - ); + ) + } else { + Task::none() } } Message::SaveFileAs => { if !self.is_loading { self.is_loading = true; - return Task::perform( + Task::perform( self.project.clone().write_to_file(None), Message::FileSaved, - ); + ) + } else { + Task::none() } } Message::FileSaved(result) => { @@ -315,13 +341,12 @@ impl App { Ok(path) => { self.project_path = Some(path); self.is_dirty = false; + Task::none() } - Err(error) => error_dialog(error), + Err(error) => Task::future(error_dialog(error)).discard(), } } } - - Task::none() } fn subscription(&self) -> iced::Subscription<Message> { @@ -354,8 +379,9 @@ impl App { |theme| Message::SwitchTheme(theme.into()) )] .width(200); - let pane_grid = - PaneGrid::new(&self.pane_state, |id, pane, _is_maximized| { + let pane_grid = 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 { @@ -364,23 +390,22 @@ impl App { self.project.get_theme(&self.config), is_focused, ), - DesignerPane::CodeView => code_view::view( - &self.editor_content, - self.theme.value().clone(), - is_focused, - ), + DesignerPane::CodeView => { + code_view::view(&self.editor_content, is_focused) + } }, Panes::ElementList => { element_list::view(self.element_list, is_focused) } } - }) - .width(Length::Fill) - .height(Length::Fill) - .spacing(10) - .on_resize(10, Message::PaneResized) - .on_click(Message::PaneClicked) - .on_drag(Message::PaneDragged); + }, + ) + .width(Length::Fill) + .height(Length::Fill) + .spacing(10) + .on_resize(10, Message::PaneResized) + .on_click(Message::PaneClicked) + .on_drag(Message::PaneDragged); let content = Column::new() .push(header) |
