cosmic/widget/
warning.rs

1// Copyright 2022 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4use super::icon;
5use crate::{Element, Renderer, Theme, theme, widget};
6use apply::Apply;
7use iced::{Alignment, Background, Color, Length};
8use iced_core::{Border, Shadow};
9use std::borrow::Cow;
10
11#[must_use]
12pub fn warning<'a, Message>(message: impl Into<Cow<'a, str>>) -> Warning<'a, Message> {
13    Warning {
14        message: message.into(),
15        on_close: None,
16    }
17}
18
19pub struct Warning<'a, Message> {
20    message: Cow<'a, str>,
21    on_close: Option<Message>,
22}
23
24impl<'a, Message: 'static + Clone> Warning<'a, Message> {
25    /// The message to emit on button press.
26    #[must_use]
27    pub fn on_close(mut self, message: Message) -> Self {
28        self.on_close = Some(message);
29        self
30    }
31
32    /// A custom button that has the desired default spacing and padding.
33    pub fn into_widget(self) -> widget::Container<'a, Message, crate::Theme, Renderer> {
34        let label = widget::container(crate::widget::text(self.message)).width(Length::Fill);
35
36        #[cfg(target_os = "linux")]
37        let close_button = icon::from_name("window-close-symbolic")
38            .size(16)
39            .apply(widget::button::icon)
40            .on_press_maybe(self.on_close);
41
42        #[cfg(not(target_os = "linux"))]
43        let close_button =
44            icon::from_svg_bytes(include_bytes!("../../res/icons/window-close-symbolic.svg"))
45                .symbolic(true)
46                .apply(widget::button::icon)
47                .icon_size(16)
48                .on_press_maybe(self.on_close);
49
50        widget::row::with_capacity(2)
51            .push(label)
52            .push(close_button)
53            .align_y(Alignment::Center)
54            .apply(widget::container)
55            .class(theme::Container::custom(warning_container))
56            .padding(10)
57            .align_y(Alignment::Center)
58            .width(Length::Fill)
59    }
60}
61
62impl<'a, Message: 'static + Clone> From<Warning<'a, Message>> for Element<'a, Message> {
63    fn from(warning: Warning<'a, Message>) -> Self {
64        Self::from(warning.into_widget())
65    }
66}
67
68#[must_use]
69pub fn warning_container(theme: &Theme) -> widget::container::Style {
70    let cosmic = theme.cosmic();
71    widget::container::Style {
72        icon_color: Some(theme.cosmic().warning.on.into()),
73        text_color: Some(theme.cosmic().warning.on.into()),
74        background: Some(Background::Color(theme.cosmic().warning_color().into())),
75        border: Border {
76            color: Color::TRANSPARENT,
77            width: 1.0,
78            radius: cosmic.corner_radii.radius_0.into(),
79        },
80        shadow: Shadow {
81            color: Color::TRANSPARENT,
82            offset: iced::Vector::new(0.0, 0.0),
83            blur_radius: 0.0,
84        },
85    }
86}