diff options
Diffstat (limited to '')
| -rw-r--r-- | iced_builder/src/error.rs | 61 | ||||
| -rw-r--r-- | iced_builder/src/lib.rs | 78 | ||||
| -rw-r--r-- | iced_builder/src/main.rs | 55 | ||||
| -rw-r--r-- | iced_builder/src/types/element_name.rs | 2 | ||||
| -rw-r--r-- | iced_builder/src/types/mod.rs | 33 | ||||
| -rw-r--r-- | iced_builder/src/types/project.rs | 14 | ||||
| -rwxr-xr-x | iced_builder/src/types/rendered_element.rs | 2 | ||||
| -rw-r--r-- | iced_builder/src/views/code_view.rs | 2 | ||||
| -rw-r--r-- | iced_builder/src/views/designer_view.rs | 5 | ||||
| -rw-r--r-- | iced_builder/src/views/element_list.rs | 2 |
10 files changed, 142 insertions, 112 deletions
diff --git a/iced_builder/src/error.rs b/iced_builder/src/error.rs new file mode 100644 index 0000000..5bf41b1 --- /dev/null +++ b/iced_builder/src/error.rs @@ -0,0 +1,61 @@ +use rfd::{MessageButtons, MessageDialog, MessageLevel}; +use std::io; +use thiserror::Error; + +#[derive(Debug, Clone, Error)] +pub enum Error { + #[error("An I/O error accured: {0}")] + IOError(String), + #[error("A Serde error accured: {0}")] + SerdeError(String), + #[error("A RustFmt error accured: {0}")] + FormatError(String), + #[error("The element tree contains no matching element")] + NonExistentElement, + #[error("The file dialog has been closed without selecting a valid option")] + DialogClosed, + #[error("{0}")] + Other(String), +} + +impl From<io::Error> for Error { + fn from(value: io::Error) -> Self { + Self::IOError(value.to_string()) + } +} + +impl From<serde_json::Error> for Error { + fn from(value: serde_json::Error) -> Self { + Self::SerdeError(value.to_string()) + } +} + +impl From<rust_format::Error> for Error { + fn from(value: rust_format::Error) -> Self { + Self::FormatError(value.to_string()) + } +} + +impl From<&'static str> for Error { + fn from(value: &'static str) -> Self { + Self::Other(value.to_owned()) + } +} + +pub fn error_dialog(description: impl Into<String>) { + MessageDialog::new() + .set_level(MessageLevel::Error) + .set_buttons(MessageButtons::Ok) + .set_title("Oops! Something went wrong.") + .set_description(description) + .show(); +} + +pub fn warning_dialog(title: impl Into<String>, description: impl Into<String>) { + MessageDialog::new() + .set_level(MessageLevel::Warning) + .set_buttons(MessageButtons::Ok) + .set_title(title) + .set_description(description) + .show(); +} diff --git a/iced_builder/src/lib.rs b/iced_builder/src/lib.rs index c6f3616..ddb080c 100644 --- a/iced_builder/src/lib.rs +++ b/iced_builder/src/lib.rs @@ -1,79 +1,5 @@ +pub mod error; pub mod types; pub mod views; -use std::{io, path::PathBuf}; - -use iced::widget::{pane_grid, text_editor}; -use types::{ - element_name::ElementName, project::Project, rendered_element::RenderedElement, DesignerPage, -}; - -use thiserror::Error; - -#[derive(Debug, Clone, Error)] -pub enum Error { - #[error("an I/O error accured: {0}")] - IOError(String), - #[error("a Serde error accured: {0}")] - SerdeError(String), - #[error("an RustFmt error accured: {0}")] - FormatError(String), - #[error("the element tree contains no matching element")] - NonExistentElement, - #[error("the file dialog has been closed without selecting a valid option")] - DialogClosed, - #[error("{0}")] - Other(String), -} - -impl From<io::Error> for Error { - fn from(value: io::Error) -> Self { - Self::IOError(value.to_string()) - } -} - -impl From<serde_json::Error> for Error { - fn from(value: serde_json::Error) -> Self { - Self::SerdeError(value.to_string()) - } -} - -impl From<rust_format::Error> for Error { - fn from(value: rust_format::Error) -> Self { - Self::FormatError(value.to_string()) - } -} - -impl From<&'static str> for Error { - fn from(value: &'static str) -> Self { - Self::Other(value.to_owned()) - } -} - -#[derive(Debug, Clone)] -pub enum Message { - ToggleDarkMode, - CopyCode, - SwitchPage(DesignerPage), - EditorAction(text_editor::Action), - RefreshEditorContent, - DropNewElement(ElementName, iced::Point, iced::Rectangle), - HandleNew( - ElementName, - Vec<(iced::advanced::widget::Id, iced::Rectangle)>, - ), - MoveElement(RenderedElement, iced::Point, iced::Rectangle), - HandleMove( - RenderedElement, - Vec<(iced::advanced::widget::Id, iced::Rectangle)>, - ), - PaneResized(pane_grid::ResizeEvent), - PaneClicked(pane_grid::Pane), - PaneDragged(pane_grid::DragEvent), - NewFile, - OpenFile, - FileOpened(Result<(PathBuf, Project), Error>), - SaveFile, - SaveFileAs, - FileSaved(Result<PathBuf, Error>), -} +pub type Result<T> = std::result::Result<T, error::Error>; diff --git a/iced_builder/src/main.rs b/iced_builder/src/main.rs index d022f29..bbf01c5 100644 --- a/iced_builder/src/main.rs +++ b/iced_builder/src/main.rs @@ -11,9 +11,9 @@ use iced::{ Alignment, Element, Length, Settings, Task, Theme, }; use iced_builder::{ - types::{Action, DesignerPage, ElementName, Project}, + error::error_dialog, + types::{Action, DesignerPage, ElementName, Message, Project}, views::{code_view, designer_view, element_list}, - Message, }; fn main() -> iced::Result { @@ -109,14 +109,12 @@ impl App { self.editor_content.perform(action); } } - Message::RefreshEditorContent => { - let code = self - .project - .clone() - .app_code() - .unwrap_or_else(|err| err.to_string()); - self.editor_content = text_editor::Content::with_text(&code); - } + Message::RefreshEditorContent => match self.project.clone().app_code() { + Ok(code) => { + self.editor_content = text_editor::Content::with_text(&code); + } + Err(error) => error_dialog(error.to_string()), + }, Message::DropNewElement(name, point, _) => { return iced_drop::zones_on_point( move |zones| Message::HandleNew(name.clone(), zones), @@ -131,8 +129,10 @@ impl App { if ids.len() > 0 { let action = Action::new(ids, &mut self.project.element_tree.clone(), None); let result = name.handle_action(self.project.element_tree.as_mut(), action); - if let Ok(Some(ref element)) = result { - self.project.element_tree = Some(element.clone()); + match result { + Ok(Some(ref element)) => self.project.element_tree = Some(element.clone()), + Err(error) => error_dialog(error.to_string()), + _ => {} } self.is_dirty = true; @@ -157,7 +157,10 @@ impl App { &mut self.project.element_tree.clone(), Some(element.get_id()), ); - let _ = element.handle_action(self.project.element_tree.as_mut(), action); + let result = element.handle_action(self.project.element_tree.as_mut(), action); + if let Err(error) = result { + error_dialog(error.to_string()); + } self.is_dirty = true; } @@ -185,19 +188,22 @@ impl App { if !self.is_loading && !self.is_dirty { self.is_loading = true; - return Task::perform(Project::from_file(), Message::FileOpened); + return Task::perform(Project::from_path(), Message::FileOpened); } } Message::FileOpened(result) => { self.is_loading = false; self.is_dirty = false; - if let Ok((path, project)) = result { - self.project = project.clone(); - self.project_path = Some(path); - self.editor_content = text_editor::Content::with_text( - &project.app_code().unwrap_or_else(|err| err.to_string()), - ); + match result { + Ok((path, project)) => { + self.project = project.clone(); + self.project_path = Some(path); + self.editor_content = text_editor::Content::with_text( + &project.app_code().unwrap_or_else(|err| err.to_string()), + ); + } + Err(error) => error_dialog(error.to_string()), } } Message::SaveFile => { @@ -225,9 +231,12 @@ impl App { Message::FileSaved(result) => { self.is_loading = false; - if let Ok(path) = result { - self.project_path = Some(path); - self.is_dirty = false; + match result { + Ok(path) => { + self.project_path = Some(path); + self.is_dirty = false; + } + Err(error) => error_dialog(error.to_string()), } } } diff --git a/iced_builder/src/types/element_name.rs b/iced_builder/src/types/element_name.rs index bf38120..d71ae30 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; +use crate::error::Error; use super::rendered_element::{ button, column, container, image, row, svg, text, Action, RenderedElement, diff --git a/iced_builder/src/types/mod.rs b/iced_builder/src/types/mod.rs index 0012905..841b255 100644 --- a/iced_builder/src/types/mod.rs +++ b/iced_builder/src/types/mod.rs @@ -6,6 +6,39 @@ pub use element_name::ElementName; pub use project::Project; pub use rendered_element::*; +use std::path::PathBuf; + +use crate::error::Error; +use iced::widget::{pane_grid, text_editor}; + +#[derive(Debug, Clone)] +pub enum Message { + ToggleDarkMode, + CopyCode, + SwitchPage(DesignerPage), + EditorAction(text_editor::Action), + RefreshEditorContent, + DropNewElement(ElementName, iced::Point, iced::Rectangle), + HandleNew( + ElementName, + Vec<(iced::advanced::widget::Id, iced::Rectangle)>, + ), + MoveElement(RenderedElement, iced::Point, iced::Rectangle), + HandleMove( + RenderedElement, + Vec<(iced::advanced::widget::Id, iced::Rectangle)>, + ), + PaneResized(pane_grid::ResizeEvent), + PaneClicked(pane_grid::Pane), + PaneDragged(pane_grid::DragEvent), + NewFile, + OpenFile, + FileOpened(Result<(PathBuf, Project), Error>), + SaveFile, + SaveFileAs, + FileSaved(Result<PathBuf, Error>), +} + #[derive(Debug, Clone)] pub enum DesignerPage { Designer, diff --git a/iced_builder/src/types/project.rs b/iced_builder/src/types/project.rs index 52da41c..8d24a75 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; +use crate::error::Error; use super::rendered_element::RenderedElement; @@ -55,10 +55,10 @@ impl Project { } } - pub async fn from_file() -> Result<(PathBuf, Self), Error> { + pub async fn from_path() -> Result<(PathBuf, Self), Error> { let picked_file = rfd::AsyncFileDialog::new() .set_title("Open a JSON file...") - .add_filter("*.JSON, *.json", &["JSON", "json"]) + .add_filter("*.json, *.JSON", &["json", "JSON"]) .pick_file() .await .ok_or(Error::DialogClosed)?; @@ -77,7 +77,7 @@ impl Project { } else { rfd::AsyncFileDialog::new() .set_title("Save to JSON file...") - .add_filter("*.JSON, *.json", &["JSON", "json"]) + .add_filter("*.json, *.JSON", &["json", "JSON"]) .save_file() .await .as_ref() @@ -103,7 +103,7 @@ impl Project { {app_code} fn main() -> iced::Result {{ - iced::application("{}", State::update, State::view).theme(iced::Theme::{}).run() + iced::application("{}", State::update, State::view).theme(State::theme).run() }} #[derive(Default)] @@ -115,6 +115,10 @@ impl Project { impl State {{ fn update(&mut self, _message: Message) {{}} + fn theme(&self) -> iced::Theme {{ + iced::Theme::{} + }} + fn view(&self) -> Element<Message> {{ {view}.into() }} diff --git a/iced_builder/src/types/rendered_element.rs b/iced_builder/src/types/rendered_element.rs index 3dad8e7..58fd18d 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, Message}; +use crate::{error::Error, types::Message}; use super::ElementName; diff --git a/iced_builder/src/views/code_view.rs b/iced_builder/src/views/code_view.rs index 4515687..e872e3d 100644 --- a/iced_builder/src/views/code_view.rs +++ b/iced_builder/src/views/code_view.rs @@ -1,5 +1,5 @@ use super::style; -use crate::{types::DesignerPage, Message}; +use crate::types::{DesignerPage, Message}; use iced::{ highlighter, widget::{button, container, pane_grid, row, text, text_editor, tooltip, Space}, diff --git a/iced_builder/src/views/designer_view.rs b/iced_builder/src/views/designer_view.rs index 2d88493..1f7de88 100644 --- a/iced_builder/src/views/designer_view.rs +++ b/iced_builder/src/views/designer_view.rs @@ -1,8 +1,5 @@ use super::style; -use crate::{ - types::{DesignerPage, RenderedElement}, - Message, -}; +use crate::types::{DesignerPage, Message, RenderedElement}; use iced::{ widget::{button, container, pane_grid, row, text, themer, Space}, Alignment, Element, Length, diff --git a/iced_builder/src/views/element_list.rs b/iced_builder/src/views/element_list.rs index a9aeb1f..6e78ae0 100644 --- a/iced_builder/src/views/element_list.rs +++ b/iced_builder/src/views/element_list.rs @@ -1,5 +1,5 @@ use super::style; -use crate::{types::ElementName, Message}; +use crate::types::{ElementName, Message}; use iced::{ widget::{column, container, pane_grid, text, Column}, Alignment, Element, Length, |
