chore: updates after iced rebase

This commit is contained in:
Ashley Wulber 2026-02-24 15:18:57 -05:00 • committed by Ashley Wulber
parent 7bb5ae7cfe
commit a48c4fc47d
16 changed files with 753 additions and 736 deletions

View file

@ -1,3 +1,5 @@
use crate::backend::render::element;
use super::tab::{MIN_ACTIVE_TAB_WIDTH, Tab, TabBackgroundTheme, TabMessage, TabRuleTheme};
use cosmic::{
Apply,
@ -64,12 +66,12 @@ pub struct State {
}
impl Scrollable for State {
fn snap_to(&mut self, offset: RelativeOffset) {
self.offset_x = Offset::Relative(offset.x.clamp(0.0, 1.0));
fn snap_to(&mut self, offset: RelativeOffset<Option<f32>>) {
self.offset_x = Offset::Relative(offset.x.unwrap_or(0.0).clamp(0.0, 1.0));
}
fn scroll_to(&mut self, offset: AbsoluteOffset) {
let new_offset = Offset::Absolute(offset.x.max(0.0));
fn scroll_to(&mut self, offset: AbsoluteOffset<Option<f32>>) {
let new_offset = Offset::Absolute(offset.x.unwrap_or(0.0).max(0.0));
self.scroll_animation = Some(ScrollAnimationState {
start_time: Instant::now(),
start: self.offset_x,
@ -159,7 +161,7 @@ where
Element::new(tab.internal(i))
});
let tabs_rule = widget::vertical_rule(4).class(if tabs.len() - 1 == active {
let tabs_rule = widget::rule::vertical(4).class(if tabs.len() - 1 == active {
if activated {
TabRuleTheme::ActiveActivated
} else {
@ -193,12 +195,12 @@ where
let mut elements = Vec::with_capacity(tabs.len() + 5);
elements.push(widget::vertical_rule(4).class(rule_style).into());
elements.push(widget::rule::vertical(4).class(rule_style).into());
elements.push(prev_button.into());
elements.extend(tabs);
elements.push(tabs_rule.into());
elements.push(next_button.into());
elements.push(widget::vertical_rule(4).class(rule_style).into());
elements.push(widget::rule::vertical(4).class(rule_style).into());
Tabs {
elements,
@ -340,9 +342,9 @@ where
}
#[allow(clippy::too_many_lines)]
fn layout(&self, tree: &mut Tree, renderer: &cosmic::Renderer, limits: &Limits) -> Node {
fn layout(&mut self, tree: &mut Tree, renderer: &cosmic::Renderer, limits: &Limits) -> Node {
let limits = limits.width(self.width).height(self.height);
let element_count = self.elements.len();
// calculate the smallest possible size
let child_limits = Limits::new(
Size::new(0.0, limits.min().height),
@ -351,10 +353,13 @@ where
.width(Length::Shrink)
.height(Length::Shrink);
let mut nodes = self.elements[2..self.elements.len() - 2]
.iter()
let mut nodes = self.elements[2..element_count - 2]
.iter_mut()
.zip(tree.children.iter_mut().skip(2))
.map(|(tab, tab_tree)| tab.as_widget().layout(tab_tree, renderer, &child_limits))
.map(|(tab, tab_tree)| {
tab.as_widget_mut()
.layout(tab_tree, renderer, &child_limits)
})
.collect::<Vec<_>>();
// sum up
@ -370,8 +375,9 @@ where
if min_size.width <= size.width {
// we don't need to scroll
let element_count = self.elements.len();
// can we make every tab equal weight and keep the active large enough?
let children = if (size.width / (self.elements.len() as f32 - 5.)).ceil() as i32
let children = if (size.width / (element_count as f32 - 5.)).ceil() as i32
>= MIN_ACTIVE_TAB_WIDTH
{
// just use a flex layout
@ -384,20 +390,20 @@ where
0.into(),
0.,
cosmic::iced::Alignment::Center,
&self.elements[2..self.elements.len() - 2],
&mut tree.children[2..self.elements.len() - 2],
&mut self.elements[2..element_count - 2],
&mut tree.children[2..element_count - 2],
)
.children()
.to_vec()
} else {
// otherwise we need a more manual approach
let min_width = (size.width - MIN_ACTIVE_TAB_WIDTH as f32 - 4.)
/ (self.elements.len() as f32 - 6.);
let min_width =
(size.width - MIN_ACTIVE_TAB_WIDTH as f32 - 4.) / (element_count as f32 - 6.);
let mut offset = 0.;
let mut nodes = self.elements[2..self.elements.len() - 3]
.iter()
.zip(tree.children[2..].iter_mut())
let mut nodes = self.elements[2..element_count - 3]
.iter_mut()
.zip(tree.children[2..element_count - 3].iter_mut())
.map(|(tab, tab_tree)| {
let child_limits = Limits::new(
Size::new(min_width, limits.min().height),
@ -406,7 +412,9 @@ where
.width(Length::Shrink)
.height(Length::Shrink);
let mut node = tab.as_widget().layout(tab_tree, renderer, &child_limits);
let mut node =
tab.as_widget_mut()
.layout(tab_tree, renderer, &child_limits);
node = node.move_to(Point::new(offset, 0.));
offset += node.bounds().width;
node
@ -508,6 +516,7 @@ where
let background_style = Catalog::style(
theme,
&theme::Container::custom(|theme| widget::container::Style {
snap: true,
icon_color: None,
text_color: None,
background: Some(Background::Color(
@ -605,6 +614,9 @@ where
let cursor = match cursor {
mouse::Cursor::Available(point) => mouse::Cursor::Available(point + offset),
mouse::Cursor::Unavailable => mouse::Cursor::Unavailable,
mouse::Cursor::Levitating(point) => {
mouse::Cursor::Levitating(point + offset)
}
};
renderer.with_layer(bounds, |renderer| {
@ -677,7 +689,7 @@ where
}
fn operate(
&self,
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
@ -691,38 +703,38 @@ where
state.cleanup_old_animations();
operation.scrollable(
state,
self.id.as_ref(),
bounds,
content_bounds,
Vector { x: 0.0, y: 0.0 }, /* seemingly unused */
Vector { x: 0.0, y: 0.0 },
state,
);
operation.container(self.id.as_ref(), bounds, &mut |operation| {
self.elements[2..self.elements.len() - 3]
.iter()
let element_count = self.elements.len();
operation.traverse(&mut |operation| {
self.elements[2..element_count - 3]
.iter_mut()
.zip(tree.children.iter_mut().skip(2))
.zip(layout.children().skip(2))
.for_each(|((child, state), layout)| {
child
.as_widget()
.as_widget_mut()
.operate(state, layout, renderer, operation);
});
});
}
#[allow(clippy::too_many_lines)]
fn on_event(
fn update(
&mut self,
tree: &mut Tree,
event: event::Event,
event: &event::Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status {
) {
let state = tree.state.downcast_mut::<State>();
state.cleanup_old_animations();
@ -849,15 +861,15 @@ where
let mut internal_shell = Shell::new(&mut messages);
let len = self.elements.len();
let result = if scrolling && cursor.position().is_some_and(|pos| pos.x < bounds.x) {
if scrolling && cursor.position().is_some_and(|pos| pos.x < bounds.x) {
self.elements[0..2]
.iter_mut()
.zip(&mut tree.children)
.zip(layout.children())
.map(|((child, state), layout)| {
child.as_widget_mut().on_event(
child.as_widget_mut().update(
state,
event.clone(),
event,
layout,
cursor,
renderer,
@ -865,8 +877,7 @@ where
&mut internal_shell,
viewport,
)
})
.fold(event::Status::Ignored, event::Status::merge)
});
} else if scrolling
&& cursor
.position()
@ -877,9 +888,9 @@ where
.zip(tree.children.iter_mut().skip(len - 3))
.zip(layout.children().skip(len - 3))
.map(|((child, state), layout)| {
child.as_widget_mut().on_event(
child.as_widget_mut().update(
state,
event.clone(),
event,
layout,
cursor,
renderer,
@ -887,8 +898,7 @@ where
&mut internal_shell,
viewport,
)
})
.fold(event::Status::Ignored, event::Status::merge)
});
} else {
self.elements[2..len - 3]
.iter_mut()
@ -898,11 +908,14 @@ where
let cursor = match cursor {
mouse::Cursor::Available(point) => mouse::Cursor::Available(point + offset),
mouse::Cursor::Unavailable => mouse::Cursor::Unavailable,
mouse::Cursor::Levitating(point) => {
mouse::Cursor::Levitating(point + offset)
}
};
child.as_widget_mut().on_event(
child.as_widget_mut().update(
state,
event.clone(),
event,
layout,
cursor,
renderer,
@ -910,8 +923,7 @@ where
&mut internal_shell,
viewport,
)
})
.fold(event::Status::Ignored, event::Status::merge)
});
};
for mut message in messages {
@ -919,14 +931,12 @@ where
x: state.offset_x.absolute(bounds.width, content_bounds.width),
y: 0.,
}) {
state.scroll_to(offset);
state.scroll_to(offset.into());
continue;
}
shell.publish(message);
}
result
}
fn mouse_interaction(
@ -992,6 +1002,9 @@ where
let cursor = match cursor {
mouse::Cursor::Available(point) => mouse::Cursor::Available(point + offset),
mouse::Cursor::Unavailable => mouse::Cursor::Unavailable,
mouse::Cursor::Levitating(point) => {
mouse::Cursor::Levitating(point + offset)
}
};
child.as_widget().mouse_interaction(
@ -1010,10 +1023,18 @@ where
fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
layout: Layout<'b>,
renderer: &cosmic::Renderer,
viewport: &Rectangle,
translation: cosmic::iced::Vector,
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
overlay::from_children(&mut self.elements, tree, layout, renderer, translation)
overlay::from_children(
&mut self.elements,
tree,
layout,
renderer,
viewport,
translation,
)
}
}