use druid;
use druid::WidgetExt;
use crate::console;
use crate::console::widget::ext::position::clicks::ClicksExt;
use crate::console::widget::ext::stateful::StatefulExt;
use crate::console::widget::ext::position::hover::InteractiveExt;
use super::audio;
use super::battery;
use super::network::networkmanager::network;
mod power;
pub fn new() -> Meta {
Meta::default()
}
#[derive(Clone, Default, std::fmt::Debug, druid::Data, druid::Lens)]
pub struct State {
text: String,
audio: audio::Audio,
battery: battery::State,
network: network::State,
}
#[derive(Clone)]
pub struct Meta {
state: std::sync::Arc<std::cell::RefCell<State>>,
}
impl Default for Meta {
fn default() -> Self {
Self {
state: std::sync::Arc::new(std::cell::RefCell::new(State::default())),
}
}
}
impl<T: druid::Data + std::fmt::Debug> console::systemtray::TrayWidget<T, druid::widget::Container<T>> for Meta {
fn widget(&self) -> druid::widget::Container<T> {
druid::widget::Container::new(
druid::widget::Container::<State>::new(
druid::widget::Flex::row()
.with_default_spacer()
.with_child(
druid::widget::Container::new(battery::icon())
.fix_height(12.)
.controller(battery::Controller)
.lens(State::battery)
)
.with_child(
audio::icon()
.controller(audio::Controller::default())
.lens(State::audio)
)
.with_default_spacer()
.with_child(
network::icon((0., 0.))
.controller(network::Controller)
.lens(State::network)
)
.with_default_spacer()
.with_child(
druid::widget::SizedBox::new(druid::widget::Svg::new(console::icons::power()))
.width(18.0)
.height(18.0),
)
.with_default_spacer()
.on_single_click({
move |env: &druid::Env, ctx, click, _widget, data: &mut State| {
let _winid = console::widget::context::menu(
env,
ctx,
data,
click,
console::systemtray::contextmenu(Context).on_event({
let wid = ctx.widget_id();
move |_env, ctx, _w, event, _data| {
match event {
druid::Event::Command(cmd) => ctx.submit_command(cmd.clone().to(druid::Target::Widget(wid))),
_ => { /* ignored */ },
}
}
}),
druid::Size::new(150., 1.),
);
}
})
.expand_height()
)
.interactive()
.lens(self.clone())
)
}
}
struct Context;
impl console::systemtray::ContextWidget<State, druid::widget::Container<State>> for Context {
fn widget(&self) -> druid::widget::Container<State> {
druid::widget::Container::new(
druid::widget::Container::new(
druid::widget::Flex::column()
.with_default_spacer()
.with_child(
druid::widget::Flex::row()
.with_default_spacer()
.with_child(console::theme::icons::volume(&100.))
.with_default_spacer()
.with_child(audio::slider())
.with_default_spacer()
.lens(State::audio).expand_width()
)
.with_default_spacer()
.with_child(power::menu())
.with_default_spacer()
).fix_width(156.)
)
}
}
impl<T: ?Sized + std::fmt::Debug> druid::Lens<T, State> for Meta {
fn with<V, F: FnOnce(&State) -> V>(&self, _data: &T, f: F) -> V {
f(&self.state.borrow())
}
fn with_mut<V, F: FnOnce(&mut State) -> V>(&self, _data: &mut T, f: F) -> V {
let mut updated = self.state.borrow().clone();
let v = f(&mut updated);
self.state.replace(updated.clone());
v
}
}