2017-07-01 22:03:21 +00:00
|
|
|
use audio::Audio;
|
2017-07-06 22:28:55 +00:00
|
|
|
use gdk;
|
2017-07-05 22:14:24 +00:00
|
|
|
use gtk;
|
2017-07-06 22:28:55 +00:00
|
|
|
use gtk::ComboBoxTextExt;
|
|
|
|
use gtk::ComboBoxExt;
|
|
|
|
use gtk::ToggleButtonExt;
|
|
|
|
use gtk::SpinButtonExt;
|
|
|
|
use gtk::ColorChooserExt;
|
|
|
|
use gtk::EntryExt;
|
|
|
|
use prefs::*;
|
2017-07-04 19:15:11 +00:00
|
|
|
use ui_tray_icon::TrayIcon;
|
2017-07-05 22:14:24 +00:00
|
|
|
use std::cell::RefCell;
|
2017-07-02 16:11:56 +00:00
|
|
|
|
2017-06-27 22:23:12 +00:00
|
|
|
|
2017-06-28 15:53:19 +00:00
|
|
|
|
2017-06-30 15:24:26 +00:00
|
|
|
// TODO: destructors
|
2017-06-29 12:55:07 +00:00
|
|
|
|
2017-06-29 13:50:24 +00:00
|
|
|
// TODO: glade stuff, config, alsacard
|
2017-06-27 22:23:12 +00:00
|
|
|
pub struct AppS {
|
2017-06-30 15:24:26 +00:00
|
|
|
pub gui: Gui,
|
2017-07-01 22:03:21 +00:00
|
|
|
pub audio: Audio,
|
2017-07-05 22:14:24 +00:00
|
|
|
pub prefs: RefCell<Prefs>,
|
2017-06-30 15:24:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl AppS {
|
|
|
|
pub fn new() -> AppS {
|
2017-07-06 22:28:55 +00:00
|
|
|
let builder_popup_window =
|
|
|
|
gtk::Builder::new_from_string(include_str!("../data/ui/popup-window.glade"));
|
|
|
|
let builder_popup_menu = gtk::Builder::new_from_string(include_str!("../data/ui/popup-menu.glade"));
|
2017-07-05 22:14:24 +00:00
|
|
|
let prefs = RefCell::new(Prefs::new().unwrap());
|
|
|
|
let gui =
|
|
|
|
Gui::new(builder_popup_window, builder_popup_menu, &prefs.borrow());
|
2017-07-02 17:08:17 +00:00
|
|
|
|
2017-06-30 15:24:26 +00:00
|
|
|
return AppS {
|
2017-07-06 22:28:55 +00:00
|
|
|
gui: gui,
|
|
|
|
audio: Audio::new(None, Some(String::from("Master")))
|
|
|
|
.unwrap(),
|
|
|
|
prefs: prefs,
|
|
|
|
};
|
2017-06-30 15:24:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct Gui {
|
2017-07-04 19:15:11 +00:00
|
|
|
pub tray_icon: TrayIcon,
|
2017-06-30 15:24:26 +00:00
|
|
|
pub popup_window: PopupWindow,
|
2017-07-06 14:53:19 +00:00
|
|
|
pub popup_menu: PopupMenu,
|
2017-07-06 22:28:55 +00:00
|
|
|
/* prefs_dialog is dynamically created and destroyed */
|
2017-07-06 14:53:19 +00:00
|
|
|
pub prefs_dialog: RefCell<Option<PrefsDialog>>,
|
2017-06-30 15:24:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Gui {
|
2017-07-06 22:28:55 +00:00
|
|
|
pub fn new(builder_popup_window: gtk::Builder,
|
|
|
|
builder_popup_menu: gtk::Builder,
|
|
|
|
prefs: &Prefs)
|
|
|
|
-> Gui {
|
2017-06-30 15:24:26 +00:00
|
|
|
return Gui {
|
2017-07-06 22:28:55 +00:00
|
|
|
tray_icon: TrayIcon::new(prefs).unwrap(),
|
|
|
|
popup_window: PopupWindow::new(builder_popup_window),
|
|
|
|
popup_menu: PopupMenu::new(builder_popup_menu),
|
|
|
|
prefs_dialog: RefCell::new(None),
|
|
|
|
};
|
2017-06-30 15:24:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-06 22:28:55 +00:00
|
|
|
create_builder_item!(PopupWindow,
|
|
|
|
popup_window: gtk::Window,
|
|
|
|
vol_scale_adj: gtk::Adjustment,
|
|
|
|
vol_scale: gtk::Scale,
|
|
|
|
mute_check: gtk::CheckButton);
|
2017-07-02 16:11:56 +00:00
|
|
|
|
|
|
|
|
2017-07-06 22:28:55 +00:00
|
|
|
create_builder_item!(PopupMenu,
|
|
|
|
menu_window: gtk::Window,
|
|
|
|
menubar: gtk::MenuBar,
|
|
|
|
menu: gtk::Menu,
|
|
|
|
about_item: gtk::MenuItem,
|
|
|
|
prefs_item: gtk::MenuItem);
|
2017-07-06 14:53:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
pub struct PrefsDialog {
|
|
|
|
pub prefs_dialog: gtk::Dialog,
|
2017-07-06 22:28:55 +00:00
|
|
|
|
|
|
|
/* DevicePrefs */
|
2017-07-06 14:53:19 +00:00
|
|
|
pub card_combo: gtk::ComboBoxText,
|
|
|
|
pub chan_combo: gtk::ComboBoxText,
|
2017-07-06 22:28:55 +00:00
|
|
|
|
|
|
|
/* ViewPrefs */
|
|
|
|
pub vol_meter_draw_check: gtk::CheckButton,
|
|
|
|
pub vol_meter_pos_spin: gtk::SpinButton,
|
|
|
|
pub vol_meter_color_button: gtk::ColorButton,
|
|
|
|
pub system_theme: gtk::CheckButton,
|
|
|
|
|
|
|
|
/* BehaviorPrefs */
|
|
|
|
pub vol_control_entry: gtk::Entry,
|
|
|
|
pub scroll_step_spin: gtk::SpinButton,
|
|
|
|
pub middle_click_combo: gtk::ComboBoxText,
|
|
|
|
pub custom_entry: gtk::Entry,
|
|
|
|
|
|
|
|
/* NotifyPrefs */
|
|
|
|
pub noti_enable_check: gtk::CheckButton,
|
|
|
|
pub noti_timeout_spin: gtk::SpinButton,
|
|
|
|
// pub noti_hotkey_check: gtk::CheckButton,
|
|
|
|
pub noti_mouse_check: gtk::CheckButton,
|
|
|
|
pub noti_popup_check: gtk::CheckButton,
|
|
|
|
pub noti_ext_check: gtk::CheckButton,
|
2017-07-06 14:53:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl PrefsDialog {
|
2017-07-06 22:28:55 +00:00
|
|
|
pub fn new() -> PrefsDialog {
|
|
|
|
let builder = gtk::Builder::new_from_string(include_str!("../data/ui/prefs-dialog.glade"));
|
|
|
|
let prefs_dialog = PrefsDialog {
|
2017-07-06 14:53:19 +00:00
|
|
|
prefs_dialog: builder.get_object("prefs_dialog").unwrap(),
|
2017-07-06 22:28:55 +00:00
|
|
|
|
2017-07-06 14:53:19 +00:00
|
|
|
card_combo: builder.get_object("card_combo").unwrap(),
|
|
|
|
chan_combo: builder.get_object("chan_combo").unwrap(),
|
2017-07-06 22:28:55 +00:00
|
|
|
|
|
|
|
vol_meter_draw_check: builder.get_object("vol_meter_draw_check")
|
|
|
|
.unwrap(),
|
|
|
|
vol_meter_pos_spin: builder.get_object("vol_meter_pos_spin")
|
|
|
|
.unwrap(),
|
|
|
|
vol_meter_color_button: builder.get_object("vol_meter_color_button")
|
|
|
|
.unwrap(),
|
|
|
|
system_theme: builder.get_object("system_theme").unwrap(),
|
|
|
|
|
|
|
|
vol_control_entry: builder.get_object("vol_control_entry").unwrap(),
|
|
|
|
scroll_step_spin: builder.get_object("scroll_step_spin").unwrap(),
|
|
|
|
middle_click_combo: builder.get_object("middle_click_combo")
|
|
|
|
.unwrap(),
|
|
|
|
custom_entry: builder.get_object("custom_entry").unwrap(),
|
|
|
|
|
|
|
|
noti_enable_check: builder.get_object("noti_enable_check").unwrap(),
|
|
|
|
noti_timeout_spin: builder.get_object("noti_timeout_spin").unwrap(),
|
|
|
|
// noti_hotkey_check: builder.get_object("noti_hotkey_check").unwrap(),
|
|
|
|
noti_mouse_check: builder.get_object("noti_mouse_check").unwrap(),
|
|
|
|
noti_popup_check: builder.get_object("noti_popup_check").unwrap(),
|
|
|
|
noti_ext_check: builder.get_object("noti_ext_check").unwrap(),
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return prefs_dialog;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn from_prefs(&self, prefs: &Prefs) {
|
|
|
|
/* DevicePrefs */
|
|
|
|
self.card_combo.remove_all();
|
|
|
|
self.card_combo.append_text(prefs.device_prefs.card.as_str());
|
|
|
|
self.card_combo.set_active(0);
|
|
|
|
|
|
|
|
self.chan_combo.remove_all();
|
|
|
|
self.chan_combo.append_text(prefs.device_prefs.channel.as_str());
|
|
|
|
self.chan_combo.set_active(0);
|
|
|
|
|
|
|
|
/* ViewPrefs */
|
|
|
|
self.vol_meter_draw_check.set_active(prefs.view_prefs.draw_vol_meter);
|
|
|
|
self.vol_meter_pos_spin.set_value(prefs.view_prefs.vol_meter_offset as
|
|
|
|
f64);
|
|
|
|
|
|
|
|
// TODO don't convert like that
|
|
|
|
let rgba = gdk::RGBA {
|
|
|
|
red: prefs.view_prefs.vol_meter_color.red as f64 / 255.0,
|
|
|
|
green: prefs.view_prefs.vol_meter_color.green as f64 / 255.0,
|
|
|
|
blue: prefs.view_prefs.vol_meter_color.blue as f64 / 255.0,
|
|
|
|
alpha: 1.0,
|
2017-07-06 14:53:19 +00:00
|
|
|
};
|
2017-07-06 22:28:55 +00:00
|
|
|
self.vol_meter_color_button.set_rgba(&rgba);
|
|
|
|
self.system_theme.set_active(prefs.view_prefs.system_theme);
|
|
|
|
|
|
|
|
/* BehaviorPrefs */
|
|
|
|
self.vol_control_entry.set_text(prefs.behavior_prefs
|
|
|
|
.vol_control_cmd
|
|
|
|
.as_ref()
|
|
|
|
.unwrap_or(&String::from(""))
|
|
|
|
.as_str());
|
|
|
|
self.scroll_step_spin.set_value(prefs.behavior_prefs.vol_scroll_step);
|
|
|
|
|
|
|
|
// TODO: make sure these values always match, must be a better way
|
|
|
|
// also check to_prefs()
|
|
|
|
self.middle_click_combo.append_text("Toggle Mute");
|
|
|
|
self.middle_click_combo.append_text("Show Preferences");
|
|
|
|
self.middle_click_combo.append_text("Volume Control");
|
|
|
|
self.middle_click_combo.append_text("Custom Command");
|
|
|
|
self.middle_click_combo.set_active(prefs.behavior_prefs
|
|
|
|
.middle_click_action
|
|
|
|
.into());
|
|
|
|
self.custom_entry.set_text(prefs.behavior_prefs
|
|
|
|
.custom_command
|
|
|
|
.as_ref()
|
|
|
|
.unwrap_or(&String::from(""))
|
|
|
|
.as_str());
|
|
|
|
|
|
|
|
/* NotifyPrefs */
|
|
|
|
self.noti_enable_check
|
|
|
|
.set_active(prefs.notify_prefs.enable_notifications);
|
|
|
|
self.noti_timeout_spin
|
|
|
|
.set_value(prefs.notify_prefs.notifcation_timeout as f64);
|
|
|
|
self.noti_mouse_check
|
|
|
|
.set_active(prefs.notify_prefs.notify_mouse_scroll);
|
|
|
|
self.noti_popup_check.set_active(prefs.notify_prefs.notify_popup);
|
|
|
|
self.noti_ext_check.set_active(prefs.notify_prefs.notify_external);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn to_prefs(&self) -> Prefs {
|
|
|
|
// TODO: remove duplication with default instance
|
|
|
|
let device_prefs =
|
|
|
|
DevicePrefs {
|
|
|
|
card: self.card_combo
|
|
|
|
.get_active_text()
|
|
|
|
.unwrap_or(String::from("(default)")),
|
|
|
|
channel: self.chan_combo
|
|
|
|
.get_active_text()
|
|
|
|
.unwrap_or(String::from("Master")),
|
|
|
|
};
|
|
|
|
|
|
|
|
// TODO don't convert like that
|
|
|
|
let vol_meter_color = VolColor {
|
|
|
|
red: (self.vol_meter_color_button.get_rgba().red * 255.0) as u8,
|
|
|
|
green: (self.vol_meter_color_button.get_rgba().green * 255.0) as u8,
|
|
|
|
blue: (self.vol_meter_color_button.get_rgba().blue * 255.0) as u8,
|
|
|
|
};
|
|
|
|
|
|
|
|
let view_prefs = ViewPrefs {
|
|
|
|
draw_vol_meter: self.vol_meter_draw_check.get_active(),
|
|
|
|
vol_meter_offset: self.vol_meter_pos_spin.get_value_as_int(),
|
|
|
|
system_theme: self.system_theme.get_active(),
|
|
|
|
vol_meter_color,
|
|
|
|
};
|
|
|
|
|
|
|
|
let vol_control_cmd =
|
|
|
|
self.vol_control_entry.get_text().and_then(|x| if x.is_empty() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(x)
|
|
|
|
});
|
|
|
|
|
|
|
|
let custom_command =
|
|
|
|
self.custom_entry.get_text().and_then(|x| if x.is_empty() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(x)
|
|
|
|
});
|
|
|
|
|
|
|
|
let behavior_prefs = BehaviorPrefs {
|
|
|
|
vol_control_cmd,
|
|
|
|
vol_scroll_step: self.scroll_step_spin.get_value(),
|
|
|
|
middle_click_action: From::from(self.middle_click_combo
|
|
|
|
.get_active()),
|
|
|
|
custom_command,
|
|
|
|
};
|
|
|
|
|
|
|
|
let notify_prefs = NotifyPrefs {
|
|
|
|
enable_notifications: self.noti_enable_check.get_active(),
|
|
|
|
notifcation_timeout: self.noti_timeout_spin.get_value_as_int() as
|
|
|
|
i64,
|
|
|
|
notify_mouse_scroll: self.noti_mouse_check.get_active(),
|
|
|
|
notify_popup: self.noti_popup_check.get_active(),
|
|
|
|
notify_external: self.noti_ext_check.get_active(),
|
|
|
|
};
|
|
|
|
|
|
|
|
return Prefs {
|
|
|
|
device_prefs,
|
|
|
|
view_prefs,
|
|
|
|
behavior_prefs,
|
|
|
|
notify_prefs,
|
|
|
|
};
|
|
|
|
|
2017-07-06 14:53:19 +00:00
|
|
|
}
|
|
|
|
}
|