summaryrefslogtreecommitdiff
path: root/iced_builder
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--iced_builder/Cargo.toml12
-rw-r--r--iced_builder/assets/windows/iced_builder.manifest8
-rw-r--r--iced_builder/assets/windows/iced_builder.rc3
-rw-r--r--iced_builder/build.rs7
-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
14 files changed, 168 insertions, 116 deletions
diff --git a/iced_builder/Cargo.toml b/iced_builder/Cargo.toml
index d08d485..e62f965 100644
--- a/iced_builder/Cargo.toml
+++ b/iced_builder/Cargo.toml
@@ -12,15 +12,19 @@ keywords = ["gui", "iced"]
iced = { version = "0.13.1", features = [ "image","svg","canvas","qr_code","advanced","tokio","highlighter"] }
iced_aw = { version = "0.11.0", default-features = false, features = ["menu","color_picker"] }
iced_drop = { path = "../iced_drop" }
-serde = { version = "1.0.210", features = ["derive"] }
-serde_json = "1.0.128"
-tokio = { version = "1.40.0", features = ["fs"] }
-rfd = "0.15.0"
+serde = { version = "1.0.214", features = ["derive"] }
+serde_json = "1.0.132"
+tokio = { version = "1.41.0", features = ["fs"] }
+rfd = { version = "0.15.0", default-features = false, features = ["async-std", "gtk3"] }
rust-format = "0.3.4"
unique_id = "0.1.5"
indexmap = { version = "2.6.0", features = ["serde"] }
thiserror = "1.0.65"
+[target.'cfg(windows)'.build-dependencies]
+embed-resource = "2.5.0"
+windows_exe_info = "0.4"
+
[[bin]]
name = "iced-builder"
path = "src/main.rs"
diff --git a/iced_builder/assets/windows/iced_builder.manifest b/iced_builder/assets/windows/iced_builder.manifest
new file mode 100644
index 0000000..82039bf
--- /dev/null
+++ b/iced_builder/assets/windows/iced_builder.manifest
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
+ <asmv3:application>
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
+ <dpiAwareness>PerMonitorV2, unaware</dpiAwareness>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+</assembly>
diff --git a/iced_builder/assets/windows/iced_builder.rc b/iced_builder/assets/windows/iced_builder.rc
new file mode 100644
index 0000000..7255b65
--- /dev/null
+++ b/iced_builder/assets/windows/iced_builder.rc
@@ -0,0 +1,3 @@
+#define RT_MANIFEST 24
+
+1 RT_MANIFEST "iced_builder.manifest"
diff --git a/iced_builder/build.rs b/iced_builder/build.rs
new file mode 100644
index 0000000..75261f8
--- /dev/null
+++ b/iced_builder/build.rs
@@ -0,0 +1,7 @@
+fn main() {
+ #[cfg(windows)]
+ {
+ embed_resource::compile("assets/windows/iced_builder.rc", embed_resource::NONE);
+ windows_exe_info::versioninfo::link_cargo_env();
+ }
+}
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,