use std::rc::Rc;
use day_reactive::Scope;
use day_spec::{Icon, StatusImage, StatusItemSpec, Symbol};
use crate::menus::lower_menu;
use crate::{IntoText, MenuContent, MenuSource, TextSource};
pub struct StatusItem {
icon: Option<Icon>,
raster: Option<StatusImage>,
template: bool,
title: Option<TextSource>,
tooltip: Option<TextSource>,
menu: Option<MenuSource>,
on_activate: Option<Rc<dyn Fn()>>,
}
impl Default for StatusItem {
fn default() -> Self {
StatusItem::new()
}
}
impl StatusItem {
pub fn new() -> StatusItem {
StatusItem {
icon: None,
raster: None,
template: false,
title: None,
tooltip: None,
menu: None,
on_activate: None,
}
}
pub fn icon(mut self, symbol: Symbol) -> StatusItem {
self.icon = Some(Icon::Symbol(symbol));
self.template = true;
self
}
pub fn vector(mut self, name: impl Into<day_spec::VectorName>) -> StatusItem {
self.icon = Some(Icon::Image(name.into().as_str().to_owned()));
self.template = true;
self
}
pub fn image(mut self, name: impl Into<day_spec::ImageName>) -> StatusItem {
self.icon = Some(Icon::Image(name.into().as_str().to_owned()));
self
}
pub fn raster(mut self, image: StatusImage) -> Self {
self.raster = Some(image);
self.template = false;
self
}
pub fn template(mut self) -> StatusItem {
self.template = true;
self
}
pub fn title<M>(mut self, title: impl IntoText<M>) -> StatusItem {
self.title = Some(title.into_text());
self
}
pub fn tooltip<M>(mut self, tooltip: impl IntoText<M>) -> StatusItem {
self.tooltip = Some(tooltip.into_text());
self
}
pub fn menu<M>(mut self, entries: impl MenuContent<M>) -> StatusItem {
self.menu = Some(entries.into_source());
self
}
pub fn on_activate(mut self, f: impl Fn() + 'static) -> StatusItem {
self.on_activate = Some(Rc::new(f));
self
}
fn lower(self, id: &str) -> StatusItemSpec {
StatusItemSpec {
id: id.to_owned(),
icon: self.icon,
raster: self.raster,
template: self.template,
title: self
.title
.as_ref()
.map(TextSource::resolve)
.unwrap_or_default(),
tooltip: self
.tooltip
.as_ref()
.map(TextSource::resolve)
.unwrap_or_default(),
menu: lower_menu(
self.menu
.as_ref()
.map(MenuSource::entries)
.unwrap_or_default(),
),
activate: self.on_activate.map_or(0, day_core::register_menu_action),
}
}
}
pub struct StatusItemHandle {
id: String,
scope: Scope,
}
impl StatusItemHandle {
pub fn remove(self) {
self.scope.dispose();
day_core::remove_status_item(&self.id);
}
}
pub fn status_item(id: &str, build: impl Fn() -> StatusItem + 'static) -> StatusItemHandle {
let scope = Scope::root().enter(Scope::child);
let key = id.to_owned();
scope.enter(|| {
day_reactive::bind(
move || {
let _ = day_localization::locale().get();
build().lower(&key)
},
|spec: &StatusItemSpec| day_core::set_status_item(spec.clone()),
);
});
StatusItemHandle {
id: id.to_owned(),
scope,
}
}