From 0030bcbd33f5c4db60aac826552042e46b51c691 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 5 Feb 2020 00:23:22 +0100 Subject: Rename module `style` to `css` in `iced_web` --- web/src/css.rs | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 web/src/css.rs (limited to 'web/src/css.rs') diff --git a/web/src/css.rs b/web/src/css.rs new file mode 100644 index 00000000..df0938da --- /dev/null +++ b/web/src/css.rs @@ -0,0 +1,162 @@ +//! Style your widgets. +use crate::{bumpalo, Align, Color, Length}; + +use std::collections::BTreeMap; + +/// A CSS rule of a VDOM node. +#[derive(Debug)] +pub enum Rule { + /// Container with vertical distribution + Column, + + /// Container with horizonal distribution + Row, + + /// Padding of the container + Padding(u16), + + /// Spacing between elements + Spacing(u16), +} + +impl Rule { + /// Returns the class name of the [`Style`]. + /// + /// [`Style`]: enum.Style.html + pub fn class<'a>(&self) -> String { + match self { + Rule::Column => String::from("c"), + Rule::Row => String::from("r"), + Rule::Padding(padding) => format!("p-{}", padding), + Rule::Spacing(spacing) => format!("s-{}", spacing), + } + } + + /// Returns the declaration of the [`Style`]. + /// + /// [`Style`]: enum.Style.html + pub fn declaration<'a>(&self, bump: &'a bumpalo::Bump) -> &'a str { + let class = self.class(); + + match self { + Rule::Column => { + let body = "{ display: flex; flex-direction: column; }"; + + bumpalo::format!(in bump, ".{} {}", class, body).into_bump_str() + } + Rule::Row => { + let body = "{ display: flex; flex-direction: row; }"; + + bumpalo::format!(in bump, ".{} {}", class, body).into_bump_str() + } + Rule::Padding(padding) => bumpalo::format!( + in bump, + ".{} {{ box-sizing: border-box; padding: {}px }}", + class, + padding + ) + .into_bump_str(), + Rule::Spacing(spacing) => bumpalo::format!( + in bump, + ".c.{} > * {{ margin-bottom: {}px }} \ + .r.{} > * {{ margin-right: {}px }} \ + .c.{} > *:last-child {{ margin-bottom: 0 }} \ + .r.{} > *:last-child {{ margin-right: 0 }}", + class, + spacing, + class, + spacing, + class, + class + ) + .into_bump_str(), + } + } +} + +/// A cascading style sheet. +#[derive(Debug)] +pub struct Css<'a> { + rules: BTreeMap, +} + +impl<'a> Css<'a> { + /// Creates an empty style [`Sheet`]. + /// + /// [`Sheet`]: struct.Sheet.html + pub fn new() -> Self { + Css { + rules: BTreeMap::new(), + } + } + + /// Inserts the [`rule`] in the [`Sheet`], if it was not previously + /// inserted. + /// + /// It returns the class name of the provided [`Rule`]. + /// + /// [`Sheet`]: struct.Sheet.html + /// [`Rule`]: enum.Rule.html + pub fn insert(&mut self, bump: &'a bumpalo::Bump, rule: Rule) -> String { + let class = rule.class(); + + if !self.rules.contains_key(&class) { + let _ = self.rules.insert(class.clone(), rule.declaration(bump)); + } + + class + } + + /// Produces the VDOM node of the style [`Sheet`]. + /// + /// [`Sheet`]: struct.Sheet.html + pub fn node(self, bump: &'a bumpalo::Bump) -> dodrio::Node<'a> { + use dodrio::builder::*; + + let mut declarations = bumpalo::collections::Vec::new_in(bump); + + declarations.push(text("html { height: 100% }")); + declarations.push(text( + "body { height: 100%; margin: 0; padding: 0; font-family: sans-serif }", + )); + declarations.push(text("p { margin: 0 }")); + declarations.push(text( + "button { border: none; cursor: pointer; outline: none }", + )); + + for declaration in self.rules.values() { + declarations.push(text(*declaration)); + } + + style(bump).children(declarations).finish() + } +} + +/// Returns the style value for the given [`Length`]. +/// +/// [`Length`]: ../enum.Length.html +pub fn length(length: Length) -> String { + match length { + Length::Shrink => String::from("auto"), + Length::Units(px) => format!("{}px", px), + Length::Fill | Length::FillPortion(_) => String::from("100%"), + } +} + +/// Returns the style value for the given [`Color`]. +/// +/// [`Color`]: ../struct.Color.html +pub fn color(Color { r, g, b, a }: Color) -> String { + format!("rgba({}, {}, {}, {})", 255.0 * r, 255.0 * g, 255.0 * b, a) +} + +/// Returns the style value for the given [`Align`]. +/// +/// [`Align`]: ../enum.Align.html +pub fn align(align: Align) -> &'static str { + match align { + Align::Start => "flex-start", + Align::Center => "center", + Align::End => "flex-end", + } +} -- cgit From fb8dc41f6dee6976395b03cc1fce3d21edb1038a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 6 Feb 2020 01:21:53 +0100 Subject: Add additional helpers to `css` module in `iced_web` --- web/src/css.rs | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'web/src/css.rs') diff --git a/web/src/css.rs b/web/src/css.rs index df0938da..6a307770 100644 --- a/web/src/css.rs +++ b/web/src/css.rs @@ -1,5 +1,5 @@ //! Style your widgets. -use crate::{bumpalo, Align, Color, Length}; +use crate::{bumpalo, Align, Background, Color, Length}; use std::collections::BTreeMap; @@ -119,7 +119,7 @@ impl<'a> Css<'a> { declarations.push(text( "body { height: 100%; margin: 0; padding: 0; font-family: sans-serif }", )); - declarations.push(text("p { margin: 0 }")); + declarations.push(text("* { margin: 0; padding: 0 }")); declarations.push(text( "button { border: none; cursor: pointer; outline: none }", )); @@ -143,6 +143,26 @@ pub fn length(length: Length) -> String { } } +/// Returns the style value for the given maximum length in units. +pub fn max_length(units: u32) -> String { + use std::u32; + + if units == u32::MAX { + String::from("initial") + } else { + format!("{}px", units) + } +} + +/// Returns the style value for the given minimum length in units. +pub fn min_length(units: u32) -> String { + if units == 0 { + String::from("initial") + } else { + format!("{}px", units) + } +} + /// Returns the style value for the given [`Color`]. /// /// [`Color`]: ../struct.Color.html @@ -150,6 +170,15 @@ pub fn color(Color { r, g, b, a }: Color) -> String { format!("rgba({}, {}, {}, {})", 255.0 * r, 255.0 * g, 255.0 * b, a) } +/// Returns the style value for the given [`Background`]. +/// +/// [`Background`]: ../struct.Background.html +pub fn background(background: Background) -> String { + match background { + Background::Color(c) => color(c), + } +} + /// Returns the style value for the given [`Align`]. /// /// [`Align`]: ../enum.Align.html -- cgit