Skip to content

Commit

Permalink
Add naive size caching to Row/Column widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns committed Feb 27, 2023
1 parent 486d1cb commit 237db49
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 15 deletions.
34 changes: 22 additions & 12 deletions native/src/widget/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Column<'a, Message, Renderer> {
max_width: f32,
align_items: Alignment,
children: Vec<Element<'a, Message, Renderer>>,
children_size_cache: Vec<Option<Size>>,
}

impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
Expand All @@ -32,6 +33,7 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
pub fn with_children(
children: Vec<Element<'a, Message, Renderer>>,
) -> Self {
let child_count = children.len();
Column {
spacing: 0.0,
padding: Padding::ZERO,
Expand All @@ -40,6 +42,7 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
max_width: f32::INFINITY,
align_items: Alignment::Start,
children,
children_size_cache: vec![None; child_count],
}
}

Expand Down Expand Up @@ -99,39 +102,46 @@ impl<'a, Message, Renderer> Default for Column<'a, Message, Renderer> {
}
}

struct ColumnItemProxy<'a, 'rend, 'row, Message, Renderer>
struct ColumnItemProxy<'a, 'rend, 'column, Message, Renderer>
where
Renderer: crate::Renderer,
{
renderer: &'rend Renderer,
row: &'row mut Column<'a, Message, Renderer>,
column: &'column mut Column<'a, Message, Renderer>,
}

impl<'a, 'rend, 'row, Message, Renderer> layout::flex::ItemProxy<Renderer>
for ColumnItemProxy<'a, 'rend, 'row, Message, Renderer>
impl<'a, 'rend, 'column, Message, Renderer> layout::flex::ItemProxy<Renderer>
for ColumnItemProxy<'a, 'rend, 'column, Message, Renderer>
where
Renderer: crate::Renderer,
{
fn width(&mut self, item_index: usize) -> Length {
self.row.children[item_index].as_widget().width()
self.column.children[item_index].as_widget().width()
}

fn height(&mut self, item_index: usize) -> Length {
self.row.children[item_index].as_widget().height()
self.column.children[item_index].as_widget().height()
}

fn measure(&mut self, item_index: usize, limits: &layout::Limits) -> Size {
self.row.children[item_index]
.as_widget_mut()
.measure(self.renderer, limits)
match self.column.children_size_cache[item_index] {
Some(size) => size,
None => {
let size = self.column.children[item_index]
.as_widget_mut()
.measure(self.renderer, limits);
self.column.children_size_cache[item_index] = Some(size);
size
}
}
}

fn layout(
&mut self,
item_index: usize,
limits: &layout::Limits,
) -> layout::Node {
self.row.children[item_index]
self.column.children[item_index]
.as_widget_mut()
.layout(self.renderer, limits)
}
Expand Down Expand Up @@ -171,7 +181,7 @@ where
let item_count = self.children.len();
let item_proxy = ColumnItemProxy {
renderer,
row: self,
column: self,
};

layout::flex::resolve(
Expand Down Expand Up @@ -199,7 +209,7 @@ where
let item_count = self.children.len();
let item_proxy = ColumnItemProxy {
renderer,
row: self,
column: self,
};

layout::flex::resolve(
Expand Down
16 changes: 13 additions & 3 deletions native/src/widget/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct Row<'a, Message, Renderer> {
height: Length,
align_items: Alignment,
children: Vec<Element<'a, Message, Renderer>>,
children_size_cache: Vec<Option<Size>>,
}

impl<'a, Message, Renderer> Row<'a, Message, Renderer> {
Expand All @@ -31,13 +32,15 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {
pub fn with_children(
children: Vec<Element<'a, Message, Renderer>>,
) -> Self {
let child_count = children.len();
Row {
spacing: 0.0,
padding: Padding::ZERO,
width: Length::Shrink,
height: Length::Shrink,
align_items: Alignment::Start,
children,
children_size_cache: vec![None; child_count],
}
}

Expand Down Expand Up @@ -113,9 +116,16 @@ where
}

fn measure(&mut self, item_index: usize, limits: &layout::Limits) -> Size {
self.row.children[item_index]
.as_widget_mut()
.measure(self.renderer, limits)
match self.row.children_size_cache[item_index] {
Some(size) => size,
None => {
let size = self.row.children[item_index]
.as_widget_mut()
.measure(self.renderer, limits);
self.row.children_size_cache[item_index] = Some(size);
size
}
}
}

fn layout(
Expand Down

0 comments on commit 237db49

Please sign in to comment.