use egui::{Response, RichText, Sense, Ui, vec2};
use crate::automation::{self, Details, Role};
use crate::controls::{Button, IconPainter, Variant};
use crate::tokens;
pub struct EmptyState<'a> {
id: &'a str,
title: &'a str,
body: Option<&'a str>,
action: Option<&'a str>,
icon: Option<IconPainter<'a>>,
}
pub struct EmptyStateOutput {
pub response: Response,
pub action: bool,
}
impl<'a> EmptyState<'a> {
pub fn new(id: &'a str, title: &'a str) -> Self {
EmptyState { id, title, body: None, action: None, icon: None }
}
pub fn body(mut self, text: &'a str) -> Self {
self.body = Some(text);
self
}
pub fn action(mut self, label: &'a str) -> Self {
self.action = Some(label);
self
}
pub fn icon(mut self, paint: IconPainter<'a>) -> Self {
self.icon = Some(paint);
self
}
pub fn show(self, ui: &mut Ui) -> EmptyStateOutput {
let t = tokens::current(ui.ctx());
let mut action = false;
let inner = ui.vertical_centered(|ui| {
let title = self.title;
ui.ctx().accesskit_node_builder(ui.unique_id(), |node| {
node.set_role(egui::accesskit::Role::Group);
node.set_label(title);
});
ui.add_space(t.space.xl);
if let Some(paint) = self.icon {
let side = t.control_height * 1.5;
let (rect, _) = ui.allocate_exact_size(vec2(side, side), Sense::hover());
paint(ui.painter(), rect, t.text.secondary);
ui.add_space(t.space.md);
}
ui.label(RichText::new(self.title).size(t.type_scale.heading).strong().color(t.text.primary));
if let Some(body) = self.body {
ui.add_space(t.space.xs);
ui.label(RichText::new(body).color(t.text.secondary));
}
if let Some(label) = self.action {
ui.add_space(t.space.lg);
action = Button::new(self.id, label).part("action").variant(Variant::Primary).show(ui).clicked();
}
ui.add_space(t.space.xl);
});
let response = inner.response;
automation::register_with(ui, &response, self.id, self.title, Role::Group, Details { value: self.body, selected: None });
EmptyStateOutput { response, action }
}
}