Implement Microphone UI

Improve Audio UI
You won't believe what happened (gone sexual)
This commit is contained in:
takotori 2023-11-12 17:43:01 +01:00
parent d07180e2c7
commit 35c58e2fcd
36 changed files with 1380 additions and 399 deletions

View file

@ -1,21 +1,19 @@
use crate::components::base::settingBoxImpl;
use adw::glib;
use adw::glib::{IsA, Object};
use glib::subclass::prelude::ObjectSubclassIsExt;
use gtk::prelude::FrameExt;
use gtk::prelude::BoxExt;
use gtk::Widget;
glib::wrapper! {
pub struct SettingBox(ObjectSubclass<settingBoxImpl::SettingBox>)
@extends gtk::Frame, gtk::Widget,
@extends gtk::Box, gtk::Widget,
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
}
impl SettingBox {
pub fn new(child: &impl IsA<Widget>, title: &str) -> Self {
pub fn new(child: &impl IsA<Widget>) -> Self {
let entry: SettingBox = Object::builder().build();
entry.set_child(Some(child));
entry.imp().resetSettingLabel.set_text(title);
entry.append(child);
entry
}
}

View file

@ -5,16 +5,13 @@ use crate::components::base::settingBox;
#[allow(non_snake_case)]
#[derive(Default, CompositeTemplate)]
#[template(resource = "/org/Xetibo/ReSet/resetSettingBox.ui")]
pub struct SettingBox {
#[template_child]
pub resetSettingLabel: TemplateChild<Label>,
}
pub struct SettingBox {}
#[glib::object_subclass]
impl ObjectSubclass for SettingBox {
const NAME: &'static str = "resetSettingFrame";
const NAME: &'static str = "resetSettingBox";
type Type = settingBox::SettingBox;
type ParentType = gtk::Frame;
type ParentType = gtk::Box;
fn class_init(klass: &mut Self::Class) {
klass.bind_template();
@ -31,7 +28,7 @@ impl ObjectImpl for SettingBox {
}
}
impl FrameImpl for SettingBox {}
impl BoxImpl for SettingBox {}
impl WidgetImpl for SettingBox {}

View file

@ -1,6 +1,8 @@
use adw::glib;
use adw::glib::Object;
use adw::subclass::prelude::ObjectSubclassIsExt;
use gtk::glib::Variant;
use gtk::prelude::ActionableExt;
use crate::components::bluetooth::bluetoothBoxImpl;
use crate::components::bluetooth::bluetoothEntry::BluetoothEntry;
@ -18,6 +20,14 @@ impl BluetoothBox {
Object::builder().build()
}
pub fn setupCallbacks(&self) {
let selfImp = self.imp();
selfImp.resetVisibility.set_action_name(Some("navigation.push"));
selfImp.resetVisibility.set_action_target_value(Some(&Variant::from("visibility")));
selfImp.resetBluetoothMainTab.set_action_name(Some("navigation.pop"));
}
pub fn scanForDevices(&self) {
let selfImp = self.imp();
let mut wifiEntries = selfImp.availableDevices.borrow_mut();

View file

@ -17,6 +17,10 @@ pub struct BluetoothBox {
pub resetBluetoothAvailableDevices: TemplateChild<ListBox>,
#[template_child]
pub resetBluetoothConnectedDevices: TemplateChild<ListBox>,
#[template_child]
pub resetVisibility: TemplateChild<ListEntry>,
#[template_child]
pub resetBluetoothMainTab: TemplateChild<ListEntry>,
pub availableDevices: RefCell<Vec<ListEntry>>,
pub connectedDevices: RefCell<Vec<ListEntry>>,
}
@ -42,6 +46,7 @@ impl ObjectImpl for BluetoothBox {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.setupCallbacks();
obj.scanForDevices();
obj.addConnectedDevices();
}

View file

@ -18,7 +18,7 @@ impl BluetoothEntry {
entryImp.resetBluetoothDeviceType.get().set_from_icon_name(match deviceType {
DeviceTypes::Mouse => Some("input-mouse-symbolic"),
DeviceTypes::Keyboard => Some("input-keyboard-symbolic"),
DeviceTypes::Headset => Some("audio-headset-symbolic"),
DeviceTypes::Headset => Some("output-headset-symbolic"),
DeviceTypes::Controller => Some("input-gaming-symbolic"),
DeviceTypes::None => Some("text-x-generic-symbolic") // no generic bluetooth device icon found
});

View file

@ -1,14 +1,14 @@
use crate::components::input::inputStreamEntryImpl;
use adw::glib;
use adw::glib::Object;
use crate::components::audio::audioBoxImpl;
glib::wrapper! {
pub struct AudioBox(ObjectSubclass<audioBoxImpl::AudioBox>)
pub struct InputStreamEntry(ObjectSubclass<inputStreamEntryImpl::InputStreamEntry>)
@extends gtk::Box, gtk::Widget,
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
}
impl AudioBox {
impl InputStreamEntry {
pub fn new() -> Self {
Object::builder().build()
}

View file

@ -0,0 +1,40 @@
use gtk::{Button, CompositeTemplate, glib, Label, ProgressBar, Scale};
use gtk::subclass::prelude::*;
use crate::components::input::inputStreamEntry;
#[allow(non_snake_case)]
#[derive(Default, CompositeTemplate)]
#[template(resource = "/org/Xetibo/ReSet/resetInputStreamEntry.ui")]
pub struct InputStreamEntry {
#[template_child]
pub resetSourceName: TemplateChild<Label>,
#[template_child]
pub resetSourceMute: TemplateChild<Button>,
#[template_child]
pub resetVolumeSlider: TemplateChild<Scale>,
#[template_child]
pub resetVolumePercentage: TemplateChild<Label>,
#[template_child]
pub resetVolumeMeter: TemplateChild<ProgressBar>,
}
#[glib::object_subclass]
impl ObjectSubclass for InputStreamEntry {
const NAME: &'static str = "resetInputStreamEntry";
type Type = inputStreamEntry::InputStreamEntry;
type ParentType = gtk::Box;
fn class_init(klass: &mut Self::Class) {
klass.bind_template();
}
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
obj.init_template();
}
}
impl BoxImpl for InputStreamEntry {}
impl ObjectImpl for InputStreamEntry {}
impl WidgetImpl for InputStreamEntry {}

View file

@ -0,0 +1,5 @@
#![allow(non_snake_case)]
pub mod inputStreamEntry;
pub mod sourceBox;
pub mod sourceBoxImpl;
pub mod inputStreamEntryImpl;

View file

@ -0,0 +1,26 @@
use crate::components::input::sourceBoxImpl;
use adw::glib;
use adw::glib::Object;
use glib::subclass::prelude::ObjectSubclassIsExt;
use glib::Variant;
use gtk::prelude::ActionableExt;
glib::wrapper! {
pub struct SourceBox(ObjectSubclass<sourceBoxImpl::SourceBox>)
@extends gtk::Box, gtk::Widget,
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
}
impl SourceBox {
pub fn new() -> Self {
Object::builder().build()
}
pub fn setupCallbacks(&self) {
let selfImp = self.imp();
selfImp.resetSourceRow.set_action_name(Some("navigation.push"));
selfImp.resetSourceRow.set_action_target_value(Some(&Variant::from("sources")));
selfImp.resetInputStreamButton.set_action_name(Some("navigation.pop"));
}
}

View file

@ -0,0 +1,52 @@
use gtk::{CompositeTemplate, DropDown, TemplateChild, glib};
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use crate::components::base::listEntry::ListEntry;
use crate::components::input::inputStreamEntry::InputStreamEntry;
use crate::components::input::sourceBox;
#[allow(non_snake_case)]
#[derive(Default, CompositeTemplate)]
#[template(resource = "/org/Xetibo/ReSet/resetMicrophone.ui")]
pub struct SourceBox {
#[template_child]
pub resetSourceDropdown: TemplateChild<DropDown>,
#[template_child]
pub resetSourceRow: TemplateChild<ListEntry>,
#[template_child]
pub resetInputStreamButton: TemplateChild<ListEntry>,
}
#[glib::object_subclass]
impl ObjectSubclass for SourceBox {
const NAME: &'static str = "resetMicrophone";
type Type = sourceBox::SourceBox;
type ParentType = gtk::Box;
fn class_init(klass: &mut Self::Class) {
InputStreamEntry::ensure_type();
ListEntry::ensure_type();
klass.bind_template();
}
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
obj.init_template();
}
}
impl BoxImpl for SourceBox {}
impl ObjectImpl for SourceBox {
fn constructed(&self) {
let obj = self.obj();
obj.setupCallbacks();
}
}
impl ListBoxRowImpl for SourceBox {}
impl WidgetImpl for SourceBox {}
impl WindowImpl for SourceBox {}
impl ApplicationWindowImpl for SourceBox {}

View file

@ -1,5 +1,6 @@
pub mod window;
pub mod wifi;
pub mod bluetooth;
pub mod audio;
mod base;
pub mod output;
mod base;
mod input;

View file

@ -0,0 +1,27 @@
use adw::glib;
use adw::glib::Object;
use glib::subclass::prelude::ObjectSubclassIsExt;
use glib::Variant;
use gtk::prelude::ActionableExt;
use crate::components::base::listEntry::ListEntry;
use crate::components::output::audioBoxImpl;
glib::wrapper! {
pub struct AudioBox(ObjectSubclass<audioBoxImpl::AudioBox>)
@extends gtk::Box, gtk::Widget,
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
}
impl AudioBox {
pub fn new() -> Self {
Object::builder().build()
}
pub fn setupCallbacks(&self) {
let selfImp = self.imp();
selfImp.resetSinksRow.set_action_name(Some("navigation.push"));
selfImp.resetSinksRow.set_action_target_value(Some(&Variant::from("outputDevices")));
selfImp.resetOutputStreamButton.set_action_name(Some("navigation.pop"));
}
}

View file

@ -1,8 +1,9 @@
use gtk::{CompositeTemplate, DropDown, TemplateChild, glib};
use gtk::{CompositeTemplate, DropDown, TemplateChild, glib, Button};
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use crate::components::audio::audioBox;
use crate::components::audio::audioSource::AudioSourceEntry;
use crate::components::output::audioBox;
use crate::components::output::audioSource::AudioSourceEntry;
use crate::components::base::listEntry::ListEntry;
#[allow(non_snake_case)]
#[derive(Default, CompositeTemplate)]
@ -10,6 +11,10 @@ use crate::components::audio::audioSource::AudioSourceEntry;
pub struct AudioBox {
#[template_child]
pub resetOutputDevice: TemplateChild<DropDown>,
#[template_child]
pub resetSinksRow: TemplateChild<ListEntry>,
#[template_child]
pub resetOutputStreamButton: TemplateChild<ListEntry>,
}
@ -21,6 +26,7 @@ impl ObjectSubclass for AudioBox {
fn class_init(klass: &mut Self::Class) {
AudioSourceEntry::ensure_type();
ListEntry::ensure_type();
klass.bind_template();
}
@ -31,7 +37,12 @@ impl ObjectSubclass for AudioBox {
impl BoxImpl for AudioBox {}
impl ObjectImpl for AudioBox {}
impl ObjectImpl for AudioBox {
fn constructed(&self) {
let obj = self.obj();
obj.setupCallbacks();
}
}
impl ListBoxRowImpl for AudioBox {}

View file

@ -1,6 +1,6 @@
use adw::glib;
use adw::glib::Object;
use crate::components::audio::audioSourceImpl;
use crate::components::output::audioSourceImpl;
glib::wrapper! {
pub struct AudioSourceEntry(ObjectSubclass<audioSourceImpl::AudioSourceEntry>)

View file

@ -1,13 +1,11 @@
use gtk::{Button, CompositeTemplate, glib, Image, Label, ProgressBar, Scale};
use gtk::subclass::prelude::*;
use crate::components::audio::audioSource;
use crate::components::output::audioSource;
#[allow(non_snake_case)]
#[derive(Default, CompositeTemplate)]
#[template(resource = "/org/Xetibo/ReSet/resetAudioSourceEntry.ui")]
#[template(resource = "/org/Xetibo/ReSet/resetOutputStreamEntry.ui")]
pub struct AudioSourceEntry {
#[template_child]
pub resetSourceIcon: TemplateChild<Image>,
#[template_child]
pub resetSourceName: TemplateChild<Label>,
#[template_child]
@ -22,7 +20,7 @@ pub struct AudioSourceEntry {
#[glib::object_subclass]
impl ObjectSubclass for AudioSourceEntry {
const NAME: &'static str = "resetAudioSourceEntry";
const NAME: &'static str = "resetOutputStreamEntry";
type Type = audioSource::AudioSourceEntry;
type ParentType = gtk::Box;

View file

@ -1,24 +1,22 @@
use std::collections::HashMap;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::{atomic::AtomicBool, Arc, Weak};
use std::thread;
use std::sync::{atomic::AtomicBool, Arc};
use std::time::Duration;
use crate::components::base::listEntry::ListEntry;
use adw::glib;
use adw::glib::Object;
use adw::prelude::{BoxExt, ButtonExt, ListBoxRowExt};
use adw::prelude::{BoxExt, ListBoxRowExt};
use adw::subclass::prelude::ObjectSubclassIsExt;
use dbus::arg::RefArg;
use dbus::blocking::Connection;
use dbus::Error;
use dbus::Path;
use gtk::glib::Variant;
use gtk::prelude::ActionableExt;
use gtk::{Button, Label, Orientation};
use ReSet_Lib::network::network::{AccessPoint, WifiStrength};
use ReSet_Lib::signals::{
AccessPointAdded, AccessPointRemoved, BluetoothDeviceAdded, BluetoothDeviceRemoved,
};
use ReSet_Lib::network::network::AccessPoint;
use ReSet_Lib::signals::AccessPointAdded;
use ReSet_Lib::signals::AccessPointRemoved;
use ReSet_Lib::utils::Events;
use crate::components::wifi::wifiBoxImpl;
@ -26,6 +24,8 @@ use crate::components::wifi::wifiEntry::WifiEntry;
use super::savedWifiEntry::SavedWifiEntry;
use ReSet_Lib::network::connection::Connection as ResetConnection;
glib::wrapper! {
pub struct WifiBox(ObjectSubclass<wifiBoxImpl::WifiBox>)
@extends gtk::Box, gtk::Widget,
@ -42,9 +42,10 @@ impl WifiBox {
pub fn setupCallbacks(&self) {
let selfImp = self.imp();
selfImp.resetSavedNetworks.set_action_name(Some("navigation.push"));
selfImp.resetSavedNetworks.set_action_target_value(Some(&Variant::from("saved")))
selfImp.resetSavedNetworks.set_action_target_value(Some(&Variant::from("saved")));
selfImp.resetAvailableNetworks.set_action_name(Some("navigation.pop"));
}
// pub fn donotdisturb() {
@ -173,3 +174,25 @@ pub async fn get_stored_connections() -> Vec<(Path<'static>, Vec<u8>)> {
dbg!(connections.clone());
connections
}
pub fn getConnectionSettings(path: Path<'static>) -> Option<ResetConnection> {
let conn = Connection::new_session().unwrap();
let proxy = conn.with_proxy(
"org.xetibo.ReSet",
"/org/xetibo/ReSet",
Duration::from_millis(1000),
);
let res: Result<(HashMap<String, HashMap<String, dbus::arg::Variant<Box<dyn RefArg>>>,>,), Error> =
proxy.method_call("org.xetibo.ReSet", "GetConnectionSettings", (path,));
if res.is_err() {
println!("lol not work");
return None;
}
let (res,) = res.unwrap();
let res = ResetConnection::convert_from_propmap(res);
if res.is_err() {
println!("lol none");
return None;
}
Some(res.unwrap())
}

View file

@ -1,6 +1,5 @@
use std::cell::RefCell;
use std::sync::{Arc, Mutex};
use gtk::{Button, CompositeTemplate, glib, ListBox, Switch};
use gtk::{CompositeTemplate, glib, ListBox, Switch};
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use crate::components::wifi::wifiBox;
@ -8,8 +7,6 @@ use crate::components::wifi::wifiBox;
use crate::components::wifi::wifiEntry::WifiEntry;
use crate::components::base::listEntry::ListEntry;
use super::wifiBox::scanForWifi;
#[allow(non_snake_case)]
#[derive(Default, CompositeTemplate)]
#[template(resource = "/org/Xetibo/ReSet/resetWiFi.ui")]
@ -17,8 +14,6 @@ pub struct WifiBox {
#[template_child]
pub resetWifiDetails: TemplateChild<ListBox>,
#[template_child]
pub resetWifiSwitchRow: TemplateChild<ListEntry>,
#[template_child]
pub resetSavedNetworks: TemplateChild<ListEntry>,
#[template_child]
pub resetWifiSwitch: TemplateChild<Switch>,
@ -26,6 +21,8 @@ pub struct WifiBox {
pub resetWifiList: TemplateChild<ListBox>,
#[template_child]
pub resetStoredWifiList: TemplateChild<ListBox>,
#[template_child]
pub resetAvailableNetworks: TemplateChild<ListEntry>,
pub wifiEntries: Arc<Mutex<Vec<ListEntry>>>,
pub savedWifiEntries: Arc<Mutex<Vec<ListEntry>>>,
}

View file

@ -1,19 +1,21 @@
use crate::components::base::popup::{self, Popup};
use crate::components::wifi::wifiEntryImpl;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::time::Duration;
use adw::glib;
use adw::glib::{Object, PropertySet};
use adw::prelude::{ButtonExt, EditableExt, EntryExt, PopoverExt};
use adw::subclass::prelude::ObjectSubclassIsExt;
use dbus::blocking::Connection;
use dbus::Error;
use glib::{clone, Cast};
use glib::{Cast, clone};
use gtk::{AlertDialog, GestureClick};
use gtk::prelude::WidgetExt;
use gtk::{AlertDialog, Editable, GestureClick, PasswordEntry, PasswordEntryBuffer, Window};
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::Duration;
use ReSet_Lib::network::network::{AccessPoint, WifiStrength};
use crate::components::wifi::wifiBox::getConnectionSettings;
use crate::components::wifi::wifiEntryImpl;
glib::wrapper! {
pub struct WifiEntry(ObjectSubclass<wifiEntryImpl::WifiEntry>)
@extends gtk::Box, gtk::Widget,
@ -75,6 +77,15 @@ impl WifiEntry {
entry.add_controller(gesture);
entry
}
pub fn setupCallbacks(&self) {
let selfImp = self.imp();
selfImp.resetWifiEditButton.connect_clicked(clone!(@ weak selfImp => move |_| {
// TODO open navigationpage
let option = getConnectionSettings(selfImp.accessPoint.borrow().associated_connection.clone());
dbg!(option);
}));
}
}
pub fn click_stored_network(entry: Arc<WifiEntry>) {

View file

@ -16,7 +16,7 @@ pub struct WifiEntry {
#[template_child]
pub resetWifiLabel: TemplateChild<Label>,
#[template_child]
pub resetWifiButton: TemplateChild<Button>,
pub resetWifiEditButton: TemplateChild<Button>,
#[template_child]
pub resetWifiConnected: TemplateChild<Image>,
#[template_child]
@ -49,6 +49,9 @@ impl ObjectSubclass for WifiEntry {
impl ObjectImpl for WifiEntry {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.setupCallbacks();
}
}

View file

@ -1,39 +1,40 @@
use gtk::prelude::FrameExt;
use std::sync::Arc;
use crate::components::audio::audioBox::AudioBox;
use crate::components::output::audioBox::AudioBox;
use crate::components::base::settingBox::SettingBox;
use crate::components::bluetooth::bluetoothBox::BluetoothBox;
use crate::components::wifi::wifiBox::{scanForWifi, show_stored_connections, WifiBox};
use adw::prelude::ButtonExt;
use glib::clone;
use glib::subclass::types::ObjectSubclassIsExt;
use gtk::{FlowBox, Label};
use gtk::{FlowBox, Frame, Label,};
use gtk::prelude::WidgetExt;
use crate::components::input::sourceBox;
use crate::components::input::sourceBox::SourceBox;
pub const HANDLE_CONNECTIVITY_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
let wifiBox = Arc::new(WifiBox::new());
show_stored_connections(wifiBox.clone());
scanForWifi(wifiBox.clone());
let wifiBox = SettingBox::new(&*wifiBox, "WiFi");
let bluetoothBox = SettingBox::new(&BluetoothBox::new(), "Bluetooth");
let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox));
let bluetoothFrame = wrapInFrame(SettingBox::new(&BluetoothBox::new()));
resetMain.remove_all();
resetMain.insert(&wifiBox, -1);
resetMain.insert(&bluetoothBox, -1);
resetMain.insert(&wifiFrame, -1);
resetMain.insert(&bluetoothFrame, -1);
resetMain.set_max_children_per_line(2);
};
pub const HANDLE_WIFI_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
let wifiBox = Arc::new(WifiBox::new());
scanForWifi(wifiBox.clone());
let wifiBox = SettingBox::new(&*wifiBox, "WiFi");
let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox));
resetMain.remove_all();
resetMain.insert(&wifiBox, -1);
resetMain.insert(&wifiFrame, -1);
resetMain.set_max_children_per_line(1);
};
pub const HANDLE_BLUETOOTH_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
let bluetoothBox = SettingBox::new(&BluetoothBox::new(), "Bluetooth");
let bluetoothFrame = wrapInFrame(SettingBox::new(&BluetoothBox::new()));
resetMain.remove_all();
resetMain.insert(&bluetoothBox, -1);
resetMain.insert(&bluetoothFrame, -1);
resetMain.set_max_children_per_line(1);
};
@ -45,23 +46,25 @@ pub const HANDLE_VPN_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
};
pub const HANDLE_AUDIO_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
let audioBox = SettingBox::new(&AudioBox::new(), "Audio");
let audioFrame = wrapInFrame(SettingBox::new(&AudioBox::new()));
let sourceFrame = wrapInFrame(SettingBox::new(&SourceBox::new()));
resetMain.remove_all();
resetMain.insert(&audioBox, -1);
resetMain.set_max_children_per_line(1);
resetMain.insert(&audioFrame, -1);
resetMain.insert(&sourceFrame, -1);
resetMain.set_max_children_per_line(2);
};
pub const HANDLE_VOLUME_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
let audioBox = SettingBox::new(&AudioBox::new(), "Audio");
let audioFrame = wrapInFrame(SettingBox::new(&AudioBox::new()));
resetMain.remove_all();
resetMain.insert(&audioBox, -1);
resetMain.insert(&audioFrame, -1);
resetMain.set_max_children_per_line(1);
};
pub const HANDLE_MICROPHONE_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
let label = Label::new(Some("not implemented yet"));
let sourceFrame = wrapInFrame(SettingBox::new(&SourceBox::new()));
resetMain.remove_all();
resetMain.insert(&label, -1);
resetMain.insert(&sourceFrame, -1);
resetMain.set_max_children_per_line(1);
};
@ -96,3 +99,10 @@ pub const HANDLE_KEYBOARD_CLICK: fn(FlowBox) = |resetMain: FlowBox| {
pub const HANDLE_HOME: fn(FlowBox) = |resetMain: FlowBox| {
resetMain.remove_all();
};
fn wrapInFrame(widget: SettingBox) -> Frame {
let frame = Frame::new(None);
frame.set_child(Some(&widget));
frame.add_css_class("resetSettingFrame");
frame
}

View file

@ -165,14 +165,14 @@ impl Window {
let audioList = vec![
SidebarEntry::new(
"Volume",
"Output",
"audio-volume-high-symbolic",
Categories::Audio,
true,
HANDLE_VOLUME_CLICK,
),
SidebarEntry::new(
"Microphone",
"Input",
"audio-input-microphone-symbolic",
Categories::Audio,
true,