cosmic/widget/button/
image.rs

1// Copyright 2023 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4use super::Builder;
5use crate::{
6    Element,
7    widget::{self, image::Handle},
8};
9use iced_core::{Length, Padding, font::Weight, widget::Id};
10use std::borrow::Cow;
11
12pub type Button<'a, Message> = Builder<'a, Message, Image<'a, Handle, Message>>;
13
14/// A button constructed from an image handle, using image button styling.
15pub fn image<'a, Message>(handle: impl Into<Handle> + 'a) -> Button<'a, Message> {
16    Button::new(Image {
17        image: widget::image(handle).border_radius([9.0; 4]),
18        selected: false,
19        on_remove: None,
20    })
21}
22
23/// The image variant of a button.
24pub struct Image<'a, Handle, Message> {
25    image: widget::Image<'a, Handle>,
26    selected: bool,
27    on_remove: Option<Message>,
28}
29
30impl<'a, Message> Button<'a, Message> {
31    #[inline]
32    pub fn new(variant: Image<'a, Handle, Message>) -> Self {
33        Self {
34            id: Id::unique(),
35            label: Cow::Borrowed(""),
36            #[cfg(feature = "a11y")]
37            name: Cow::Borrowed(""),
38            #[cfg(feature = "a11y")]
39            description: Cow::Borrowed(""),
40            tooltip: Cow::Borrowed(""),
41            on_press: None,
42            width: Length::Shrink,
43            height: Length::Shrink,
44            padding: Padding::from(0),
45            spacing: 0,
46            icon_size: 16,
47            line_height: 20,
48            font_size: 14,
49            font_weight: Weight::Normal,
50            class: crate::theme::style::Button::Image,
51            variant,
52        }
53    }
54
55    #[inline]
56    pub fn on_remove(mut self, message: Message) -> Self {
57        self.variant.on_remove = Some(message);
58        self
59    }
60
61    #[inline]
62    pub fn on_remove_maybe(mut self, message: Option<Message>) -> Self {
63        self.variant.on_remove = message;
64        self
65    }
66
67    #[inline]
68    pub fn selected(mut self, selected: bool) -> Self {
69        self.variant.selected = selected;
70        self
71    }
72}
73
74impl<'a, Message> From<Button<'a, Message>> for Element<'a, Message>
75where
76    Handle: Clone + std::hash::Hash,
77    Message: Clone + 'static,
78{
79    fn from(builder: Button<'a, Message>) -> Element<'a, Message> {
80        let content = builder
81            .variant
82            .image
83            .width(builder.width)
84            .height(builder.height);
85
86        let mut button = super::custom_image_button(content, builder.variant.on_remove)
87            .padding(0)
88            .selected(builder.variant.selected)
89            .id(builder.id)
90            .on_press_maybe(builder.on_press)
91            .class(builder.class);
92
93        #[cfg(feature = "a11y")]
94        {
95            button = button.name(builder.name).description(builder.description);
96        }
97
98        button.into()
99    }
100}