From e70e88690b21c6c2aabc950b5fcabc8c9670760c Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Thu, 6 Jul 2017 00:14:24 +0200 Subject: [PATCH] Update --- src/app_state.rs | 16 +++-- src/errors.rs | 16 ++--- src/main.rs | 7 --- src/prefs.rs | 10 ++-- src/ui_tray_icon.rs | 140 ++++++++++++++++++++++++++------------------ 5 files changed, 109 insertions(+), 80 deletions(-) diff --git a/src/app_state.rs b/src/app_state.rs index ca5d03b21..0fa146f71 100644 --- a/src/app_state.rs +++ b/src/app_state.rs @@ -1,6 +1,8 @@ -use gtk; use audio::Audio; +use gtk; +use prefs::Prefs; use ui_tray_icon::TrayIcon; +use std::cell::RefCell; @@ -10,6 +12,7 @@ use ui_tray_icon::TrayIcon; pub struct AppS { pub gui: Gui, pub audio: Audio, + pub prefs: RefCell, } @@ -18,11 +21,15 @@ impl AppS { 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")); + let prefs = RefCell::new(Prefs::new().unwrap()); + let gui = + Gui::new(builder_popup_window, builder_popup_menu, &prefs.borrow()); return AppS { - gui: Gui::new(builder_popup_window, builder_popup_menu), + gui: gui, audio: Audio::new(None, Some(String::from("Master"))) .unwrap(), + prefs: prefs, }; } } @@ -38,10 +45,11 @@ pub struct Gui { impl Gui { pub fn new(builder_popup_window: gtk::Builder, - builder_popup_menu: gtk::Builder) + builder_popup_menu: gtk::Builder, + prefs: &Prefs) -> Gui { return Gui { - tray_icon: TrayIcon::new().unwrap(), + tray_icon: TrayIcon::new(prefs).unwrap(), popup_window: PopupWindow::new(builder_popup_window), popup_menu: PopupMenu::new(builder_popup_menu), }; diff --git a/src/errors.rs b/src/errors.rs index aa325a462..c5c21d48a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -89,24 +89,24 @@ macro_rules! try_er { ($expr:expr, $ret:expr) => (match $expr { ::std::result::Result::Ok(val) => val, ::std::result::Result::Err(err) => { - err!("{:?}", err); - return $ret; + error!("{:?}", err); + ::std::process::exit(1); }, }); ($expr:expr, $ret:expr, $fmt:expr) => (match $expr { ::std::result::Result::Ok(val) => val, ::std::result::Result::Err(err) => { - err!("Original error: {:?}", err); - err!($fmt); - return $ret; + error!("Original error: {:?}", err); + error!($fmt); + std::process::exit(1); }, }); ($expr:expr, $ret:expr, $fmt:expr, $($arg:tt)+) => (match $expr { ::std::result::Result::Ok(val) => val, ::std::result::Result::Err(err) => { - err!("Original error: {:?}", err); - err!(format!($fmt, $(arg)+)); - return $ret; + error!("Original error: {:?}", err); + error!(format!($fmt, $(arg)+)); + std::process::exit(1); }, }) } diff --git a/src/main.rs b/src/main.rs index c9812daec..ccb88bfd2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,7 +50,6 @@ mod support_ui; mod support_alsa; use app_state::*; -use prefs::*; @@ -65,12 +64,6 @@ fn main() { let apps = Rc::new(AppS::new()); - let mut prefs = prefs::Prefs::new().unwrap(); - println!("Channel: {}", prefs.to_str()); - prefs.store_config(); - - println!("Control_cmd: {:?}", prefs.get_avail_vol_control_cmd()); - ui_entry::init(apps); gtk::main(); diff --git a/src/prefs.rs b/src/prefs.rs index 0638e5b33..00cf8b780 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -36,7 +36,7 @@ impl Default for MiddleClickAction { #[serde(default)] pub struct DevicePrefs { pub card: String, - pub channel: String, + pub channel: String, // TODO: normalize volume? } @@ -56,7 +56,7 @@ pub struct ViewPrefs { pub draw_vol_meter: bool, pub vol_meter_offset: i64, pub system_theme: bool, - pub vol_meter_color: VolColor, + pub vol_meter_color: VolColor, // TODO: Display text folume/text volume pos? } @@ -96,7 +96,7 @@ impl Default for VolColor { pub struct BehaviorPrefs { pub vol_control_cmd: Option, pub vol_scroll_step: f64, - pub middle_click_action: MiddleClickAction, + pub middle_click_action: MiddleClickAction, // TODO: fine scroll step? } @@ -118,7 +118,7 @@ pub struct NotifyPrefs { pub notifcation_timeout: i64, pub notify_mouse_scroll: bool, pub notify_popup: bool, - pub notify_external: bool, + pub notify_external: bool, // TODO: notify_hotkeys? } @@ -141,7 +141,7 @@ pub struct Prefs { pub device_prefs: DevicePrefs, pub view_prefs: ViewPrefs, pub behavior_prefs: BehaviorPrefs, - pub notify_prefs: NotifyPrefs, + pub notify_prefs: NotifyPrefs, // TODO: HotKeys? } diff --git a/src/ui_tray_icon.rs b/src/ui_tray_icon.rs index 613a88133..81aab6b13 100644 --- a/src/ui_tray_icon.rs +++ b/src/ui_tray_icon.rs @@ -6,6 +6,7 @@ use gdk_pixbuf; use gdk_pixbuf_sys::GDK_COLORSPACE_RGB; use gtk::prelude::*; use gtk; +use prefs::Prefs; use std::cell::Cell; use std::cell::RefCell; use std::rc::Rc; @@ -15,50 +16,74 @@ use support_ui::*; // TODO: on_apply -const ICON_MIN_SIZE: i64 = 16; +const ICON_MIN_SIZE: i32 = 16; pub struct TrayIcon { - pub volmeter: VolMeter, - pub audio_pix: AudioPix, + pub volmeter: Option, + pub audio_pix: RefCell, pub status_icon: gtk::StatusIcon, - pub icon_size: Cell, + pub icon_size: Cell, } impl TrayIcon { - // TODO: take settings as parameter - pub fn new() -> Result { - let volmeter = VolMeter::new(); - let audio_pix = AudioPix::new_from_pnmixer()?; + pub fn new(prefs: &Prefs) -> Result { + let draw_vol_meter = prefs.view_prefs.draw_vol_meter; + + let volmeter = { + if draw_vol_meter { + Some(VolMeter::new(prefs)) + } else { + None + } + }; + let audio_pix = AudioPix::new(ICON_MIN_SIZE, prefs)?; let status_icon = gtk::StatusIcon::new(); return Ok(TrayIcon { volmeter, - audio_pix, + audio_pix: RefCell::new(audio_pix), status_icon, icon_size: Cell::new(ICON_MIN_SIZE), }); } - fn update(&self, audio: &Audio, m_size: Option) { + fn update(&self, + prefs: &Prefs, + audio: &Audio, + m_size: Option) + -> Result<()> { match m_size { Some(s) => { if s < ICON_MIN_SIZE { self.icon_size.set(ICON_MIN_SIZE); + } else { self.icon_size.set(s); } + /* if icon size changed, we have to re-init audio pix */ + let pixbuf = AudioPix::new(self.icon_size.get(), &prefs)?; + *self.audio_pix.borrow_mut() = pixbuf; } None => (), } - let cur_vol = try_w!(audio.vol()); - let pixbuf = self.audio_pix.select_pix(audio.vol_level()); - let vol_pix = try_w!(self.volmeter.meter_draw(cur_vol as i64, &pixbuf)); + let cur_vol = audio.vol()?; + let audio_pix = self.audio_pix.borrow(); + let pixbuf = audio_pix.select_pix(audio.vol_level()); - self.status_icon.set_from_pixbuf(Some(&vol_pix)); + let volmeter = &self.volmeter.as_ref(); + match volmeter { + &Some(v) => { + let vol_pix = v.meter_draw(cur_vol as i64, &pixbuf)?; + self.status_icon.set_from_pixbuf(Some(&vol_pix)); + } + &None => self.status_icon.set_from_pixbuf(Some(pixbuf)), + }; + + return Ok(()); } } @@ -77,13 +102,12 @@ pub struct VolMeter { impl VolMeter { - // TODO: take settings - pub fn new() -> VolMeter { + pub fn new(prefs: &Prefs) -> VolMeter { return VolMeter { - red: 245, - green: 121, - blue: 0, - x_offset_pct: 10, + red: prefs.view_prefs.vol_meter_color.red, + green: prefs.view_prefs.vol_meter_color.green, + blue: prefs.view_prefs.vol_meter_color.blue, + x_offset_pct: prefs.view_prefs.vol_meter_offset, y_offset_pct: 10, /* dynamic */ width: Cell::new(0), @@ -182,41 +206,47 @@ pub struct AudioPix { impl AudioPix { - // TODO: take settings - pub fn new_from_theme(size: i32) -> Result { - let theme: gtk::IconTheme = gtk::IconTheme::get_default().ok_or( - "Couldn't get default icon theme", - )?; - let pix = AudioPix { - muted: pixbuf_new_from_theme("audio-volume-muted", size, &theme)?, - low: pixbuf_new_from_theme("audio-volume-low", size, &theme)?, - medium: pixbuf_new_from_theme("audio-volume-medium", size, &theme)?, - high: pixbuf_new_from_theme("audio-volume-high", size, &theme)?, - /* 'audio-volume-off' is not available in every icon set. - * Check freedesktop standard for more info: - * http://standards.freedesktop.org/icon-naming-spec/ - * icon-naming-spec-latest.html - */ - off: pixbuf_new_from_theme("audio-volume-off", size, &theme).or( - pixbuf_new_from_theme("audio-volume-low", size, &theme), - )?, - }; + pub fn new(size: i32, prefs: &Prefs) -> Result { + let system_theme = prefs.view_prefs.system_theme; + let pix = { + if system_theme { + let theme: gtk::IconTheme = gtk::IconTheme::get_default().ok_or( + "Couldn't get default icon theme", + )?; + AudioPix { + muted: pixbuf_new_from_theme("audio-volume-muted", + size, &theme)?, + low: pixbuf_new_from_theme("audio-volume-low", + size, &theme)?, + medium: pixbuf_new_from_theme("audio-volume-medium", + size, &theme)?, + high: pixbuf_new_from_theme("audio-volume-high", + size, &theme)?, + /* 'audio-volume-off' is not available in every icon set. + * Check freedesktop standard for more info: + * http://standards.freedesktop.org/icon-naming-spec/ + * icon-naming-spec-latest.html + */ + off: pixbuf_new_from_theme("audio-volume-off", + size, &theme).or( + pixbuf_new_from_theme("audio-volume-low", + size, &theme), + )?, + } + } else { + AudioPix { + muted: pixbuf_new_from_file("pnmixer-muted.png")?, + low: pixbuf_new_from_file("pnmixer-low.png")?, + medium: pixbuf_new_from_file("pnmixer-medium.png")?, + high: pixbuf_new_from_file("pnmixer-high.png")?, + off: pixbuf_new_from_file("pnmixer-off.png")?, + } + } + }; return Ok(pix); } - pub fn new_from_pnmixer() -> Result { - gtk::IconTheme::get_default().ok_or("Couldn't get default icon theme")?; - let pix = AudioPix { - muted: pixbuf_new_from_file("pnmixer-muted.png")?, - low: pixbuf_new_from_file("pnmixer-low.png")?, - medium: pixbuf_new_from_file("pnmixer-medium.png")?, - high: pixbuf_new_from_file("pnmixer-high.png")?, - off: pixbuf_new_from_file("pnmixer-off.png")?, - }; - - return Ok(pix); - } pub fn select_pix(&self, vol_level: VolLevel) -> &gdk_pixbuf::Pixbuf { match vol_level { @@ -233,7 +263,7 @@ impl AudioPix { pub fn init_tray_icon(appstate: Rc) { let audio = &appstate.audio; let tray_icon = &appstate.gui.tray_icon; - tray_icon.update(&audio, None); + try_e!(tray_icon.update(&appstate.prefs.borrow_mut(), &audio, None)); tray_icon.status_icon.set_visible(true); @@ -243,7 +273,7 @@ pub fn init_tray_icon(appstate: Rc) { appstate.audio.connect_handler( Box::new(move |s, u| match (s, u) { (AudioSignal::ValuesChanged, _) => { - apps.gui.tray_icon.update(&apps.audio, None); + try_w!(apps.gui.tray_icon.update(&apps.prefs.borrow_mut(), &apps.audio, None)); } _ => (), }), @@ -254,7 +284,7 @@ pub fn init_tray_icon(appstate: Rc) { { let apps = appstate.clone(); tray_icon.status_icon.connect_size_changed(move |_, size| { - apps.gui.tray_icon.update(&apps.audio, Some(size as i64)); + try_wr!(apps.gui.tray_icon.update(&apps.prefs.borrow_mut(), &apps.audio, Some(size)), false); return false; }); } @@ -317,8 +347,6 @@ fn on_tray_icon_scroll_event(appstate: &AppS, event: &gdk::EventScroll) -> bool { - let audio = &appstate.audio; - let scroll_dir: gdk::ScrollDirection = event.get_direction(); match scroll_dir { gdk::ScrollDirection::Up => {