summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/options.rs58
-rwxr-xr-xsrc/types/rendered_element.rs40
-rw-r--r--src/values.rs1
-rw-r--r--src/values/padding.rs76
-rw-r--r--src/values/rotation.rs37
5 files changed, 183 insertions, 29 deletions
diff --git a/src/options.rs b/src/options.rs
index 5a3e1fb..c381294 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -1,12 +1,12 @@
use std::collections::BTreeMap;
-use iced::Padding;
#[allow(unused_imports)]
use iced::widget::{Button, Column, Container, Image, Row, Svg, Text};
+use iced::{Padding, Rotation};
use crate::values::ValueFromStr;
-pub trait ApplyOptions {
+pub trait ApplyOptions: Sized {
fn apply_options(self, options: BTreeMap<String, Option<String>>) -> Self;
}
@@ -15,10 +15,62 @@ impl<Message> ApplyOptions for Button<'_, Message> {
let mut button = self;
if let Some(padding) = options.get("padding").expect("padding key") {
- let padding: Padding = Padding::value_from_str(padding).unwrap();
+ let padding = Padding::value_from_str(padding).unwrap();
button = button.padding(padding);
}
button
}
}
+
+impl<Message> ApplyOptions for Column<'_, Message> {
+ fn apply_options(self, options: BTreeMap<String, Option<String>>) -> Self {
+ let mut column = self;
+
+ if let Some(padding) = options.get("padding").expect("padding key") {
+ let padding = Padding::value_from_str(padding).unwrap();
+ column = column.padding(padding);
+ }
+
+ column
+ }
+}
+
+impl<Message> ApplyOptions for Row<'_, Message> {
+ fn apply_options(self, options: BTreeMap<String, Option<String>>) -> Self {
+ let mut row = self;
+
+ if let Some(padding) = options.get("padding").expect("padding key") {
+ let padding = Padding::value_from_str(padding).unwrap();
+ row = row.padding(padding);
+ }
+
+ row
+ }
+}
+
+impl<Handle> ApplyOptions for Image<Handle> {
+ fn apply_options(self, options: BTreeMap<String, Option<String>>) -> Self {
+ let mut image = self;
+
+ if let Some(rotation) = options.get("rotation").expect("rotation key") {
+ let rotation = Rotation::value_from_str(rotation).unwrap();
+ image = image.rotation(rotation);
+ }
+
+ image
+ }
+}
+
+impl ApplyOptions for Svg<'_> {
+ fn apply_options(self, options: BTreeMap<String, Option<String>>) -> Self {
+ let mut svg = self;
+
+ if let Some(rotation) = options.get("rotation").expect("rotation key") {
+ let rotation = Rotation::value_from_str(rotation).unwrap();
+ svg = svg.rotation(rotation);
+ }
+
+ svg
+ }
+}
diff --git a/src/types/rendered_element.rs b/src/types/rendered_element.rs
index f4ae6f3..f9a83c1 100755
--- a/src/types/rendered_element.rs
+++ b/src/types/rendered_element.rs
@@ -335,8 +335,12 @@ impl<'a> From<RenderedElement> for Element<'a, Message> {
.into()
}
}
- ElementName::Svg(p) => widget::svg(p).into(),
- ElementName::Image(p) => widget::image(p).into(),
+ ElementName::Svg(p) => {
+ widget::svg(p).apply_options(copy.options).into()
+ }
+ ElementName::Image(p) => {
+ widget::image(p).apply_options(copy.options).into()
+ }
ElementName::Container => {
widget::container(if child_elements.len() == 1 {
child_elements[0].clone().into()
@@ -350,11 +354,13 @@ impl<'a> From<RenderedElement> for Element<'a, Message> {
child_elements.into_iter().map(Into::into).collect(),
)
.padding(20)
+ .apply_options(copy.options)
.into(),
ElementName::Column => widget::Column::from_vec(
child_elements.into_iter().map(Into::into).collect(),
)
.padding(20)
+ .apply_options(copy.options)
.into(),
};
iced_drop::droppable(content)
@@ -446,13 +452,27 @@ 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())).preset_options(&[
+ "width",
+ "height",
+ "content_fit",
+ "rotation",
+ "opacity",
+ ])
}
pub fn image(path: &str) -> RenderedElement {
- RenderedElement::new(ElementName::Image(path.to_owned()))
+ RenderedElement::new(ElementName::Image(path.to_owned())).preset_options(&[
+ "width",
+ "height",
+ "content_fit",
+ "rotation",
+ "opacity",
+ "scale",
+ ])
}
+// TODO: Container options
pub fn container(content: Option<RenderedElement>) -> RenderedElement {
match content {
Some(el) => RenderedElement::with(ElementName::Container, vec![el]),
@@ -462,6 +482,9 @@ pub fn container(content: Option<RenderedElement>) -> RenderedElement {
pub fn row(child_elements: Option<Vec<RenderedElement>>) -> RenderedElement {
RenderedElement::with(ElementName::Row, child_elements.unwrap_or_default())
+ .preset_options(&[
+ "spacing", "padding", "width", "height", "align_y", "clip",
+ ])
}
pub fn column(child_elements: Option<Vec<RenderedElement>>) -> RenderedElement {
@@ -469,4 +492,13 @@ pub fn column(child_elements: Option<Vec<RenderedElement>>) -> RenderedElement {
ElementName::Column,
child_elements.unwrap_or_default(),
)
+ .preset_options(&[
+ "spacing",
+ "padding",
+ "width",
+ "height",
+ "max_width",
+ "align_x",
+ "clip",
+ ])
}
diff --git a/src/values.rs b/src/values.rs
index 0ac17cb..23e47d7 100644
--- a/src/values.rs
+++ b/src/values.rs
@@ -1,4 +1,5 @@
mod padding;
+mod rotation;
pub trait ValueFromStr: Sized {
type Err;
diff --git a/src/values/padding.rs b/src/values/padding.rs
index 3cec7a7..01e333b 100644
--- a/src/values/padding.rs
+++ b/src/values/padding.rs
@@ -1,37 +1,69 @@
+use std::num::ParseFloatError;
use std::str::FromStr;
use iced::Padding;
use super::ValueFromStr;
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
pub enum PaddingError {
- Nah,
+ #[error("wrong number of values")]
+ WrongNumberOfValues,
+ #[error("float parsing error: {0}")]
+ ParseFloatError(ParseFloatError),
+ #[error("missing bracket")]
+ MissingBracket,
+ #[error("empty string given")]
+ Empty,
+}
+
+impl From<ParseFloatError> for PaddingError {
+ fn from(value: ParseFloatError) -> Self {
+ Self::ParseFloatError(value)
+ }
}
impl ValueFromStr for Padding {
type Err = PaddingError;
fn value_from_str(s: &str) -> Result<Self, Self::Err> {
- s.strip_prefix('[')
- .and_then(|s| s.strip_suffix(']'))
- .map(|s| {
- 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
- }
- })
- .ok_or(PaddingError::Nah)
+ if s.is_empty() {
+ return Err(PaddingError::Empty);
+ }
+ let values = s
+ .strip_prefix('[')
+ .ok_or(PaddingError::MissingBracket)?
+ .strip_suffix(']')
+ .ok_or(PaddingError::MissingBracket)?
+ .split(',')
+ .map(|n| f32::from_str(n))
+ .collect::<Result<Vec<_>, _>>()?;
+ match values.len() {
+ 1 => Ok(Padding {
+ top: values[0],
+ right: values[0],
+ bottom: values[0],
+ left: values[0],
+ }),
+ 2 => Ok(Padding {
+ top: values[0],
+ right: values[1],
+ bottom: values[0],
+ left: values[1],
+ }),
+ 3 => Ok(Padding {
+ top: values[0],
+ right: values[1],
+ bottom: values[2],
+ left: values[1],
+ }),
+ 4 => Ok(Padding {
+ top: values[0],
+ right: values[1],
+ bottom: values[2],
+ left: values[3],
+ }),
+ _ => Err(PaddingError::WrongNumberOfValues),
+ }
}
}
diff --git a/src/values/rotation.rs b/src/values/rotation.rs
new file mode 100644
index 0000000..2b7a223
--- /dev/null
+++ b/src/values/rotation.rs
@@ -0,0 +1,37 @@
+use std::num::ParseFloatError;
+use std::str::FromStr;
+
+use iced::{Radians, Rotation};
+
+use super::ValueFromStr;
+
+#[derive(Debug, thiserror::Error)]
+pub enum ParseRotationError {
+ #[error("float parsing error: {0}")]
+ ParseFloatError(ParseFloatError),
+ #[error("invalid prefix")]
+ InvalidPrefix,
+}
+
+impl From<ParseFloatError> for ParseRotationError {
+ fn from(value: ParseFloatError) -> Self {
+ Self::ParseFloatError(value)
+ }
+}
+
+impl ValueFromStr for Rotation {
+ type Err = ParseRotationError;
+
+ fn value_from_str(s: &str) -> Result<Self, Self::Err> {
+ if s.starts_with(|c: char| !c.is_digit(10)) {
+ let (prefix, value) = s.split_at(1);
+ match prefix {
+ "s" => Ok(Rotation::Solid(Radians(f32::from_str(value)?))),
+ "f" => Ok(Rotation::Floating(Radians(f32::from_str(value)?))),
+ _ => Err(ParseRotationError::InvalidPrefix),
+ }
+ } else {
+ Ok(Rotation::Floating(Radians(f32::from_str(s)?)))
+ }
+ }
+}