Move towards a new reconciler model, undo a lot of the weird stretch integrations I had done, separate out Layout and Appearance concepts, introduce ComponentKey and constructor lifecycle for components
This commit is contained in:
parent
6fd3f79099
commit
91266cc841
31 changed files with 820 additions and 941 deletions
|
|
@ -17,8 +17,10 @@ use std::collections::HashMap;
|
|||
use toml;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::stretch::style::Style;
|
||||
|
||||
use crate::StylesList;
|
||||
use crate::styles::Style;
|
||||
use crate::styles::Appearance;
|
||||
use crate::stylesheet::StyleSheet;
|
||||
|
||||
static CONFIG_FILE_NAME: &str = "alchemy.toml";
|
||||
|
|
@ -85,13 +87,19 @@ impl ThemeEngine {
|
|||
|
||||
/// Given a theme key, style keys, and a style, configures the style for layout
|
||||
/// and appearance.
|
||||
pub fn configure_style_for_keys_in_theme(&self, theme: &str, keys: &StylesList, style: &mut Style) {
|
||||
pub fn configure_style_for_keys_in_theme(
|
||||
&self,
|
||||
theme: &str,
|
||||
keys: &StylesList,
|
||||
style: &mut Style,
|
||||
appearance: &mut Appearance
|
||||
) {
|
||||
let themes = self.themes.read().unwrap();
|
||||
|
||||
match themes.get(theme) {
|
||||
Some(theme) => {
|
||||
for key in &keys.0 {
|
||||
theme.apply_styles(key, style);
|
||||
theme.apply_styles(key, style, appearance);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -102,8 +110,8 @@ impl ThemeEngine {
|
|||
}
|
||||
|
||||
/// The same logic as `configure_style_for_keys_in_theme`, but defaults to the default theme.
|
||||
pub fn configure_style_for_keys(&self, keys: &StylesList, style: &mut Style) {
|
||||
self.configure_style_for_keys_in_theme("default", keys, style)
|
||||
pub fn configure_styles_for_keys(&self, keys: &StylesList, style: &mut Style, appearance: &mut Appearance) {
|
||||
self.configure_style_for_keys_in_theme("default", keys, style, appearance)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@ pub use lazy_static::lazy_static;
|
|||
#[cfg(feature="parser")]
|
||||
#[macro_use] pub extern crate cssparser;
|
||||
|
||||
mod stretch;
|
||||
pub use stretch::{geometry, node, number, result, Stretch, Error};
|
||||
pub use stretch::result::Layout;
|
||||
|
||||
pub mod color;
|
||||
pub use color::Color;
|
||||
|
||||
|
|
@ -25,12 +21,15 @@ pub use spacedlist::SpacedList;
|
|||
mod spacedset;
|
||||
pub use spacedset::SpacedSet;
|
||||
|
||||
pub mod stretch;
|
||||
pub use stretch::result::Layout;
|
||||
|
||||
mod style_keys;
|
||||
pub use style_keys::StyleKey;
|
||||
pub type StylesList = SpacedSet<StyleKey>;
|
||||
|
||||
pub mod styles;
|
||||
pub use styles::{Style, Styles};
|
||||
pub use styles::{Appearance, Styles};
|
||||
|
||||
pub mod stylesheet;
|
||||
pub use stylesheet::StyleSheet;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
//! This module is included while awaiting an upstream merge in stretch proper.
|
||||
//! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
use core::any::Any;
|
||||
use core::f32;
|
||||
|
||||
use crate::node::{Node, Storage, Stretch};
|
||||
use crate::result;
|
||||
use crate::styles::*;
|
||||
|
||||
use crate::number::Number::*;
|
||||
use crate::number::*;
|
||||
|
||||
use crate::geometry::{Point, Rect, Size};
|
||||
use crate::stretch::node::{Node, Storage, Stretch};
|
||||
use crate::stretch::result;
|
||||
use crate::stretch::style::*;
|
||||
use crate::stretch::number::Number::*;
|
||||
use crate::stretch::number::*;
|
||||
use crate::stretch::geometry::{Point, Rect, Size};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ComputeResult {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
//! This module is included while awaiting an upstream merge in stretch proper.
|
||||
//! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
use core::ops::Add;
|
||||
|
||||
use crate::number::Number;
|
||||
use crate::styles as style;
|
||||
use crate::stretch::number::Number;
|
||||
use crate::stretch::style;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Rect<T> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//! Identifier for a Node
|
||||
//!
|
||||
//!
|
||||
///! This module is included while awaiting an upstream merge in stretch proper.
|
||||
///! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct Id {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
//! This module is included while awaiting an upstream merge in stretch proper.
|
||||
//! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
pub mod geometry;
|
||||
pub mod node;
|
||||
pub mod number;
|
||||
pub mod result;
|
||||
pub mod style;
|
||||
|
||||
mod algo;
|
||||
mod id;
|
||||
|
||||
pub use crate::node::Stretch;
|
||||
|
||||
use core::any::Any;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
//! This module is included while awaiting an upstream merge in stretch proper.
|
||||
//! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
use core::any::Any;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -6,12 +9,12 @@ use std::sync::Mutex;
|
|||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::geometry::Size;
|
||||
use crate::stretch::geometry::Size;
|
||||
use crate::stretch::id;
|
||||
use crate::number::Number;
|
||||
use crate::result::{Cache, Layout};
|
||||
use crate::styles::*;
|
||||
use crate::Error;
|
||||
use crate::stretch::number::Number;
|
||||
use crate::stretch::result::{Cache, Layout};
|
||||
use crate::stretch::style::*;
|
||||
use crate::stretch::Error;
|
||||
|
||||
type MeasureFunc = Box<Fn(Size<Number>) -> Result<Size<f32>, Box<Any>> + Send + Sync + 'static>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
//! This module is included while awaiting an upstream merge in stretch proper.
|
||||
//! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
use core::ops;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
//! This module is included while awaiting an upstream merge in stretch proper.
|
||||
//! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
use crate::stretch::algo::ComputeResult;
|
||||
use crate::geometry::{Point, Size};
|
||||
use crate::number::Number;
|
||||
use crate::stretch::geometry::{Point, Size};
|
||||
use crate::stretch::number::Number;
|
||||
|
||||
#[derive(Copy, Debug, Clone)]
|
||||
pub struct Layout {
|
||||
|
|
|
|||
335
styles/src/stretch/style.rs
Normal file
335
styles/src/stretch/style.rs
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
//! This module is included while awaiting an upstream merge in stretch proper.
|
||||
//! You should not rely on it, and consider it an implementation detail.
|
||||
|
||||
use crate::stretch::geometry::{Rect, Size};
|
||||
use crate::stretch::number::Number;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AlignItems {
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
Baseline,
|
||||
Stretch,
|
||||
}
|
||||
|
||||
impl Default for AlignItems {
|
||||
fn default() -> AlignItems {
|
||||
AlignItems::Stretch
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AlignSelf {
|
||||
Auto,
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
Baseline,
|
||||
Stretch,
|
||||
}
|
||||
|
||||
impl Default for AlignSelf {
|
||||
fn default() -> AlignSelf {
|
||||
AlignSelf::Auto
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AlignContent {
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
Stretch,
|
||||
SpaceBetween,
|
||||
SpaceAround,
|
||||
}
|
||||
|
||||
impl Default for AlignContent {
|
||||
fn default() -> AlignContent {
|
||||
AlignContent::Stretch
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Direction {
|
||||
Inherit,
|
||||
LTR,
|
||||
RTL,
|
||||
}
|
||||
|
||||
impl Default for Direction {
|
||||
fn default() -> Direction {
|
||||
Direction::Inherit
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Display {
|
||||
Flex,
|
||||
None,
|
||||
}
|
||||
|
||||
impl Default for Display {
|
||||
fn default() -> Display {
|
||||
Display::Flex
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum FlexDirection {
|
||||
Row,
|
||||
Column,
|
||||
RowReverse,
|
||||
ColumnReverse,
|
||||
}
|
||||
|
||||
impl Default for FlexDirection {
|
||||
fn default() -> FlexDirection {
|
||||
FlexDirection::Row
|
||||
}
|
||||
}
|
||||
|
||||
impl FlexDirection {
|
||||
pub(crate) fn is_row(self) -> bool {
|
||||
self == FlexDirection::Row || self == FlexDirection::RowReverse
|
||||
}
|
||||
|
||||
pub(crate) fn is_column(self) -> bool {
|
||||
self == FlexDirection::Column || self == FlexDirection::ColumnReverse
|
||||
}
|
||||
|
||||
pub(crate) fn is_reverse(self) -> bool {
|
||||
self == FlexDirection::RowReverse || self == FlexDirection::ColumnReverse
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum JustifyContent {
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
SpaceBetween,
|
||||
SpaceAround,
|
||||
SpaceEvenly,
|
||||
}
|
||||
|
||||
impl Default for JustifyContent {
|
||||
fn default() -> JustifyContent {
|
||||
JustifyContent::FlexStart
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Overflow {
|
||||
Visible,
|
||||
Hidden,
|
||||
Scroll,
|
||||
}
|
||||
|
||||
impl Default for Overflow {
|
||||
fn default() -> Overflow {
|
||||
Overflow::Visible
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PositionType {
|
||||
Relative,
|
||||
Absolute,
|
||||
}
|
||||
|
||||
impl Default for PositionType {
|
||||
fn default() -> PositionType {
|
||||
PositionType::Relative
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum FlexWrap {
|
||||
NoWrap,
|
||||
Wrap,
|
||||
WrapReverse,
|
||||
}
|
||||
|
||||
impl Default for FlexWrap {
|
||||
fn default() -> FlexWrap {
|
||||
FlexWrap::NoWrap
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Dimension {
|
||||
Undefined,
|
||||
Auto,
|
||||
Points(f32),
|
||||
Percent(f32),
|
||||
}
|
||||
|
||||
impl Default for Dimension {
|
||||
fn default() -> Dimension {
|
||||
Dimension::Undefined
|
||||
}
|
||||
}
|
||||
|
||||
impl Dimension {
|
||||
pub(crate) fn resolve(self, parent_width: Number) -> Number {
|
||||
match self {
|
||||
Dimension::Points(points) => Number::Defined(points),
|
||||
Dimension::Percent(percent) => parent_width * percent,
|
||||
_ => Number::Undefined,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_defined(self) -> bool {
|
||||
match self {
|
||||
Dimension::Points(_) => true,
|
||||
Dimension::Percent(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Rect<Dimension> {
|
||||
fn default() -> Rect<Dimension> {
|
||||
Rect { start: Default::default(), end: Default::default(), top: Default::default(), bottom: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Size<Dimension> {
|
||||
fn default() -> Size<Dimension> {
|
||||
Size { width: Dimension::Auto, height: Dimension::Auto }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Style {
|
||||
pub display: Display,
|
||||
pub position_type: PositionType,
|
||||
pub direction: Direction,
|
||||
pub flex_direction: FlexDirection,
|
||||
pub flex_wrap: FlexWrap,
|
||||
pub overflow: Overflow,
|
||||
pub align_items: AlignItems,
|
||||
pub align_self: AlignSelf,
|
||||
pub align_content: AlignContent,
|
||||
pub justify_content: JustifyContent,
|
||||
pub position: Rect<Dimension>,
|
||||
pub margin: Rect<Dimension>,
|
||||
pub padding: Rect<Dimension>,
|
||||
pub border: Rect<Dimension>,
|
||||
pub flex_grow: f32,
|
||||
pub flex_shrink: f32,
|
||||
pub flex_basis: Dimension,
|
||||
pub size: Size<Dimension>,
|
||||
pub min_size: Size<Dimension>,
|
||||
pub max_size: Size<Dimension>,
|
||||
pub aspect_ratio: Number,
|
||||
}
|
||||
|
||||
impl Default for Style {
|
||||
fn default() -> Style {
|
||||
Style {
|
||||
display: Default::default(),
|
||||
position_type: Default::default(),
|
||||
direction: Default::default(),
|
||||
flex_direction: Default::default(),
|
||||
flex_wrap: Default::default(),
|
||||
overflow: Default::default(),
|
||||
align_items: Default::default(),
|
||||
align_self: Default::default(),
|
||||
align_content: Default::default(),
|
||||
justify_content: Default::default(),
|
||||
position: Default::default(),
|
||||
margin: Default::default(),
|
||||
padding: Default::default(),
|
||||
border: Default::default(),
|
||||
flex_grow: 0.0,
|
||||
flex_shrink: 1.0,
|
||||
flex_basis: Dimension::Auto,
|
||||
size: Default::default(),
|
||||
min_size: Default::default(),
|
||||
max_size: Default::default(),
|
||||
aspect_ratio: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Style {
|
||||
pub(crate) fn min_main_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.min_size.width,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.min_size.height,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn max_main_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.max_size.width,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.max_size.height,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn main_margin_start(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.start,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.top,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn main_margin_end(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.end,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.bottom,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn cross_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.size.height,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.size.width,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn min_cross_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.min_size.height,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.min_size.width,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn max_cross_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.max_size.height,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.max_size.width,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn cross_margin_start(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.top,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.start,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn cross_margin_end(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.bottom,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.end,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn align_self(&self, parent: &Style) -> AlignSelf {
|
||||
if self.align_self == AlignSelf::Auto {
|
||||
match parent.align_items {
|
||||
AlignItems::FlexStart => AlignSelf::FlexStart,
|
||||
AlignItems::FlexEnd => AlignSelf::FlexEnd,
|
||||
AlignItems::Center => AlignSelf::Center,
|
||||
AlignItems::Baseline => AlignSelf::Baseline,
|
||||
AlignItems::Stretch => AlignSelf::Stretch,
|
||||
}
|
||||
} else {
|
||||
self.align_self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,224 +7,17 @@ use proc_macro2::{TokenStream, Ident, Span};
|
|||
#[cfg(feature="tokenize")]
|
||||
use quote::{quote, ToTokens};
|
||||
|
||||
pub use crate::geometry::{Rect, Size};
|
||||
pub use crate::number::Number;
|
||||
pub use crate::color::Color;
|
||||
|
||||
pub use crate::stretch::geometry::{Point, Rect, Size};
|
||||
pub use crate::stretch::number::Number;
|
||||
pub use crate::stretch::result::Layout;
|
||||
|
||||
/// Describes how items should be aligned.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AlignItems {
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
Baseline,
|
||||
Stretch,
|
||||
}
|
||||
|
||||
impl Default for AlignItems {
|
||||
fn default() -> AlignItems {
|
||||
AlignItems::Stretch
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how this item should be aligned.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AlignSelf {
|
||||
Auto,
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
Baseline,
|
||||
Stretch,
|
||||
}
|
||||
|
||||
impl Default for AlignSelf {
|
||||
fn default() -> AlignSelf {
|
||||
AlignSelf::Auto
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how content should be aligned.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AlignContent {
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
Stretch,
|
||||
SpaceBetween,
|
||||
SpaceAround,
|
||||
}
|
||||
|
||||
impl Default for AlignContent {
|
||||
fn default() -> AlignContent {
|
||||
AlignContent::Stretch
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how things should flow - particularly important for start/end positions.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Direction {
|
||||
Inherit,
|
||||
LTR,
|
||||
RTL,
|
||||
}
|
||||
|
||||
impl Default for Direction {
|
||||
fn default() -> Direction {
|
||||
Direction::Inherit
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes whether an item is visible or not.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Display {
|
||||
Flex,
|
||||
None,
|
||||
}
|
||||
|
||||
impl Default for Display {
|
||||
fn default() -> Display {
|
||||
Display::Flex
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how items should be aligned.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum FlexDirection {
|
||||
Row,
|
||||
Column,
|
||||
RowReverse,
|
||||
ColumnReverse,
|
||||
}
|
||||
|
||||
impl Default for FlexDirection {
|
||||
fn default() -> FlexDirection {
|
||||
FlexDirection::Row
|
||||
}
|
||||
}
|
||||
|
||||
impl FlexDirection {
|
||||
/// Checks if this is a row.
|
||||
pub(crate) fn is_row(self) -> bool {
|
||||
self == FlexDirection::Row || self == FlexDirection::RowReverse
|
||||
}
|
||||
|
||||
/// Checks if this is a column.
|
||||
pub(crate) fn is_column(self) -> bool {
|
||||
self == FlexDirection::Column || self == FlexDirection::ColumnReverse
|
||||
}
|
||||
|
||||
/// Checks if this is a reversed direction.
|
||||
pub(crate) fn is_reverse(self) -> bool {
|
||||
self == FlexDirection::RowReverse || self == FlexDirection::ColumnReverse
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how content should be justified.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum JustifyContent {
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
SpaceBetween,
|
||||
SpaceAround,
|
||||
SpaceEvenly,
|
||||
}
|
||||
|
||||
impl Default for JustifyContent {
|
||||
fn default() -> JustifyContent {
|
||||
JustifyContent::FlexStart
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how content should overflow.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Overflow {
|
||||
Visible,
|
||||
Hidden,
|
||||
Scroll,
|
||||
}
|
||||
|
||||
impl Default for Overflow {
|
||||
fn default() -> Overflow {
|
||||
Overflow::Visible
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how content should be positioned.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PositionType {
|
||||
Relative,
|
||||
Absolute,
|
||||
}
|
||||
|
||||
impl Default for PositionType {
|
||||
fn default() -> PositionType {
|
||||
PositionType::Relative
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how content should wrap.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum FlexWrap {
|
||||
NoWrap,
|
||||
Wrap,
|
||||
WrapReverse,
|
||||
}
|
||||
|
||||
impl Default for FlexWrap {
|
||||
fn default() -> FlexWrap {
|
||||
FlexWrap::NoWrap
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes a Dimension; automatic, undefined, or a value.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum Dimension {
|
||||
Undefined,
|
||||
Auto,
|
||||
Points(f32),
|
||||
Percent(f32),
|
||||
}
|
||||
|
||||
impl Default for Dimension {
|
||||
fn default() -> Dimension {
|
||||
Dimension::Undefined
|
||||
}
|
||||
}
|
||||
|
||||
impl Dimension {
|
||||
/// Internal method for Stretch.
|
||||
pub(crate) fn resolve(self, parent_width: Number) -> Number {
|
||||
match self {
|
||||
Dimension::Points(points) => Number::Defined(points),
|
||||
Dimension::Percent(percent) => parent_width * percent,
|
||||
_ => Number::Undefined,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether this Dimension is defined by a value or not.
|
||||
pub(crate) fn is_defined(self) -> bool {
|
||||
match self {
|
||||
Dimension::Points(_) => true,
|
||||
Dimension::Percent(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Rect<Dimension> {
|
||||
fn default() -> Rect<Dimension> {
|
||||
Rect { start: Default::default(), end: Default::default(), top: Default::default(), bottom: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Size<Dimension> {
|
||||
fn default() -> Size<Dimension> {
|
||||
Size { width: Dimension::Auto, height: Dimension::Auto }
|
||||
}
|
||||
}
|
||||
pub use crate::stretch::style::{
|
||||
Style,
|
||||
AlignContent, AlignItems, AlignSelf, Dimension, Direction, Display,
|
||||
FlexDirection, JustifyContent, Overflow, PositionType, FlexWrap
|
||||
};
|
||||
|
||||
/// Describes the backface-visibility for a view. This may be removed in a later release.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
|
|
@ -308,34 +101,10 @@ impl Default for FontFamily {
|
|||
}
|
||||
}
|
||||
|
||||
/// `Style` is passed into the Stretch Flexbox rendering system to produce a computed
|
||||
/// `Layout`. This is also passed to native nodes, to transform into per-platform style
|
||||
/// commands.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Style {
|
||||
pub display: Display,
|
||||
pub position_type: PositionType,
|
||||
pub direction: Direction,
|
||||
pub flex_direction: FlexDirection,
|
||||
pub flex_wrap: FlexWrap,
|
||||
pub overflow: Overflow,
|
||||
pub align_items: AlignItems,
|
||||
pub align_self: AlignSelf,
|
||||
pub align_content: AlignContent,
|
||||
pub justify_content: JustifyContent,
|
||||
pub position: Rect<Dimension>,
|
||||
pub margin: Rect<Dimension>,
|
||||
pub padding: Rect<Dimension>,
|
||||
pub border: Rect<Dimension>,
|
||||
pub flex_grow: f32,
|
||||
pub flex_shrink: f32,
|
||||
pub flex_basis: Dimension,
|
||||
pub size: Size<Dimension>,
|
||||
pub min_size: Size<Dimension>,
|
||||
pub max_size: Size<Dimension>,
|
||||
pub aspect_ratio: Number,
|
||||
|
||||
// Appearance-based styles
|
||||
/// When applying layout to a backing view, you'll get two calls - one with a `Layout`,
|
||||
/// which contains the computed frame, and one with an `Appearance`, which contains things
|
||||
/// like colors, fonts, and so on.
|
||||
pub struct Appearance {
|
||||
pub background_color: Color,
|
||||
pub font_size: f32,
|
||||
pub font_style: FontStyle,
|
||||
|
|
@ -348,35 +117,12 @@ pub struct Style {
|
|||
pub tint_color: Color
|
||||
}
|
||||
|
||||
impl Default for Style {
|
||||
fn default() -> Style {
|
||||
Style {
|
||||
display: Default::default(),
|
||||
position_type: Default::default(),
|
||||
direction: Default::default(),
|
||||
flex_direction: Default::default(),
|
||||
flex_wrap: Default::default(),
|
||||
overflow: Default::default(),
|
||||
align_items: Default::default(),
|
||||
align_self: Default::default(),
|
||||
align_content: Default::default(),
|
||||
justify_content: Default::default(),
|
||||
position: Default::default(),
|
||||
margin: Default::default(),
|
||||
padding: Default::default(),
|
||||
border: Default::default(),
|
||||
flex_grow: 0.0,
|
||||
flex_shrink: 1.0,
|
||||
flex_basis: Dimension::Auto,
|
||||
size: Default::default(),
|
||||
min_size: Default::default(),
|
||||
max_size: Default::default(),
|
||||
aspect_ratio: Default::default(),
|
||||
impl Default for Appearance {
|
||||
fn default() -> Appearance {
|
||||
Appearance {
|
||||
background_color: Color::transparent(),
|
||||
|
||||
// @TODO: We can definitely judge a default value better here.
|
||||
font_size: 14.,
|
||||
|
||||
font_style: FontStyle::default(),
|
||||
font_weight: FontWeight::default(),
|
||||
opacity: 1.,
|
||||
|
|
@ -389,95 +135,6 @@ impl Default for Style {
|
|||
}
|
||||
}
|
||||
|
||||
impl Style {
|
||||
/// Determines the minimum main size, given flex direction.
|
||||
pub(crate) fn min_main_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.min_size.width,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.min_size.height,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the maximum main size, given flex direction.
|
||||
pub(crate) fn max_main_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.max_size.width,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.max_size.height,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the main margin start, given flex direction.
|
||||
pub(crate) fn main_margin_start(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.start,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.top,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the main margin end, given flex direction.
|
||||
pub(crate) fn main_margin_end(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.end,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.bottom,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the cross size, given flex direction.
|
||||
pub(crate) fn cross_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.size.height,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.size.width,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the minimum cross size, given flex direction.
|
||||
pub(crate) fn min_cross_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.min_size.height,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.min_size.width,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the maximum cross size, given flex direction.
|
||||
pub(crate) fn max_cross_size(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.max_size.height,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.max_size.width,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the cross margin start, given flex direction.
|
||||
pub(crate) fn cross_margin_start(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.top,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.start,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the cross margin end, given flex direction.
|
||||
pub(crate) fn cross_margin_end(&self, direction: FlexDirection) -> Dimension {
|
||||
match direction {
|
||||
FlexDirection::Row | FlexDirection::RowReverse => self.margin.bottom,
|
||||
FlexDirection::Column | FlexDirection::ColumnReverse => self.margin.end,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the inherited align_self style, given a parent `&Style`.
|
||||
pub(crate) fn align_self(&self, parent: &Style) -> AlignSelf {
|
||||
if self.align_self == AlignSelf::Auto {
|
||||
match parent.align_items {
|
||||
AlignItems::FlexStart => AlignSelf::FlexStart,
|
||||
AlignItems::FlexEnd => AlignSelf::FlexEnd,
|
||||
AlignItems::Center => AlignSelf::Center,
|
||||
AlignItems::Baseline => AlignSelf::Baseline,
|
||||
AlignItems::Stretch => AlignSelf::Stretch,
|
||||
}
|
||||
} else {
|
||||
self.align_self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// These exist purely for use in the parser code.
|
||||
///
|
||||
/// A `Style` is what's used for a node; `Styles` are what's parsed and stored.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::styles::{Dimension, Rect, Size, Style, Styles};
|
||||
use crate::stretch::style::Style;
|
||||
use crate::styles::{Appearance, Dimension, Rect, Size, Styles};
|
||||
|
||||
/// A `StyleSheet` contains selectors and parsed `Styles` attributes.
|
||||
/// It also has some logic to apply styles for n keys to a given `Style` node.
|
||||
|
|
@ -20,9 +21,9 @@ impl StyleSheet {
|
|||
StyleSheet(styles)
|
||||
}
|
||||
|
||||
pub fn apply_styles(&self, key: &str, style: &mut Style) {
|
||||
pub fn apply_styles(&self, key: &str, style: &mut Style, appearance: &mut Appearance) {
|
||||
match self.0.get(key) {
|
||||
Some(styles) => { reduce_styles_into_style(styles, style); },
|
||||
Some(styles) => { reduce_styles_into_style(styles, style, appearance); },
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,14 +31,14 @@ impl StyleSheet {
|
|||
|
||||
/// This takes a list of styles, and a mutable style object, and attempts to configure the
|
||||
/// style object in a way that makes sense given n styles.
|
||||
fn reduce_styles_into_style(styles: &Vec<Styles>, layout: &mut Style) {
|
||||
fn reduce_styles_into_style(styles: &Vec<Styles>, layout: &mut Style, appearance: &mut Appearance) {
|
||||
for style in styles { match style {
|
||||
Styles::AlignContent(val) => { layout.align_content = *val; },
|
||||
Styles::AlignItems(val) => { layout.align_items = *val; },
|
||||
Styles::AlignSelf(val) => { layout.align_self = *val; },
|
||||
Styles::AspectRatio(val) => { layout.aspect_ratio = *val; },
|
||||
Styles::BackfaceVisibility(_val) => { },
|
||||
Styles::BackgroundColor(val) => { layout.background_color = *val; },
|
||||
Styles::BackgroundColor(val) => { appearance.background_color = *val; },
|
||||
|
||||
Styles::BorderColor(_val) => { },
|
||||
Styles::BorderEndColor(_val) => { },
|
||||
|
|
@ -102,9 +103,9 @@ fn reduce_styles_into_style(styles: &Vec<Styles>, layout: &mut Style) {
|
|||
|
||||
Styles::FontFamily(_val) => { },
|
||||
Styles::FontLineHeight(_val) => { },
|
||||
Styles::FontSize(val) => { layout.font_size = *val; },
|
||||
Styles::FontStyle(val) => { layout.font_style = *val; },
|
||||
Styles::FontWeight(val) => { layout.font_weight = *val; },
|
||||
Styles::FontSize(val) => { appearance.font_size = *val; },
|
||||
Styles::FontStyle(val) => { appearance.font_style = *val; },
|
||||
Styles::FontWeight(val) => { appearance.font_weight = *val; },
|
||||
|
||||
Styles::Height(val) => {
|
||||
layout.size = Size {
|
||||
|
|
@ -206,7 +207,7 @@ fn reduce_styles_into_style(styles: &Vec<Styles>, layout: &mut Style) {
|
|||
};
|
||||
},
|
||||
|
||||
Styles::Opacity(val) => { layout.opacity = *val; },
|
||||
Styles::Opacity(val) => { appearance.opacity = *val; },
|
||||
Styles::Overflow(val) => { layout.overflow = *val; },
|
||||
|
||||
Styles::PaddingBottom(val) => {
|
||||
|
|
@ -283,11 +284,11 @@ fn reduce_styles_into_style(styles: &Vec<Styles>, layout: &mut Style) {
|
|||
};
|
||||
},
|
||||
|
||||
Styles::TextAlignment(val) => { layout.text_alignment = *val; },
|
||||
Styles::TextColor(val) => { layout.text_color = *val; },
|
||||
Styles::TextDecorationColor(val) => { layout.text_decoration_color = *val; },
|
||||
Styles::TextShadowColor(val) => { layout.text_shadow_color = *val; },
|
||||
Styles::TintColor(val) => { layout.tint_color = *val; },
|
||||
Styles::TextAlignment(val) => { appearance.text_alignment = *val; },
|
||||
Styles::TextColor(val) => { appearance.text_color = *val; },
|
||||
Styles::TextDecorationColor(val) => { appearance.text_decoration_color = *val; },
|
||||
Styles::TextShadowColor(val) => { appearance.text_shadow_color = *val; },
|
||||
Styles::TintColor(val) => { appearance.tint_color = *val; },
|
||||
|
||||
Styles::Top(val) => {
|
||||
layout.position = Rect {
|
||||
|
|
|
|||
Reference in a new issue