mirror of
https://github.com/Xetibo/ReSet.git
synced 2025-07-01 15:57:46 +02:00
chore: Rename UI files
This commit is contained in:
parent
ed00b26749
commit
2f1099267a
35 changed files with 679 additions and 176 deletions
|
@ -15,7 +15,8 @@ use gtk::gio;
|
|||
use gtk::prelude::ActionableExt;
|
||||
use ReSet_Lib::audio::audio::{InputStream, Sink};
|
||||
|
||||
use super::audioSource::{self, AudioSourceEntry};
|
||||
use super::inputStreamEntry::InputStreamEntry;
|
||||
use super::sinkEntry::SinkEntry;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AudioBox(ObjectSubclass<audioBoxImpl::AudioBox>)
|
||||
|
@ -41,7 +42,7 @@ impl AudioBox {
|
|||
.set_action_target_value(Some(&Variant::from("outputDevices")));
|
||||
|
||||
selfImp
|
||||
.resetOutputStreamButton
|
||||
.resetInputStreamButton
|
||||
.set_action_name(Some("navigation.pop"));
|
||||
}
|
||||
}
|
||||
|
@ -55,16 +56,12 @@ pub fn populate_sinks(output_box: Arc<AudioBox>) {
|
|||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box_imp = output_box_ref.imp();
|
||||
// TODO handle default mapping
|
||||
// TODO handle default mapping
|
||||
// output_box_imp.resetVolumePercentage.set_text();
|
||||
// output_box_imp.resetVolumeSlider.let
|
||||
for stream in sinks {
|
||||
let entry = ListEntry::new(&AudioSourceEntry::new(
|
||||
stream.name,
|
||||
stream.volume,
|
||||
stream.muted,
|
||||
stream.index,
|
||||
));
|
||||
// TODO create sink handler -> currently only allows input streams
|
||||
let entry = ListEntry::new(&SinkEntry::new(stream));
|
||||
entry.set_activatable(false);
|
||||
output_box_imp.resetSinks.append(&entry);
|
||||
}
|
||||
|
@ -87,14 +84,9 @@ pub fn populate_streams(listeners: Arc<Listeners>, output_box: Arc<AudioBox>) {
|
|||
glib::idle_add_once(move || {
|
||||
let output_box_imp = output_box_ref.imp();
|
||||
for stream in streams {
|
||||
let entry = ListEntry::new(&AudioSourceEntry::new(
|
||||
stream.name,
|
||||
stream.volume,
|
||||
stream.muted,
|
||||
stream.index,
|
||||
));
|
||||
let entry = ListEntry::new(&InputStreamEntry::new(stream));
|
||||
entry.set_activatable(false);
|
||||
output_box_imp.resetOutputStreams.append(&entry);
|
||||
output_box_imp.resetInputStreams.append(&entry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,20 +3,22 @@ use std::sync::{Arc, Mutex};
|
|||
|
||||
use crate::components::base::listEntry::ListEntry;
|
||||
use crate::components::output::audioBox;
|
||||
use crate::components::output::audioSource::AudioSourceEntry;
|
||||
use crate::components::output::inputStreamEntry::InputStreamEntry;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::{glib, Box, Button, CompositeTemplate, DropDown, Label, TemplateChild};
|
||||
use gtk::{prelude::*, ProgressBar, Scale};
|
||||
use ReSet_Lib::audio::audio::{InputStream, Sink};
|
||||
|
||||
use super::sinkEntry::SinkEntry;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Default, CompositeTemplate)]
|
||||
#[template(resource = "/org/Xetibo/ReSet/resetAudio.ui")]
|
||||
#[template(resource = "/org/Xetibo/ReSet/resetAudioOutput.ui")]
|
||||
pub struct AudioBox {
|
||||
#[template_child]
|
||||
pub resetSinksRow: TemplateChild<ListEntry>,
|
||||
#[template_child]
|
||||
pub resetOutputDevice: TemplateChild<DropDown>,
|
||||
pub resetInputDevice: TemplateChild<DropDown>,
|
||||
#[template_child]
|
||||
pub resetSinkMute: TemplateChild<Button>,
|
||||
#[template_child]
|
||||
|
@ -28,9 +30,9 @@ pub struct AudioBox {
|
|||
#[template_child]
|
||||
pub resetSinks: TemplateChild<Box>,
|
||||
#[template_child]
|
||||
pub resetOutputStreamButton: TemplateChild<ListEntry>,
|
||||
pub resetInputStreamButton: TemplateChild<ListEntry>,
|
||||
#[template_child]
|
||||
pub resetOutputStreams: TemplateChild<Box>,
|
||||
pub resetInputStreams: TemplateChild<Box>,
|
||||
pub resetDefaultSink: RefCell<Option<Sink>>,
|
||||
pub resetSinkList: Arc<Mutex<Vec<Sink>>>,
|
||||
pub resetInputStreamList: Arc<Mutex<Vec<InputStream>>>,
|
||||
|
@ -38,12 +40,13 @@ pub struct AudioBox {
|
|||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for AudioBox {
|
||||
const NAME: &'static str = "resetAudio";
|
||||
const NAME: &'static str = "resetAudioOutput";
|
||||
type Type = audioBox::AudioBox;
|
||||
type ParentType = gtk::Box;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
AudioSourceEntry::ensure_type();
|
||||
InputStreamEntry::ensure_type();
|
||||
SinkEntry::ensure_type();
|
||||
ListEntry::ensure_type();
|
||||
klass.bind_template();
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
use crate::components::output::audioSourceImpl;
|
||||
use adw::glib;
|
||||
use adw::glib::Object;
|
||||
use glib::subclass::types::ObjectSubclassIsExt;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AudioSourceEntry(ObjectSubclass<audioSourceImpl::AudioSourceEntry>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||
}
|
||||
|
||||
impl AudioSourceEntry {
|
||||
pub fn new(name: String, volume: Vec<u32>, muted: bool, index: u32) -> 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.associatedIndex.set(index);
|
||||
imp.isMuted.set(muted);
|
||||
let mut volume_borrow = imp.volume.borrow_mut();
|
||||
*volume_borrow = volume;
|
||||
imp.resetSourceName.set_text(name.as_str());
|
||||
let fraction = (volume_borrow.first().unwrap_or_else(|| &(0 as u32)) / 100) as f64;
|
||||
imp.resetVolumeMeter.set_fraction(fraction);
|
||||
let percentage = (fraction * 100 as f64).to_string();
|
||||
imp.resetVolumePercentage.set_text(&percentage);
|
||||
}
|
||||
obj
|
||||
}
|
||||
}
|
72
src/components/output/inputStreamEntry.rs
Normal file
72
src/components/output/inputStreamEntry.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use adw::glib;
|
||||
use adw::glib::Object;
|
||||
use adw::prelude::RangeExt;
|
||||
use dbus::blocking::Connection;
|
||||
use dbus::Error;
|
||||
use glib::subclass::types::ObjectSubclassIsExt;
|
||||
use glib::{clone, Propagation};
|
||||
use ReSet_Lib::audio::audio::InputStream;
|
||||
|
||||
use super::inputStreamEntryImpl;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct InputStreamEntry(ObjectSubclass<inputStreamEntryImpl::InputStreamEntry>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||
}
|
||||
|
||||
impl InputStreamEntry {
|
||||
pub fn new(stream: InputStream) -> 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 volume = stream.volume.first().unwrap_or_else(|| &(0 as u32));
|
||||
let fraction = (*volume as f64 / 655.36).round();
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
imp.resetVolumePercentage.set_text(&percentage);
|
||||
imp.resetVolumeSlider.set_value(*volume as f64);
|
||||
imp.stream.replace(stream);
|
||||
imp.resetVolumeSlider.connect_change_value(
|
||||
clone!(@weak imp => @default-return Propagation::Stop, move |_, _, value| {
|
||||
let fraction = (value / 655.36).round();
|
||||
println!("{fraction}");
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
imp.resetVolumePercentage.set_text(&percentage);
|
||||
set_inputstream_volume(value, imp.stream.clone());
|
||||
Propagation::Proceed
|
||||
}),
|
||||
);
|
||||
}
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
||||
fn set_inputstream_volume(value: f64, stream: Arc<RefCell<InputStream>>) -> bool {
|
||||
let mut stream = stream.borrow_mut().clone();
|
||||
// let x = stream.volume.iter_mut().map(|_| value as u32);
|
||||
stream.volume = vec![value as u32; stream.channels as usize];
|
||||
dbg!(stream.volume.clone());
|
||||
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.xetibo.ReSet",
|
||||
"/org/xetibo/ReSet",
|
||||
Duration::from_millis(100),
|
||||
);
|
||||
let res: Result<(bool,), Error> =
|
||||
proxy.method_call("org.xetibo.ReSet", "SetInputStreamVolume", (stream,));
|
||||
if res.is_err() {
|
||||
return false;
|
||||
}
|
||||
res.unwrap().0
|
||||
}
|
|
@ -1,34 +1,35 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::components::output::audioSource;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::{glib, Button, CompositeTemplate, DropDown, Label, ProgressBar, Scale};
|
||||
use ReSet_Lib::audio::audio::InputStream;
|
||||
|
||||
use super::inputStreamEntry;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Default, CompositeTemplate)]
|
||||
#[template(resource = "/org/Xetibo/ReSet/resetOutputStreamEntry.ui")]
|
||||
pub struct AudioSourceEntry {
|
||||
#[template(resource = "/org/Xetibo/ReSet/resetInputStreamEntry.ui")]
|
||||
pub struct InputStreamEntry {
|
||||
#[template_child]
|
||||
pub resetSourceName: TemplateChild<Label>,
|
||||
pub resetSinkName: TemplateChild<Label>,
|
||||
#[template_child]
|
||||
pub resetSelectedSink: TemplateChild<DropDown>,
|
||||
#[template_child]
|
||||
pub resetSourceMute: TemplateChild<Button>,
|
||||
pub resetSinkMute: TemplateChild<Button>,
|
||||
#[template_child]
|
||||
pub resetVolumeSlider: TemplateChild<Scale>,
|
||||
#[template_child]
|
||||
pub resetVolumePercentage: TemplateChild<Label>,
|
||||
#[template_child]
|
||||
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
||||
pub associatedIndex: Cell<u32>,
|
||||
pub isMuted: Cell<bool>,
|
||||
pub volume: RefCell<Vec<u32>>,
|
||||
pub stream: Arc<RefCell<InputStream>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for AudioSourceEntry {
|
||||
const NAME: &'static str = "resetOutputStreamEntry";
|
||||
type Type = audioSource::AudioSourceEntry;
|
||||
impl ObjectSubclass for InputStreamEntry {
|
||||
const NAME: &'static str = "resetInputStreamEntry";
|
||||
type Type = inputStreamEntry::InputStreamEntry;
|
||||
type ParentType = gtk::Box;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
|
@ -40,8 +41,8 @@ impl ObjectSubclass for AudioSourceEntry {
|
|||
}
|
||||
}
|
||||
|
||||
impl BoxImpl for AudioSourceEntry {}
|
||||
impl BoxImpl for InputStreamEntry {}
|
||||
|
||||
impl ObjectImpl for AudioSourceEntry {}
|
||||
impl ObjectImpl for InputStreamEntry {}
|
||||
|
||||
impl WidgetImpl for AudioSourceEntry {}
|
||||
impl WidgetImpl for InputStreamEntry {}
|
|
@ -1,5 +1,7 @@
|
|||
#![allow(non_snake_case)]
|
||||
pub mod audioSource;
|
||||
pub mod audioBox;
|
||||
pub mod audioBoxImpl;
|
||||
pub mod audioSourceImpl;
|
||||
pub mod inputStreamEntry;
|
||||
pub mod inputStreamEntryImpl;
|
||||
pub mod sinkEntry;
|
||||
pub mod sinkEntryImpl;
|
||||
|
|
72
src/components/output/sinkEntry.rs
Normal file
72
src/components/output/sinkEntry.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use adw::glib;
|
||||
use adw::glib::Object;
|
||||
use adw::prelude::RangeExt;
|
||||
use dbus::blocking::Connection;
|
||||
use dbus::Error;
|
||||
use glib::subclass::types::ObjectSubclassIsExt;
|
||||
use glib::{clone, Propagation};
|
||||
use ReSet_Lib::audio::audio::Sink;
|
||||
|
||||
use super::sinkEntryImpl;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct SinkEntry(ObjectSubclass<sinkEntryImpl::SinkEntry>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||
}
|
||||
|
||||
impl SinkEntry {
|
||||
pub fn new(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 volume = stream.volume.first().unwrap_or_else(|| &(0 as u32));
|
||||
let fraction = (*volume as f64 / 655.36).round();
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
imp.resetVolumePercentage.set_text(&percentage);
|
||||
imp.resetVolumeSlider.set_value(*volume as f64);
|
||||
imp.stream.replace(stream);
|
||||
imp.resetVolumeSlider.connect_change_value(
|
||||
clone!(@weak imp => @default-return Propagation::Stop, move |_, _, value| {
|
||||
let fraction = (value / 655.36).round();
|
||||
println!("{fraction}");
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
imp.resetVolumePercentage.set_text(&percentage);
|
||||
set_inputstream_volume(value, imp.stream.clone());
|
||||
Propagation::Proceed
|
||||
}),
|
||||
);
|
||||
}
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
||||
fn set_inputstream_volume(value: f64, stream: Arc<RefCell<Sink>>) -> bool {
|
||||
let mut stream = stream.borrow_mut().clone();
|
||||
// let x = stream.volume.iter_mut().map(|_| value as u32);
|
||||
stream.volume = vec![value as u32; stream.channels as usize];
|
||||
dbg!(stream.volume.clone());
|
||||
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.xetibo.ReSet",
|
||||
"/org/xetibo/ReSet",
|
||||
Duration::from_millis(100),
|
||||
);
|
||||
let res: Result<(bool,), Error> =
|
||||
proxy.method_call("org.xetibo.ReSet", "SetSinkVolume", (stream,));
|
||||
if res.is_err() {
|
||||
return false;
|
||||
}
|
||||
res.unwrap().0
|
||||
}
|
47
src/components/output/sinkEntryImpl.rs
Normal file
47
src/components/output/sinkEntryImpl.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::components::output::sinkEntry;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::{glib, Button, CompositeTemplate, DropDown, Label, ProgressBar, Scale, CheckButton};
|
||||
use ReSet_Lib::audio::audio::Sink;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Default, CompositeTemplate)]
|
||||
#[template(resource = "/org/Xetibo/ReSet/resetSinkEntry.ui")]
|
||||
pub struct SinkEntry {
|
||||
#[template_child]
|
||||
pub resetSinkName: TemplateChild<Label>,
|
||||
#[template_child]
|
||||
pub resetSelectedSink: TemplateChild<CheckButton>,
|
||||
#[template_child]
|
||||
pub resetSinkMute: TemplateChild<Button>,
|
||||
#[template_child]
|
||||
pub resetVolumeSlider: TemplateChild<Scale>,
|
||||
#[template_child]
|
||||
pub resetVolumePercentage: TemplateChild<Label>,
|
||||
#[template_child]
|
||||
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
||||
pub stream: Arc<RefCell<Sink>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for SinkEntry {
|
||||
const NAME: &'static str = "resetSinkEntry";
|
||||
type Type = sinkEntry::SinkEntry;
|
||||
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 SinkEntry {}
|
||||
|
||||
impl ObjectImpl for SinkEntry {}
|
||||
|
||||
impl WidgetImpl for SinkEntry {}
|
Loading…
Add table
Add a link
Reference in a new issue