azalea_shell/window/taskbar/widget/
brightness.rs

1use azalea_service::{ListenerHandle, StaticServiceManager};
2use gtk::prelude::*;
3use relm4::RelmWidgetExt;
4use relm4::{ComponentParts, ComponentSender, SimpleComponent, component};
5
6use crate::icon;
7
8use crate::service;
9
10crate::init! {
11    Model {
12        brightness: f64,
13        _service_handle: ListenerHandle,
14    }
15
16    Config {
17    }
18}
19
20#[derive(Debug)]
21pub enum Input {
22    Scroll(f64),
23    Brightness(service::brightness::Output),
24}
25
26#[component(pub)]
27impl SimpleComponent for Model {
28    type Init = Init;
29    type Input = Input;
30    type Output = ();
31
32    view! {
33        gtk::Box {
34            inline_css: "padding: 2px 8px 2px 4px",
35            set_valign: gtk::Align::Center,
36            set_css_classes: &[
37                "azalea-tertiary-border",
38                "azalea-circle-bubble",
39                "azalea-tertiary-container",
40                "azalea-secondary-container-hover",
41            ],
42            set_spacing: 8,
43
44            gtk::Image {
45                set_icon_name: Some(icon::BRIGHTNESS),
46            },
47
48            gtk::Label {
49                #[watch]
50                set_label: &format!("{}%", model.brightness_percent()),
51            },
52
53            gtk::Frame {
54                set_width_request: 100,
55                set_height_request: 5,
56                set_vexpand: false,
57                set_valign: gtk::Align::Center,
58
59                #[watch]
60                inline_css: &format!(
61                    "background-image: linear-gradient(to right, var(--tertiary) {}%, var(--on-tertiary) 0);",
62                    model.brightness_percent()
63                ),
64            },
65
66            add_controller = gtk::EventControllerScroll {
67                set_flags: gtk::EventControllerScrollFlags::BOTH_AXES,
68                connect_scroll[sender] => move |_this, _dx, dy| {
69                    sender.input(Input::Scroll(dy));
70                    false.into()
71                },
72            },
73        },
74    }
75
76    fn init(
77        _init: Self::Init,
78        _root: Self::Root,
79        sender: ComponentSender<Self>,
80    ) -> ComponentParts<Self> {
81        let model = Model {
82            brightness: 0.,
83            _service_handle: service::brightness::Service::forward(
84                sender.input_sender().clone(),
85                Input::Brightness,
86            ),
87        };
88
89        let widgets = view_output!();
90
91        ComponentParts { model, widgets }
92    }
93
94    fn update(&mut self, input: Self::Input, _sender: ComponentSender<Self>) {
95        match input {
96            Input::Scroll(delta) => {
97                let brightness = self.brightness - delta * 0.05;
98                if brightness >= 0. && brightness <= 1. {
99                    service::brightness::Service::send(
100                        service::brightness::Input::SystemBrightness(brightness),
101                    );
102                }
103            }
104            Input::Brightness(output) => match output {
105                service::brightness::Output::SystemBrightness(brightness) => {
106                    self.brightness = brightness
107                }
108            },
109        }
110    }
111}
112
113impl Model {
114    fn brightness_percent(&self) -> i64 {
115        (self.brightness * 100.) as i64
116    }
117}