use chrono::{DateTime, Duration, Utc};
use egui::{Color32, CornerRadius, Frame, Label, Margin, Response, RichText, Stroke, Ui, Widget};
#[derive(Debug, Clone, PartialEq)]
pub struct Toast {
pub message: String,
pub color: Color32,
pub inner_margin: i8,
pub outer_margin: i8,
pub corner_radius: u8,
pub width: Option<f32>,
pub start_time: DateTime<Utc>,
pub duration: Duration,
}
impl Default for Toast {
fn default() -> Self {
Self {
message: "No message provided".to_string(),
color: Color32::from_rgb(200, 200, 255), inner_margin: 10,
outer_margin: 1,
corner_radius: 4,
width: None, start_time: Utc::now(), duration: Duration::seconds(3), }
}
}
impl Toast {
pub fn new(message: &str) -> Self {
let color = Color32::from_rgb(200, 200, 255); Self {
message: message.to_string(),
color,
..Default::default()
}
}
pub fn with_color(mut self, color: Color32) -> Self {
self.color = color;
self
}
pub fn inner_margin(mut self, margin: i8) -> Self {
self.inner_margin = margin;
self
}
pub fn outer_margin(mut self, margin: i8) -> Self {
self.outer_margin = margin;
self
}
pub fn corner_radius(mut self, radius: u8) -> Self {
self.corner_radius = radius;
self
}
pub fn width(mut self, width: f32) -> Self {
self.width = Some(width);
self
}
pub fn duration(mut self, duration: Duration) -> Self {
self.duration = duration;
self
}
pub fn has_expired(&self) -> bool {
Utc::now().signed_duration_since(self.start_time) >= self.duration
}
}
impl Widget for Toast {
fn ui(self, ui: &mut Ui) -> Response {
let frame = Frame::default()
.fill(self.color)
.stroke(Stroke::new(1.0, Color32::from_rgb(200, 200, 200)))
.corner_radius(CornerRadius::same(self.corner_radius))
.inner_margin(Margin::same(self.inner_margin))
.outer_margin(Margin::same(self.outer_margin));
let response = frame
.show(ui, |ui| {
if let Some(width) = self.width {
ui.set_width(width);
}
ui.horizontal(|ui| {
let r1 = ui
.add(Label::new(RichText::new(&self.message).color(Color32::BLACK)).wrap());
ui.add_space(ui.available_width());
r1
})
.inner
})
.inner;
response
}
}
pub fn toast(message: &str) -> Toast {
Toast::new(message)
}