diff options
Diffstat (limited to '')
| -rw-r--r-- | src/options.rs | 58 | ||||
| -rwxr-xr-x | src/types/rendered_element.rs | 40 | ||||
| -rw-r--r-- | src/values.rs | 1 | ||||
| -rw-r--r-- | src/values/padding.rs | 76 | ||||
| -rw-r--r-- | src/values/rotation.rs | 37 |
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)?))) + } + } +} |
