summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpml68 <contact@pml68.dev>2025-02-22 23:48:19 +0100
committerpml68 <contact@pml68.dev>2025-02-22 23:48:19 +0100
commit09cd0fe9f2d5d775cd1b645300ac56bc203a20cd (patch)
treefdbac1602752c780c7ed704a49dc7a03c8087d7c
parentfeat: update to Rust 2024 (diff)
downloadiced-builder-09cd0fe9f2d5d775cd1b645300ac56bc203a20cd.tar.gz
feat: start working on options backend (`ApplyOptions` trait)
-rw-r--r--src/main.rs28
-rw-r--r--src/options.rs44
-rw-r--r--src/types.rs14
-rwxr-xr-xsrc/types/rendered_element.rs49
4 files changed, 90 insertions, 45 deletions
diff --git a/src/main.rs b/src/main.rs
index 13510b9..6c4e8d6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,6 +4,7 @@ mod environment;
mod error;
#[allow(clippy::all, dead_code)]
mod icon;
+mod options;
mod panes;
mod theme;
mod types;
@@ -15,8 +16,7 @@ use config::Config;
use dialogs::{error_dialog, unsaved_changes_dialog, warning_dialog};
use error::Error;
use iced::advanced::widget::Id;
-use iced::widget::pane_grid::{self, Pane, PaneGrid};
-use iced::widget::{Column, container, pick_list, row, text_editor};
+use iced::widget::{Column, container, pane_grid, pick_list, row, text_editor};
use iced::{Alignment, Element, Length, Task, Theme, clipboard, keyboard};
use iced_anim::transition::Easing;
use iced_anim::{Animated, Animation};
@@ -62,7 +62,7 @@ struct App {
config: Config,
theme: Animated<Theme>,
pane_state: pane_grid::State<Panes>,
- focus: Option<Pane>,
+ focus: Option<pane_grid::Pane>,
designer_page: DesignerPane,
element_list: &'static [ElementName],
editor_content: text_editor::Content,
@@ -209,7 +209,7 @@ impl App {
let action = Action::new(
&ids,
eltree_clone.as_ref(),
- Some(element.get_id()),
+ Some(element.id()),
);
let result = element.handle_action(
self.project.element_tree.as_mut(),
@@ -354,8 +354,9 @@ impl App {
|theme| Message::SwitchTheme(theme.into())
)]
.width(200);
- let pane_grid =
- PaneGrid::new(&self.pane_state, |id, pane, _is_maximized| {
+ let pane_grid = 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 {
@@ -374,13 +375,14 @@ impl App {
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);
+ },
+ )
+ .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/src/options.rs b/src/options.rs
new file mode 100644
index 0000000..9514dcb
--- /dev/null
+++ b/src/options.rs
@@ -0,0 +1,44 @@
+use std::collections::BTreeMap;
+use std::str::FromStr;
+
+use iced::Padding;
+use iced::widget::{Button, Column, Container, Image, Row, Svg, Text};
+
+pub trait ApplyOptions {
+ fn apply_options(self, options: BTreeMap<String, Option<String>>) -> Self;
+}
+
+impl<'a, Message> ApplyOptions for Button<'a, Message> {
+ fn apply_options(self, options: BTreeMap<String, Option<String>>) -> Self {
+ let mut button = self;
+
+ if let Some(padding) = options.get("padding").expect("padding key") {
+ let padding: Padding = padding
+ .strip_prefix('[')
+ .and_then(|s| s.strip_suffix(']'))
+ .and_then(|s| {
+ Some(
+ s.split(',')
+ .map(|n| f32::from_str(n).unwrap())
+ .collect::<Vec<_>>(),
+ )
+ })
+ .and_then(|s| {
+ if s.len() == 4 {
+ Some(Padding {
+ top: s[0],
+ right: s[1],
+ bottom: s[2],
+ left: s[3],
+ })
+ } else {
+ None
+ }
+ })
+ .unwrap();
+ button = button.padding(padding);
+ }
+
+ button
+ }
+}
diff --git a/src/types.rs b/src/types.rs
index 2b743cd..73728e3 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -5,7 +5,7 @@ pub mod rendered_element;
use std::path::PathBuf;
pub use element_name::ElementName;
-use iced::Theme;
+use iced::advanced::widget::Id;
use iced::widget::{pane_grid, text_editor};
use iced_anim::Event;
pub use project::Project;
@@ -15,21 +15,15 @@ use crate::Error;
#[derive(Debug, Clone)]
pub enum Message {
- SwitchTheme(Event<Theme>),
+ SwitchTheme(Event<iced::Theme>),
CopyCode,
SwitchPage(DesignerPane),
EditorAction(text_editor::Action),
RefreshEditorContent,
DropNewElement(ElementName, iced::Point, iced::Rectangle),
- HandleNew(
- ElementName,
- Vec<(iced::advanced::widget::Id, iced::Rectangle)>,
- ),
+ HandleNew(ElementName, Vec<(Id, iced::Rectangle)>),
MoveElement(RenderedElement, iced::Point, iced::Rectangle),
- HandleMove(
- RenderedElement,
- Vec<(iced::advanced::widget::Id, iced::Rectangle)>,
- ),
+ HandleMove(RenderedElement, Vec<(Id, iced::Rectangle)>),
PaneResized(pane_grid::ResizeEvent),
PaneClicked(pane_grid::Pane),
PaneDragged(pane_grid::DragEvent),
diff --git a/src/types/rendered_element.rs b/src/types/rendered_element.rs
index e321449..94c55a0 100755
--- a/src/types/rendered_element.rs
+++ b/src/types/rendered_element.rs
@@ -4,9 +4,9 @@ use iced::advanced::widget::Id;
use iced::{Element, Length, widget};
use serde::{Deserialize, Serialize};
-use super::ElementName;
use crate::Error;
-use crate::types::Message;
+use crate::options::ApplyOptions;
+use crate::types::{ElementName, Message};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RenderedElement {
@@ -36,12 +36,12 @@ impl RenderedElement {
}
}
- pub fn get_id(&self) -> &Id {
+ pub fn id(&self) -> &Id {
&self.id
}
pub fn find_by_id(&mut self, id: &Id) -> Option<&mut Self> {
- if self.get_id() == id {
+ if self.id() == id {
Some(self)
} else if let Some(child_elements) = self.child_elements.as_mut() {
for element in child_elements {
@@ -111,7 +111,7 @@ 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)
+ child_elements.iter().position(|x| x.id() == id)
{
child_elements.insert(index + 1, element.clone());
} else {
@@ -158,25 +158,25 @@ impl RenderedElement {
fn preset_options(mut self, options: &[&str]) -> Self {
for opt in options {
- let _ = self.options.insert(opt.to_string(), None);
+ let _ = self.options.insert((*opt).to_string(), None);
}
self
}
- pub fn option<'a>(mut self, option: &'a str, value: &'a str) -> Self {
+ pub fn option(mut self, option: String, value: String) -> Self {
let _ = self
.options
- .entry(option.to_owned())
- .and_modify(|opt| *opt = Some(value.to_owned()));
+ .entry(option)
+ .and_modify(|opt| *opt = Some(value));
self
}
- pub fn into_element<'a>(self) -> Element<'a, Message> {
+ pub fn text_view<'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().into_element());
+ children = children.push(el.clone().text_view());
}
}
iced_drop::droppable(
@@ -191,7 +191,7 @@ impl RenderedElement {
.padding(10)
.style(widget::container::bordered_box),
)
- .id(self.get_id().clone())
+ .id(self.id().clone())
.drag_hide(true)
.on_drop(move |point, rect| {
Message::MoveElement(self.clone(), point, rect)
@@ -313,24 +313,26 @@ impl std::fmt::Display for RenderedElement {
impl<'a> From<RenderedElement> for Element<'a, Message> {
fn from(value: RenderedElement) -> Self {
- let child_elements = match value.child_elements {
- Some(ref elements) => elements.clone(),
- None => vec![],
- };
+ let copy = value.clone();
+ let child_elements = copy.child_elements.unwrap_or_default();
- let content: Element<'a, Message> = match value.name.clone() {
+ let content: Element<'a, Message> = match copy.name {
ElementName::Text(s) => {
- if s == String::new() {
+ if &s == "" {
widget::text("New Text").into()
} else {
widget::text(s).into()
}
}
ElementName::Button(s) => {
- if s == String::new() {
- widget::button(widget::text("New Button")).into()
+ if &s == "" {
+ widget::button(widget::text("New Button"))
+ .apply_options(copy.options)
+ .into()
} else {
- widget::button(widget::text(s)).into()
+ widget::button(widget::text(s))
+ .apply_options(copy.options)
+ .into()
}
}
ElementName::Svg(p) => widget::svg(p).into(),
@@ -356,7 +358,7 @@ impl<'a> From<RenderedElement> for Element<'a, Message> {
.into(),
};
iced_drop::droppable(content)
- .id(value.get_id().clone())
+ .id(value.id().clone())
.drag_hide(true)
.on_drop(move |point, rect| {
Message::MoveElement(value.clone(), point, rect)
@@ -433,11 +435,14 @@ pub fn text(text: &str) -> RenderedElement {
"line_height",
"width",
"height",
+ "align_x",
+ "align_y",
])
}
pub fn button(text: &str) -> RenderedElement {
RenderedElement::new(ElementName::Button(text.to_owned()))
+ .preset_options(&["width", "height", "padding", "clip"])
}
pub fn svg(path: &str) -> RenderedElement {