1 | /* smplayer, GUI front-end for mplayer.
|
---|
2 | Copyright (C) 2006-2014 Ricardo Villalba <rvm@users.sourceforge.net>
|
---|
3 | umplayer, Copyright (C) 2010 Ori Rejwan
|
---|
4 |
|
---|
5 | This program is free software; you can redistribute it and/or modify
|
---|
6 | it under the terms of the GNU General Public License as published by
|
---|
7 | the Free Software Foundation; either version 2 of the License, or
|
---|
8 | (at your option) any later version.
|
---|
9 |
|
---|
10 | This program is distributed in the hope that it will be useful,
|
---|
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | GNU General Public License for more details.
|
---|
14 |
|
---|
15 | You should have received a copy of the GNU General Public License
|
---|
16 | along with this program; if not, write to the Free Software
|
---|
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
18 | */
|
---|
19 |
|
---|
20 | #include "panelseeker.h"
|
---|
21 | #include <QPainter>
|
---|
22 | #include <QSlider>
|
---|
23 | #include <QMouseEvent>
|
---|
24 | #include <QDebug>
|
---|
25 | #include <QToolTip>
|
---|
26 | #include "global.h"
|
---|
27 | #include "preferences.h"
|
---|
28 | #include "config.h"
|
---|
29 | #include "helper.h"
|
---|
30 |
|
---|
31 |
|
---|
32 | using namespace Global;
|
---|
33 |
|
---|
34 |
|
---|
35 | PanelSeeker::PanelSeeker(QWidget *parent) :
|
---|
36 | QAbstractSlider(parent), isPressed(false), leftRightMargin(5), bufferingPixShift(0),
|
---|
37 | frozen(false), delayPeriod(100), frozenPeriod(500)
|
---|
38 | {
|
---|
39 | setAttribute(Qt::WA_StyledBackground, true);
|
---|
40 | setAttribute(Qt::WA_Hover, true);
|
---|
41 | setEnabled(false);
|
---|
42 | setState(Stopped, true);
|
---|
43 | setTracking(pref->update_while_seeking);
|
---|
44 | connect(this, SIGNAL(valueChanged(int)), this, SLOT(moved(int)));
|
---|
45 | setRange(0, 100);
|
---|
46 | freezeTimer = new QTimer(this);
|
---|
47 | freezeTimer->setInterval(frozenPeriod);
|
---|
48 | freezeTimer->setSingleShot(true);
|
---|
49 | dragDelayTimer = new QTimer(this);
|
---|
50 | dragDelayTimer->setInterval(delayPeriod);
|
---|
51 | dragDelayTimer->setSingleShot(true);
|
---|
52 | connect(freezeTimer, SIGNAL(timeout()), this, SLOT(stopFreeze()));
|
---|
53 | connect(dragDelayTimer, SIGNAL(timeout()), this, SLOT(goToSliderPosition()));
|
---|
54 | }
|
---|
55 |
|
---|
56 |
|
---|
57 | void PanelSeeker::paintEvent(QPaintEvent * e)
|
---|
58 | {
|
---|
59 | QPainter p(this);
|
---|
60 |
|
---|
61 | p.drawPixmap( leftRightMargin, (height()- leftPix.height())/2 , leftPix );
|
---|
62 | p.drawTiledPixmap(QRect(leftRightMargin + leftPix.width(), (height()- centerPix.height())/2 ,width() - 2*leftRightMargin - leftPix.width() - rightPix.width(),centerPix.height()), centerPix);
|
---|
63 |
|
---|
64 | p.drawPixmap( width()-rightPix.width() - leftRightMargin , (height()- rightPix.height())/2 , rightPix);
|
---|
65 |
|
---|
66 | if(state.testFlag(Buffering))
|
---|
67 | {
|
---|
68 | p.drawTiledPixmap(QRect(leftRightMargin + leftPix.width(), (height()- bufferingPix.height())/2, width() - 2*leftRightMargin -leftPix.width() - rightPix.width(), bufferingPix.height()), bufferingPix, QPoint(bufferingPixShift, 0) );
|
---|
69 | }
|
---|
70 | else
|
---|
71 | {
|
---|
72 | if(isEnabled())
|
---|
73 | {
|
---|
74 | p.drawTiledPixmap(QRect(leftRightMargin + leftPix.width(), (height()- progressPix.height())/2 , knobRect.center().x() - leftRightMargin - leftPix.width(), progressPix.height()), progressPix);
|
---|
75 | }
|
---|
76 | p.drawPixmap(knobRect.toRect(), knobCurrentPix );
|
---|
77 | }
|
---|
78 |
|
---|
79 |
|
---|
80 | }
|
---|
81 |
|
---|
82 | void PanelSeeker::setKnobIcon( QPixmap pix )
|
---|
83 | {
|
---|
84 | int w = pix.width();
|
---|
85 | int h = pix.height();
|
---|
86 | knobPix.setPixmap(pix.copy(0, 0, w, h/4 ), MyIcon::Normal, MyIcon::Off);
|
---|
87 | knobPix.setPixmap(pix.copy(0, h/4, w, h/4 ), MyIcon::MouseOver, MyIcon::Off);
|
---|
88 | knobPix.setPixmap(pix.copy(0, h/2, w, h/4 ), MyIcon::MouseDown, MyIcon::Off);
|
---|
89 | knobPix.setPixmap(pix.copy(0, 3*h/4, w, h/4 ), MyIcon::Disabled, MyIcon::Off);
|
---|
90 | knobCurrentPix = knobPix.pixmap(MyIcon::Normal, MyIcon::Off);
|
---|
91 | /* setSliderValue(minimum()); */
|
---|
92 | setState(Normal, true);
|
---|
93 | }
|
---|
94 |
|
---|
95 | /*
|
---|
96 | void PanelSeeker::setSingleKnobIcon(QPixmap pix)
|
---|
97 | {
|
---|
98 | knobPix.setPixmap(pix, MyIcon::Normal, MyIcon::Off);
|
---|
99 | knobPix.setPixmap(pix, MyIcon::MouseOver, MyIcon::Off);
|
---|
100 | knobPix.setPixmap(pix, MyIcon::MouseDown, MyIcon::Off);
|
---|
101 | knobPix.setPixmap(pix, MyIcon::Disabled, MyIcon::Off);
|
---|
102 | setSliderValue(minimum());
|
---|
103 | setState(Normal, true);
|
---|
104 | }
|
---|
105 | */
|
---|
106 |
|
---|
107 | void PanelSeeker::mousePressEvent(QMouseEvent *m)
|
---|
108 | {
|
---|
109 | m->accept();
|
---|
110 | setTracking(pref->update_while_seeking);
|
---|
111 | if(m->button() == Qt::LeftButton)
|
---|
112 | {
|
---|
113 | #if QT_VERSION >= 0x050000
|
---|
114 | QPointF pos = m->localPos();
|
---|
115 | #else
|
---|
116 | QPointF pos = m->posF();
|
---|
117 | #endif
|
---|
118 | if(knobRect.contains(pos))
|
---|
119 | {
|
---|
120 | isPressed = true;
|
---|
121 | mousePressPos = pos;
|
---|
122 | mousePressDifference = pos.x() - knobRect.center().x();
|
---|
123 | setSliderDown(true);
|
---|
124 | setState(Pressed, true);
|
---|
125 | }
|
---|
126 | else
|
---|
127 | {
|
---|
128 | isPressed = false;
|
---|
129 | #if QT_VERSION >= 0x050000
|
---|
130 | knobAdjust( m->localPos().x() - knobRect.center().x(), true);
|
---|
131 | #else
|
---|
132 | knobAdjust( m->posF().x() - knobRect.center().x(), true);
|
---|
133 | #endif
|
---|
134 | }
|
---|
135 | }
|
---|
136 | }
|
---|
137 |
|
---|
138 | void PanelSeeker::mouseMoveEvent(QMouseEvent *m)
|
---|
139 | {
|
---|
140 | m->accept();
|
---|
141 | if(isPressed)
|
---|
142 | {
|
---|
143 | #if QT_VERSION >= 0x050000
|
---|
144 | knobAdjust(m->localPos().x() - knobRect.center().x() - mousePressDifference );
|
---|
145 | #else
|
---|
146 | knobAdjust(m->posF().x() - knobRect.center().x() - mousePressDifference );
|
---|
147 | #endif
|
---|
148 | }
|
---|
149 | }
|
---|
150 |
|
---|
151 | void PanelSeeker::mouseReleaseEvent(QMouseEvent *m)
|
---|
152 | {
|
---|
153 | setSliderDown(false);
|
---|
154 | if(isPressed)
|
---|
155 | {
|
---|
156 | isPressed = false;
|
---|
157 | setState(Pressed, false);
|
---|
158 | frozen = true;
|
---|
159 | freezeTimer->start();
|
---|
160 | /*if(mousePressPos == m->pos())
|
---|
161 | {
|
---|
162 | knobAdjust( m->posF().x() - knobRect.center().x(), true);
|
---|
163 | triggerAction(SliderMove);
|
---|
164 | } */
|
---|
165 | }
|
---|
166 | }
|
---|
167 |
|
---|
168 | void PanelSeeker::resetKnob( bool start)
|
---|
169 | {
|
---|
170 | if(start)
|
---|
171 | {
|
---|
172 | moved(minimum());
|
---|
173 | }
|
---|
174 | else
|
---|
175 | {
|
---|
176 | moved(maximum());
|
---|
177 | }
|
---|
178 | }
|
---|
179 |
|
---|
180 | void PanelSeeker::knobAdjust(qreal x, bool isSetValue)
|
---|
181 | {
|
---|
182 | if(state.testFlag(Buffering)) return;
|
---|
183 | qreal value = minimum() + (knobRect.center().x() - (leftRightMargin + knobCurrentPix.width()/2) +x ) * (maximum() - minimum()) /(width() - (leftRightMargin) - (leftRightMargin) - knobCurrentPix.width()) ;
|
---|
184 | if(isSetValue)
|
---|
185 | {
|
---|
186 | frozen = true;
|
---|
187 | if( state.testFlag(Stopped) ) value = minimum();
|
---|
188 | setValue(qRound(value));
|
---|
189 | freezeTimer->start();
|
---|
190 | }
|
---|
191 | else {
|
---|
192 | if(hasTracking())
|
---|
193 | {
|
---|
194 | blockSignals(true);
|
---|
195 | moved(qRound(value));
|
---|
196 | blockSignals(false);
|
---|
197 | emit sliderMoved(qRound(value));
|
---|
198 | if(!dragDelayTimer->isActive())
|
---|
199 | dragDelayTimer->start();
|
---|
200 | }
|
---|
201 | else
|
---|
202 | moved(qRound(value));
|
---|
203 | }
|
---|
204 | }
|
---|
205 |
|
---|
206 | bool PanelSeeker::event(QEvent *e)
|
---|
207 | {
|
---|
208 | if(e->type() == QEvent::HoverMove || e->type() == QEvent::HoverEnter )
|
---|
209 | {
|
---|
210 | QHoverEvent* he = static_cast<QHoverEvent*>(e);
|
---|
211 | if( knobRect.contains(he->pos()) )
|
---|
212 | {
|
---|
213 | setState(Hovered, true);
|
---|
214 | }
|
---|
215 | else
|
---|
216 | {
|
---|
217 | setState(Hovered, false);
|
---|
218 | }
|
---|
219 | }
|
---|
220 | if(e->type() == QEvent::HoverLeave)
|
---|
221 | {
|
---|
222 | setState(Hovered, false);
|
---|
223 | }
|
---|
224 | return QAbstractSlider::event(e);
|
---|
225 | }
|
---|
226 |
|
---|
227 | qreal PanelSeeker::valueForPos(int pos)
|
---|
228 | {
|
---|
229 | qreal value = (qreal)( pos - (leftRightMargin + knobCurrentPix.width()/2) ) * maximum() /(width() - (leftRightMargin) - (leftRightMargin) - knobCurrentPix.width());
|
---|
230 | return value;
|
---|
231 | }
|
---|
232 |
|
---|
233 | void PanelSeeker::setState(State st, bool on)
|
---|
234 | {
|
---|
235 | if(on)
|
---|
236 | {
|
---|
237 | if(state.testFlag(st)) return;
|
---|
238 | state |= st;
|
---|
239 | }
|
---|
240 | else
|
---|
241 | {
|
---|
242 | if(!state.testFlag(st)) return;
|
---|
243 | state &= ~st;
|
---|
244 | }
|
---|
245 | if(state.testFlag(Buffering))
|
---|
246 | {
|
---|
247 | startTimer(100);
|
---|
248 | }
|
---|
249 | if(state.testFlag(Disabled))
|
---|
250 | {
|
---|
251 | knobCurrentPix = knobPix.pixmap(MyIcon::Disabled, MyIcon::Off);
|
---|
252 | }
|
---|
253 | else if(state.testFlag(Pressed))
|
---|
254 | {
|
---|
255 | knobCurrentPix = knobPix.pixmap(MyIcon::MouseDown, MyIcon::Off);
|
---|
256 | }
|
---|
257 | else if(state.testFlag(Hovered))
|
---|
258 | {
|
---|
259 | knobCurrentPix = knobPix.pixmap(MyIcon::MouseOver, MyIcon::Off);
|
---|
260 | }
|
---|
261 | else
|
---|
262 | {
|
---|
263 | knobCurrentPix = knobPix.pixmap(MyIcon::Normal, MyIcon::Off);
|
---|
264 | }
|
---|
265 | update();
|
---|
266 | }
|
---|
267 |
|
---|
268 | void PanelSeeker::moved( int value)
|
---|
269 | {
|
---|
270 | if(value > maximum()) value = maximum();
|
---|
271 | if(value < minimum()) value = minimum();
|
---|
272 | if( state.testFlag(Stopped) ) value = minimum();
|
---|
273 |
|
---|
274 | qreal ratio = (qreal)(value - minimum())/(maximum()-minimum());
|
---|
275 | qreal centerPixel = ratio*(width() - (leftRightMargin ) - (leftRightMargin) - knobCurrentPix.width());
|
---|
276 | QSize size = knobPix.size(MyIcon::Normal, MyIcon::Off);
|
---|
277 | knobRect = QRectF(QPointF(centerPixel + (leftRightMargin + knobCurrentPix.width()/2) - size.width()/2, ( height() - size.height())/2 ), size );
|
---|
278 | setSliderPosition(value);
|
---|
279 | update();
|
---|
280 | }
|
---|
281 |
|
---|
282 | void PanelSeeker::resizeEvent(QResizeEvent *)
|
---|
283 | {
|
---|
284 | setSliderValue(value());
|
---|
285 | }
|
---|
286 |
|
---|
287 | void PanelSeeker::changeEvent(QEvent *e)
|
---|
288 | {
|
---|
289 | if(e->type() == QEvent::EnabledChange)
|
---|
290 | {
|
---|
291 | if(isEnabled())
|
---|
292 | {
|
---|
293 | setState(Disabled, false);
|
---|
294 | setState(Stopped, false);
|
---|
295 |
|
---|
296 | }
|
---|
297 | else
|
---|
298 | {
|
---|
299 | setState(Disabled, true);
|
---|
300 | setState(Stopped, true);
|
---|
301 | }
|
---|
302 | }
|
---|
303 | }
|
---|
304 |
|
---|
305 | void PanelSeeker::timerEvent(QTimerEvent *t)
|
---|
306 | {
|
---|
307 | if(!state.testFlag(Buffering))
|
---|
308 | {
|
---|
309 | killTimer(t->timerId());
|
---|
310 | bufferingPixShift = 0;
|
---|
311 | }
|
---|
312 | else
|
---|
313 | {
|
---|
314 | bufferingPixShift +=1;
|
---|
315 | bufferingPixShift = qRound(bufferingPixShift)% bufferingPix.width();
|
---|
316 | update();
|
---|
317 | }
|
---|
318 | }
|
---|
319 |
|
---|
320 | void PanelSeeker::setSliderValue(int value)
|
---|
321 | {
|
---|
322 | if(!isPressed && !frozen)
|
---|
323 | {
|
---|
324 | blockSignals(true);
|
---|
325 | moved(value);
|
---|
326 | setValue(value);
|
---|
327 | blockSignals(false);
|
---|
328 | }
|
---|
329 | }
|
---|
330 |
|
---|
331 | void PanelSeeker::stopFreeze()
|
---|
332 | {
|
---|
333 | frozen = false;
|
---|
334 | update();
|
---|
335 | }
|
---|
336 |
|
---|
337 | void PanelSeeker::goToSliderPosition()
|
---|
338 | {
|
---|
339 | emit valueChanged(sliderPosition());
|
---|
340 | dragDelayTimer->stop();
|
---|
341 | }
|
---|
342 |
|
---|
343 | void PanelSeeker::wheelEvent(QWheelEvent *e)
|
---|
344 | {
|
---|
345 | blockSignals(true);
|
---|
346 | QAbstractSlider::wheelEvent(e);
|
---|
347 | moved(value());
|
---|
348 | blockSignals(false);
|
---|
349 | frozen = true;
|
---|
350 | freezeTimer->start();
|
---|
351 | if(!dragDelayTimer->isActive())
|
---|
352 | dragDelayTimer->start();
|
---|
353 |
|
---|
354 | }
|
---|
355 |
|
---|
356 | #include "moc_panelseeker.cpp"
|
---|