diff --git a/pagetop/src/base/component/anchor.rs b/pagetop/src/base/component/anchor.rs index 5bae4ef2..2bb15ee4 100644 --- a/pagetop/src/base/component/anchor.rs +++ b/pagetop/src/base/component/anchor.rs @@ -23,7 +23,7 @@ pub struct Anchor { weight : isize, id : IdentifierValue, classes : Classes, - spaces : Spaces, + layout : InlineLayout, anchor_type: AnchorType, href : AttributeValue, html : Markup, @@ -40,7 +40,7 @@ impl ComponentTrait for Anchor { weight : 0, id : IdentifierValue::new(), classes : Classes::new(), - spaces : Spaces::new(), + layout : InlineLayout::new(), anchor_type: AnchorType::Link, href : AttributeValue::new(), html : html! {}, @@ -75,7 +75,7 @@ impl ComponentTrait for Anchor { a id=[self.id().get()] class=[self.classes().get()] - style=[self.spaces().get()] + style=[self.layout().get()] href=[self.href().get()] target=[target] { @@ -130,8 +130,8 @@ impl Anchor { self } - pub fn with_spaces(mut self, spaces: &[SpaceSet]) -> Self { - self.alter_spaces(spaces); + pub fn with_layout(mut self, layout: &[LayoutSet]) -> Self { + self.alter_layout(layout); self } @@ -192,8 +192,8 @@ impl Anchor { self } - pub fn alter_spaces(&mut self, spaces: &[SpaceSet]) -> &mut Self { - self.spaces.add(spaces); + pub fn alter_layout(&mut self, layout: &[LayoutSet]) -> &mut Self { + self.layout.set(layout); self } @@ -248,8 +248,8 @@ impl Anchor { &self.classes } - pub fn spaces(&self) -> &Spaces { - &self.spaces + pub fn layout(&self) -> &InlineLayout { + &self.layout } pub fn anchor_type(&self) -> &AnchorType { diff --git a/pagetop/src/base/component/grid/column.rs b/pagetop/src/base/component/grid/column.rs index bca2e516..d535f2e2 100644 --- a/pagetop/src/base/component/grid/column.rs +++ b/pagetop/src/base/component/grid/column.rs @@ -22,7 +22,7 @@ pub struct Column { weight : isize, id : IdentifierValue, classes : Classes, - spaces : Spaces, + layout : InlineLayout, size : ColumnSize, components: ComponentsBundle, template : String, @@ -35,7 +35,7 @@ impl ComponentTrait for Column { weight : 0, id : IdentifierValue::new(), classes : Classes::new(), - spaces : Spaces::new(), + layout : InlineLayout::new(), size : ColumnSize::Default, components: ComponentsBundle::new(), template : "default".to_owned(), @@ -74,7 +74,7 @@ impl ComponentTrait for Column { fn default_render(&self, context: &mut InContext) -> Markup { html! { - div id=[self.id().get()] class=[self.classes().get()] style=[self.spaces().get()] { + div id=[self.id().get()] class=[self.classes().get()] style=[self.layout().get()] { (self.components().render(context)) } } @@ -113,8 +113,8 @@ impl Column { self } - pub fn with_spaces(mut self, spaces: &[SpaceSet]) -> Self { - self.alter_spaces(spaces); + pub fn with_layout(mut self, layout: &[LayoutSet]) -> Self { + self.alter_layout(layout); self } @@ -155,8 +155,8 @@ impl Column { self } - pub fn alter_spaces(&mut self, spaces: &[SpaceSet]) -> &mut Self { - self.spaces.add(spaces); + pub fn alter_layout(&mut self, layout: &[LayoutSet]) -> &mut Self { + self.layout.set(layout); self } @@ -184,8 +184,8 @@ impl Column { &self.classes } - pub fn spaces(&self) -> &Spaces { - &self.spaces + pub fn layout(&self) -> &InlineLayout { + &self.layout } pub fn size(&self) -> &ColumnSize { diff --git a/pagetop/src/base/component/grid/row.rs b/pagetop/src/base/component/grid/row.rs index 65f72c5f..eb59ed9e 100644 --- a/pagetop/src/base/component/grid/row.rs +++ b/pagetop/src/base/component/grid/row.rs @@ -7,7 +7,7 @@ pub struct Row { weight : isize, id : IdentifierValue, classes : Classes, - spaces : Spaces, + layout : InlineLayout, columns : ComponentsBundle, template : String, } @@ -19,7 +19,7 @@ impl ComponentTrait for Row { weight : 0, id : IdentifierValue::new(), classes : Classes::new_with_default("row"), - spaces : Spaces::new(), + layout : InlineLayout::new(), columns : ComponentsBundle::new(), template : "default".to_owned(), } @@ -39,7 +39,7 @@ impl ComponentTrait for Row { fn default_render(&self, context: &mut InContext) -> Markup { html! { - div id=[self.id().get()] class=[self.classes().get()] style=[self.spaces().get()] { + div id=[self.id().get()] class=[self.classes().get()] style=[self.layout().get()] { (self.columns().render(context)) } } @@ -78,8 +78,8 @@ impl Row { self } - pub fn with_spaces(mut self, spaces: &[SpaceSet]) -> Self { - self.alter_spaces(spaces); + pub fn with_layout(mut self, layout: &[LayoutSet]) -> Self { + self.alter_layout(layout); self } @@ -115,8 +115,8 @@ impl Row { self } - pub fn alter_spaces(&mut self, spaces: &[SpaceSet]) -> &mut Self { - self.spaces.add(spaces); + pub fn alter_layout(&mut self, layout: &[LayoutSet]) -> &mut Self { + self.layout.set(layout); self } @@ -140,8 +140,8 @@ impl Row { &self.classes } - pub fn spaces(&self) -> &Spaces { - &self.spaces + pub fn layout(&self) -> &InlineLayout { + &self.layout } pub fn columns(&self) -> &ComponentsBundle { diff --git a/pagetop/src/base/component/icon.rs b/pagetop/src/base/component/icon.rs index 1237ccc3..d731940d 100644 --- a/pagetop/src/base/component/icon.rs +++ b/pagetop/src/base/component/icon.rs @@ -7,7 +7,7 @@ pub struct Icon { weight : isize, icon_name : String, classes : Classes, - spaces : Spaces, + layout : InlineLayout, } impl ComponentTrait for Icon { @@ -17,7 +17,7 @@ impl ComponentTrait for Icon { weight : 0, icon_name : "question-circle-fill".to_owned(), classes : Classes::new(), - spaces : Spaces::new(), + layout : InlineLayout::new(), } } @@ -43,7 +43,7 @@ impl ComponentTrait for Icon { } fn default_render(&self, _context: &mut InContext) -> Markup { - html! { i class=[self.classes().get()] style=[self.spaces().get()] {}; } + html! { i class=[self.classes().get()] style=[self.layout().get()] {}; } } fn as_ref_any(&self) -> &dyn AnyComponent { @@ -82,8 +82,8 @@ impl Icon { self } - pub fn with_spaces(mut self, spaces: &[SpaceSet]) -> Self { - self.alter_spaces(spaces); + pub fn with_layout(mut self, layout: &[LayoutSet]) -> Self { + self.alter_layout(layout); self } @@ -109,8 +109,8 @@ impl Icon { self } - pub fn alter_spaces(&mut self, spaces: &[SpaceSet]) -> &mut Self { - self.spaces.add(spaces); + pub fn alter_layout(&mut self, layout: &[LayoutSet]) -> &mut Self { + self.layout.set(layout); self } @@ -124,7 +124,7 @@ impl Icon { &self.classes } - pub fn spaces(&self) -> &Spaces { - &self.spaces + pub fn layout(&self) -> &InlineLayout { + &self.layout } } diff --git a/pagetop/src/base/module/demopage.rs b/pagetop/src/base/module/demopage.rs index b443b83d..1a5e4235 100644 --- a/pagetop/src/base/module/demopage.rs +++ b/pagetop/src/base/module/demopage.rs @@ -37,12 +37,17 @@ async fn demo() -> app::Result { fn hello_world() -> Container { Container::header() + .with_id("hello-world") .with_component(grid::Row::new() + .with_layout( + &[LayoutSet::PaddingSide(UnitValue::RelEm(2.0), UnitValue::RelPct(5.0))] + ) .with_column(grid::Column::new() + .with_size(grid::ColumnSize::Is4of12) .with_component(Heading::h1(html! { (l("page_title")) }) - .with_display(HeadingDisplay::Large) + .with_display(HeadingDisplay::Medium) ) .with_component(Paragraph::with(html! { (t("welcome_to", &args!["app" => SETTINGS.app.name.as_str()])) @@ -65,6 +70,10 @@ fn hello_world() -> Container { ("Offered services") }) .with_left_icon(Icon::with("card-checklist")) + .with_layout(&[ + LayoutSet::PaddingSide(UnitValue::UnSet, UnitValue::RelEm(1.5)), + LayoutSet::RadiusAll(UnitValue::RelEm(1.5)), + ]) ) .with_component(Anchor::button("#", html! { ("Get quote") @@ -75,19 +84,26 @@ fn hello_world() -> Container { .with_column(grid::Column::new() .with_component(Image::image("/theme/images/demo-header.svg")) ) - .with_spaces(&[SpaceSet::PaddingBoth(SpaceValue::RelEm(2.0), SpaceValue::RelPct(5.0))]) ) } fn just_visiting() -> Container { Container::new() + .with_id("visiting") .with_component(grid::Row::new() - .with_column(grid::Column::new() - .with_size(grid::ColumnSize::Is5of12) - .with_component(Image::image("/theme/images/demo-visiting.svg")) - .with_spaces(&[SpaceSet::PaddingAll(SpaceValue::RelPct(2.0))]) + .with_layout( + &[LayoutSet::PaddingSide(UnitValue::RelEm(1.0), UnitValue::RelPct(5.0))] ) .with_column(grid::Column::new() + .with_layout(&[LayoutSet::PaddingAll(UnitValue::RelPct(2.0))]) + .with_size(grid::ColumnSize::Is5of12) + .with_component(Image::image("/theme/images/demo-visiting.svg")) + ) + .with_column(grid::Column::new() + .with_layout(&[ + LayoutSet::PaddingTop(UnitValue::RelPct(2.5)), + LayoutSet::PaddingLeft(UnitValue::RelPct(5.0)), + ]) .with_component(Heading::h2(html! { (l("visiting_title")) }) @@ -103,83 +119,110 @@ fn just_visiting() -> Container { .with_display(ParagraphDisplay::Small) ) .with_component(Paragraph::with(html! { (l("visiting_text2")) })) - .with_spaces(&[ - SpaceSet::PaddingTop(SpaceValue::RelPct(2.5)), - SpaceSet::PaddingLeft(SpaceValue::RelPct(5.0)), - ]) ) - .with_spaces(&[SpaceSet::PaddingBoth(SpaceValue::RelEm(1.0), SpaceValue::RelPct(5.0))]) ) } -fn about_pagetop() -> Chunck { - Chunck::with(html! { - div id="pagetop" class="basic-2" { - div class="container" { - div class="row" { - div class="col-lg-6 col-xl-5" { - div class="text-container" { - h2 { (l("pagetop_title")) } - p { (l("pagetop_text1")) } - p { (l("pagetop_text2")) } - p { (l("pagetop_text3")) } - } - } - div class="col-lg-6 col-xl-7" { - div class="image-container" { - img class="img-fluid" src="/bootsier/images/demo-pagetop.svg" alt="alternative" {} - } - } - } - } - } - }) +fn about_pagetop() -> Container { + Container::new() + .with_id("pagetop") + .with_component(grid::Row::new() + .with_layout( + &[LayoutSet::PaddingSide(UnitValue::RelEm(1.0), UnitValue::RelPct(5.0))] + ) + .with_column(grid::Column::new() + .with_layout(&[ + LayoutSet::PaddingTop(UnitValue::RelPct(2.5)), + LayoutSet::PaddingLeft(UnitValue::RelPct(5.0)), + ]) + .with_size(grid::ColumnSize::Is7of12) + .with_component(Heading::h2(html! { + (l("pagetop_title")) + }) + ) + .with_component(Paragraph::with(html! { + (l("pagetop_text1")) + }) + .with_display(ParagraphDisplay::Small) + ) + .with_component(Paragraph::with(html! { + (l("pagetop_text2")) + }) + ) + .with_component(Paragraph::with(html! { + (l("pagetop_text3")) + }) + ) + ) + .with_column(grid::Column::new() + .with_layout(&[LayoutSet::PaddingAll(UnitValue::RelPct(2.0))]) + .with_component(Image::image("/theme/images/demo-pagetop.svg")) + ) + ) } -fn promo_pagetop() -> Chunck { - Chunck::with(html! { - div id="promo" class="basic-3" { - div class="container" { - div class="row" { - div class="col-lg-6 col-xl-5" { - div class="text-container" { - h2 { (l("pagetop_promo_title")) } - p { (e("pagetop_promo_text1", &args![ - "pagetop" => - "PageTop" - ])) } - } - } - div class="col-lg-6 col-xl-7" { - div class="image-container" { - img class="img-fluid" src="/bootsier/images/demo-pagetop.svg" alt="alternative" {} - } - } - } - } - } - }) +fn promo_pagetop() -> Container { + Container::new() + .with_id("promo") + .with_component(grid::Row::new() + .with_layout( + &[LayoutSet::PaddingSide(UnitValue::RelEm(1.0), UnitValue::RelPct(5.0))] + ) + .with_column(grid::Column::new() + .with_layout(&[LayoutSet::PaddingAll(UnitValue::RelPct(2.0))]) + .with_size(grid::ColumnSize::Is5of12) + .with_component(Image::image("/theme/images/demo-pagetop.svg")) + ) + .with_column(grid::Column::new() + .with_layout(&[ + LayoutSet::PaddingTop(UnitValue::RelPct(2.5)), + LayoutSet::PaddingLeft(UnitValue::RelPct(5.0)), + ]) + .with_component(Heading::h2(html! { + (l("pagetop_promo_title")) + }) + ) + .with_component(Paragraph::with(html! { + (e("pagetop_promo_text1", &args![ + "pagetop" => "PageTop" + ])) + }) + .with_display(ParagraphDisplay::Small) + ) + ) + ) } -fn reporting_problems() -> Chunck { - Chunck::with(html! { - div id="reporting" class="basic-4" { - div class="container" { - div class="row" { - div class="col-lg-6 col-xl-5" { - div class="text-container" { - h2 { (l("report_problems_title")) } - p { (l("report_problems_text1")) } - p { (l("report_problems_text2")) } - } - } - div class="col-lg-6 col-xl-7" { - div class="image-container" { - img class="img-fluid" src="/bootsier/images/demo-pagetop.svg" alt="alternative" {} - } - } - } - } - } - }) +fn reporting_problems() -> Container { + Container::new() + .with_id("reporting") + .with_component(grid::Row::new() + .with_layout( + &[LayoutSet::PaddingSide(UnitValue::RelEm(1.0), UnitValue::RelPct(5.0))] + ) + .with_column(grid::Column::new() + .with_layout(&[ + LayoutSet::PaddingTop(UnitValue::RelPct(2.5)), + LayoutSet::PaddingLeft(UnitValue::RelPct(5.0)), + ]) + .with_size(grid::ColumnSize::Is7of12) + .with_component(Heading::h2(html! { + (l("report_problems_title")) + }) + ) + .with_component(Paragraph::with(html! { + (l("report_problems_text1")) + }) + .with_display(ParagraphDisplay::Small) + ) + .with_component(Paragraph::with(html! { + (l("report_problems_text2")) + }) + ) + ) + .with_column(grid::Column::new() + .with_layout(&[LayoutSet::PaddingAll(UnitValue::RelPct(2.0))]) + .with_component(Image::image("/theme/images/demo-pagetop.svg")) + ) + ) } diff --git a/pagetop/src/base/theme/bulmix.rs b/pagetop/src/base/theme/bulmix.rs index 7acbe441..77e0ce2b 100644 --- a/pagetop/src/base/theme/bulmix.rs +++ b/pagetop/src/base/theme/bulmix.rs @@ -101,7 +101,7 @@ impl ThemeTrait for Bulmix { let icon = component_ref::(component); Some(html! { span class="icon" { - i class=[icon.classes().get()] style=[icon.spaces().get()] {}; + i class=[icon.classes().get()] style=[icon.layout().get()] {}; } }) }, diff --git a/pagetop/src/html.rs b/pagetop/src/html.rs index eb720c41..17d271a2 100644 --- a/pagetop/src/html.rs +++ b/pagetop/src/html.rs @@ -17,5 +17,8 @@ pub use identifier::IdentifierValue; mod classes; pub use classes::{Classes, ClassesOp}; -mod spacing; -pub use spacing::{Spaces, SpaceSet, SpaceValue}; +mod unit; +pub use unit::UnitValue; + +mod layout; +pub use layout::{InlineLayout, LayoutSet}; diff --git a/pagetop/src/html/layout.rs b/pagetop/src/html/layout.rs new file mode 100644 index 00000000..b94a10fa --- /dev/null +++ b/pagetop/src/html/layout.rs @@ -0,0 +1,165 @@ +use crate::concat_string; + +use super::unit::UnitValue; + +const RADIUS_BOTTOM_LEFT: &str = "border-bottom-left-radius"; +const RADIUS_BOTTOM_RIGHT: &str = "border-bottom-right-radius"; +const RADIUS_TOP_LEFT: &str = "border-top-left-radius"; +const RADIUS_TOP_RIGHT: &str = "border-top-right-radius"; + +const MARGIN_BOTTOM: &str = "margin-bottom"; +const MARGIN_LEFT: &str = "margin-left"; +const MARGIN_RIGHT: &str = "margin-right"; +const MARGIN_TOP: &str = "margin-top"; + +const PADDING_BOTTOM: &str = "padding-bottom"; +const PADDING_LEFT: &str = "padding-left"; +const PADDING_RIGHT: &str = "padding-right"; +const PADDING_TOP: &str = "padding-top"; + +pub enum LayoutSet { + Margin(UnitValue, UnitValue, UnitValue, UnitValue), + MarginAll(UnitValue), + MarginSide(UnitValue, UnitValue), + MarginBottom(UnitValue), + MarginLeft(UnitValue), + MarginRight(UnitValue), + MarginTop(UnitValue), + + Padding(UnitValue, UnitValue, UnitValue, UnitValue), + PaddingAll(UnitValue), + PaddingSide(UnitValue, UnitValue), + PaddingBottom(UnitValue), + PaddingLeft(UnitValue), + PaddingRight(UnitValue), + PaddingTop(UnitValue), + + Radius(UnitValue, UnitValue, UnitValue, UnitValue), + RadiusAll(UnitValue), + RadiusBottomLeft(UnitValue), + RadiusBottomRight(UnitValue), + RadiusTopLeft(UnitValue), + RadiusTopRight(UnitValue), +} + +impl LayoutSet { + fn set(&self, into_spaces: &mut InlineLayout) { + match self { + + // MARGIN LAYOUT. + LayoutSet::Margin(top, right, bottom, left) => { + self.add(MARGIN_TOP, top, into_spaces); + self.add(MARGIN_RIGHT, right, into_spaces); + self.add(MARGIN_BOTTOM, bottom, into_spaces); + self.add(MARGIN_LEFT, left, into_spaces); + }, + LayoutSet::MarginAll(val) => { + self.add(MARGIN_TOP, val, into_spaces); + self.add(MARGIN_RIGHT, val, into_spaces); + self.add(MARGIN_BOTTOM, val, into_spaces); + self.add(MARGIN_LEFT, val, into_spaces); + }, + LayoutSet::MarginSide(top_bottom, right_left) => { + self.add(MARGIN_TOP, top_bottom, into_spaces); + self.add(MARGIN_RIGHT, right_left, into_spaces); + self.add(MARGIN_BOTTOM, top_bottom, into_spaces); + self.add(MARGIN_LEFT, right_left, into_spaces); + }, + LayoutSet::MarginTop(val) => self.add(MARGIN_TOP, val, into_spaces), + LayoutSet::MarginRight(val) => self.add(MARGIN_RIGHT, val, into_spaces), + LayoutSet::MarginBottom(val) => self.add(MARGIN_BOTTOM, val, into_spaces), + LayoutSet::MarginLeft(val) => self.add(MARGIN_LEFT, val, into_spaces), + + // PADDING LAYOUT. + LayoutSet::Padding(top, right, bottom, left) => { + self.add(PADDING_TOP, top, into_spaces); + self.add(PADDING_RIGHT, right, into_spaces); + self.add(PADDING_BOTTOM, bottom, into_spaces); + self.add(PADDING_LEFT, left, into_spaces); + }, + LayoutSet::PaddingAll(val) => { + self.add(PADDING_TOP, val, into_spaces); + self.add(PADDING_RIGHT, val, into_spaces); + self.add(PADDING_BOTTOM, val, into_spaces); + self.add(PADDING_LEFT, val, into_spaces); + }, + LayoutSet::PaddingSide(top_bottom, right_left) => { + self.add(PADDING_TOP, top_bottom, into_spaces); + self.add(PADDING_RIGHT, right_left, into_spaces); + self.add(PADDING_BOTTOM, top_bottom, into_spaces); + self.add(PADDING_LEFT, right_left, into_spaces); + }, + LayoutSet::PaddingTop(val) => self.add(PADDING_TOP, val, into_spaces), + LayoutSet::PaddingRight(val) => self.add(PADDING_RIGHT, val, into_spaces), + LayoutSet::PaddingBottom(val) => self.add(PADDING_BOTTOM, val, into_spaces), + LayoutSet::PaddingLeft(val) => self.add(PADDING_LEFT, val, into_spaces), + + // BORDER RADIUS LAYOUT. + LayoutSet::Radius(top_left, top_right, bottom_right, bottom_left) => { + self.add(RADIUS_TOP_LEFT, top_left, into_spaces); + self.add(RADIUS_TOP_RIGHT, top_right, into_spaces); + self.add(RADIUS_BOTTOM_RIGHT, bottom_right, into_spaces); + self.add(RADIUS_BOTTOM_LEFT, bottom_left, into_spaces); + }, + LayoutSet::RadiusAll(val) => { + self.add(RADIUS_TOP_LEFT, val, into_spaces); + self.add(RADIUS_TOP_RIGHT, val, into_spaces); + self.add(RADIUS_BOTTOM_RIGHT, val, into_spaces); + self.add(RADIUS_BOTTOM_LEFT, val, into_spaces); + }, + LayoutSet::RadiusTopLeft(val) => self.add(RADIUS_TOP_LEFT, val, into_spaces), + LayoutSet::RadiusTopRight(val) => self.add(RADIUS_TOP_RIGHT, val, into_spaces), + LayoutSet::RadiusBottomRight(val) => self.add(RADIUS_BOTTOM_RIGHT, val, into_spaces), + LayoutSet::RadiusBottomLeft(val) => self.add(RADIUS_BOTTOM_LEFT, val, into_spaces), + } + } + + fn add(&self, property: &str, value: &UnitValue, into_spaces: &mut InlineLayout) { + let val = value.to_string(); + let style = InlineProperty { + property: property.to_owned(), + inline : concat_string!(property, ":", val, ";"), + }; + match into_spaces.0.iter().position(|s| s.property.eq(&style.property)) { + Some(pos) => { + into_spaces.0.remove(pos); + if !val.is_empty() { + into_spaces.0.insert(pos, style); + } + }, + _ => if !val.is_empty() { + into_spaces.0.push(style) + } + } + } +} + +struct InlineProperty { + property: String, + inline : String, +} + +pub struct InlineLayout(Vec); + +impl InlineLayout { + pub fn new() -> Self { + InlineLayout(Vec::new()) + } + + pub fn set(&mut self, layout: &[LayoutSet]) -> &Self { + for i in 0..layout.len() { + layout[i].set(self); + } + self + } + + pub fn get(&self) -> Option { + if self.0.len() == 0 { + None + } else { + let mut inline = "".to_owned(); + self.0.iter().for_each(|s| inline.push_str(s.inline.as_str())); + Some(inline) + } + } +} diff --git a/pagetop/src/html/spacing.rs b/pagetop/src/html/spacing.rs deleted file mode 100644 index a3d138c0..00000000 --- a/pagetop/src/html/spacing.rs +++ /dev/null @@ -1,177 +0,0 @@ -use crate::concat_string; - -const MARGIN_BOTTOM: &str = "margin-bottom"; -const MARGIN_LEFT: &str = "margin-left"; -const MARGIN_RIGHT: &str = "margin-right"; -const MARGIN_TOP: &str = "margin-top"; - -const PADDING_BOTTOM: &str = "padding-bottom"; -const PADDING_LEFT: &str = "padding-left"; -const PADDING_RIGHT: &str = "padding-right"; -const PADDING_TOP: &str = "padding-top"; - -struct SpaceStyle { - property: String, - inline : String, -} - -pub struct Spaces(Vec); - -// About pixels: Pixels (px) are relative to the viewing device. For low-dpi -// devices, 1px is one device pixel (dot) of the display. For printers and high -// resolution screens 1px implies multiple device pixels. - -// About em: 2em means 2 times the size of the current font. The em and rem -// units are practical in creating perfectly scalable layout! - -// About viewport: If the browser window size is 50cm wide, 1vw = 0.5cm. - -pub enum SpaceValue { - Auto, - - Cm(isize), // Centimeters. - In(isize), // Inches (1in = 96px = 2.54cm). - Mm(isize), // Millimeters. - Pc(isize), // Picas (1pc = 12pt). - Pt(isize), // Points (1pt = 1/72 of 1in). - Px(isize), // Pixels (1px = 1/96th of 1in). - - RelEm(f32), // Relative to the font-size of the element. - RelPct(f32), // Percentage relative to the parent element. - RelRem(f32), // Relative to font-size of the root element. - RelVh(f32), // Relative to 1% of the height of the viewport. - RelVw(f32), // Relative to 1% of the value of the viewport. - - UnSet, -} - -impl SpaceValue { - fn add(&self, property: &str, into_spaces: &mut Spaces) { - let style = SpaceStyle { - property: property.to_owned(), - inline : match self { - SpaceValue::Auto => concat_string!(property, ":auto;"), - // Absolute value. - SpaceValue::Cm(aw) => concat_string!(property, ":", aw.to_string(), "cm;"), - SpaceValue::In(aw) => concat_string!(property, ":", aw.to_string(), "in;"), - SpaceValue::Mm(aw) => concat_string!(property, ":", aw.to_string(), "mm;"), - SpaceValue::Pc(aw) => concat_string!(property, ":", aw.to_string(), "pc;"), - SpaceValue::Pt(aw) => concat_string!(property, ":", aw.to_string(), "pt;"), - SpaceValue::Px(aw) => concat_string!(property, ":", aw.to_string(), "px;"), - // Relative value. - SpaceValue::RelEm(rw) => concat_string!(property, ":", rw.to_string(), "em;"), - SpaceValue::RelPct(rw) => concat_string!(property, ":", rw.to_string(), "%;"), - SpaceValue::RelRem(rw) => concat_string!(property, ":", rw.to_string(), "rem;"), - SpaceValue::RelVh(rw) => concat_string!(property, ":", rw.to_string(), "vh;"), - SpaceValue::RelVw(rw) => concat_string!(property, ":", rw.to_string(), "vw;"), - - _ => "".to_owned(), - } - }; - match into_spaces.0.iter().position(|s| s.property.eq(&style.property)) { - Some(pos) => { - into_spaces.0.remove(pos); - if !style.inline.is_empty() { - into_spaces.0.insert(pos, style); - } - }, - _ => if !style.inline.is_empty() { - into_spaces.0.push(style) - } - } - } -} - -pub enum SpaceSet { - Margin(SpaceValue, SpaceValue, SpaceValue, SpaceValue), - MarginAll(SpaceValue), - MarginBoth(SpaceValue, SpaceValue), - MarginBottom(SpaceValue), - MarginLeft(SpaceValue), - MarginRight(SpaceValue), - MarginTop(SpaceValue), - Padding(SpaceValue, SpaceValue, SpaceValue, SpaceValue), - PaddingAll(SpaceValue), - PaddingBoth(SpaceValue, SpaceValue), - PaddingBottom(SpaceValue), - PaddingLeft(SpaceValue), - PaddingRight(SpaceValue), - PaddingTop(SpaceValue), -} - -impl SpaceSet { - fn add(&self, into_spaces: &mut Spaces) { - match self { - SpaceSet::Margin(top, right, bottom, left) => { - top.add(MARGIN_TOP, into_spaces); - right.add(MARGIN_RIGHT, into_spaces); - bottom.add(MARGIN_BOTTOM, into_spaces); - left.add(MARGIN_LEFT, into_spaces); - }, - SpaceSet::MarginAll(value) => { - value.add(MARGIN_TOP, into_spaces); - value.add(MARGIN_RIGHT, into_spaces); - value.add(MARGIN_BOTTOM, into_spaces); - value.add(MARGIN_LEFT, into_spaces); - }, - SpaceSet::MarginBoth(top_bottom, right_left) => { - top_bottom.add(MARGIN_TOP, into_spaces); - right_left.add(MARGIN_RIGHT, into_spaces); - top_bottom.add(MARGIN_BOTTOM, into_spaces); - right_left.add(MARGIN_LEFT, into_spaces); - }, - - SpaceSet::MarginBottom(value) => value.add(MARGIN_BOTTOM, into_spaces), - SpaceSet::MarginLeft(value) => value.add(MARGIN_LEFT, into_spaces), - SpaceSet::MarginRight(value) => value.add(MARGIN_RIGHT, into_spaces), - SpaceSet::MarginTop(value) => value.add(MARGIN_TOP, into_spaces), - - SpaceSet::Padding(top, right, bottom, left) => { - top.add(PADDING_TOP, into_spaces); - right.add(PADDING_RIGHT, into_spaces); - bottom.add(PADDING_BOTTOM, into_spaces); - left.add(PADDING_LEFT, into_spaces); - }, - SpaceSet::PaddingAll(value) => { - value.add(PADDING_TOP, into_spaces); - value.add(PADDING_RIGHT, into_spaces); - value.add(PADDING_BOTTOM, into_spaces); - value.add(PADDING_LEFT, into_spaces); - }, - SpaceSet::PaddingBoth(top_bottom, right_left) => { - top_bottom.add(PADDING_TOP, into_spaces); - right_left.add(PADDING_RIGHT, into_spaces); - top_bottom.add(PADDING_BOTTOM, into_spaces); - right_left.add(PADDING_LEFT, into_spaces); - }, - - SpaceSet::PaddingBottom(value) => value.add(PADDING_BOTTOM, into_spaces), - SpaceSet::PaddingLeft(value) => value.add(PADDING_LEFT, into_spaces), - SpaceSet::PaddingRight(value) => value.add(PADDING_RIGHT, into_spaces), - SpaceSet::PaddingTop(value) => value.add(PADDING_TOP, into_spaces), - } - } -} - -impl Spaces { - pub fn new() -> Self { - Spaces(Vec::new()) - } - - pub fn add(&mut self, spaces: &[SpaceSet]) -> &Self { - for i in 0..spaces.len() { - spaces[i].add(self); - } - self - } - - pub fn get(&self) -> Option { - if self.0.len() == 0 { - None - } else { - let mut inline = "".to_owned(); - self.0.iter().for_each(|s| inline.push_str(s.inline.as_str())); - Some(inline) - } - } -} diff --git a/pagetop/src/html/unit.rs b/pagetop/src/html/unit.rs new file mode 100644 index 00000000..61641184 --- /dev/null +++ b/pagetop/src/html/unit.rs @@ -0,0 +1,52 @@ +use crate::concat_string; + +// About pixels: Pixels (px) are relative to the viewing device. For low-dpi +// devices, 1px is one device pixel (dot) of the display. For printers and high +// resolution screens 1px implies multiple device pixels. + +// About em: 2em means 2 times the size of the current font. The em and rem +// units are practical in creating perfectly scalable layout! + +// About viewport: If the browser window size is 50cm wide, 1vw = 0.5cm. + +pub enum UnitValue { + Auto, + + Cm(isize), // Centimeters. + In(isize), // Inches (1in = 96px = 2.54cm). + Mm(isize), // Millimeters. + Pc(isize), // Picas (1pc = 12pt). + Pt(isize), // Points (1pt = 1/72 of 1in). + Px(isize), // Pixels (1px = 1/96th of 1in). + + RelEm(f32), // Relative to the font-size of the element. + RelPct(f32), // Percentage relative to the parent element. + RelRem(f32), // Relative to font-size of the root element. + RelVh(f32), // Relative to 1% of the height of the viewport. + RelVw(f32), // Relative to 1% of the value of the viewport. + + UnSet, +} + +impl ToString for UnitValue { + fn to_string(&self) -> String { + match self { + UnitValue::Auto => "auto".to_owned(), + // Absolute value. + UnitValue::Cm(aw) => concat_string!(aw.to_string(), "cm"), + UnitValue::In(aw) => concat_string!(aw.to_string(), "in"), + UnitValue::Mm(aw) => concat_string!(aw.to_string(), "mm"), + UnitValue::Pc(aw) => concat_string!(aw.to_string(), "pc"), + UnitValue::Pt(aw) => concat_string!(aw.to_string(), "pt"), + UnitValue::Px(aw) => concat_string!(aw.to_string(), "px"), + // Relative value. + UnitValue::RelEm(rw) => concat_string!(rw.to_string(), "em"), + UnitValue::RelPct(rw) => concat_string!(rw.to_string(), "%"), + UnitValue::RelRem(rw) => concat_string!(rw.to_string(), "rem"), + UnitValue::RelVh(rw) => concat_string!(rw.to_string(), "vh"), + UnitValue::RelVw(rw) => concat_string!(rw.to_string(), "vw"), + + _ => "".to_owned(), + } + } +} diff --git a/pagetop/src/locale.rs b/pagetop/src/locale.rs index 93e9e7e8..86f5c966 100644 --- a/pagetop/src/locale.rs +++ b/pagetop/src/locale.rs @@ -1,5 +1,5 @@ -pub use fluent_templates::{static_loader as static_locale, Loader as Locale}; pub use fluent_templates; +pub use fluent_templates::{Loader as Locale, static_loader as static_locale}; pub use fluent_templates::fluent_bundle::FluentValue; #[macro_export] diff --git a/pagetop/static/bootsier/images/demo-pagetop.svg b/pagetop/static/theme/images/demo-pagetop.svg similarity index 100% rename from pagetop/static/bootsier/images/demo-pagetop.svg rename to pagetop/static/theme/images/demo-pagetop.svg