[165] | 1 | /* smplayer, GUI front-end for mplayer.
|
---|
[188] | 2 | Copyright (C) 2006-2017 Ricardo Villalba <rvm@users.sourceforge.net>
|
---|
[165] | 3 | umplayer, Copyright (C) 2010 Ori Rejwan
|
---|
[137] | 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);
|
---|
[142] | 44 | connect(this, SIGNAL(valueChanged(int)), this, SLOT(moved(int)));
|
---|
[137] | 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 )
|
---|
[165] | 83 | {
|
---|
[137] | 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);
|
---|
[165] | 91 | /* setSliderValue(minimum()); */
|
---|
[137] | 92 | setState(Normal, true);
|
---|
| 93 | }
|
---|
| 94 |
|
---|
[165] | 95 | /*
|
---|
[137] | 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 | }
|
---|
[165] | 105 | */
|
---|
[137] | 106 |
|
---|
| 107 | void PanelSeeker::mousePressEvent(QMouseEvent *m)
|
---|
| 108 | {
|
---|
| 109 | m->accept();
|
---|
| 110 | setTracking(pref->update_while_seeking);
|
---|
| 111 | if(m->button() == Qt::LeftButton)
|
---|
| 112 | {
|
---|
[165] | 113 | #if QT_VERSION >= 0x050000
|
---|
| 114 | QPointF pos = m->localPos();
|
---|
| 115 | #else
|
---|
[137] | 116 | QPointF pos = m->posF();
|
---|
[165] | 117 | #endif
|
---|
[137] | 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;
|
---|
[165] | 129 | #if QT_VERSION >= 0x050000
|
---|
| 130 | knobAdjust( m->localPos().x() - knobRect.center().x(), true);
|
---|
| 131 | #else
|
---|
[137] | 132 | knobAdjust( m->posF().x() - knobRect.center().x(), true);
|
---|
[165] | 133 | #endif
|
---|
[137] | 134 | }
|
---|
| 135 | }
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 | void PanelSeeker::mouseMoveEvent(QMouseEvent *m)
|
---|
| 139 | {
|
---|
| 140 | m->accept();
|
---|
| 141 | if(isPressed)
|
---|
| 142 | {
|
---|
[165] | 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
|
---|
[137] | 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 | {
|
---|
[170] | 307 | if (bufferingPix.width() < 1) return;
|
---|
| 308 |
|
---|
[137] | 309 | if(!state.testFlag(Buffering))
|
---|
| 310 | {
|
---|
| 311 | killTimer(t->timerId());
|
---|
| 312 | bufferingPixShift = 0;
|
---|
| 313 | }
|
---|
| 314 | else
|
---|
| 315 | {
|
---|
| 316 | bufferingPixShift +=1;
|
---|
| 317 | bufferingPixShift = qRound(bufferingPixShift)% bufferingPix.width();
|
---|
| 318 | update();
|
---|
| 319 | }
|
---|
| 320 | }
|
---|
| 321 |
|
---|
| 322 | void PanelSeeker::setSliderValue(int value)
|
---|
| 323 | {
|
---|
| 324 | if(!isPressed && !frozen)
|
---|
| 325 | {
|
---|
| 326 | blockSignals(true);
|
---|
| 327 | moved(value);
|
---|
| 328 | setValue(value);
|
---|
| 329 | blockSignals(false);
|
---|
| 330 | }
|
---|
| 331 | }
|
---|
| 332 |
|
---|
| 333 | void PanelSeeker::stopFreeze()
|
---|
| 334 | {
|
---|
| 335 | frozen = false;
|
---|
| 336 | update();
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 | void PanelSeeker::goToSliderPosition()
|
---|
| 340 | {
|
---|
| 341 | emit valueChanged(sliderPosition());
|
---|
| 342 | dragDelayTimer->stop();
|
---|
| 343 | }
|
---|
| 344 |
|
---|
| 345 | void PanelSeeker::wheelEvent(QWheelEvent *e)
|
---|
| 346 | {
|
---|
| 347 | blockSignals(true);
|
---|
| 348 | QAbstractSlider::wheelEvent(e);
|
---|
| 349 | moved(value());
|
---|
| 350 | blockSignals(false);
|
---|
| 351 | frozen = true;
|
---|
| 352 | freezeTimer->start();
|
---|
| 353 | if(!dragDelayTimer->isActive())
|
---|
| 354 | dragDelayTimer->start();
|
---|
| 355 |
|
---|
| 356 | }
|
---|
| 357 |
|
---|
[170] | 358 | void PanelTimeSeeker::wheelEvent(QWheelEvent *e) {
|
---|
| 359 | qDebug("PanelTimeSeeker::wheelEvent: delta: %d", e->delta());
|
---|
| 360 | e->accept();
|
---|
| 361 |
|
---|
| 362 | if (e->orientation() == Qt::Vertical) {
|
---|
| 363 | if (e->delta() >= 0)
|
---|
| 364 | emit wheelUp();
|
---|
| 365 | else
|
---|
| 366 | emit wheelDown();
|
---|
| 367 | } else {
|
---|
| 368 | qDebug("PanelTimeSeeker::wheelEvent: horizontal event received, doing nothing");
|
---|
| 369 | }
|
---|
| 370 | }
|
---|
| 371 |
|
---|
[137] | 372 | #include "moc_panelseeker.cpp"
|
---|