| 1 |
################################################################################ |
|---|
| 2 |
# Copyright (C) 2006 Travis Shirk <travis@pobox.com> |
|---|
| 3 |
# |
|---|
| 4 |
# This program is free software; you can redistribute it and/or modify |
|---|
| 5 |
# it under the terms of the GNU General Public License as published by |
|---|
| 6 |
# the Free Software Foundation; either version 2 of the License, or |
|---|
| 7 |
# (at your option) any later version. |
|---|
| 8 |
# |
|---|
| 9 |
# This program is distributed in the hope that it will be useful, |
|---|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 |
# GNU General Public License for more details. |
|---|
| 13 |
# |
|---|
| 14 |
# You should have received a copy of the GNU General Public License |
|---|
| 15 |
# along with this program; if not, write to the Free Software |
|---|
| 16 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 17 |
# |
|---|
| 18 |
# $Id$ |
|---|
| 19 |
################################################################################ |
|---|
| 20 |
import gtk |
|---|
| 21 |
import mesk.gtk_utils |
|---|
| 22 |
from mesk.i18n import _ |
|---|
| 23 |
|
|---|
| 24 |
class StatusIcon(object): |
|---|
| 25 |
ICON_IMG = 'data/images/mesk-22.png' |
|---|
| 26 |
|
|---|
| 27 |
def __init__(self, main_window, audio_ctrl): |
|---|
| 28 |
self.main_window = main_window |
|---|
| 29 |
self.audio_ctrl = audio_ctrl |
|---|
| 30 |
self.status_icon = gtk.status_icon_new_from_file(self.ICON_IMG) |
|---|
| 31 |
self.status_icon.connect('activate', self._on_trayicon_activate) |
|---|
| 32 |
self.status_icon.connect('popup-menu', self._on_trayicon_menu) |
|---|
| 33 |
self.status_icon.set_tooltip(None) |
|---|
| 34 |
|
|---|
| 35 |
# Connect to source change signals for updating tooltip |
|---|
| 36 |
audio_ctrl.connect('source-changed', self._on_audio_source_changed) |
|---|
| 37 |
audio_ctrl.connect('tag-update', self._on_audio_source_tag_update) |
|---|
| 38 |
|
|---|
| 39 |
# Right click menu |
|---|
| 40 |
self.status_icon_menu = StatusIconMenu(self.main_window, |
|---|
| 41 |
self.audio_ctrl) |
|---|
| 42 |
|
|---|
| 43 |
self.status_icon.set_visible(True) |
|---|
| 44 |
|
|---|
| 45 |
def _on_trayicon_activate(self, status_icon): |
|---|
| 46 |
if not self.main_window.is_visible(): |
|---|
| 47 |
self.main_window.deiconify() |
|---|
| 48 |
self.main_window.present() |
|---|
| 49 |
else: |
|---|
| 50 |
self.main_window.hide() |
|---|
| 51 |
|
|---|
| 52 |
def _on_trayicon_menu(self, status_icon, button, time): |
|---|
| 53 |
self.status_icon_menu.popup(None, None, gtk.status_icon_position_menu, |
|---|
| 54 |
button, time, status_icon) |
|---|
| 55 |
|
|---|
| 56 |
def _on_audio_source_changed(self, ctrl, old, new): |
|---|
| 57 |
if new is None and new[1]: |
|---|
| 58 |
return |
|---|
| 59 |
src = new[1] |
|---|
| 60 |
self._update_tooltip(src) |
|---|
| 61 |
|
|---|
| 62 |
def _on_audio_source_tag_update(self, ctrl, src): |
|---|
| 63 |
self._update_tooltip(src) |
|---|
| 64 |
|
|---|
| 65 |
def _update_tooltip(self, src): |
|---|
| 66 |
if src is None: |
|---|
| 67 |
self.status_icon.set_tooltip(None) |
|---|
| 68 |
return |
|---|
| 69 |
|
|---|
| 70 |
title = src.meta_data.title |
|---|
| 71 |
artist = src.meta_data.artist |
|---|
| 72 |
album = src.meta_data.album |
|---|
| 73 |
year = src.meta_data.year |
|---|
| 74 |
|
|---|
| 75 |
tooltip = u'' |
|---|
| 76 |
if title: |
|---|
| 77 |
tooltip += title |
|---|
| 78 |
if artist or album: |
|---|
| 79 |
if artist: |
|---|
| 80 |
tooltip += u'\n%s' % artist |
|---|
| 81 |
if album: |
|---|
| 82 |
tooltip += u'\n%s' % album |
|---|
| 83 |
if year: |
|---|
| 84 |
tooltip += ' (%d)' % int(year) |
|---|
| 85 |
|
|---|
| 86 |
self.status_icon.set_tooltip(tooltip) |
|---|
| 87 |
|
|---|
| 88 |
class StatusIconMenu(gtk.Menu): |
|---|
| 89 |
def __init__(self, main_window, audio_ctrl): |
|---|
| 90 |
gtk.Menu.__init__(self) |
|---|
| 91 |
self.main_window = main_window |
|---|
| 92 |
self.audio_ctrl = audio_ctrl |
|---|
| 93 |
|
|---|
| 94 |
play = gtk.ImageMenuItem(stock_id='gtk-media-play', |
|---|
| 95 |
accel_group=None) |
|---|
| 96 |
play.connect('activate', self._on_play) |
|---|
| 97 |
self.add(play) |
|---|
| 98 |
self.play_menuitem = play |
|---|
| 99 |
|
|---|
| 100 |
pause = gtk.ImageMenuItem(stock_id='gtk-media-pause', |
|---|
| 101 |
accel_group=None) |
|---|
| 102 |
pause.connect('activate', self._on_pause) |
|---|
| 103 |
self.add(pause) |
|---|
| 104 |
self.pause_menuitem = pause |
|---|
| 105 |
|
|---|
| 106 |
stop = gtk.ImageMenuItem(stock_id='gtk-media-stop', |
|---|
| 107 |
accel_group=None) |
|---|
| 108 |
stop.connect('activate', self._on_stop) |
|---|
| 109 |
self.add(stop) |
|---|
| 110 |
self.stop_menuitem = stop |
|---|
| 111 |
|
|---|
| 112 |
prev = gtk.ImageMenuItem(stock_id='gtk-media-previous', |
|---|
| 113 |
accel_group=None) |
|---|
| 114 |
prev.connect('activate', self._on_prev) |
|---|
| 115 |
self.add(prev) |
|---|
| 116 |
self.prev_menuitem = prev |
|---|
| 117 |
|
|---|
| 118 |
next = gtk.ImageMenuItem(stock_id='gtk-media-next', accel_group=None) |
|---|
| 119 |
next.connect('activate', self._on_next) |
|---|
| 120 |
self.add(next) |
|---|
| 121 |
self.next_menuitem = next |
|---|
| 122 |
|
|---|
| 123 |
self.add(gtk.SeparatorMenuItem()) |
|---|
| 124 |
|
|---|
| 125 |
quit = gtk.ImageMenuItem(stock_id=gtk.STOCK_QUIT, accel_group=None) |
|---|
| 126 |
quit.connect('activate', self._on_quit) |
|---|
| 127 |
self.add(quit) |
|---|
| 128 |
|
|---|
| 129 |
self.show_all() |
|---|
| 130 |
|
|---|
| 131 |
def popup(self, parent_menu_shell, parent_menu_item, func, button, |
|---|
| 132 |
activate_time, data=None): |
|---|
| 133 |
# Show/hide menuitems based on player state. |
|---|
| 134 |
if self.audio_ctrl.is_stopped(): |
|---|
| 135 |
self.play_menuitem.show() |
|---|
| 136 |
self.pause_menuitem.hide() |
|---|
| 137 |
self.stop_menuitem.hide() |
|---|
| 138 |
self.prev_menuitem.hide() |
|---|
| 139 |
self.next_menuitem.hide() |
|---|
| 140 |
elif self.audio_ctrl.is_paused(): |
|---|
| 141 |
self.play_menuitem.show() |
|---|
| 142 |
self.pause_menuitem.hide() |
|---|
| 143 |
self.stop_menuitem.show() |
|---|
| 144 |
self.prev_menuitem.show() |
|---|
| 145 |
self.next_menuitem.show() |
|---|
| 146 |
elif self.audio_ctrl.is_playing(): |
|---|
| 147 |
self.play_menuitem.hide() |
|---|
| 148 |
self.pause_menuitem.show() |
|---|
| 149 |
self.stop_menuitem.show() |
|---|
| 150 |
self.prev_menuitem.show() |
|---|
| 151 |
self.next_menuitem.show() |
|---|
| 152 |
|
|---|
| 153 |
gtk.Menu.popup(self, parent_menu_shell, parent_menu_item, func, button, |
|---|
| 154 |
activate_time, data) |
|---|
| 155 |
|
|---|
| 156 |
def _on_play(self, widget): |
|---|
| 157 |
self.audio_ctrl.play() |
|---|
| 158 |
|
|---|
| 159 |
def _on_stop(self, widget): |
|---|
| 160 |
self.audio_ctrl.stop() |
|---|
| 161 |
|
|---|
| 162 |
def _on_pause(self, widget): |
|---|
| 163 |
self.audio_ctrl.pause() |
|---|
| 164 |
|
|---|
| 165 |
def _on_next(self, widget): |
|---|
| 166 |
self.audio_ctrl.next() |
|---|
| 167 |
|
|---|
| 168 |
def _on_prev(self, widget): |
|---|
| 169 |
self.audio_ctrl.prev() |
|---|
| 170 |
|
|---|
| 171 |
def _on_quit(self, widget): |
|---|
| 172 |
self.main_window.quit() |
|---|