summaryrefslogtreecommitdiff
path: root/iced_builder/src/codegen
diff options
context:
space:
mode:
authorpml68 <contact@pml68.me>2024-09-22 23:53:02 +0200
committerpml68 <contact@pml68.me>2024-09-23 00:00:45 +0200
commitf5c35e48c480355036778d26aacde498e5c15e68 (patch)
treebf949b406bd8f0719f06095bb14bf9872a7493e5 /iced_builder/src/codegen
parentMerge pull request #1 from pml68/feat/codegen (diff)
downloadiced-builder-f5c35e48c480355036778d26aacde498e5c15e68.tar.gz
feat: restructure project, start drag and drop
Diffstat (limited to 'iced_builder/src/codegen')
-rw-r--r--iced_builder/src/codegen/mod.rs158
1 files changed, 158 insertions, 0 deletions
diff --git a/iced_builder/src/codegen/mod.rs b/iced_builder/src/codegen/mod.rs
new file mode 100644
index 0000000..88c0c61
--- /dev/null
+++ b/iced_builder/src/codegen/mod.rs
@@ -0,0 +1,158 @@
+use rust_format::{Config, Edition, Formatter, RustFmt};
+
+use crate::types::{rendered_element::RenderedElement, ElementName};
+
+impl RenderedElement {
+ fn props_codegen(&self) -> String {
+ let mut props_string = String::new();
+
+ for (k, v) in self.props.clone() {
+ props_string = format!("{props_string}.{k}({v})");
+ }
+
+ props_string
+ }
+
+ fn codegen(&self) -> (String, String) {
+ let mut imports = String::new();
+ let mut view = String::new();
+ let props = self.props_codegen();
+
+ let mut elements = String::new();
+
+ match self.name {
+ ElementName::Column | ElementName::Row | ElementName::Container => {
+ for element in &self.child_elements {
+ let (c_imports, children) = element.codegen();
+ imports = format!("{imports}{c_imports}");
+ elements = format!("{elements}{},", children);
+ }
+ }
+ _ => {}
+ }
+
+ match &self.name {
+ ElementName::Container => {
+ imports = format!("{imports}container,");
+ view = if self.child_elements.len() < 2 {
+ format!("{view}\ncontainer({elements}){props}")
+ } else {
+ format!("{view}\ncontainer(){props}")
+ };
+ }
+ ElementName::Row => {
+ imports = format!("{imports}row,");
+ view = format!("{view}\nrow![{elements}]{props}");
+ }
+ ElementName::Column => {
+ imports = format!("{imports}column,");
+ view = format!("{view}\ncolumn![{elements}]{props}");
+ }
+ ElementName::Text(string) => {
+ imports = format!("{imports}text,");
+ view = format!(
+ "{view}\ntext(\"{}\"){props}",
+ if *string == String::new() {
+ "New Text"
+ } else {
+ string
+ }
+ );
+ }
+ ElementName::Button(string) => {
+ imports = format!("{imports}button,");
+ view = format!(
+ "{view}\nbutton(\"{}\"){props}",
+ if *string == String::new() {
+ "New Button"
+ } else {
+ string
+ }
+ );
+ }
+ ElementName::Image(path) => {
+ imports = format!("{imports}image,");
+ view = format!("{view}\nimage(\"{path}\"){props}");
+ }
+ ElementName::SVG(path) => {
+ imports = format!("{imports}svg,");
+ view = format!("{view}\nsvg(\"{path}\"){props}");
+ }
+ }
+
+ (imports, view)
+ }
+
+ pub fn app_code(
+ &self,
+ title: &str,
+ theme: Option<iced::Theme>,
+ ) -> Result<String, Box<dyn std::error::Error>> {
+ let (imports, view) = self.codegen();
+ let mut app_code = format!("use iced::{{widget::{{{imports}}},Sandbox,Settings,Element}};");
+
+ app_code = format!(
+ r#"{app_code}
+
+ fn main() -> iced::Result {{
+ App::run(Settings::default())
+ }}
+
+ struct App;
+
+ impl Sandbox for App {{
+ type Message = ();
+
+ fn new() -> Self {{
+ Self {{}}
+ }}
+
+ fn title(&self) -> String {{
+ "{title}".into()
+ }}
+
+ fn theme(&self) -> iced::Theme {{
+ iced::Theme::{}
+ }}
+
+ fn update(&mut self, message: Self::Message) {{
+
+ }}
+
+ fn view(&self) -> Element<Self::Message> {{
+ {view}.into()
+ }}
+ }}"#,
+ if let Some(c) = theme {
+ c.to_string().replace(' ', "")
+ } else {
+ "default()".to_owned()
+ }
+ );
+ let config = Config::new_str()
+ .edition(Edition::Rust2021)
+ .option("trailing_comma", "Never")
+ .option("imports_granularity", "Crate");
+ let rustfmt = RustFmt::from_config(config);
+ Ok(rustfmt.format_str(app_code)?)
+ }
+
+ pub fn test() -> String {
+ let mut text1 = RenderedElement::new(ElementName::Text("wow"));
+ text1.set_property("height", "120.5");
+ text1.set_property("width", "230");
+
+ let element = RenderedElement::new(ElementName::Container).push(RenderedElement::from_vec(
+ ElementName::Row,
+ vec![
+ text1,
+ RenderedElement::new(ElementName::Text("heh")),
+ RenderedElement::new(ElementName::SVG(
+ "/mnt/drive_d/git/obs-website/src/lib/assets/bars-solid.svg",
+ )),
+ ],
+ ));
+
+ element.app_code("new app", None).unwrap()
+ }
+}