libcosmic-yoda/src/widget/button/icon.rs
Lionel DARNIS 7a191cf086 yoda: warning cleanup sweep (dead code + clippy --fix) (squashed)
Squash of 4 yoda commits:
- 84437e21 yoda: libcosmic-yoda dead-code purge (14->0 warnings)
- 999db0a4 yoda: cosmic-theme cleanup (4->0 warnings) — workspace at 0 warnings total
- 4743bb8e yoda: cargo clippy --fix on libcosmic-yoda (115->33 warnings)
- 675f3b59 chore: reduce local stack warnings
2026-05-25 13:07:48 +02:00

205 lines
6 KiB
Rust

// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
use super::{Builder, ButtonClass};
use crate::Element;
use crate::widget::icon::Handle;
use crate::widget::tooltip;
use apply::Apply;
use iced_core::font::Weight;
use iced_core::text::LineHeight;
use iced_core::widget::Id;
use iced_core::{Alignment, Length, Padding};
use std::borrow::Cow;
pub type Button<'a, Message> = Builder<'a, Message, Icon>;
/// The icon variant of a button.
pub struct Icon {
handle: Handle,
vertical: bool,
selected: bool,
}
/// A button constructed from an icon handle, using icon button styling.
pub fn icon<'a, Message>(handle: impl Into<Handle>) -> Button<'a, Message> {
Button::new(Icon {
handle: handle.into(),
vertical: false,
selected: false,
})
}
impl<Message> Button<'_, Message> {
pub fn new(icon: Icon) -> Self {
let guard = crate::theme::THEME.lock().unwrap();
let theme = guard.cosmic();
let padding = theme.space_xxs();
Self {
id: Id::unique(),
label: Cow::Borrowed(""),
#[cfg(feature = "a11y")]
name: Cow::Borrowed(""),
#[cfg(feature = "a11y")]
description: Cow::Borrowed(""),
tooltip: Cow::Borrowed(""),
on_press: None,
width: Length::Shrink,
height: Length::Shrink,
padding: Padding::from(padding),
spacing: theme.space_xxxs(),
icon_size: if icon.handle.symbolic { 16 } else { 24 },
line_height: 20,
font_size: 14,
font_weight: Weight::Normal,
class: ButtonClass::Icon,
variant: icon,
}
}
/// Applies the **Extra Small** button size preset.
pub fn extra_small(mut self) -> Self {
let guard = crate::theme::THEME.lock().unwrap();
let theme = guard.cosmic();
self.font_size = 14;
self.font_weight = Weight::Normal;
self.icon_size = 16;
self.line_height = 20;
self.padding = Padding::from(theme.space_xxs());
self.spacing = theme.space_xxxs();
self
}
/// Applies the **Medium** button size preset.
pub fn medium(mut self) -> Self {
let guard = crate::theme::THEME.lock().unwrap();
let theme = guard.cosmic();
self.font_size = 24;
self.font_weight = Weight::Normal;
self.icon_size = 32;
self.line_height = 32;
self.padding = Padding::from(theme.space_xs());
self.spacing = theme.space_xxs();
self
}
/// Applies the **Large** button size preset.
pub fn large(mut self) -> Self {
let guard = crate::theme::THEME.lock().unwrap();
let theme = guard.cosmic();
self.font_size = 28;
self.font_weight = Weight::Normal;
self.icon_size = 40;
self.line_height = 36;
self.padding = Padding::from(theme.space_xs());
self.spacing = theme.space_xxs();
self
}
/// Applies the **Extra Large** button size preset.
pub fn extra_large(mut self) -> Self {
let guard = crate::theme::THEME.lock().unwrap();
let theme = guard.cosmic();
let padding = theme.space_xs();
self.font_size = 32;
self.font_weight = Weight::Light;
self.icon_size = 56;
self.line_height = 44;
self.padding = Padding::from(padding);
self.spacing = theme.space_xxs();
self
}
#[inline]
pub fn selected(mut self, selected: bool) -> Self {
self.variant.selected = selected;
self
}
#[inline]
pub fn vertical(mut self, vertical: bool) -> Self {
self.variant.vertical = vertical;
self.class = ButtonClass::IconVertical;
self
}
}
impl<'a, Message: Clone + 'static> From<Button<'a, Message>> for Element<'a, Message> {
fn from(builder: Button<'a, Message>) -> Element<'a, Message> {
let mut content = Vec::with_capacity(2);
content.push(
crate::widget::icon(builder.variant.handle.clone())
.size(builder.icon_size)
.into(),
);
if !builder.label.is_empty() {
content.push(
crate::widget::text(builder.label)
.size(builder.font_size)
.line_height(LineHeight::Absolute(builder.line_height.into()))
.font(crate::font::Font {
weight: builder.font_weight,
..crate::font::default()
})
.into(),
);
}
let button = if builder.variant.vertical {
crate::widget::column::with_children(content)
.padding(builder.padding)
.spacing(builder.spacing)
.align_x(Alignment::Center)
.apply(super::custom)
} else {
crate::widget::row::with_children(content)
.padding(builder.padding)
.width(builder.width)
.height(builder.height)
.spacing(builder.spacing)
.align_y(Alignment::Center)
.apply(super::custom)
};
#[cfg(feature = "a11y")]
let button = {
let mut button = button;
button = button.name(builder.name).description(builder.description);
button
};
let button = button
.padding(0)
.id(builder.id)
.on_press_maybe(builder.on_press)
.selected(builder.variant.selected)
.class(builder.class);
if builder.tooltip.is_empty() {
button.into()
} else {
tooltip(
button,
crate::widget::text(builder.tooltip)
.size(builder.font_size)
.font(crate::font::Font {
weight: builder.font_weight,
..crate::font::default()
}),
tooltip::Position::Top,
)
.into()
}
}
}