This commit is contained in:
Julian Ospald 2017-07-06 00:14:24 +02:00
parent 973e6a0257
commit e70e88690b
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28
5 changed files with 109 additions and 80 deletions

View File

@ -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<Prefs>,
}
@ -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),
};

View File

@ -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);
},
})
}

View File

@ -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();

View File

@ -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<String>,
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?
}

View File

@ -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<VolMeter>,
pub audio_pix: RefCell<AudioPix>,
pub status_icon: gtk::StatusIcon,
pub icon_size: Cell<i64>,
pub icon_size: Cell<i32>,
}
impl TrayIcon {
// TODO: take settings as parameter
pub fn new() -> Result<TrayIcon> {
let volmeter = VolMeter::new();
let audio_pix = AudioPix::new_from_pnmixer()?;
pub fn new(prefs: &Prefs) -> Result<TrayIcon> {
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<i64>) {
fn update(&self,
prefs: &Prefs,
audio: &Audio,
m_size: Option<i32>)
-> 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<AudioPix> {
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<AudioPix> {
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<AudioPix> {
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<AppS>) {
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<AppS>) {
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<AppS>) {
{
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 => {