2023-06-13 18:32:38 +02:00
|
|
|
use cosmic::{
|
|
|
|
|
iced::Element,
|
|
|
|
|
iced_core::{
|
2023-06-22 21:01:20 +02:00
|
|
|
gradient,
|
2023-06-13 18:32:38 +02:00
|
|
|
layout::{Layout, Limits, Node},
|
2023-06-22 21:01:05 +02:00
|
|
|
mouse::Cursor,
|
2023-10-02 19:37:23 +02:00
|
|
|
renderer::{self, Renderer as IcedRenderer},
|
2023-06-13 18:32:38 +02:00
|
|
|
widget::{Tree, Widget},
|
2023-06-22 21:01:20 +02:00
|
|
|
Background, Color, Degrees, Gradient, Length, Point, Rectangle, Size,
|
2023-06-13 18:32:38 +02:00
|
|
|
},
|
|
|
|
|
iced_widget::text::StyleSheet as TextStyleSheet,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub struct TabText<'a, Message, Renderer>
|
|
|
|
|
where
|
2023-10-02 19:37:23 +02:00
|
|
|
Renderer: IcedRenderer,
|
2023-06-13 18:32:38 +02:00
|
|
|
Renderer::Theme: TextStyleSheet,
|
|
|
|
|
{
|
|
|
|
|
text: Element<'a, Message, Renderer>,
|
2023-06-22 21:01:20 +02:00
|
|
|
background: Color,
|
2023-06-13 18:32:38 +02:00
|
|
|
height: Length,
|
|
|
|
|
width: Length,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn tab_text<'a, Message, Renderer>(
|
|
|
|
|
text: impl Into<Element<'a, Message, Renderer>>,
|
|
|
|
|
) -> TabText<'a, Message, Renderer>
|
|
|
|
|
where
|
2023-10-02 19:37:23 +02:00
|
|
|
Renderer: IcedRenderer,
|
2023-06-13 18:32:38 +02:00
|
|
|
Renderer::Theme: TextStyleSheet,
|
|
|
|
|
{
|
2023-06-22 21:01:20 +02:00
|
|
|
TabText::new(text, Color::TRANSPARENT)
|
2023-06-13 18:32:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, Message, Renderer> TabText<'a, Message, Renderer>
|
|
|
|
|
where
|
2023-10-02 19:37:23 +02:00
|
|
|
Renderer: IcedRenderer,
|
2023-06-13 18:32:38 +02:00
|
|
|
Renderer::Theme: TextStyleSheet,
|
|
|
|
|
{
|
2023-06-22 21:01:20 +02:00
|
|
|
pub fn new(text: impl Into<Element<'a, Message, Renderer>>, background: Color) -> Self {
|
2023-06-13 18:32:38 +02:00
|
|
|
TabText {
|
|
|
|
|
width: Length::Shrink,
|
|
|
|
|
height: Length::Shrink,
|
2023-06-22 21:01:20 +02:00
|
|
|
background,
|
2023-06-13 18:32:38 +02:00
|
|
|
text: text.into(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-22 21:01:20 +02:00
|
|
|
pub fn background(mut self, background: Color) -> Self {
|
|
|
|
|
self.background = background;
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-13 18:32:38 +02:00
|
|
|
pub fn width(mut self, width: impl Into<Length>) -> Self {
|
|
|
|
|
let width = width.into();
|
|
|
|
|
self.width = width;
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn height(mut self, height: impl Into<Length>) -> Self {
|
|
|
|
|
let height = height.into();
|
|
|
|
|
self.height = height;
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, Message, Renderer> Widget<Message, Renderer> for TabText<'a, Message, Renderer>
|
|
|
|
|
where
|
2023-10-02 19:37:23 +02:00
|
|
|
Renderer: IcedRenderer,
|
2023-06-13 18:32:38 +02:00
|
|
|
Renderer::Theme: TextStyleSheet,
|
|
|
|
|
{
|
|
|
|
|
fn width(&self) -> Length {
|
|
|
|
|
self.width
|
|
|
|
|
}
|
|
|
|
|
fn height(&self) -> Length {
|
|
|
|
|
self.height
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn children(&self) -> Vec<Tree> {
|
|
|
|
|
vec![Tree::new(&self.text)]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn diff(&mut self, tree: &mut Tree) {
|
|
|
|
|
tree.diff_children(std::slice::from_mut(&mut self.text))
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-14 15:02:45 -08:00
|
|
|
fn layout(&self, tree: &mut Tree, renderer: &Renderer, limits: &Limits) -> Node {
|
2023-06-13 18:32:38 +02:00
|
|
|
let limits = limits.width(self.width).height(self.height);
|
|
|
|
|
let child_limits = Limits::new(
|
2023-06-22 20:58:39 +02:00
|
|
|
Size::new(limits.min().width, limits.min().height - 4.),
|
|
|
|
|
Size::new(limits.max().width * 2., limits.max().height - 4.),
|
2023-06-13 18:32:38 +02:00
|
|
|
);
|
2023-12-14 15:02:45 -08:00
|
|
|
let mut content =
|
|
|
|
|
self.text
|
|
|
|
|
.as_widget()
|
|
|
|
|
.layout(&mut tree.children[0], renderer, &child_limits);
|
2023-06-22 20:58:39 +02:00
|
|
|
content.move_to(Point::new(0., 2.));
|
2023-06-13 18:32:38 +02:00
|
|
|
let size = limits.resolve(content.size());
|
|
|
|
|
|
|
|
|
|
Node::with_children(size, vec![content])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn draw(
|
|
|
|
|
&self,
|
|
|
|
|
tree: &Tree,
|
|
|
|
|
renderer: &mut Renderer,
|
|
|
|
|
theme: &Renderer::Theme,
|
|
|
|
|
style: &renderer::Style,
|
|
|
|
|
layout: Layout<'_>,
|
2023-06-22 21:01:05 +02:00
|
|
|
cursor: Cursor,
|
2023-06-13 18:32:38 +02:00
|
|
|
_viewport: &Rectangle,
|
|
|
|
|
) {
|
|
|
|
|
let bounds = layout.bounds();
|
|
|
|
|
let content_layout = layout.children().next().unwrap();
|
|
|
|
|
|
|
|
|
|
renderer.with_layer(bounds, |renderer| {
|
|
|
|
|
self.text.as_widget().draw(
|
|
|
|
|
&tree.children[0],
|
|
|
|
|
renderer,
|
|
|
|
|
theme,
|
|
|
|
|
style,
|
|
|
|
|
content_layout,
|
2023-06-22 21:01:05 +02:00
|
|
|
cursor,
|
2023-06-13 18:32:38 +02:00
|
|
|
&bounds,
|
|
|
|
|
);
|
|
|
|
|
});
|
2023-06-22 21:01:20 +02:00
|
|
|
|
|
|
|
|
let gradient_bounds = Rectangle {
|
|
|
|
|
x: (bounds.x + bounds.width - 24.).max(bounds.x),
|
|
|
|
|
width: 24.0_f32.min(bounds.width),
|
|
|
|
|
..bounds
|
|
|
|
|
};
|
|
|
|
|
|
2024-02-27 00:29:23 +01:00
|
|
|
let mut transparent_background = self.background;
|
2023-06-22 21:01:20 +02:00
|
|
|
transparent_background.a = 0.0;
|
|
|
|
|
renderer.fill_quad(
|
|
|
|
|
renderer::Quad {
|
|
|
|
|
bounds: gradient_bounds,
|
|
|
|
|
border_radius: 0.0.into(),
|
|
|
|
|
border_width: 0.0,
|
|
|
|
|
border_color: Color::TRANSPARENT,
|
|
|
|
|
},
|
|
|
|
|
Background::Gradient(Gradient::Linear(
|
|
|
|
|
gradient::Linear::new(Degrees(180.))
|
|
|
|
|
.add_stop(0.0, transparent_background)
|
|
|
|
|
.add_stop(1.0, self.background),
|
|
|
|
|
)),
|
|
|
|
|
);
|
2023-06-13 18:32:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>> for TabText<'a, Message, Renderer>
|
|
|
|
|
where
|
2023-10-02 19:37:23 +02:00
|
|
|
Renderer: IcedRenderer + 'a,
|
2023-06-13 18:32:38 +02:00
|
|
|
Renderer::Theme: TextStyleSheet,
|
|
|
|
|
Message: 'a,
|
|
|
|
|
{
|
|
|
|
|
fn into(self) -> Element<'a, Message, Renderer> {
|
|
|
|
|
Element::new(self)
|
|
|
|
|
}
|
|
|
|
|
}
|