mirror of
https://github.com/Xetibo/ReSet.git
synced 2025-04-15 09:28:33 +02:00
feat: Add default Sink and Source Switching
This commit is contained in:
parent
dbcf2ab635
commit
c619284146
|
@ -72,7 +72,11 @@ pub fn populate_sources(output_box: Arc<SourceBox>) {
|
|||
output_box_imp.resetVolumePercentage.set_text(&percentage);
|
||||
output_box_imp.resetVolumeSlider.set_value(*volume as f64);
|
||||
for stream in sinks {
|
||||
let entry = ListEntry::new(&SourceEntry::new(stream));
|
||||
let mut is_default = false;
|
||||
if output_box_imp.resetDefaultSource.borrow().name == stream.name {
|
||||
is_default = true;
|
||||
}
|
||||
let entry = ListEntry::new(&SourceEntry::new(is_default, output_box_imp.resetDefaultCheckButton.clone(), stream));
|
||||
entry.set_activatable(false);
|
||||
output_box_imp.resetSources.append(&entry);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::{Arc, Mutex};
|
|||
use crate::components::base::listEntry::ListEntry;
|
||||
use crate::components::input::sourceBox;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::{glib, CompositeTemplate, DropDown, TemplateChild};
|
||||
use gtk::{glib, CompositeTemplate, DropDown, TemplateChild, CheckButton};
|
||||
use gtk::{prelude::*, Button, Label, ProgressBar, Scale};
|
||||
use ReSet_Lib::audio::audio::{OutputStream, Source};
|
||||
|
||||
|
@ -33,6 +33,7 @@ pub struct SourceBox {
|
|||
pub resetOutputStreamButton: TemplateChild<ListEntry>,
|
||||
#[template_child]
|
||||
pub resetOutputStreams: TemplateChild<gtk::Box>,
|
||||
pub resetDefaultCheckButton: Arc<CheckButton>,
|
||||
pub resetDefaultSource: Arc<RefCell<Source>>,
|
||||
pub resetSourceList: Arc<Mutex<Vec<Source>>>,
|
||||
pub resetOutputStreamList: Arc<Mutex<Vec<OutputStream>>>,
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use adw::glib;
|
||||
use adw::glib::Object;
|
||||
use adw::prelude::{ButtonExt, RangeExt};
|
||||
use adw::prelude::{ButtonExt, RangeExt, CheckButtonExt};
|
||||
use dbus::blocking::Connection;
|
||||
use dbus::Error;
|
||||
use glib::subclass::types::ObjectSubclassIsExt;
|
||||
use glib::{clone, Propagation};
|
||||
use ReSet_Lib::audio::audio::Source;
|
||||
use gtk::CheckButton;
|
||||
|
||||
use super::sourceEntryImpl;
|
||||
|
||||
|
@ -20,7 +22,7 @@ glib::wrapper! {
|
|||
}
|
||||
|
||||
impl SourceEntry {
|
||||
pub fn new(stream: Source) -> Self {
|
||||
pub fn new(is_default: bool, check_group: Arc<CheckButton>, stream: Source) -> Self {
|
||||
let obj: Self = Object::builder().build();
|
||||
// TODO use event callback for progress bar -> this is the "im speaking" indicator
|
||||
// TODO map the slider to volume
|
||||
|
@ -30,6 +32,7 @@ impl SourceEntry {
|
|||
{
|
||||
let imp = obj.imp();
|
||||
imp.resetSourceName.set_text(stream.name.clone().as_str());
|
||||
let name = Arc::new(stream.name.clone());
|
||||
let volume = stream.volume.first().unwrap_or_else(|| &(0 as u32));
|
||||
let fraction = (*volume as f64 / 655.36).round();
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
|
@ -49,6 +52,18 @@ impl SourceEntry {
|
|||
Propagation::Proceed
|
||||
}),
|
||||
);
|
||||
imp.resetSelectedSource.set_group(Some(&*check_group));
|
||||
// check_group.set_group(Some(&*imp.resetSelectedSink));
|
||||
if is_default {
|
||||
imp.resetSelectedSource.set_active(true);
|
||||
} else {
|
||||
imp.resetSelectedSource.set_active(false);
|
||||
}
|
||||
imp.resetSelectedSource.connect_toggled(move |button| {
|
||||
if button.is_active() {
|
||||
set_default_source(name.clone());
|
||||
}
|
||||
});
|
||||
imp.resetSourceMute
|
||||
.connect_clicked(clone!(@weak imp => move |_| {
|
||||
let stream = imp.stream.clone();
|
||||
|
@ -102,3 +117,20 @@ pub fn toggle_source_mute(index: u32, muted: bool) -> bool {
|
|||
}
|
||||
res.unwrap().0
|
||||
}
|
||||
|
||||
pub fn set_default_source(name: Arc<String>) {
|
||||
thread::spawn(move || {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.xetibo.ReSet",
|
||||
"/org/xetibo/ReSet",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let res: Result<(bool,), Error> =
|
||||
proxy.method_call("org.xetibo.ReSet", "SetDefaultSink", (name.as_str(),));
|
||||
if res.is_err() {
|
||||
return;
|
||||
}
|
||||
// handle change
|
||||
});
|
||||
}
|
||||
|
|
|
@ -73,7 +73,11 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
|||
output_box_imp.resetVolumeSlider.set_value(*volume as f64);
|
||||
for stream in sinks {
|
||||
// TODO create sink handler -> currently only allows input streams
|
||||
let entry = ListEntry::new(&SinkEntry::new(stream));
|
||||
let mut is_default = false;
|
||||
if output_box_imp.resetDefaultSink.borrow().name == stream.name {
|
||||
is_default = true;
|
||||
}
|
||||
let entry = ListEntry::new(&SinkEntry::new(is_default, output_box_imp.resetDefaultCheckButton.clone(), stream));
|
||||
entry.set_activatable(false);
|
||||
output_box_imp.resetSinks.append(&entry);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::{Arc, Mutex};
|
|||
use crate::components::base::listEntry::ListEntry;
|
||||
use crate::components::output::inputStreamEntry::InputStreamEntry;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::{glib, Box, Button, CompositeTemplate, DropDown, Label, TemplateChild};
|
||||
use gtk::{glib, Box, Button, CompositeTemplate, DropDown, Label, TemplateChild, CheckButton};
|
||||
use gtk::{prelude::*, ProgressBar, Scale};
|
||||
use ReSet_Lib::audio::audio::{InputStream, Sink};
|
||||
|
||||
|
@ -33,6 +33,7 @@ pub struct SinkBox {
|
|||
pub resetInputStreamButton: TemplateChild<ListEntry>,
|
||||
#[template_child]
|
||||
pub resetInputStreams: TemplateChild<Box>,
|
||||
pub resetDefaultCheckButton: Arc<CheckButton>,
|
||||
pub resetDefaultSink: Arc<RefCell<Sink>>,
|
||||
pub resetSinkList: Arc<Mutex<Vec<Sink>>>,
|
||||
pub resetInputStreamList: Arc<Mutex<Vec<InputStream>>>,
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use adw::glib;
|
||||
use adw::glib::Object;
|
||||
use adw::prelude::{ButtonExt, RangeExt};
|
||||
use adw::prelude::{ButtonExt, CheckButtonExt, RangeExt};
|
||||
use dbus::blocking::Connection;
|
||||
use dbus::Error;
|
||||
use glib::subclass::types::ObjectSubclassIsExt;
|
||||
use glib::{clone, Propagation};
|
||||
use gtk::CheckButton;
|
||||
use ReSet_Lib::audio::audio::Sink;
|
||||
|
||||
use super::sinkEntryImpl;
|
||||
|
@ -20,16 +21,14 @@ glib::wrapper! {
|
|||
}
|
||||
|
||||
impl SinkEntry {
|
||||
pub fn new(stream: Sink) -> Self {
|
||||
pub fn new(is_default: bool, check_group: Arc<CheckButton>, stream: Sink) -> Self {
|
||||
let obj: Self = Object::builder().build();
|
||||
// TODO use event callback for progress bar -> this is the "im speaking" indicator
|
||||
// TODO map the slider to volume
|
||||
// TODO properly use volume fraction
|
||||
// TODO map mute to callback
|
||||
// TODO map dropdown
|
||||
{
|
||||
let imp = obj.imp();
|
||||
imp.resetSinkName.set_text(stream.name.clone().as_str());
|
||||
let name = Arc::new(stream.name.clone());
|
||||
let volume = stream.volume.first().unwrap_or_else(|| &(0 as u32));
|
||||
let fraction = (*volume as f64 / 655.36).round();
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
|
@ -49,6 +48,18 @@ impl SinkEntry {
|
|||
Propagation::Proceed
|
||||
}),
|
||||
);
|
||||
imp.resetSelectedSink.set_group(Some(&*check_group));
|
||||
// check_group.set_group(Some(&*imp.resetSelectedSink));
|
||||
if is_default {
|
||||
imp.resetSelectedSink.set_active(true);
|
||||
} else {
|
||||
imp.resetSelectedSink.set_active(false);
|
||||
}
|
||||
imp.resetSelectedSink.connect_toggled(move |button| {
|
||||
if button.is_active() {
|
||||
set_default_sink(name.clone());
|
||||
}
|
||||
});
|
||||
imp.resetSinkMute
|
||||
.connect_clicked(clone!(@weak imp => move |_| {
|
||||
let stream = imp.stream.clone();
|
||||
|
@ -102,3 +113,21 @@ pub fn toggle_sink_mute(index: u32, muted: bool) -> bool {
|
|||
}
|
||||
res.unwrap().0
|
||||
}
|
||||
|
||||
pub fn set_default_sink(name: Arc<String>) {
|
||||
thread::spawn(move || {
|
||||
dbg!(name.clone());
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.xetibo.ReSet",
|
||||
"/org/xetibo/ReSet",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let res: Result<(bool,), Error> =
|
||||
proxy.method_call("org.xetibo.ReSet", "SetDefaultSink", (name.as_str(),));
|
||||
if res.is_err() {
|
||||
return;
|
||||
}
|
||||
// handle change
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue