Skip to main content

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