Skip to content

Commit 1e1dee9

Browse files
committed
perf(stack): optimize node creation in Tabs layout
1 parent f4f2c0d commit 1e1dee9

File tree

1 file changed

+43
-60
lines changed

1 file changed

+43
-60
lines changed

src/shell/element/stack/tabs.rs

Lines changed: 43 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -374,13 +374,21 @@ where
374374
state.scrolling = min_size.width > size.width;
375375
if !state.scrolling {
376376
// we don't need to scroll
377+
nodes.clear();
378+
379+
// add placeholder nodes for the not rendered scroll-buttons/rules
380+
let placeholder_node = Node::new(Size::new(0., 0.));
381+
let placeholder_node_with_child =
382+
Node::with_children(Size::new(0., 0.), vec![Node::new(Size::new(0., 0.))]);
383+
nodes.push(placeholder_node.clone());
384+
nodes.push(placeholder_node_with_child.clone());
377385

378386
// can we make every tab equal weight and keep the active large enough?
379-
let children = if (size.width / (self.elements.len() as f32 - 5.)).ceil() as i32
387+
if (size.width / (self.elements.len() as f32 - 5.)).ceil() as i32
380388
>= MIN_ACTIVE_TAB_WIDTH
381389
{
382390
// just use a flex layout
383-
cosmic::iced_core::layout::flex::resolve(
391+
let node = cosmic::iced_core::layout::flex::resolve(
384392
cosmic::iced_core::layout::flex::Axis::Horizontal,
385393
renderer,
386394
&limits,
@@ -391,16 +399,16 @@ where
391399
cosmic::iced::Alignment::Center,
392400
&self.elements[2..self.elements.len() - 2],
393401
&mut tree.children[2..self.elements.len() - 2],
394-
)
395-
.children()
396-
.to_vec()
402+
);
403+
404+
nodes.extend_from_slice(node.children());
397405
} else {
398406
// otherwise we need a more manual approach
399407
let min_width = (size.width - MIN_ACTIVE_TAB_WIDTH as f32 - 4.)
400408
/ (self.elements.len() as f32 - 6.);
401409
let mut offset = 0.;
402410

403-
let mut nodes = self.elements[2..self.elements.len() - 3]
411+
let tab_nodes = self.elements[2..self.elements.len() - 3]
404412
.iter()
405413
.zip(tree.children[2..].iter_mut())
406414
.map(|(tab, tab_tree)| {
@@ -415,76 +423,51 @@ where
415423
node = node.move_to(Point::new(offset, 0.));
416424
offset += node.bounds().width;
417425
node
418-
})
419-
.collect::<Vec<_>>();
426+
});
427+
428+
nodes.extend(tab_nodes);
420429
nodes.push({
421430
let node = Node::new(Size::new(4., limits.max().height));
422431
node.move_to(Point::new(offset, 0.))
423432
});
424-
nodes
425433
};
426434

427-
// and add placeholder nodes for the not rendered scroll-buttons/rules
428-
Node::with_children(
429-
size,
430-
vec![
431-
Node::new(Size::new(0., 0.)),
432-
Node::with_children(Size::new(0., 0.), vec![Node::new(Size::new(0., 0.))]),
433-
]
434-
.into_iter()
435-
.chain(children)
436-
.chain(vec![
437-
Node::with_children(Size::new(0., 0.), vec![Node::new(Size::new(0., 0.))]),
438-
Node::new(Size::new(0., 0.)),
439-
])
440-
.collect::<Vec<_>>(),
441-
)
435+
// add placeholder nodes for the not rendered scroll-buttons/rules
436+
nodes.push(placeholder_node_with_child);
437+
nodes.push(placeholder_node);
442438
} else {
443439
// we scroll, so use the computed min size, but add scroll buttons.
444440
let mut offset = 30.;
445441
for node in &mut nodes {
446-
*node = node.clone().move_to(Point::new(offset, 0.));
442+
node.move_to_mut(Point::new(offset, 0.));
447443
offset += node.bounds().width;
448444
}
449445
let last_position = Point::new(size.width - 34., 0.);
450446
nodes.remove(nodes.len() - 1);
451447

452-
Node::with_children(
453-
size,
454-
vec![Node::new(Size::new(4., size.height)), {
455-
let mut node = Node::with_children(
456-
Size::new(16., 16.),
457-
vec![Node::new(Size::new(16., 16.))],
458-
);
459-
node = node.move_to(Point::new(9., (size.height - 16.) / 2.));
460-
node
461-
}]
462-
.into_iter()
463-
.chain(nodes)
464-
.chain(vec![
465-
{
466-
let mut node = Node::new(Size::new(4., size.height));
467-
node = node.move_to(last_position);
468-
node
469-
},
470-
{
471-
let mut node = Node::with_children(
472-
Size::new(16., 16.),
473-
vec![Node::new(Size::new(16., 16.))],
474-
);
475-
node =
476-
node.move_to(last_position + Vector::new(9., (size.height - 16.) / 2.));
477-
node
478-
},
479-
{
480-
let mut node = Node::new(Size::new(4., size.height));
481-
node = node.move_to(last_position + Vector::new(30., 0.));
482-
node
483-
},
484-
])
485-
.collect(),
486-
)
448+
// prepend nodes for the prev scroll button.
449+
nodes.splice(
450+
..0,
451+
vec![
452+
Node::new(Size::new(4., size.height)),
453+
Node::with_children(Size::new(16., 16.), vec![Node::new(Size::new(16., 16.))])
454+
.move_to(Point::new(9., (size.height - 16.) / 2.)),
455+
],
456+
);
457+
458+
// append nodes from the next scroll button.
459+
nodes.push(Node::new(Size::new(4., size.height)).move_to(last_position));
460+
nodes.push(
461+
Node::with_children(Size::new(16., 16.), vec![Node::new(Size::new(16., 16.))])
462+
.move_to(last_position + Vector::new(9., (size.height - 16.) / 2.)),
463+
);
464+
465+
nodes.push(
466+
Node::new(Size::new(4., size.height)).move_to(last_position + Vector::new(30., 0.)),
467+
);
487468
}
469+
470+
Node::with_children(size, nodes)
488471
}
489472

490473
#[allow(clippy::too_many_lines)]

0 commit comments

Comments
 (0)