summaryrefslogtreecommitdiff
path: root/iced_builder
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--iced_builder/build.rs5
-rw-r--r--iced_builder/src/dialogs.rs4
-rw-r--r--iced_builder/src/error.rs5
-rw-r--r--iced_builder/src/main.rs152
-rw-r--r--iced_builder/src/types/element_name.rs3
-rw-r--r--iced_builder/src/types/mod.rs12
-rw-r--r--iced_builder/src/types/project.rs8
-rwxr-xr-xiced_builder/src/types/rendered_element.rs91
-rw-r--r--iced_builder/src/views/code_view.rs12
-rw-r--r--iced_builder/src/views/designer_view.rs10
-rw-r--r--iced_builder/src/views/element_list.rs19
11 files changed, 186 insertions, 135 deletions
diff --git a/iced_builder/build.rs b/iced_builder/build.rs
index 54edc54..438ce37 100644
--- a/iced_builder/build.rs
+++ b/iced_builder/build.rs
@@ -3,7 +3,10 @@ fn main() {
iced_fontello::build("fonts/icons.toml").expect("Build icons font");
#[cfg(windows)]
{
- embed_resource::compile("assets/windows/iced_builder.rc", embed_resource::NONE);
+ embed_resource::compile(
+ "assets/windows/iced_builder.rc",
+ embed_resource::NONE,
+ );
windows_exe_info::versioninfo::link_cargo_env();
}
}
diff --git a/iced_builder/src/dialogs.rs b/iced_builder/src/dialogs.rs
index edd6cea..047ffd2 100644
--- a/iced_builder/src/dialogs.rs
+++ b/iced_builder/src/dialogs.rs
@@ -9,7 +9,9 @@ pub fn error_dialog(description: impl Into<String>) {
.show();
}
-pub fn unsaved_changes_dialog(description: impl Into<String>) -> MessageDialogResult {
+pub fn unsaved_changes_dialog(
+ description: impl Into<String>,
+) -> MessageDialogResult {
MessageDialog::new()
.set_level(MessageLevel::Warning)
.set_buttons(MessageButtons::OkCancel)
diff --git a/iced_builder/src/error.rs b/iced_builder/src/error.rs
index 2fea184..8876016 100644
--- a/iced_builder/src/error.rs
+++ b/iced_builder/src/error.rs
@@ -1,5 +1,6 @@
use std::io;
use std::sync::Arc;
+
use thiserror::Error;
#[derive(Debug, Clone, Error)]
@@ -10,7 +11,9 @@ pub enum Error {
FormatError(Arc<rust_format::Error>),
#[error("The element tree contains no matching element")]
NonExistentElement,
- #[error("The file dialog has been closed without selecting a valid option")]
+ #[error(
+ "The file dialog has been closed without selecting a valid option"
+ )]
DialogClosed,
#[error("{0}")]
Other(String),
diff --git a/iced_builder/src/main.rs b/iced_builder/src/main.rs
index e42e854..ab708df 100644
--- a/iced_builder/src/main.rs
+++ b/iced_builder/src/main.rs
@@ -1,22 +1,16 @@
use std::path::PathBuf;
-use iced::{
- advanced::widget::Id,
- clipboard, keyboard,
- widget::{
- container,
- pane_grid::{self, Pane, PaneGrid},
- pick_list, row, text_editor, Column,
- },
- Alignment, Element, Length, Task, Theme,
-};
+use iced::advanced::widget::Id;
+use iced::widget::pane_grid::{self, Pane, PaneGrid};
+use iced::widget::{container, pick_list, row, text_editor, Column};
+use iced::{clipboard, keyboard, Alignment, Element, Length, Task, Theme};
use iced_anim::{Animation, Spring};
-use iced_builder::{
- dialogs::{error_dialog, unsaved_changes_dialog},
- icon,
- types::{Action, DesignerPage, ElementName, Message, Project},
- views::{code_view, designer_view, element_list},
+use iced_builder::dialogs::{error_dialog, unsaved_changes_dialog};
+use iced_builder::icon;
+use iced_builder::types::{
+ Action, DesignerPage, ElementName, Message, Project,
};
+use iced_builder::views::{code_view, designer_view, element_list};
use rfd::MessageDialogResult;
const THEMES: &'static [Theme] = &[Theme::SolarizedDark, Theme::SolarizedLight];
@@ -50,12 +44,14 @@ enum Panes {
impl App {
fn new() -> (Self, Task<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)),
- });
+ 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_dirty: false,
@@ -98,19 +94,24 @@ impl App {
Message::ToggleTheme(event) => {
self.theme.update(event);
}
- Message::CopyCode => return clipboard::write(self.editor_content.text()),
+ Message::CopyCode => {
+ return clipboard::write(self.editor_content.text())
+ }
Message::SwitchPage(page) => self.designer_page = page,
Message::EditorAction(action) => {
if let text_editor::Action::Scroll { lines: _ } = action {
self.editor_content.perform(action);
}
}
- Message::RefreshEditorContent => match self.project.clone().app_code() {
- Ok(code) => {
- 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()),
}
- Err(error) => error_dialog(error.to_string()),
- },
+ }
Message::DropNewElement(name, point, _) => {
return iced_drop::zones_on_point(
move |zones| Message::HandleNew(name.clone(), zones),
@@ -123,10 +124,19 @@ impl App {
Message::HandleNew(name, zones) => {
let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect();
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);
+ let action = Action::new(
+ ids,
+ &mut self.project.element_tree.clone(),
+ None,
+ );
+ let result = name.handle_action(
+ self.project.element_tree.as_mut(),
+ action,
+ );
match result {
- Ok(Some(ref element)) => self.project.element_tree = Some(element.clone()),
+ Ok(Some(ref element)) => {
+ self.project.element_tree = Some(element.clone())
+ }
Err(error) => error_dialog(error.to_string()),
_ => {}
}
@@ -152,7 +162,10 @@ impl App {
&mut self.project.element_tree.clone(),
Some(element.get_id()),
);
- let result = 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());
}
@@ -167,7 +180,10 @@ impl App {
Message::PaneClicked(pane) => {
self.focus = Some(pane);
}
- Message::PaneDragged(pane_grid::DragEvent::Dropped { pane, target }) => {
+ Message::PaneDragged(pane_grid::DragEvent::Dropped {
+ pane,
+ target,
+ }) => {
self.pane_state.drop(pane, target);
}
Message::PaneDragged(_) => {}
@@ -192,7 +208,10 @@ impl App {
if !self.is_dirty {
self.is_loading = true;
- return Task::perform(Project::from_path(), Message::FileOpened);
+ return Task::perform(
+ Project::from_path(),
+ Message::FileOpened,
+ );
} else {
if let MessageDialogResult::Ok = unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and open another project?") {
self.is_dirty = false;
@@ -211,7 +230,9 @@ impl App {
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()),
+ &project
+ .app_code()
+ .unwrap_or_else(|err| err.to_string()),
);
}
Err(error) => error_dialog(error.to_string()),
@@ -260,11 +281,13 @@ impl App {
if modifiers.command() {
match key.as_ref() {
keyboard::Key::Character("o") => Some(Message::OpenFile),
- keyboard::Key::Character("s") => Some(if modifiers.shift() {
- Message::SaveFileAs
- } else {
- Message::SaveFile
- }),
+ keyboard::Key::Character("s") => {
+ Some(if modifiers.shift() {
+ Message::SaveFileAs
+ } else {
+ Message::SaveFile
+ })
+ }
keyboard::Key::Character("n") => Some(Message::NewFile),
_ => None,
}
@@ -281,30 +304,33 @@ impl App {
|theme| { Message::ToggleTheme(theme.into()) }
)]
.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_page {
- DesignerPage::DesignerView => designer_view::view(
- &self.project.element_tree,
- self.project.get_theme(),
- is_focused,
- ),
- DesignerPage::CodeView => code_view::view(
- &self.editor_content,
- self.theme.value().clone(),
- is_focused,
- ),
- },
- Panes::ElementList => element_list::view(&self.element_list, is_focused),
- }
- })
- .width(Length::Fill)
- .height(Length::Fill)
- .spacing(10)
- .on_resize(10, Message::PaneResized)
- .on_click(Message::PaneClicked)
- .on_drag(Message::PaneDragged);
+ 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_page {
+ DesignerPage::DesignerView => designer_view::view(
+ &self.project.element_tree,
+ self.project.get_theme(),
+ is_focused,
+ ),
+ DesignerPage::CodeView => code_view::view(
+ &self.editor_content,
+ self.theme.value().clone(),
+ is_focused,
+ ),
+ },
+ Panes::ElementList => {
+ element_list::view(&self.element_list, is_focused)
+ }
+ }
+ })
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .spacing(10)
+ .on_resize(10, Message::PaneResized)
+ .on_click(Message::PaneClicked)
+ .on_drag(Message::PaneDragged);
let content = Column::new()
.push(header)
diff --git a/iced_builder/src/types/element_name.rs b/iced_builder/src/types/element_name.rs
index cdbdf8f..5567cff 100644
--- a/iced_builder/src/types/element_name.rs
+++ b/iced_builder/src/types/element_name.rs
@@ -1,10 +1,9 @@
use serde::{Deserialize, Serialize};
-use crate::{Error, Result};
-
use super::rendered_element::{
button, column, container, image, row, svg, text, Action, RenderedElement,
};
+use crate::{Error, Result};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ElementName {
diff --git a/iced_builder/src/types/mod.rs b/iced_builder/src/types/mod.rs
index 02fab4a..161b5e1 100644
--- a/iced_builder/src/types/mod.rs
+++ b/iced_builder/src/types/mod.rs
@@ -2,18 +2,16 @@ pub mod element_name;
pub mod project;
pub mod rendered_element;
+use std::path::PathBuf;
+
pub use element_name::ElementName;
+use iced::widget::{pane_grid, text_editor};
+use iced::Theme;
+use iced_anim::SpringEvent;
pub use project::Project;
pub use rendered_element::*;
-use std::path::PathBuf;
-
use crate::Result;
-use iced::{
- widget::{pane_grid, text_editor},
- Theme,
-};
-use iced_anim::SpringEvent;
#[derive(Debug, Clone)]
pub enum Message {
diff --git a/iced_builder/src/types/project.rs b/iced_builder/src/types/project.rs
index 3bd5975..f4dbcc4 100644
--- a/iced_builder/src/types/project.rs
+++ b/iced_builder/src/types/project.rs
@@ -1,12 +1,11 @@
-use rust_format::{Config, Edition, Formatter, RustFmt};
use std::path::{Path, PathBuf};
use iced::Theme;
+use rust_format::{Config, Edition, Formatter, RustFmt};
use serde::{Deserialize, Serialize};
-use crate::{Error, Result};
-
use super::rendered_element::RenderedElement;
+use crate::{Error, Result};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Project {
@@ -96,7 +95,8 @@ impl Project {
match self.element_tree {
Some(ref element_tree) => {
let (imports, view) = element_tree.codegen();
- let mut app_code = format!("use iced::{{widget::{{{imports}}},Element}};");
+ let mut app_code =
+ format!("use iced::{{widget::{{{imports}}},Element}};");
app_code = format!(
r#"// Automatically generated by iced Builder
diff --git a/iced_builder/src/types/rendered_element.rs b/iced_builder/src/types/rendered_element.rs
index 3bb3626..35198a1 100755
--- a/iced_builder/src/types/rendered_element.rs
+++ b/iced_builder/src/types/rendered_element.rs
@@ -1,12 +1,13 @@
+use std::collections::BTreeMap;
+
use blob_uuid::random_blob;
use iced::advanced::widget::Id;
use iced::{widget, Element, Length};
use serde::{Deserialize, Serialize};
-use crate::{types::Message, Result};
-use std::collections::BTreeMap;
-
use super::ElementName;
+use crate::types::Message;
+use crate::Result;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RenderedElement {
@@ -55,7 +56,10 @@ impl RenderedElement {
}
}
- pub fn find_parent(&mut self, child_element: &RenderedElement) -> Option<&mut Self> {
+ pub fn find_parent(
+ &mut self,
+ child_element: &RenderedElement,
+ ) -> Option<&mut Self> {
if child_element == self {
return Some(self);
} else if self.child_elements.is_some() {
@@ -92,7 +96,9 @@ impl RenderedElement {
pub fn remove(&mut self, element: &RenderedElement) {
if let Some(child_elements) = self.child_elements.as_mut() {
- if let Some(index) = child_elements.iter().position(|x| x == element) {
+ if let Some(index) =
+ child_elements.iter().position(|x| x == element)
+ {
let _ = child_elements.remove(index);
}
}
@@ -106,7 +112,9 @@ impl RenderedElement {
pub fn insert_after(&mut self, id: Id, element: &RenderedElement) {
if let Some(child_elements) = self.child_elements.as_mut() {
- if let Some(index) = child_elements.iter().position(|x| x.get_id() == id) {
+ if let Some(index) =
+ child_elements.iter().position(|x| x.get_id() == id)
+ {
child_elements.insert(index + 1, element.clone());
} else {
child_elements.push(element.clone());
@@ -178,16 +186,21 @@ impl RenderedElement {
}
iced_drop::droppable(
widget::container(
- widget::column![widget::text(self.name.clone().to_string()), children]
- .width(Length::Fill)
- .spacing(10),
+ widget::column![
+ widget::text(self.name.clone().to_string()),
+ children
+ ]
+ .width(Length::Fill)
+ .spacing(10),
)
.padding(10)
.style(widget::container::bordered_box),
)
.id(self.get_id())
.drag_hide(true)
- .on_drop(move |point, rect| Message::MoveElement(self.clone(), point, rect))
+ .on_drop(move |point, rect| {
+ Message::MoveElement(self.clone(), point, rect)
+ })
.into()
}
@@ -327,28 +340,32 @@ impl<'a> From<RenderedElement> for Element<'a, Message> {
}
ElementName::SVG(p) => widget::svg(p).into(),
ElementName::Image(p) => widget::image(p).into(),
- ElementName::Container => widget::container(if child_elements.len() == 1 {
- child_elements[0].clone().into()
- } else {
- Element::from("")
- })
+ ElementName::Container => {
+ widget::container(if child_elements.len() == 1 {
+ child_elements[0].clone().into()
+ } else {
+ Element::from("")
+ })
+ .padding(20)
+ .into()
+ }
+ ElementName::Row => widget::Row::from_iter(
+ child_elements.into_iter().map(|el| el.into()),
+ )
+ .padding(20)
+ .into(),
+ ElementName::Column => widget::Column::from_iter(
+ child_elements.into_iter().map(|el| el.into()),
+ )
.padding(20)
.into(),
- ElementName::Row => {
- widget::Row::from_iter(child_elements.into_iter().map(|el| el.into()))
- .padding(20)
- .into()
- }
- ElementName::Column => {
- widget::Column::from_iter(child_elements.into_iter().map(|el| el.into()))
- .padding(20)
- .into()
- }
};
iced_drop::droppable(content)
.id(value.get_id())
.drag_hide(true)
- .on_drop(move |point, rect| Message::MoveElement(value.clone(), point, rect))
+ .on_drop(move |point, rect| {
+ Message::MoveElement(value.clone(), point, rect)
+ })
.into()
}
}
@@ -378,8 +395,10 @@ impl Action {
} else {
let id: Id = match source_id {
Some(id) if ids.contains(&id) => {
- let element_id = ids[ids.iter().position(|x| *x == id).unwrap()].clone();
- if ids.len() > 2 && ids[ids.clone().len() - 1] == element_id {
+ let element_id =
+ ids[ids.iter().position(|x| *x == id).unwrap()].clone();
+ if ids.len() > 2 && ids[ids.clone().len() - 1] == element_id
+ {
return Self::Stop;
}
element_id
@@ -394,7 +413,8 @@ impl Action {
// Element IS a parent but ISN'T a non-empty container
match element.is_parent()
- && !(element.name == ElementName::Container && !element.is_empty())
+ && !(element.name == ElementName::Container
+ && !element.is_empty())
{
true => {
action = Self::PushFront(id);
@@ -425,12 +445,8 @@ impl Action {
}
pub fn text(text: &str) -> RenderedElement {
- RenderedElement::new(ElementName::Text(text.to_owned())).preset_options(vec![
- "size",
- "line_height",
- "width",
- "height",
- ])
+ RenderedElement::new(ElementName::Text(text.to_owned()))
+ .preset_options(vec!["size", "line_height", "width", "height"])
}
pub fn button(text: &str) -> RenderedElement {
@@ -457,5 +473,8 @@ pub fn row(child_elements: Option<Vec<RenderedElement>>) -> RenderedElement {
}
pub fn column(child_elements: Option<Vec<RenderedElement>>) -> RenderedElement {
- RenderedElement::with(ElementName::Column, child_elements.unwrap_or_default())
+ RenderedElement::with(
+ ElementName::Column,
+ child_elements.unwrap_or_default(),
+ )
}
diff --git a/iced_builder/src/views/code_view.rs b/iced_builder/src/views/code_view.rs
index 5b5fd37..1be75d9 100644
--- a/iced_builder/src/views/code_view.rs
+++ b/iced_builder/src/views/code_view.rs
@@ -1,11 +1,10 @@
+use iced::widget::{
+ button, container, pane_grid, row, text, text_editor, tooltip, Space,
+};
+use iced::{Alignment, Length, Theme};
use super::style;
use crate::icon::copy;
use crate::types::{DesignerPage, Message};
-use iced::{
- highlighter,
- widget::{button, container, pane_grid, row, text, text_editor, tooltip, Space},
- Alignment, Length,
-};
pub fn view<'a>(
editor_content: &'a text_editor::Content,
@@ -21,7 +20,8 @@ pub fn view<'a>(
tooltip::Position::FollowCursor
),
Space::with_width(20),
- button("Switch to Designer view").on_press(Message::SwitchPage(DesignerPage::DesignerView))
+ button("Switch to Designer view")
+ .on_press(Message::SwitchPage(DesignerPage::DesignerView))
]
.align_y(Alignment::Center);
let title_bar = pane_grid::TitleBar::new(title)
diff --git a/iced_builder/src/views/designer_view.rs b/iced_builder/src/views/designer_view.rs
index 1f7de88..76456db 100644
--- a/iced_builder/src/views/designer_view.rs
+++ b/iced_builder/src/views/designer_view.rs
@@ -1,9 +1,8 @@
+use iced::widget::{button, container, pane_grid, row, text, themer, Space};
+use iced::{Alignment, Element, Length};
+
use super::style;
use crate::types::{DesignerPage, Message, RenderedElement};
-use iced::{
- widget::{button, container, pane_grid, row, text, themer, Space},
- Alignment, Element, Length,
-};
pub fn view<'a>(
element_tree: &Option<RenderedElement>,
@@ -21,7 +20,8 @@ pub fn view<'a>(
let title = row![
text("Designer"),
Space::with_width(Length::Fill),
- button("Switch to Code view").on_press(Message::SwitchPage(DesignerPage::CodeView)),
+ button("Switch to Code view")
+ .on_press(Message::SwitchPage(DesignerPage::CodeView)),
]
.align_y(Alignment::Center);
let title_bar = pane_grid::TitleBar::new(title)
diff --git a/iced_builder/src/views/element_list.rs b/iced_builder/src/views/element_list.rs
index 6e78ae0..0a75a93 100644
--- a/iced_builder/src/views/element_list.rs
+++ b/iced_builder/src/views/element_list.rs
@@ -1,10 +1,9 @@
+use iced::widget::{column, container, pane_grid, text, Column};
+use iced::{Alignment, Element, Length};
+use iced_drop::droppable;
+
use super::style;
use crate::types::{ElementName, Message};
-use iced::{
- widget::{column, container, pane_grid, text, Column},
- Alignment, Element, Length,
-};
-use iced_drop::droppable;
fn items_list_view<'a>(items: &'a Vec<ElementName>) -> Element<'a, Message> {
let mut column = Column::new()
@@ -13,10 +12,12 @@ fn items_list_view<'a>(items: &'a Vec<ElementName>) -> Element<'a, Message> {
.width(Length::Fill);
for item in items {
- column = column.push(
- droppable(text(item.clone().to_string()))
- .on_drop(move |point, rect| Message::DropNewElement(item.clone(), point, rect)),
- );
+ column =
+ column.push(droppable(text(item.clone().to_string())).on_drop(
+ move |point, rect| {
+ Message::DropNewElement(item.clone(), point, rect)
+ },
+ ));
}
container(column)