azalea_shell/factory/search/
apps.rs

1use azalea_service::StaticServiceManager;
2use gtk::{gio, prelude::*};
3use relm4::{
4    FactorySender,
5    prelude::{DynamicIndex, FactoryComponent},
6};
7
8use crate::{
9    icon,
10    service::{self, search::AppInfo},
11};
12
13#[derive(Debug)]
14pub struct Model {
15    visible: bool,
16    app_info: AppInfo,
17}
18
19#[derive(Clone, Debug)]
20pub enum Input {
21    Click,
22    Filter(String),
23    FilterShowAll(String),
24}
25
26#[derive(Debug)]
27pub enum Output {}
28
29#[relm4::factory(pub)]
30impl FactoryComponent for Model {
31    type Init = AppInfo;
32    type Input = Input;
33    type Output = Output;
34    type CommandOutput = ();
35    type ParentWidget = gtk::Box;
36
37    view! {
38        #[root]
39        gtk::Button {
40            #[watch]
41            set_visible: self.visible,
42            connect_clicked => Input::Click,
43
44            gtk::Box {
45                set_spacing: 12,
46
47                add_css_class: "azalea-padding",
48
49                gtk::Image {
50                    set_from_gicon: self.app_info.icon
51                        .as_ref()
52                        .and_then(|i| gio::Icon::deserialize(&i))
53                        .as_ref()
54                        .unwrap_or(&gio::ThemedIcon::from_names(&[icon::APPS]).upcast::<gio::Icon>())
55                },
56
57                gtk::Label {
58                    set_label: &self.app_info.display_name,
59                }
60            }
61        }
62    }
63
64    fn init_model(
65        app_info: Self::Init,
66        _index: &DynamicIndex,
67        _sender: FactorySender<Self>,
68    ) -> Self {
69        Self {
70            visible: false,
71            app_info,
72        }
73    }
74
75    fn update(&mut self, message: Self::Input, _sender: FactorySender<Self>) {
76        match message {
77            Input::Click => drop(service::search::Service::send(
78                service::search::Input::LaunchApplication(self.app_info.id.clone()),
79            )),
80            Input::Filter(search) => {
81                self.visible =
82                    search.len() > 0 && self.app_info.name.to_lowercase().starts_with(&search)
83            }
84            Input::FilterShowAll(search) => {
85                self.visible =
86                    search.len() == 0 || self.app_info.name.to_lowercase().starts_with(&search)
87            }
88        };
89    }
90}