mirror of
https://github.com/Xetibo/ReSet.git
synced 2025-04-08 14:42:02 +02:00
feat: Add conditional features based on daemon capabilities
This commit is contained in:
parent
9dbf4228fc
commit
f8f23faece
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||
|
||||
use gtk::FlowBox;
|
||||
|
||||
use crate::components::base::utils::{Listeners, Position};
|
||||
use crate::components::{base::utils::{Listeners, Position}, utils::Capabilities};
|
||||
|
||||
// extern "C" {
|
||||
// pub fn startup() -> SidebarInfo;
|
||||
|
@ -12,7 +12,7 @@ use crate::components::base::utils::{Listeners, Position};
|
|||
// pub fn run_test();
|
||||
// }
|
||||
|
||||
pub type RegularClickEvent = fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>);
|
||||
pub type RegularClickEvent = fn(&Capabilities, Arc<Listeners>, FlowBox, Rc<RefCell<Position>>);
|
||||
pub type PluginClickEvent = Rc<dyn Fn(FlowBox, Rc<RefCell<Position>>, Vec<gtk::Box>)>;
|
||||
|
||||
pub trait TSideBarInfo {
|
||||
|
@ -28,7 +28,9 @@ pub struct ReSetSidebarInfo {
|
|||
pub name: &'static str,
|
||||
pub icon_name: &'static str,
|
||||
pub parent: Option<&'static str>,
|
||||
// pub pre_click:
|
||||
pub click_event: RegularClickEvent,
|
||||
// pub post_click:
|
||||
}
|
||||
|
||||
impl TSideBarInfo for ReSetSidebarInfo {
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
use std::cell::Cell;
|
||||
use std::time::Duration;
|
||||
|
||||
use adw::gdk::pango::EllipsizeMode;
|
||||
use adw::prelude::ListModelExtManual;
|
||||
use adw::{ActionRow, ComboRow};
|
||||
use dbus::blocking::Connection;
|
||||
use dbus::Error;
|
||||
use glib::prelude::Cast;
|
||||
use glib::Object;
|
||||
use gtk::prelude::{GObjectPropertyExpressionExt, ListBoxRowExt, ListItemExt, WidgetExt};
|
||||
|
@ -12,6 +17,21 @@ pub const BLUETOOTH: &str = "org.Xetibo.ReSet.Bluetooth";
|
|||
pub const AUDIO: &str = "org.Xetibo.ReSet.Audio";
|
||||
pub const BASE: &str = "org.Xetibo.ReSet.Daemon";
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Capabilities {
|
||||
pub wifi: Cell<bool>,
|
||||
pub bluetooth: Cell<bool>,
|
||||
pub audio: Cell<bool>,
|
||||
}
|
||||
|
||||
impl Capabilities {
|
||||
pub fn set(&self, wifi: bool, bluetooth: bool, audio: bool) {
|
||||
self.wifi.set(wifi);
|
||||
self.bluetooth.set(bluetooth);
|
||||
self.audio.set(audio);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_dropdown_label_factory() -> SignalListItemFactory {
|
||||
let factory = SignalListItemFactory::new();
|
||||
factory.connect_setup(|_, item| {
|
||||
|
@ -68,3 +88,10 @@ pub fn set_action_row_ellipsis(element: ActionRow) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_capabilities() -> Vec<String> {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000));
|
||||
let res: Result<(Vec<String>,), Error> = proxy.method_call(BASE, "GetCapabilities", ());
|
||||
res.unwrap().0
|
||||
}
|
||||
|
|
48
src/components/window/consts.rs
Normal file
48
src/components/window/consts.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use crate::components::plugin::function::ReSetSidebarInfo;
|
||||
|
||||
use super::handle_sidebar_click::{
|
||||
HANDLE_AUDIO_CLICK, HANDLE_BLUETOOTH_CLICK, HANDLE_CONNECTIVITY_CLICK, HANDLE_MICROPHONE_CLICK,
|
||||
HANDLE_VOLUME_CLICK, HANDLE_WIFI_CLICK,
|
||||
};
|
||||
|
||||
pub const CONNECTIVITY_SIDEBAR: ReSetSidebarInfo = ReSetSidebarInfo {
|
||||
name: "Connectivity",
|
||||
icon_name: "network-wired-symbolic",
|
||||
parent: None,
|
||||
click_event: HANDLE_CONNECTIVITY_CLICK,
|
||||
};
|
||||
|
||||
pub const WIFI_SIDEBAR: ReSetSidebarInfo = ReSetSidebarInfo {
|
||||
name: "WiFi",
|
||||
icon_name: "network-wireless-symbolic",
|
||||
parent: Some("Connectivity"),
|
||||
click_event: HANDLE_WIFI_CLICK,
|
||||
};
|
||||
|
||||
pub const BLUETOOTH_SIDEBAR: ReSetSidebarInfo = ReSetSidebarInfo {
|
||||
name: "Bluetooth",
|
||||
icon_name: "bluetooth-symbolic",
|
||||
parent: Some("Connectivity"),
|
||||
click_event: HANDLE_BLUETOOTH_CLICK,
|
||||
};
|
||||
|
||||
pub const AUDIO_SIDEBAR: ReSetSidebarInfo = ReSetSidebarInfo {
|
||||
name: "Audio",
|
||||
icon_name: "audio-headset-symbolic",
|
||||
parent: None,
|
||||
click_event: HANDLE_AUDIO_CLICK,
|
||||
};
|
||||
|
||||
pub const SINK_SIDEBAR: ReSetSidebarInfo = ReSetSidebarInfo {
|
||||
name: "Output",
|
||||
icon_name: "audio-volume-high-symbolic",
|
||||
parent: Some("Audio"),
|
||||
click_event: HANDLE_VOLUME_CLICK,
|
||||
};
|
||||
|
||||
pub const SOURCE_SIDEBAR: ReSetSidebarInfo = ReSetSidebarInfo {
|
||||
name: "Input",
|
||||
icon_name: "audio-input-microphone-symbolic",
|
||||
parent: Some("Audio"),
|
||||
click_event: HANDLE_MICROPHONE_CLICK,
|
||||
};
|
|
@ -12,63 +12,96 @@ use crate::components::base::utils::{start_audio_listener, Listeners, Position};
|
|||
use crate::components::bluetooth::bluetooth_box::{
|
||||
populate_connected_bluetooth_devices, BluetoothBox,
|
||||
};
|
||||
use crate::components::utils::Capabilities;
|
||||
use crate::components::wifi::wifi_box::{
|
||||
scan_for_wifi, show_stored_connections, start_event_listener, WifiBox,
|
||||
};
|
||||
use gtk::prelude::WidgetExt;
|
||||
use gtk::{Align, FlowBox, FlowBoxChild, Frame};
|
||||
|
||||
pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Connectivity) {
|
||||
return;
|
||||
}
|
||||
pub const HANDLE_CONNECTIVITY_CLICK: fn(
|
||||
&Capabilities,
|
||||
Arc<Listeners>,
|
||||
FlowBox,
|
||||
Rc<RefCell<Position>>,
|
||||
) = |capabilities: &Capabilities,
|
||||
listeners: Arc<Listeners>,
|
||||
reset_main: FlowBox,
|
||||
position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Connectivity) {
|
||||
return;
|
||||
}
|
||||
reset_main.remove_all();
|
||||
|
||||
let mut count = 0;
|
||||
|
||||
if capabilities.wifi.get() {
|
||||
let wifi_box = WifiBox::new(listeners.clone());
|
||||
start_event_listener(listeners.clone(), wifi_box.clone());
|
||||
show_stored_connections(wifi_box.clone());
|
||||
scan_for_wifi(wifi_box.clone());
|
||||
let wifi_frame = wrap_in_flow_box_child(SettingBox::new(&*wifi_box));
|
||||
reset_main.insert(&wifi_frame, -1);
|
||||
count += 1;
|
||||
}
|
||||
|
||||
if capabilities.bluetooth.get() {
|
||||
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
||||
populate_connected_bluetooth_devices(listeners, bluetooth_box.clone());
|
||||
// start_bluetooth_listener(listeners, bluetooth_box.clone());
|
||||
let bluetooth_frame = wrap_in_flow_box_child(SettingBox::new(&*bluetooth_box));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&wifi_frame, -1);
|
||||
reset_main.insert(&bluetooth_frame, -1);
|
||||
reset_main.set_max_children_per_line(2);
|
||||
};
|
||||
count += 1;
|
||||
}
|
||||
|
||||
pub const HANDLE_WIFI_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
reset_main.set_max_children_per_line(count);
|
||||
};
|
||||
|
||||
pub const HANDLE_WIFI_CLICK: fn(&Capabilities, Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|_: &Capabilities,
|
||||
listeners: Arc<Listeners>,
|
||||
reset_main: FlowBox,
|
||||
position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Wifi) {
|
||||
return;
|
||||
}
|
||||
reset_main.remove_all();
|
||||
|
||||
let wifi_box = WifiBox::new(listeners.clone());
|
||||
start_event_listener(listeners, wifi_box.clone());
|
||||
show_stored_connections(wifi_box.clone());
|
||||
scan_for_wifi(wifi_box.clone());
|
||||
let wifi_frame = wrap_in_flow_box_child(SettingBox::new(&*wifi_box));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&wifi_frame, -1);
|
||||
|
||||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_BLUETOOTH_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Bluetooth) {
|
||||
return;
|
||||
}
|
||||
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
||||
populate_connected_bluetooth_devices(listeners, bluetooth_box.clone());
|
||||
// start_bluetooth_listener(listeners, bluetooth_box.clone());
|
||||
let bluetooth_frame = wrap_in_flow_box_child(SettingBox::new(&*bluetooth_box));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&bluetooth_frame, -1);
|
||||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
pub const HANDLE_BLUETOOTH_CLICK: fn(
|
||||
&Capabilities,
|
||||
Arc<Listeners>,
|
||||
FlowBox,
|
||||
Rc<RefCell<Position>>,
|
||||
) = |_: &Capabilities,
|
||||
listeners: Arc<Listeners>,
|
||||
reset_main: FlowBox,
|
||||
position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Bluetooth) {
|
||||
return;
|
||||
}
|
||||
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
||||
populate_connected_bluetooth_devices(listeners, bluetooth_box.clone());
|
||||
// start_bluetooth_listener(listeners, bluetooth_box.clone());
|
||||
let bluetooth_frame = wrap_in_flow_box_child(SettingBox::new(&*bluetooth_box));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&bluetooth_frame, -1);
|
||||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_AUDIO_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
pub const HANDLE_AUDIO_CLICK: fn(&Capabilities, Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|_: &Capabilities,
|
||||
listeners: Arc<Listeners>,
|
||||
reset_main: FlowBox,
|
||||
position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Audio) {
|
||||
return;
|
||||
}
|
||||
|
@ -92,8 +125,11 @@ pub const HANDLE_AUDIO_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>)
|
|||
reset_main.set_max_children_per_line(2);
|
||||
};
|
||||
|
||||
pub const HANDLE_VOLUME_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
pub const HANDLE_VOLUME_CLICK: fn(&Capabilities, Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|_: &Capabilities,
|
||||
listeners: Arc<Listeners>,
|
||||
reset_main: FlowBox,
|
||||
position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::AudioOutput) {
|
||||
return;
|
||||
}
|
||||
|
@ -109,25 +145,35 @@ pub const HANDLE_VOLUME_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>
|
|||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_MICROPHONE_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::AudioInput) {
|
||||
return;
|
||||
}
|
||||
let audio_input = Arc::new(SourceBox::new());
|
||||
start_audio_listener(listeners.clone(), None, Some(audio_input.clone()));
|
||||
if !listeners.pulse_listener.load(Ordering::SeqCst) {
|
||||
spin_loop();
|
||||
}
|
||||
populate_sources(audio_input.clone());
|
||||
let source_frame = wrap_in_flow_box_child(SettingBox::new(&*audio_input));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&source_frame, -1);
|
||||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
pub const HANDLE_MICROPHONE_CLICK: fn(
|
||||
&Capabilities,
|
||||
Arc<Listeners>,
|
||||
FlowBox,
|
||||
Rc<RefCell<Position>>,
|
||||
) = |_: &Capabilities,
|
||||
listeners: Arc<Listeners>,
|
||||
reset_main: FlowBox,
|
||||
position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::AudioInput) {
|
||||
return;
|
||||
}
|
||||
let audio_input = Arc::new(SourceBox::new());
|
||||
start_audio_listener(listeners.clone(), None, Some(audio_input.clone()));
|
||||
if !listeners.pulse_listener.load(Ordering::SeqCst) {
|
||||
spin_loop();
|
||||
}
|
||||
populate_sources(audio_input.clone());
|
||||
let source_frame = wrap_in_flow_box_child(SettingBox::new(&*audio_input));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&source_frame, -1);
|
||||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_HOME: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
pub const HANDLE_HOME: fn(&Capabilities, Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|_: &Capabilities,
|
||||
listeners: Arc<Listeners>,
|
||||
reset_main: FlowBox,
|
||||
position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners, position, Position::Home) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,3 +3,4 @@ pub mod reset_window;
|
|||
pub mod reset_window_impl;
|
||||
pub mod sidebar_entry;
|
||||
pub mod sidebar_entry_impl;
|
||||
pub mod consts;
|
||||
|
|
|
@ -16,11 +16,17 @@ use re_set_lib::utils::plugin_setup::FRONTEND_PLUGINS;
|
|||
|
||||
use crate::components::base::setting_box::SettingBox;
|
||||
use crate::components::base::utils::{Listeners, Position};
|
||||
use crate::components::plugin::function::{PluginSidebarInfo, ReSetSidebarInfo};
|
||||
use crate::components::plugin::function::PluginSidebarInfo;
|
||||
use crate::components::utils::get_capabilities;
|
||||
use crate::components::window::handle_sidebar_click::*;
|
||||
use crate::components::window::reset_window_impl;
|
||||
use crate::components::window::sidebar_entry::SidebarEntry;
|
||||
|
||||
use super::consts::{
|
||||
AUDIO_SIDEBAR, BLUETOOTH_SIDEBAR, CONNECTIVITY_SIDEBAR, SINK_SIDEBAR, SOURCE_SIDEBAR,
|
||||
WIFI_SIDEBAR,
|
||||
};
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct ReSetWindow(ObjectSubclass<reset_window_impl::ReSetWindow>)
|
||||
@extends adw::ApplicationWindow, gtk::Window, gtk::Widget,
|
||||
|
@ -112,45 +118,29 @@ impl ReSetWindow {
|
|||
|
||||
pub fn setup_sidebar_entries(&self) {
|
||||
let self_imp = self.imp();
|
||||
let capabilities = get_capabilities();
|
||||
let wifi = capabilities.contains(&"WiFi".to_string());
|
||||
let bluetooth = capabilities.contains(&"Bluetooth".to_string());
|
||||
let audio = capabilities.contains(&"Audio".to_string());
|
||||
self_imp.capabilities.set(wifi, bluetooth, audio);
|
||||
|
||||
let sidebar_list = vec![
|
||||
ReSetSidebarInfo {
|
||||
name: "Connectivity",
|
||||
icon_name: "network-wired-symbolic",
|
||||
parent: None,
|
||||
click_event: HANDLE_CONNECTIVITY_CLICK,
|
||||
},
|
||||
ReSetSidebarInfo {
|
||||
name: "WiFi",
|
||||
icon_name: "network-wireless-symbolic",
|
||||
parent: Some("Connectivity"),
|
||||
click_event: HANDLE_WIFI_CLICK,
|
||||
},
|
||||
ReSetSidebarInfo {
|
||||
name: "Bluetooth",
|
||||
icon_name: "bluetooth-symbolic",
|
||||
parent: Some("Connectivity"),
|
||||
click_event: HANDLE_BLUETOOTH_CLICK,
|
||||
},
|
||||
ReSetSidebarInfo {
|
||||
name: "Audio",
|
||||
icon_name: "audio-headset-symbolic",
|
||||
parent: None,
|
||||
click_event: HANDLE_AUDIO_CLICK,
|
||||
},
|
||||
ReSetSidebarInfo {
|
||||
name: "Output",
|
||||
icon_name: "audio-volume-high-symbolic",
|
||||
parent: Some("Audio"),
|
||||
click_event: HANDLE_VOLUME_CLICK,
|
||||
},
|
||||
ReSetSidebarInfo {
|
||||
name: "Input",
|
||||
icon_name: "audio-input-microphone-symbolic",
|
||||
parent: Some("Audio"),
|
||||
click_event: HANDLE_MICROPHONE_CLICK,
|
||||
},
|
||||
];
|
||||
// let sidebar_list = vec![CONNECTIVITY_SIDEBAR, WIFI_SIDEBAR, BLUETOOTH_SIDEBAR, AUDIO_SIDEBAR, SINK_SIDEBAR, SOURCE_SIDEBAR];
|
||||
let mut sidebar_list = Vec::new();
|
||||
|
||||
if wifi || bluetooth {
|
||||
sidebar_list.push(CONNECTIVITY_SIDEBAR);
|
||||
}
|
||||
if wifi {
|
||||
sidebar_list.push(WIFI_SIDEBAR);
|
||||
};
|
||||
if bluetooth {
|
||||
sidebar_list.push(BLUETOOTH_SIDEBAR);
|
||||
};
|
||||
if audio {
|
||||
sidebar_list.push(AUDIO_SIDEBAR);
|
||||
sidebar_list.push(SINK_SIDEBAR);
|
||||
sidebar_list.push(SOURCE_SIDEBAR);
|
||||
}
|
||||
|
||||
let mut plugin_sidebar_list = vec![];
|
||||
unsafe {
|
||||
|
@ -191,6 +181,7 @@ impl ReSetWindow {
|
|||
}
|
||||
|
||||
HANDLE_VOLUME_CLICK(
|
||||
&self_imp.capabilities,
|
||||
self_imp.listeners.clone(),
|
||||
self_imp.reset_main.clone(),
|
||||
self_imp.position.clone(),
|
||||
|
@ -361,6 +352,7 @@ fn setup_callback(window: Rc<ReSetWindow>) -> Rc<ReSetWindow> {
|
|||
let click_event = result.imp().on_click_event.borrow();
|
||||
if let Some(event) = click_event.on_click_event {
|
||||
event(
|
||||
&imp.capabilities,
|
||||
imp.listeners.clone(),
|
||||
imp.reset_main.get(),
|
||||
imp.position.clone(),
|
||||
|
|
|
@ -12,6 +12,7 @@ use gtk::{Button, CompositeTemplate, FlowBox, ListBox, SearchEntry};
|
|||
|
||||
use crate::components::base::error::ReSetError;
|
||||
use crate::components::base::utils::{Listeners, Position};
|
||||
use crate::components::utils::Capabilities;
|
||||
use crate::components::wifi::wifi_box::WifiBox;
|
||||
use crate::components::window::reset_window;
|
||||
use crate::components::window::sidebar_entry::SidebarEntry;
|
||||
|
@ -40,6 +41,7 @@ pub struct ReSetWindow {
|
|||
pub listeners: Arc<Listeners>,
|
||||
pub position: Rc<RefCell<Position>>,
|
||||
pub error_popup: ReSetError,
|
||||
pub capabilities: Capabilities,
|
||||
}
|
||||
|
||||
unsafe impl Send for ReSetWindow {}
|
||||
|
|
Loading…
Reference in a new issue