ltk/widget/tab_strip/
parts.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>

use crate::types::{ Color, Length };
use crate::widget::button::ButtonVariant;
use crate::widget::{ button, icon_button, image, Element };

use super::icons;
use super::theme::{ CLOSE_ICON, CLOSE_SIZE };
use super::{ TabIcon, TabItem };

/// The tab's icon at `size`, a symbolic one in `ink`.
pub( super ) fn icon<Msg: Clone>( tab: &TabItem, size: Length, ink: Color ) -> Option<Element<Msg>>
{
	let ( rgba, w, h ) = match tab.icon.as_ref()?
	{
		TabIcon::Image( data )  => data.clone(),
		TabIcon::Symbol( name ) => icons::tinted( name, ink )?,
	};
	Some( image( rgba, w, h ).size( size, size ).into() )
}

pub( super ) fn close<Msg: Clone>( msg: Msg, ink: Color, icon_size: f32 ) -> Element<Msg>
{
	symbol_button( CLOSE_ICON, "x", msg, ink, CLOSE_SIZE, icon_size, false )
}

/// A borderless button with a symbolic icon in `ink`, or `fallback` as text when the theme lacks the icon.
pub( super ) fn symbol_button<Msg: Clone>( name: &str, fallback: &str, msg: Msg, ink: Color, size: f32, icon_size: f32, focusable: bool ) -> Element<Msg>
{
	let base = match icons::tinted( name, ink )
	{
		Some( ( rgba, w, h ) ) => icon_button( rgba, w, h ).icon_size( Length::widget( icon_size ) ),
		None                   => button( fallback ),
	};
	base.variant( ButtonVariant::Tertiary )
		.focusable( focusable )
		.width( Length::widget( size ) )
		.height( Length::widget( size ) )
		.on_press( msg )
		.into()
}