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:
Ryan McGrath 2019-05-27 00:22:33 -07:00
parent 6fd3f79099
commit 91266cc841
No known key found for this signature in database
GPG key ID: 811674B62B666830
31 changed files with 820 additions and 941 deletions

View file

@ -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.