Skip to content
Snippets Groups Projects
Commit 058f8a18 authored by MrGVSV's avatar MrGVSV
Browse files

Resolved issue with inheritance

parent 5e87dd1f
No related branches found
No related tags found
No related merge requests found
......@@ -1734,9 +1734,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.7.0"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
dependencies = [
"autocfg",
"hashbrown",
......@@ -1849,6 +1849,7 @@ dependencies = [
"desync",
"flo_rope",
"futures",
"indexmap",
"kayak_font",
"kayak_render_macros",
"morphorm",
......
......@@ -20,3 +20,4 @@ kayak_render_macros = { path = "../kayak_render_macros" }
morphorm = { git = "https://github.com/geom3trik/morphorm", rev = "1243152d4cebea46fd3e5098df26402c73acae91" }
resources = "1.1"
uuid = { version = "0.8", features = ["v4"] }
indexmap = "1.8"
......@@ -379,7 +379,7 @@ impl KayakContext {
pub fn render(&mut self) {
let dirty_nodes: Vec<_> =
if let Ok(mut dirty_nodes) = self.widget_manager.dirty_nodes.lock() {
dirty_nodes.drain().collect()
dirty_nodes.drain(..).collect()
} else {
panic!("Couldn't get lock on dirty nodes!")
};
......
......@@ -8,7 +8,7 @@ pub enum StyleProp<T: Default + Clone> {
/// This prop is unset, meaning its actual value is not determined until style resolution,
/// wherein it will be set to the property's default value.
///
/// When [merging](Style::merge) styles, only style properties of this type may be
/// When [merging](Style::apply) styles, only style properties of this type may be
/// overwritten.
Unset,
/// Like [StyleProp::Unset], properties of this type wait until style resolution for their
......@@ -78,7 +78,10 @@ macro_rules! define_styles {
impl $name {
/// Returns a `Style` object where all fields are set to [`StyleProp::Default`]
pub(crate) fn defaulted() -> Self {
///
/// This should only be used when default properties are required or desired. Otherwise, you
/// may be better off using `Style::default` (which sets all properties to [`StyleProp::Unset`]).
pub(crate) fn new_default() -> Self {
Self {
$($field: StyleProp::Default),*
}
......@@ -93,15 +96,25 @@ macro_rules! define_styles {
)*
}
/// Merges two `Style` objects
/// Applies a `Style` over this one
///
/// Values from `other` are applied to any field that is marked as [`StyleProp::Unset`]
pub fn merge(&mut self, other: &Self) {
$(
if matches!(self.$field, StyleProp::Unset) {
self.$field = other.$field.clone();
}
)*
/// Values from `other` are applied to any field in this one that is marked as [`StyleProp::Unset`]
pub fn apply<T: AsRefOption<Style>>(&mut self, other: T) {
if let Some(other) = other.as_ref_option() {
$(
if matches!(self.$field, StyleProp::Unset) {
self.$field = other.$field.clone();
}
)*
}
}
/// Applies the given style and returns the updated style
///
/// This is simply a builder-like wrapper around the [`Style::apply`] method.
pub fn with_style<T: AsRefOption<Style>>(mut self, other: T) -> Self {
self.apply(other);
self
}
}
};
......@@ -177,3 +190,32 @@ impl Style {
}
}
}
/// A trait used to allow reading a value as an `Option<&T>`
pub trait AsRefOption<T> {
fn as_ref_option(&self) -> Option<&T>;
}
impl AsRefOption<Style> for Style {
fn as_ref_option(&self) -> Option<&Style> {
Some(&self)
}
}
impl AsRefOption<Style> for &Style {
fn as_ref_option(&self) -> Option<&Style> {
Some(self)
}
}
impl AsRefOption<Style> for Option<Style> {
fn as_ref_option(&self) -> Option<&Style> {
self.as_ref()
}
}
impl AsRefOption<Style> for Option<&Style> {
fn as_ref_option(&self) -> Option<&Style> {
self.clone()
}
}
\ No newline at end of file
use std::{
collections::HashSet,
sync::{Arc, Mutex},
};
use indexmap::IndexSet;
use crate::layout_cache::Rect;
use crate::{
......@@ -20,8 +20,8 @@ use crate::{
#[derive(Debug)]
pub struct WidgetManager {
pub(crate) current_widgets: Arena<Option<BoxedWidget>>,
pub(crate) dirty_render_nodes: HashSet<Index>,
pub(crate) dirty_nodes: Arc<Mutex<HashSet<Index>>>,
pub(crate) dirty_render_nodes: IndexSet<Index>,
pub(crate) dirty_nodes: Arc<Mutex<IndexSet<Index>>>,
pub(crate) nodes: Arena<Option<Node>>,
/// A tree containing all widgets in the hierarchy.
pub tree: Tree,
......@@ -38,8 +38,8 @@ impl WidgetManager {
pub fn new() -> Self {
Self {
current_widgets: Arena::new(),
dirty_render_nodes: HashSet::new(),
dirty_nodes: Arc::new(Mutex::new(HashSet::new())),
dirty_render_nodes: IndexSet::new(),
dirty_nodes: Arc::new(Mutex::new(IndexSet::new())),
nodes: Arena::new(),
tree: Tree::default(),
node_tree: Tree::default(),
......@@ -173,12 +173,18 @@ impl WidgetManager {
pub fn render(&mut self) {
let initial_styles = Style::initial();
let default_styles = Style::defaulted();
for dirty_node_index in self.dirty_render_nodes.drain() {
let default_styles = Style::new_default();
for dirty_node_index in self.dirty_render_nodes.drain(..) {
let dirty_widget = self.current_widgets[dirty_node_index].as_ref().unwrap();
// Get the parent styles. Will be one of the following:
// 1. Already-resolved node styles (best)
// 2. Unresolved widget prop styles
// 3. Unresolved default styles
let parent_styles =
if let Some(parent_widget_id) = self.tree.parents.get(&dirty_node_index) {
if let Some(parent) = self.current_widgets[*parent_widget_id].as_ref() {
if let Some(parent) = self.nodes[*parent_widget_id].as_ref() {
parent.resolved_styles.clone()
} else if let Some(parent) = self.current_widgets[*parent_widget_id].as_ref() {
if let Some(styles) = parent.get_props().get_styles() {
styles
} else {
......@@ -215,9 +221,9 @@ impl WidgetManager {
let raw_styles = dirty_widget.get_props().get_styles();
let mut styles = raw_styles.clone().unwrap_or_default();
// Fill in all `initial` values
styles.merge(&initial_styles);
// Fill in all `inherited` values
// Fill in all `initial` values for any unset property
styles.apply(&initial_styles);
// Fill in all `inherited` values for any `inherit` property
styles.inherit(&parent_styles);
let children = self
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment