music.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use std::path::Path;
  2. use std::thread;
  3. use mpd;
  4. use mpd::idle;
  5. use mpd::idle::Idle;
  6. use mpd::song::Song;
  7. use mpd::status::State;
  8. use style;
  9. use ui::context::Context;
  10. use widgets::{Message, MessageSender, Update, Widget, WidgetParams};
  11. const WIDTH: u16 = 250;
  12. pub struct Mpd {
  13. context: Context,
  14. tx: MessageSender,
  15. state: State,
  16. song: Option<Song>
  17. }
  18. pub fn mpd(params: WidgetParams) -> Box<Widget> {
  19. let widget = Mpd {
  20. context: params.context,
  21. tx: params.tx,
  22. state: State::Stop,
  23. song: None
  24. };
  25. Box::new(widget)
  26. }
  27. impl Mpd {
  28. fn icon(&self) -> &'static str {
  29. match self.state {
  30. State::Play => "",
  31. State::Pause => "",
  32. State::Stop => ""
  33. }
  34. }
  35. fn get_text(&self) -> String {
  36. match self.song {
  37. Some(ref song) => match (&song.title, &song.tags.get("Artist")) {
  38. (&Some(ref title), &Some(ref artist)) => format!("{} - {}", artist, title),
  39. (&Some(ref title), &None) => title.to_string(),
  40. _ => {
  41. let path = Path::new(&song.file);
  42. let path = path.file_name().and_then(|s| s.to_str());
  43. path.unwrap_or("Unknown").to_string()
  44. }
  45. },
  46. None => "mpd".to_string()
  47. }
  48. }
  49. }
  50. impl Widget for Mpd {
  51. fn init(&mut self) {
  52. let tx = self.tx.clone();
  53. thread::spawn(move || monitor_thread(tx));
  54. }
  55. fn render(&mut self, x: u16, w: u16) {
  56. style::render(&self.context, self.icon(), &self.get_text(), x, w);
  57. }
  58. fn width(&mut self) -> u16 {
  59. WIDTH
  60. }
  61. fn handle_event(&mut self, event: &Message) -> Update {
  62. match event {
  63. &Message::MpdEvent(ref state, ref song) => {
  64. self.state = state.clone();
  65. self.song = song.clone();
  66. Update::Rerender
  67. },
  68. &Message::MousePress(_x) => {
  69. toggle();
  70. Update::Nothing
  71. },
  72. _ => Update::Nothing
  73. }
  74. }
  75. }
  76. fn monitor_thread(tx: MessageSender) {
  77. let mut conn = mpd::client::Client::connect("127.0.0.1:6600").unwrap();
  78. loop {
  79. match (conn.status(), conn.currentsong()) {
  80. (Ok(status), Ok(song)) => {
  81. let state = status.state;
  82. let event = Message::MpdEvent(state, song);
  83. tx.send(event).expect("Failed to send mpd event");
  84. },
  85. _ => {}
  86. }
  87. conn.wait(&[idle::Subsystem::Player]).ok();
  88. }
  89. }
  90. fn toggle() {
  91. let mut conn = mpd::client::Client::connect("127.0.0.1:6600").unwrap();
  92. conn.toggle_pause().expect("Failed to pause");
  93. }