2017-07-14 15:23:42 +00:00
|
|
|
//! Global GUI state.
|
|
|
|
|
|
|
|
|
2017-06-26 07:08:37 +00:00
|
|
|
use app_state::*;
|
2017-07-19 00:51:42 +00:00
|
|
|
use audio_frontend::*;
|
2017-06-26 07:08:37 +00:00
|
|
|
use gtk::DialogExt;
|
|
|
|
use gtk::MessageDialogExt;
|
|
|
|
use gtk::WidgetExt;
|
|
|
|
use gtk::WindowExt;
|
|
|
|
use gtk;
|
|
|
|
use gtk_sys::GTK_RESPONSE_YES;
|
|
|
|
use prefs::*;
|
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::rc::Rc;
|
|
|
|
use support_audio::*;
|
|
|
|
use ui_popup_menu::*;
|
|
|
|
use ui_popup_window::*;
|
|
|
|
use ui_prefs_dialog::*;
|
|
|
|
use ui_tray_icon::*;
|
|
|
|
|
|
|
|
#[cfg(feature = "notify")]
|
|
|
|
use notif::*;
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-07-14 15:23:42 +00:00
|
|
|
/// The GUI struct mostly describing the main widgets (mostly wrapped)
|
|
|
|
/// the user interacts with.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub struct Gui {
|
|
|
|
_cant_construct: (),
|
2017-07-14 15:23:42 +00:00
|
|
|
/// The tray icon.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub tray_icon: TrayIcon,
|
2017-07-14 15:23:42 +00:00
|
|
|
/// The popup window.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub popup_window: PopupWindow,
|
2017-07-14 15:23:42 +00:00
|
|
|
/// The popup menu.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub popup_menu: PopupMenu,
|
|
|
|
/* prefs_dialog is dynamically created and destroyed */
|
2017-07-14 15:23:42 +00:00
|
|
|
/// The preferences dialog.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub prefs_dialog: RefCell<Option<PrefsDialog>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Gui {
|
2017-07-14 15:23:42 +00:00
|
|
|
/// Constructor. The prefs dialog is initialized as `None`.
|
2017-06-26 07:08:37 +00:00
|
|
|
pub fn new(builder_popup_window: gtk::Builder,
|
|
|
|
builder_popup_menu: gtk::Builder,
|
|
|
|
prefs: &Prefs)
|
|
|
|
-> Gui {
|
|
|
|
return Gui {
|
|
|
|
_cant_construct: (),
|
|
|
|
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-07-14 15:23:42 +00:00
|
|
|
/// Initialize the GUI system.
|
2017-07-18 15:20:17 +00:00
|
|
|
pub fn init<T>(appstate: Rc<AppS<T>>)
|
|
|
|
where T: AudioFrontend + 'static
|
|
|
|
{
|
2017-06-26 07:08:37 +00:00
|
|
|
{
|
|
|
|
/* "global" audio signal handler */
|
|
|
|
let apps = appstate.clone();
|
|
|
|
appstate.audio.connect_handler(
|
|
|
|
Box::new(move |s, u| match (s, u) {
|
|
|
|
(AudioSignal::CardDisconnected, _) => {
|
2017-07-18 15:20:17 +00:00
|
|
|
try_w!(audio_reload(apps.audio.as_ref(),
|
2017-06-26 07:08:37 +00:00
|
|
|
&apps.prefs.borrow(),
|
|
|
|
AudioUser::Unknown));
|
|
|
|
},
|
|
|
|
(AudioSignal::CardError, _) => {
|
|
|
|
if run_audio_error_dialog(&apps.gui.popup_menu.menu_window) == (GTK_RESPONSE_YES as i32) {
|
2017-07-18 15:20:17 +00:00
|
|
|
try_w!(audio_reload(apps.audio.as_ref(),
|
2017-06-26 07:08:37 +00:00
|
|
|
&apps.prefs.borrow(),
|
|
|
|
AudioUser::Unknown));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
init_tray_icon(appstate.clone());
|
|
|
|
init_popup_window(appstate.clone());
|
|
|
|
init_popup_menu(appstate.clone());
|
|
|
|
init_prefs_callback(appstate.clone());
|
|
|
|
|
|
|
|
#[cfg(feature = "notify")]
|
|
|
|
init_notify(appstate.clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-14 15:23:42 +00:00
|
|
|
/// Used to run a dialog when an audio error occured, suggesting the user
|
|
|
|
/// may reload the audio system either manually or by confirming the dialog
|
|
|
|
/// via the confirmation button.
|
|
|
|
///
|
|
|
|
/// # Returns
|
|
|
|
///
|
|
|
|
/// `GTK_RESPONSE_YES` if the user wants to reload the audio system,
|
|
|
|
/// `GTK_RESPONSE_NO` otherwise.
|
2017-06-26 07:08:37 +00:00
|
|
|
fn run_audio_error_dialog(parent: >k::Window) -> i32 {
|
|
|
|
error!("Connection with audio failed, you probably need to restart pnmixer.");
|
|
|
|
|
|
|
|
let dialog = gtk::MessageDialog::new(Some(parent),
|
|
|
|
gtk::DIALOG_DESTROY_WITH_PARENT,
|
|
|
|
gtk::MessageType::Error,
|
|
|
|
gtk::ButtonsType::YesNo,
|
|
|
|
"Warning: Connection to sound system failed.");
|
|
|
|
dialog.set_property_secondary_text(Some("Do you want to re-initialize the audio connection ?
|
|
|
|
|
|
|
|
If you do not, you will either need to restart PNMixer
|
|
|
|
or select the 'Reload Audio' option in the right-click
|
|
|
|
menu in order for PNMixer to function."));
|
|
|
|
|
|
|
|
dialog.set_title("PNMixer-rs Error");
|
|
|
|
|
|
|
|
let resp = dialog.run();
|
|
|
|
dialog.destroy();
|
|
|
|
|
|
|
|
return resp;
|
|
|
|
}
|