summaryrefslogtreecommitdiff
path: root/iced_builder/src/types
diff options
context:
space:
mode:
Diffstat (limited to 'iced_builder/src/types')
-rw-r--r--iced_builder/src/types/element_name.rs12
-rw-r--r--iced_builder/src/types/project.rs73
-rwxr-xr-xiced_builder/src/types/rendered_element.rs33
3 files changed, 75 insertions, 43 deletions
diff --git a/iced_builder/src/types/element_name.rs b/iced_builder/src/types/element_name.rs
index e172227..0e8aa65 100644
--- a/iced_builder/src/types/element_name.rs
+++ b/iced_builder/src/types/element_name.rs
@@ -3,13 +3,13 @@ use serde::{Deserialize, Serialize};
use super::rendered_element::{
button, column, container, image, row, svg, text, Action, RenderedElement,
};
-use crate::{Error, Result};
+use crate::Error;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ElementName {
Text(String),
Button(String),
- SVG(String),
+ Svg(String),
Image(String),
Container,
Row,
@@ -20,7 +20,7 @@ impl ElementName {
pub const ALL: &'static [Self; 7] = &[
Self::Text(String::new()),
Self::Button(String::new()),
- Self::SVG(String::new()),
+ Self::Svg(String::new()),
Self::Image(String::new()),
Self::Container,
Self::Row,
@@ -31,11 +31,11 @@ impl ElementName {
&self,
element_tree: Option<&mut RenderedElement>,
action: Action,
- ) -> Result<Option<RenderedElement>> {
+ ) -> Result<Option<RenderedElement>, Error> {
let element = match self {
Self::Text(_) => text(""),
Self::Button(_) => button(""),
- Self::SVG(_) => svg(""),
+ Self::Svg(_) => svg(""),
Self::Image(_) => image(""),
Self::Container => container(None),
Self::Row => row(None),
@@ -75,7 +75,7 @@ impl std::fmt::Display for ElementName {
match self {
Self::Text(_) => "Text",
Self::Button(_) => "Button",
- Self::SVG(_) => "SVG",
+ Self::Svg(_) => "SVG",
Self::Image(_) => "Image",
Self::Container => "Container",
Self::Row => "Row",
diff --git a/iced_builder/src/types/project.rs b/iced_builder/src/types/project.rs
index 6f3b7ed..6479b1d 100644
--- a/iced_builder/src/types/project.rs
+++ b/iced_builder/src/types/project.rs
@@ -1,18 +1,23 @@
use std::path::{Path, PathBuf};
+extern crate fxhash;
+use fxhash::FxHashMap;
use iced::Theme;
-use rust_format::{Config, Edition, Formatter, RustFmt};
+use rust_format::{Edition, Formatter, RustFmt};
use serde::{Deserialize, Serialize};
use super::rendered_element::RenderedElement;
-use crate::theme::theme_from_str;
-use crate::{Error, Result};
+use crate::config::Config;
+use crate::theme::{theme_from_str, theme_index, theme_to_string};
+use crate::Error;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Project {
pub title: Option<String>,
pub theme: Option<String>,
pub element_tree: Option<RenderedElement>,
+ #[serde(skip)]
+ theme_cache: FxHashMap<String, String>,
}
impl Default for Project {
@@ -27,24 +32,42 @@ impl Project {
title: None,
theme: None,
element_tree: None,
+ theme_cache: FxHashMap::default(),
}
}
- pub fn get_theme(&self, config: &crate::config::Config) -> Theme {
+ pub fn get_theme(&self, config: &Config) -> Theme {
match &self.theme {
Some(theme) => theme_from_str(Some(config), theme),
- None => Theme::Dark,
+ None => Theme::default(),
}
}
- pub async fn from_path(path: PathBuf) -> Result<(PathBuf, Self)> {
+ fn theme_code(&mut self, theme: &Theme) -> String {
+ let theme_name = theme.to_string();
+ if theme_index(&theme_name, Theme::ALL).is_none() {
+ self.theme_cache
+ .entry(theme_name)
+ .or_insert(theme_to_string(theme))
+ .to_string()
+ } else {
+ theme_name.replace(" ", "")
+ }
+ }
+
+ pub async fn from_path(
+ path: PathBuf,
+ config: Config,
+ ) -> Result<(PathBuf, Self), Error> {
let contents = tokio::fs::read_to_string(&path).await?;
- let element: Self = serde_json::from_str(&contents)?;
+ let mut project: Self = serde_json::from_str(&contents)?;
+
+ let _ = project.theme_code(&project.get_theme(&config));
- Ok((path, element))
+ Ok((path, project))
}
- pub async fn from_file() -> Result<(PathBuf, Self)> {
+ pub async fn from_file(config: Config) -> Result<(PathBuf, Self), Error> {
let picked_file = rfd::AsyncFileDialog::new()
.set_title("Open a JSON file...")
.add_filter("*.json, *.JSON", &["json", "JSON"])
@@ -54,10 +77,13 @@ impl Project {
let path = picked_file.path().to_owned();
- Self::from_path(path).await
+ Self::from_path(path, config).await
}
- pub async fn write_to_file(self, path: Option<PathBuf>) -> Result<PathBuf> {
+ pub async fn write_to_file(
+ self,
+ path: Option<PathBuf>,
+ ) -> Result<PathBuf, Error> {
let path = if let Some(p) = path {
p
} else {
@@ -78,16 +104,25 @@ impl Project {
Ok(path)
}
- pub fn app_code(&self, config: &crate::config::Config) -> Result<String> {
+ pub fn app_code(&mut self, config: &Config) -> Result<String, Error> {
match self.element_tree {
Some(ref element_tree) => {
let (imports, view) = element_tree.codegen();
- let mut app_code =
- format!("use iced::{{widget::{{{imports}}},Element}};");
-
- app_code = format!(
+ let theme = self.get_theme(config);
+ let theme_code = self.theme_code(&theme);
+ let mut theme_imports = "";
+ if theme_index(&theme.to_string(), Theme::ALL).is_none() {
+ if theme_code.contains("Extended") {
+ theme_imports = "use iced::{{color,theme::{{Palette,palette::{{Extended,Background,Primary,Secondary,Success,Danger,Pair}}}}}};\n";
+ } else {
+ theme_imports = "use iced::{{color,theme::Palette}};\n"
+ }
+ }
+
+ let app_code = format!(
r#"// Automatically generated by iced Builder
- {app_code}
+ use iced::{{widget::{{{imports}}},Element}};
+ {theme_imports}
fn main() -> iced::Result {{
iced::application("{}", State::update, State::view).theme(State::theme).run()
@@ -114,9 +149,9 @@ impl Project {
Some(ref t) => t,
None => "New app",
},
- self.get_theme(config).to_string().replace(" ", "")
+ theme_code
);
- let config = Config::new_str()
+ let config = rust_format::Config::new_str()
.edition(Edition::Rust2021)
.option("trailing_comma", "Never")
.option("imports_granularity", "Crate");
diff --git a/iced_builder/src/types/rendered_element.rs b/iced_builder/src/types/rendered_element.rs
index d7efed1..177b43d 100755
--- a/iced_builder/src/types/rendered_element.rs
+++ b/iced_builder/src/types/rendered_element.rs
@@ -7,7 +7,7 @@ use uuid::Uuid;
use super::ElementName;
use crate::types::Message;
-use crate::Result;
+use crate::Error;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RenderedElement {
@@ -62,7 +62,7 @@ impl RenderedElement {
child_element: &RenderedElement,
) -> Option<&mut Self> {
if child_element == self {
- Some(self)
+ return Some(self);
} else if self.child_elements.is_some() {
if self
.child_elements
@@ -71,20 +71,17 @@ impl RenderedElement {
.contains(child_element)
{
return Some(self);
- } else {
- if let Some(child_elements) = self.child_elements.as_mut() {
- for element in child_elements {
- let element = element.find_parent(child_element);
- if element.is_some() {
- return element;
- }
+ }
+ if let Some(child_elements) = self.child_elements.as_mut() {
+ for element in child_elements {
+ let element = element.find_parent(child_element);
+ if element.is_some() {
+ return element;
}
}
- return None;
}
- } else {
- return None;
}
+ return None;
}
pub fn is_parent(&self) -> bool {
@@ -128,7 +125,7 @@ impl RenderedElement {
&self,
element_tree: Option<&mut RenderedElement>,
action: Action,
- ) -> Result<()> {
+ ) -> Result<(), Error> {
let element_tree = element_tree.unwrap();
match action {
@@ -175,12 +172,12 @@ impl RenderedElement {
self
}
- pub fn as_element<'a>(self) -> Element<'a, Message> {
+ pub fn into_element<'a>(self) -> Element<'a, Message> {
let mut children = widget::column![];
if let Some(els) = self.child_elements.clone() {
for el in els {
- children = children.push(el.clone().as_element());
+ children = children.push(el.clone().into_element());
}
}
iced_drop::droppable(
@@ -263,7 +260,7 @@ impl RenderedElement {
imports = format!("{imports}image,");
view = format!("{view}\nimage(\"{path}\"){options}");
}
- ElementName::SVG(path) => {
+ ElementName::Svg(path) => {
imports = format!("{imports}svg,");
view = format!("{view}\nsvg(\"{path}\"){options}");
}
@@ -337,7 +334,7 @@ impl<'a> From<RenderedElement> for Element<'a, Message> {
widget::button(widget::text(s)).into()
}
}
- ElementName::SVG(p) => widget::svg(p).into(),
+ ElementName::Svg(p) => widget::svg(p).into(),
ElementName::Image(p) => widget::image(p).into(),
ElementName::Container => {
widget::container(if child_elements.len() == 1 {
@@ -457,7 +454,7 @@ pub fn button(text: &str) -> RenderedElement {
}
pub fn svg(path: &str) -> RenderedElement {
- RenderedElement::new(ElementName::SVG(path.to_owned()))
+ RenderedElement::new(ElementName::Svg(path.to_owned()))
}
pub fn image(path: &str) -> RenderedElement {