fix(stack): show tab text overlay when overflowing

This commit is contained in:
Michael Aaron Murphy 2024-02-27 16:53:55 +01:00 committed by Victoria Brekenfeld
parent feaf57225a
commit e7cf8581cc
3 changed files with 190 additions and 218 deletions

View file

@ -1,6 +1,5 @@
use super::tab::{Tab, TabBackgroundTheme, TabMessage, TabRuleTheme, MIN_ACTIVE_TAB_WIDTH};
use cosmic::{
font::Font,
iced::{id::Id, widget, Element},
iced_core::{
event,
@ -11,19 +10,15 @@ use cosmic::{
scrollable::{AbsoluteOffset, RelativeOffset},
Operation, OperationOutputWrapper, Scrollable,
},
text::StyleSheet as TextStyleSheet,
tree::{self, Tree},
Widget,
},
Background, Clipboard, Color, Length, Point, Rectangle, Shell, Size, Vector,
},
iced_style::{
button::StyleSheet as ButtonStyleSheet, container::StyleSheet as ContainerStyleSheet,
rule::StyleSheet as RuleStyleSheet,
Background, Clipboard, Color, Length, Point, Rectangle, Renderer, Shell, Size, Vector,
},
iced_style::container::StyleSheet as ContainerStyleSheet,
iced_widget::container::draw_background,
theme,
widget::{icon::from_name, Icon},
widget::icon::from_name,
Apply,
};
use keyframe::{
@ -35,12 +30,8 @@ use std::{
time::{Duration, Instant},
};
pub struct Tabs<'a, Message, Renderer>
where
Renderer: cosmic::iced_core::Renderer,
Renderer::Theme: RuleStyleSheet,
{
elements: Vec<Element<'a, Message, Renderer>>,
pub struct Tabs<'a, Message> {
elements: Vec<cosmic::Element<'a, Message>>,
id: Option<Id>,
height: Length,
width: Length,
@ -118,18 +109,9 @@ impl Offset {
const SCROLL_ANIMATION_DURATION: Duration = Duration::from_millis(200);
const TAB_ANIMATION_DURATION: Duration = Duration::from_millis(150);
impl<'a, Message, Renderer> Tabs<'a, Message, Renderer>
impl<'a, Message> Tabs<'a, Message>
where
Renderer: cosmic::iced_core::Renderer + 'a,
Renderer: cosmic::iced_core::text::Renderer<Font = Font>,
Renderer::Theme: ButtonStyleSheet<Style = theme::iced::Button>,
Renderer::Theme: ContainerStyleSheet<Style = theme::Container>,
Renderer::Theme: RuleStyleSheet<Style = theme::Rule>,
Renderer::Theme: TextStyleSheet,
Message: TabMessage + 'a,
widget::Button<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>,
widget::Container<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>,
Icon: Into<Element<'a, Message, Renderer>>,
Message: TabMessage + 'static,
{
pub fn new(
tabs: impl IntoIterator<Item = Tab<Message>>,
@ -322,10 +304,8 @@ impl State {
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for Tabs<'a, Message, Renderer>
impl<'a, Message> Widget<Message, cosmic::Renderer> for Tabs<'a, Message>
where
Renderer: cosmic::iced_core::Renderer,
Renderer::Theme: ContainerStyleSheet<Style = theme::Container> + RuleStyleSheet,
Message: TabMessage,
{
fn width(&self) -> Length {
@ -348,7 +328,7 @@ where
}
fn state(&self) -> tree::State {
tree::State::Some(Box::new(State::default()))
tree::State::Some(Box::<State>::default())
}
fn children(&self) -> Vec<Tree> {
@ -356,10 +336,11 @@ where
}
fn diff(&mut self, tree: &mut Tree) {
tree.diff_children(&mut self.elements)
tree.diff_children(&mut self.elements);
}
fn layout(&self, tree: &mut Tree, renderer: &Renderer, limits: &Limits) -> Node {
#[allow(clippy::too_many_lines)]
fn layout(&self, tree: &mut Tree, renderer: &cosmic::Renderer, limits: &Limits) -> Node {
let limits = limits.width(self.width).height(self.height);
// calculate the smallest possible size
@ -379,7 +360,7 @@ where
// sum up
let min_size = nodes
.iter()
.map(|node| node.size())
.map(Node::size)
.fold(Size::new(0., 0.), |a, b| Size {
width: a.width + b.width,
height: a.height.max(b.height),
@ -499,11 +480,12 @@ where
}
}
#[allow(clippy::too_many_lines)]
fn draw(
&self,
tree: &Tree,
renderer: &mut Renderer,
theme: &<Renderer as cosmic::iced_core::Renderer>::Theme,
renderer: &mut cosmic::Renderer,
theme: &cosmic::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
@ -637,8 +619,8 @@ where
&offset_viewport,
);
},
)
})
);
});
}
});
});
@ -693,7 +675,7 @@ where
&self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
) {
let state = tree.state.downcast_mut::<State>();
@ -717,17 +699,18 @@ where
child
.as_widget()
.operate(state, layout, renderer, operation);
})
});
});
}
#[allow(clippy::too_many_lines)]
fn on_event(
&mut self,
tree: &mut Tree,
event: event::Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &Renderer,
renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
@ -775,10 +758,10 @@ where
return Some(Difference::Movement);
};
(a_bounds != b_bounds).then(|| {
if a_bounds.position() != b_bounds.position() {
Difference::Movement
} else {
if a_bounds.position() == b_bounds.position() {
Difference::Focus
} else {
Difference::Movement
}
})
})
@ -857,12 +840,7 @@ where
let mut internal_shell = Shell::new(&mut messages);
let len = self.elements.len();
let result = if scrolling
&& cursor
.position()
.map(|pos| pos.x < bounds.x)
.unwrap_or(false)
{
let result = if scrolling && cursor.position().is_some_and(|pos| pos.x < bounds.x) {
self.elements[0..2]
.iter_mut()
.zip(&mut tree.children)
@ -883,8 +861,7 @@ where
} else if scrolling
&& cursor
.position()
.map(|pos| pos.x >= bounds.x + bounds.width)
.unwrap_or(false)
.is_some_and(|pos| pos.x >= bounds.x + bounds.width)
{
self.elements[len - 3..len]
.iter_mut()
@ -928,7 +905,6 @@ where
.fold(event::Status::Ignored, event::Status::merge)
};
std::mem::drop(internal_shell);
for mut message in messages {
if let Some(offset) = message.populate_scroll(AbsoluteOffset {
x: state.offset_x.absolute(bounds.width, content_bounds.width),
@ -950,7 +926,7 @@ where
layout: Layout<'_>,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
renderer: &cosmic::Renderer,
) -> mouse::Interaction {
let state = tree.state.downcast_ref::<State>();
@ -972,12 +948,7 @@ where
..bounds
};
if scrolling
&& cursor
.position()
.map(|pos| pos.x < bounds.x)
.unwrap_or(false)
{
if scrolling && cursor.position().is_some_and(|pos| pos.x < bounds.x) {
self.elements[0..2]
.iter()
.zip(&tree.children)
@ -991,8 +962,7 @@ where
} else if scrolling
&& cursor
.position()
.map(|pos| pos.x >= bounds.x + bounds.width)
.unwrap_or(false)
.is_some_and(|pos| pos.x >= bounds.x + bounds.width)
{
self.elements[self.elements.len() - 3..self.elements.len()]
.iter()
@ -1032,8 +1002,8 @@ where
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
renderer: &cosmic::Renderer,
) -> Option<overlay::Element<'b, Message, cosmic::Renderer>> {
overlay::from_children(&mut self.elements, tree, layout, renderer)
}
}