diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/mod.rs | 160 | ||||
| -rw-r--r-- | src/lib.rs | 0 | ||||
| -rw-r--r-- | src/main.rs | 301 | ||||
| -rw-r--r-- | src/types/mod.rs | 25 | ||||
| -rw-r--r-- | src/types/rendered_element.rs | 47 |
5 files changed, 0 insertions, 533 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs deleted file mode 100644 index 2dd9cff..0000000 --- a/src/codegen/mod.rs +++ /dev/null @@ -1,160 +0,0 @@ -use std::path::PathBuf; - -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(\"{}\"){props}", path.display().to_string()); - } - ElementName::SVG(path) => { - imports = format!("{imports}svg,"); - view = format!("{view}\nsvg(\"{}\"){props}", path.display().to_string()); - } - } - - (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(PathBuf::from( - "/mnt/drive_d/git/obs-website/src/lib/assets/bars-solid.svg", - ))), - ], - )); - - element.app_code("new app", None).unwrap() - } -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index e69de29..0000000 --- a/src/lib.rs +++ /dev/null diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index d3fafc6..0000000 --- a/src/main.rs +++ /dev/null @@ -1,301 +0,0 @@ -mod codegen; -mod types; - -use iced::{ - clipboard, executor, - highlighter::{self, Highlighter}, - theme, - widget::{ - button, column, container, - pane_grid::{self, Pane, PaneGrid}, - row, text, text_editor, tooltip, Column, Space, - }, - Alignment, Application, Color, Command, Element, Font, Length, Settings, -}; -use types::{rendered_element::RenderedElement, DesignerPage, DesignerState}; - -fn main() -> iced::Result { - App::run(Settings { - fonts: vec![include_bytes!("../fonts/icons.ttf").as_slice().into()], - ..Settings::default() - }) -} - -struct App { - is_saved: bool, - current_project: Option<String>, - dark_theme: bool, - pane_state: pane_grid::State<Panes>, - focus: Option<Pane>, - designer_state: DesignerState, - element_list: Vec<String>, - editor_content: text_editor::Content, -} - -#[derive(Debug, Clone)] -enum Message { - ToggleTheme, - CopyCode, - Resized(pane_grid::ResizeEvent), - Clicked(pane_grid::Pane), -} - -#[derive(Clone, Debug)] -enum Panes { - Designer, - ElementList, -} - -impl Application for App { - type Message = Message; - type Theme = theme::Theme; - type Executor = executor::Default; - type Flags = (); - - fn new(_flags: ()) -> (Self, Command<Message>) { - let state = pane_grid::State::with_configuration(pane_grid::Configuration::Split { - axis: pane_grid::Axis::Vertical, - ratio: 0.8, - a: Box::new(pane_grid::Configuration::Pane(Panes::Designer)), - b: Box::new(pane_grid::Configuration::Pane(Panes::ElementList)), - }); - ( - Self { - is_saved: true, - current_project: None, - dark_theme: true, - pane_state: state, - focus: None, - designer_state: DesignerState { - designer_content: vec![], - designer_page: DesignerPage::CodeView, - }, - element_list: vec!["Column", "Row", "PickList", "PaneGrid", "Button", "Text"] - .into_iter() - .map(|c| c.to_owned()) - .collect(), - editor_content: text_editor::Content::with_text(&RenderedElement::test()), - }, - Command::none(), - ) - } - - fn title(&self) -> String { - let saved_state = if self.is_saved { "" } else { " *" }; - - let project_name = match &self.current_project { - Some(n) => format!(" - {n}"), - None => "".to_owned(), - }; - - format!("iced Builder{project_name}{saved_state}") - } - - fn theme(&self) -> iced::Theme { - if self.dark_theme { - theme::Theme::CatppuccinMocha - } else { - theme::Theme::CatppuccinLatte - } - } - - fn update(&mut self, message: Message) -> Command<Message> { - match message { - Message::ToggleTheme => self.dark_theme = !self.dark_theme, - Message::CopyCode => return clipboard::write(self.editor_content.text()), - Message::Resized(pane_grid::ResizeEvent { split, ratio }) => { - self.pane_state.resize(split, ratio); - } - Message::Clicked(pane) => { - self.focus = Some(pane); - } - } - - Command::none() - } - - fn view(&self) -> Element<Message> { - let header = row![button("Toggle Theme") - .on_press(Message::ToggleTheme) - .padding(5)] - .width(200); - let pane_grid = PaneGrid::new(&self.pane_state, |id, pane, _is_maximized| { - let is_focused = Some(id) == self.focus; - match pane { - Panes::Designer => match self.designer_state.designer_page { - DesignerPage::Designer => { - let content = column![text("Designer"),] - .align_items(Alignment::Center) - .height(Length::Fill) - .width(Length::Fill); - let title = text("Designer").style(if is_focused { - PANE_ID_COLOR_FOCUSED - } else { - PANE_ID_COLOR_UNFOCUSED - }); - let title_bar = pane_grid::TitleBar::new(title) - .padding(10) - .style(style::title_bar); - pane_grid::Content::new(content) - .title_bar(title_bar) - .style(if is_focused { - style::pane_focused - } else { - style::pane_active - }) - } - DesignerPage::CodeView => { - let title = row![ - text("Generated Code").style(if is_focused { - PANE_ID_COLOR_FOCUSED - } else { - PANE_ID_COLOR_UNFOCUSED - }), - Space::with_width(Length::Fill), - tooltip( - button( - container( - text('\u{0e801}').font(Font::with_name("editor-icons")) - ) - .width(30) - .center_x() - ) - .on_press(Message::CopyCode), - "Copy code to clipboard", - tooltip::Position::Left - ) - ]; - let title_bar = pane_grid::TitleBar::new(title) - .padding(10) - .style(style::title_bar); - pane_grid::Content::new( - text_editor(&self.editor_content) - .highlight::<Highlighter>( - highlighter::Settings { - theme: highlighter::Theme::Base16Mocha, - extension: "rs".to_string(), - }, - |highlight, _theme| highlight.to_format(), - ) - .height(Length::Fill) - .padding(20), - ) - .title_bar(title_bar) - .style(if is_focused { - style::pane_focused - } else { - style::pane_active - }) - } - }, - Panes::ElementList => { - let items_list = items_list_view(&self.element_list); - let content = column![items_list] - .align_items(Alignment::Center) - .height(Length::Fill) - .width(Length::Fill); - let title = text("Element List").style(if is_focused { - PANE_ID_COLOR_FOCUSED - } else { - PANE_ID_COLOR_UNFOCUSED - }); - let title_bar = pane_grid::TitleBar::new(title) - .padding(10) - .style(style::title_bar); - pane_grid::Content::new(content) - .title_bar(title_bar) - .style(if is_focused { - style::pane_focused - } else { - style::pane_active - }) - } - } - }) - .width(Length::Fill) - .height(Length::Fill) - .spacing(10) - .on_resize(10, Message::Resized) - .on_click(Message::Clicked); - - let content = Column::new() - .push(header) - .push(pane_grid) - .spacing(5) - .align_items(Alignment::Center) - .width(Length::Fill); - - container(content).height(Length::Fill).into() - } -} - -const fn from_grayscale(grayscale: f32) -> Color { - Color { - r: grayscale, - g: grayscale, - b: grayscale, - a: 1.0, - } -} - -// #ffffff -const PANE_ID_COLOR_FOCUSED: Color = from_grayscale(1.0); - -// #e8e8e8 -const PANE_ID_COLOR_UNFOCUSED: Color = from_grayscale(0xE8 as f32 / 255.0); - -fn items_list_view(items: &Vec<String>) -> Element<'static, Message> { - let mut column = Column::new() - .spacing(20) - .align_items(Alignment::Center) - .width(Length::Fill); - - for value in items { - column = column.push(text(value)); - } - - container(column).height(250.0).width(300).into() -} - -mod style { - use iced::widget::container; - use iced::{Border, Theme}; - - pub fn title_bar(theme: &Theme) -> container::Appearance { - let palette = theme.extended_palette(); - - container::Appearance { - text_color: Some(palette.background.strong.text), - background: Some(palette.background.strong.color.into()), - ..Default::default() - } - } - - pub fn pane_active(theme: &Theme) -> container::Appearance { - let palette = theme.extended_palette(); - - container::Appearance { - background: Some(palette.background.weak.color.into()), - border: Border { - width: 1.0, - color: palette.background.strong.color, - ..Border::default() - }, - ..Default::default() - } - } - - pub fn pane_focused(theme: &Theme) -> container::Appearance { - let palette = theme.extended_palette(); - - container::Appearance { - background: Some(palette.background.weak.color.into()), - border: Border { - width: 4.0, - color: palette.background.strong.color, - ..Border::default() - }, - ..Default::default() - } - } -} diff --git a/src/types/mod.rs b/src/types/mod.rs deleted file mode 100644 index 7a04d79..0000000 --- a/src/types/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -pub mod rendered_element; - -use rendered_element::RenderedElement; -use std::path::PathBuf; - -pub struct DesignerState { - pub designer_content: Vec<RenderedElement>, - pub designer_page: DesignerPage, -} - -#[derive(Debug)] -pub enum ElementName { - Text(&'static str), - Button(&'static str), - SVG(PathBuf), - Image(PathBuf), - Container, - Row, - Column, -} - -pub enum DesignerPage { - Designer, - CodeView, -} diff --git a/src/types/rendered_element.rs b/src/types/rendered_element.rs deleted file mode 100644 index f05594d..0000000 --- a/src/types/rendered_element.rs +++ /dev/null @@ -1,47 +0,0 @@ -use std::collections::HashMap; - -use unique_id::{string::StringGenerator, Generator}; - -use iced::advanced::widget::Id; - -use super::ElementName; - -#[derive(Debug)] -pub struct RenderedElement { - pub id: Id, - pub child_elements: Vec<RenderedElement>, - pub name: ElementName, - pub props: HashMap<&'static str, &'static str>, -} - -impl RenderedElement { - pub fn new(name: ElementName) -> Self { - let gen = StringGenerator::default(); - Self { - id: Id::new(gen.next_id()), - child_elements: vec![], - name, - props: HashMap::new(), - } - } - - pub fn from_vec(name: ElementName, child_elements: Vec<RenderedElement>) -> Self { - let gen = StringGenerator::default(); - Self { - id: Id::new(gen.next_id()), - child_elements, - name, - props: HashMap::new(), - } - } - - pub fn push(mut self, element: RenderedElement) -> Self { - self.child_elements.push(element); - self - } - - pub fn set_property(&mut self, prop: &'static str, value: &'static str) { - let prop_ref = self.props.entry(prop).or_insert(value); - *prop_ref = value; - } -} |
