2 # Copyright (C) 2009 Anton Khirnov <wyskas@gmail.com>
4 # Nephilim 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 3 of the License, or
7 # (at your option) any later version.
9 # Nephilim 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.
14 # You should have received a copy of the GNU General Public License
15 # along with Nephilim. If not, see <http://www.gnu.org/licenses/>.
18 from PyQt4
import QtGui
, QtCore
20 from ..common
import Button
21 from ..plugin
import Plugin
24 class wgPlayControl(QtGui
.QToolBar
):
25 """Displays controls for interacting with playing, like play, volume ..."""
43 class VolumeSlider(QtGui
.QSlider
):
45 def __init__(self
, parent
):
46 QtGui
.QSlider
.__init
__(self
, parent
)
47 self
.setOrientation(parent
.orientation())
49 self
.setToolTip('Volume control')
51 def paintEvent(self
, event
):
52 painter
= QtGui
.QPainter(self
)
53 painter
.eraseRect(self
.rect())
55 grad
= QtGui
.QLinearGradient(0, 0, self
.width(), self
.height())
56 grad
.setColorAt(0, self
.palette().color(QtGui
.QPalette
.Window
))
57 grad
.setColorAt(1, self
.palette().color(QtGui
.QPalette
.Highlight
))
58 if self
.orientation() == QtCore
.Qt
.Horizontal
:
59 rect
= QtCore
.QRect(0, 0, self
.width() * self
.value() / self
.maximum(), self
.height())
61 rect
= QtCore
.QRect(0, self
.height() * (1 - float(self
.value()) / self
.maximum()), self
.width(), self
.height())
62 painter
.fillRect(rect
, QtGui
.QBrush(grad
))
64 def __init__(self
, p
, parent
= None):
65 QtGui
.QToolBar
.__init
__(self
, p
.name
, parent
)
68 self
.logger
= p
.logger
69 self
.setObjectName(p
.name
)
71 status
= self
.p
.mpclient
.status
73 self
.play_icon
= QtGui
.QIcon(':icons/media-playback-start.svg')
74 self
.pause_icon
= QtGui
.QIcon(':icons/media-playback-pause.svg')
76 self
.play_action
= self
.addAction(self
.play_icon
, 'play', self
.on_play_click
)
77 self
.stop_action
= self
.addAction(QtGui
.QIcon(':icons/media-playback-stop.svg'), 'stop', self
.on_stop_click
)
78 self
.prev_action
= self
.addAction(QtGui
.QIcon(':icons/media-skip-backward.svg'), 'previous', self
.on_prev_click
)
79 self
.next_action
= self
.addAction(QtGui
.QIcon(':icons/media-skip-forward.svg'), 'next', self
.on_next_click
)
82 self
.vol_slider
= self
.VolumeSlider(self
)
83 self
.vol_slider
.setSliderPosition(status
['volume'])
84 self
.vol_slider
.valueChanged
.connect(self
.onVolumeSliderChange
)
85 self
.addWidget(self
.vol_slider
)
88 self
.random
= self
.addAction(QtGui
.QIcon(':icons/media-playlist-shuffle.svgz'), 'random')
89 self
.random
.setCheckable(True)
90 self
.random
.setChecked(status
['random'])
91 self
.random
.toggled
.connect(self
.p
.mpclient
.random
)
92 self
.p
.mpclient
.random_changed
.connect(self
.random
.setChecked
)
94 self
.repeat
= self
.addAction(QtGui
.QIcon(':icons/media-playlist-repeat.svg'), 'repeat')
95 self
.repeat
.setCheckable(True)
96 self
.repeat
.setChecked(status
['repeat'])
97 self
.p
.mpclient
.repeat_changed
.connect(self
.repeat
.setChecked
)
98 self
.repeat
.toggled
.connect(self
.p
.mpclient
.repeat
)
100 self
.single
= self
.addAction(QtGui
.QIcon(':icons/single.png'), 'single mode')
101 self
.single
.setCheckable(True)
102 self
.single
.setChecked(status
['single'])
103 self
.p
.mpclient
.single_changed
.connect(self
.single
.setChecked
)
104 self
.single
.toggled
.connect(self
.p
.mpclient
.single
)
106 self
.consume
= self
.addAction(QtGui
.QIcon(':icons/consume.png'), 'consume mode')
107 self
.consume
.setCheckable(True)
108 self
.consume
.setChecked(status
['consume'])
109 self
.p
.mpclient
.consume_changed
.connect(self
.consume
.setChecked
)
110 self
.consume
.toggled
.connect(self
.p
.mpclient
.consume
)
112 self
.xfade
= QtGui
.QSpinBox(self
)
113 self
.xfade
.setValue(self
.p
.mpclient
.status
['xfade'])
114 self
.p
.mpclient
.crossfade_changed
.connect(self
.xfade
.setValue
)
115 self
.xfade
.valueChanged
.connect(self
.p
.mpclient
.crossfade
)
116 self
.xfade
.setToolTip('Set crossfade between songs in seconds.')
117 self
.addWidget(self
.xfade
)
119 self
.outputs_menu
= QtGui
.QMenu('Audio outputs')
120 outputs
= self
.addAction(QtGui
.QIcon(':icons/outputs.png'), 'Audio outputs')
121 outputs
.triggered
.connect(lambda : self
.outputs_menu
.popup(QtGui
.QCursor
.pos()))
122 self
.__update
_outputs
()
123 self
.p
.mpclient
.connect_changed
.connect(self
.__update
_outputs
)
126 self
.orientationChanged
.connect(self
.vol_slider
.setOrientation
)
128 self
.p
.mpclient
.state_changed
.connect(self
.onStateChange
)
129 self
.p
.mpclient
.volume_changed
.connect(self
.onVolumeChange
)
131 def __update_outputs(self
):
132 self
.outputs_menu
.clear()
133 for output
in self
.p
.mpclient
.outputs
:
134 act
= self
.outputs_menu
.addAction(output
.name
)
135 act
.setCheckable(True)
136 act
.setChecked(output
.state
)
137 act
.toggled
.connect(output
.set_state
)
138 output
.state_changed
.connect(act
.setChecked
)
140 def onStateChange(self
, new_state
):
141 status
= self
.p
.mpclient
.status
143 if new_state
== 'play':
144 self
.play_action
.setIcon(self
.pause_icon
)
145 self
.play_action
.setToolTip('pause')
146 elif new_state
== 'pause' or new_state
== 'stop':
147 self
.play_action
.setIcon(self
.play_icon
)
148 self
.play_action
.setToolTip('play')
150 def onVolumeChange(self
, new_vol
):
151 self
.vol_slider
.setValue(new_vol
)
153 def on_play_click(self
):
154 status
=self
.p
.mpclient
.status
155 if status
['state']=='play':
156 self
.logger
.info('Toggling playback')
157 self
.p
.mpclient
.pause()
158 elif status
['state']=='stop':
159 self
.logger
.info('Pausing playback')
160 self
.p
.mpclient
.play(None)
162 self
.p
.mpclient
.resume()
163 def on_stop_click(self
):
164 self
.logger
.info('Stopping playback')
165 self
.p
.mpclient
.stop()
166 def on_prev_click(self
):
167 self
.logger
.info('Playing previous')
168 self
.p
.mpclient
.previous()
169 def on_next_click(self
):
170 self
.logger
.info('Playing next')
171 self
.p
.mpclient
.next()
172 def onVolumeSliderChange(self
, val
):
173 self
.p
.mpclient
.set_volume(val
)
175 class PlayControl(Plugin
):
177 info
= 'Controls playback.'
183 self
.o
= wgPlayControl(self
, None)
184 QtGui
.QApplication
.instance().main_win
.addToolBar(QtCore
.Qt
.TopToolBarArea
, self
.o
)
186 QtGui
.QApplication
.instance().main_win
.removeToolBar(self
.o
)