summaryrefslogtreecommitdiff
path: root/iced_builder/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--iced_builder/src/error.rs61
-rw-r--r--iced_builder/src/lib.rs78
-rw-r--r--iced_builder/src/main.rs55
-rw-r--r--iced_builder/src/types/element_name.rs2
-rw-r--r--iced_builder/src/types/mod.rs33
-rw-r--r--iced_builder/src/types/project.rs14
-rwxr-xr-xiced_builder/src/types/rendered_element.rs2
-rw-r--r--iced_builder/src/views/code_view.rs2
-rw-r--r--iced_builder/src/views/designer_view.rs5
-rw-r--r--iced_builder/src/views/element_list.rs2
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,