source: smplayer/trunk/src/mplayerwindow.cpp@ 178

Last change on this file since 178 was 176, checked in by Silvan Scherrer, 9 years ago

smplayer: update trunk to version 16.4

  • Property svn:eol-style set to LF
File size: 14.7 KB
Line 
1/* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2016 Ricardo Villalba <rvm@users.sourceforge.net>
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
19#include "mplayerwindow.h"
20#include "global.h"
21#include "desktopinfo.h"
22#include "colorutils.h"
23
24#ifndef MINILIB
25#include "images.h"
26#endif
27
28#include <QLabel>
29#include <QTimer>
30#include <QCursor>
31#include <QEvent>
32#include <QLayout>
33#include <QPixmap>
34#include <QPainter>
35#include <QApplication>
36#include <QTimer>
37#include <QDebug>
38
39#if LOGO_ANIMATION
40#include <QPropertyAnimation>
41#endif
42
43Screen::Screen(QWidget* parent, Qt::WindowFlags f)
44 : QWidget(parent, f )
45 , check_mouse_timer(0)
46 , mouse_last_position(QPoint(0,0))
47 , autohide_cursor(false)
48 , autohide_interval(0)
49{
50 setMouseTracking(true);
51 setFocusPolicy( Qt::NoFocus );
52 setMinimumSize( QSize(0,0) );
53
54 check_mouse_timer = new QTimer(this);
55 connect( check_mouse_timer, SIGNAL(timeout()), this, SLOT(checkMousePos()) );
56
57 setAutoHideInterval(1000);
58 setAutoHideCursor(false);
59}
60
61Screen::~Screen() {
62}
63
64void Screen::setAutoHideCursor(bool b) {
65 qDebug("Screen::setAutoHideCursor: %d", b);
66
67 autohide_cursor = b;
68 if (autohide_cursor) {
69 check_mouse_timer->setInterval(autohide_interval);
70 check_mouse_timer->start();
71 } else {
72 check_mouse_timer->stop();
73 }
74}
75
76void Screen::checkMousePos() {
77 //qDebug("Screen::checkMousePos");
78
79 if (!autohide_cursor) {
80 setCursor(QCursor(Qt::ArrowCursor));
81 return;
82 }
83
84 QPoint pos = mapFromGlobal(QCursor::pos());
85
86 //qDebug("Screen::checkMousePos: x: %d, y: %d", pos.x(), pos.y());
87
88 if (mouse_last_position != pos) {
89 setCursor(QCursor(Qt::ArrowCursor));
90 } else {
91 setCursor(QCursor(Qt::BlankCursor));
92 }
93 mouse_last_position = pos;
94}
95
96void Screen::mouseMoveEvent( QMouseEvent * e ) {
97 //qDebug("Screen::mouseMoveEvent");
98 emit mouseMoved(e->pos());
99
100 if (cursor().shape() != Qt::ArrowCursor) {
101 //qDebug(" showing mouse cursor" );
102 setCursor(QCursor(Qt::ArrowCursor));
103 }
104}
105
106void Screen::playingStarted() {
107 qDebug("Screen::playingStarted");
108 setAutoHideCursor(true);
109}
110
111void Screen::playingStopped() {
112 qDebug("Screen::playingStopped");
113 setAutoHideCursor(false);
114}
115
116/* ---------------------------------------------------------------------- */
117
118MplayerLayer::MplayerLayer(QWidget* parent, Qt::WindowFlags f)
119 : Screen(parent, f)
120#if REPAINT_BACKGROUND_OPTION
121 , repaint_background(false)
122#endif
123 , playing(false)
124{
125#ifndef Q_OS_WIN
126 #if QT_VERSION < 0x050000
127 setAttribute(Qt::WA_OpaquePaintEvent);
128 #if QT_VERSION >= 0x040400
129 setAttribute(Qt::WA_NativeWindow);
130 #endif
131 setAttribute(Qt::WA_PaintUnclipped);
132 //setAttribute(Qt::WA_PaintOnScreen);
133 #endif
134#endif
135}
136
137MplayerLayer::~MplayerLayer() {
138}
139
140#if REPAINT_BACKGROUND_OPTION
141void MplayerLayer::setRepaintBackground(bool b) {
142 qDebug("MplayerLayer::setRepaintBackground: %d", b);
143 repaint_background = b;
144}
145
146void MplayerLayer::paintEvent( QPaintEvent * e ) {
147 //qDebug("MplayerLayer::paintEvent: repaint_background: %d", repaint_background);
148 if (repaint_background || !playing) {
149 //qDebug("MplayerLayer::paintEvent: painting");
150 QPainter painter(this);
151 painter.eraseRect( e->rect() );
152 //painter.fillRect( e->rect(), QColor(255,0,0) );
153 }
154}
155#endif
156
157void MplayerLayer::playingStarted() {
158 qDebug("MplayerLayer::playingStarted");
159 repaint();
160 playing = true;
161
162#ifndef Q_OS_WIN
163 setAttribute(Qt::WA_PaintOnScreen);
164#endif
165
166 Screen::playingStarted();
167}
168
169void MplayerLayer::playingStopped() {
170 qDebug("MplayerLayer::playingStopped");
171 playing = false;
172
173#ifndef Q_OS_WIN
174 setAttribute(Qt::WA_PaintOnScreen, false);
175#endif
176
177 repaint();
178 Screen::playingStopped();
179}
180
181/* ---------------------------------------------------------------------- */
182
183MplayerWindow::MplayerWindow(QWidget* parent, Qt::WindowFlags f)
184 : Screen(parent, f)
185 , video_width(0)
186 , video_height(0)
187 , aspect((double) 4/3)
188 , monitoraspect(0)
189 , mplayerlayer(0)
190 , logo(0)
191 , offset_x(0)
192 , offset_y(0)
193 , zoom_factor(1.0)
194 , orig_x(0)
195 , orig_y(0)
196 , orig_width(0)
197 , orig_height(0)
198 , allow_video_movement(false)
199#if DELAYED_RESIZE
200 , resize_timer(0)
201#endif
202 , delay_left_click(false)
203 , left_click_timer(0)
204 , double_clicked(false)
205#if LOGO_ANIMATION
206 , animated_logo(false)
207#endif
208 , corner_widget(0)
209 , drag_state(NOT_DRAGGING)
210 , start_drag(QPoint(0,0))
211 , mouse_drag_tracking(false)
212{
213 setAutoFillBackground(true);
214 ColorUtils::setBackgroundColor( this, QColor(0,0,0) );
215
216 mplayerlayer = new MplayerLayer(this);
217 mplayerlayer->setObjectName("mplayerlayer");
218 mplayerlayer->setAutoFillBackground(true);
219
220 logo = new QLabel( mplayerlayer );
221 logo->setObjectName("mplayerwindow logo");
222 logo->setAutoFillBackground(true);
223 ColorUtils::setBackgroundColor( logo, QColor(0,0,0) );
224
225 QVBoxLayout * mplayerlayerLayout = new QVBoxLayout( mplayerlayer );
226 mplayerlayerLayout->addWidget( logo, 0, Qt::AlignHCenter | Qt::AlignVCenter );
227
228 setSizePolicy( QSizePolicy::Expanding , QSizePolicy::Expanding );
229 setFocusPolicy( Qt::StrongFocus );
230
231 installEventFilter(this);
232 mplayerlayer->installEventFilter(this);
233 //logo->installEventFilter(this);
234
235#if DELAYED_RESIZE
236 resize_timer = new QTimer(this);
237 resize_timer->setSingleShot(true);
238 resize_timer->setInterval(50);
239 connect( resize_timer, SIGNAL(timeout()), this, SLOT(resizeLater()) );
240#endif
241
242 left_click_timer = new QTimer(this);
243 left_click_timer->setSingleShot(true);
244 left_click_timer->setInterval(qApp->doubleClickInterval()+10);
245 connect(left_click_timer, SIGNAL(timeout()), this, SIGNAL(leftClicked()));
246
247 retranslateStrings();
248}
249
250MplayerWindow::~MplayerWindow() {
251}
252
253void MplayerWindow::setCornerWidget(QWidget * w) {
254 corner_widget = w;
255
256 QHBoxLayout * blayout = new QHBoxLayout;
257 blayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding));
258 blayout->addWidget(corner_widget);
259
260 QVBoxLayout * layout = new QVBoxLayout(this);
261 layout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding));
262 layout->addLayout(blayout);
263}
264
265#if USE_COLORKEY
266void MplayerWindow::setColorKey( QColor c ) {
267 ColorUtils::setBackgroundColor( mplayerlayer, c );
268}
269#endif
270
271void MplayerWindow::retranslateStrings() {
272 //qDebug("MplayerWindow::retranslateStrings");
273#ifndef MINILIB
274 logo->setPixmap( Images::icon("background") );
275#endif
276}
277
278void MplayerWindow::setLogoVisible( bool b) {
279 if (corner_widget) {
280 corner_widget->setVisible(b);
281 }
282
283#if !LOGO_ANIMATION
284 logo->setVisible(b);
285#else
286 if (!animated_logo) {
287 logo->setVisible(b);
288 } else {
289 if (b) {
290 logo->show();
291 QPropertyAnimation * animation = new QPropertyAnimation(logo, "pos");
292 animation->setDuration(200);
293 animation->setEasingCurve(QEasingCurve::OutBounce);
294 animation->setStartValue(QPoint(logo->x(), 0 - logo->y()));
295 animation->setEndValue(logo->pos());
296 animation->start();
297 } else {
298 QPropertyAnimation * animation = new QPropertyAnimation(logo, "pos");
299 animation->setDuration(200);
300 animation->setEasingCurve(QEasingCurve::OutBounce);
301 animation->setEndValue(QPoint(width(), logo->y()));
302 animation->setStartValue(logo->pos());
303 animation->start();
304 connect(animation, SIGNAL(finished()), logo, SLOT(hide()));
305 //logo->hide();
306 }
307 }
308#endif
309}
310
311/*
312void MplayerWindow::changePolicy() {
313 setSizePolicy( QSizePolicy::Preferred , QSizePolicy::Preferred );
314}
315*/
316
317void MplayerWindow::setResolution( int w, int h)
318{
319 video_width = w;
320 video_height = h;
321
322 //mplayerlayer->move(1,1);
323 updateVideoWindow();
324}
325
326
327void MplayerWindow::resizeEvent( QResizeEvent * /* e */)
328{
329 /*qDebug("MplayerWindow::resizeEvent: %d, %d",
330 e->size().width(), e->size().height() );*/
331
332#if !DELAYED_RESIZE
333 offset_x = 0;
334 offset_y = 0;
335
336 updateVideoWindow();
337 setZoom(zoom_factor);
338#else
339 resize_timer->start();
340#endif
341}
342
343#if DELAYED_RESIZE
344void MplayerWindow::resizeLater() {
345 offset_x = 0;
346 offset_y = 0;
347
348 updateVideoWindow();
349 setZoom(zoom_factor);
350}
351#endif
352
353void MplayerWindow::setMonitorAspect(double asp) {
354 monitoraspect = asp;
355}
356
357void MplayerWindow::setAspect( double asp) {
358 aspect = asp;
359 if (monitoraspect!=0) {
360 aspect = aspect / monitoraspect * DesktopInfo::desktop_aspectRatio(this);
361 }
362 updateVideoWindow();
363}
364
365
366void MplayerWindow::updateVideoWindow()
367{
368 //qDebug("MplayerWindow::updateVideoWindow");
369
370 //qDebug("aspect= %f", aspect);
371
372 int w_width = size().width();
373 int w_height = size().height();
374
375 int w = w_width;
376 int h = w_height;
377 int x = 0;
378 int y = 0;
379
380 if (aspect != 0) {
381 int pos1_w = w_width;
382 int pos1_h = w_width / aspect + 0.5;
383
384 int pos2_h = w_height;
385 int pos2_w = w_height * aspect + 0.5;
386
387 //qDebug("pos1_w: %d, pos1_h: %d", pos1_w, pos1_h);
388 //qDebug("pos2_w: %d, pos2_h: %d", pos2_w, pos2_h);
389
390 if (pos1_h <= w_height) {
391 //qDebug("Pos1!");
392 w = pos1_w;
393 h = pos1_h;
394
395 y = (w_height - h) /2;
396 } else {
397 //qDebug("Pos2!");
398 w = pos2_w;
399 h = pos2_h;
400
401 x = (w_width - w) /2;
402 }
403 }
404
405 mplayerlayer->move(x,y);
406 mplayerlayer->resize(w, h);
407
408 orig_x = x;
409 orig_y = y;
410 orig_width = w;
411 orig_height = h;
412
413 //qDebug( "w_width: %d, w_height: %d", w_width, w_height);
414 //qDebug("w: %d, h: %d", w,h);
415}
416
417
418void MplayerWindow::mouseReleaseEvent( QMouseEvent * e) {
419 qDebug( "MplayerWindow::mouseReleaseEvent" );
420
421 if (e->button() == Qt::LeftButton) {
422 e->accept();
423 if (delay_left_click) {
424 if (!double_clicked) left_click_timer->start();
425 double_clicked = false;
426 } else {
427 emit leftClicked();
428 }
429 }
430 else
431 if (e->button() == Qt::MidButton) {
432 e->accept();
433 emit middleClicked();
434 }
435 else
436 if (e->button() == Qt::XButton1) {
437 e->accept();
438 emit xbutton1Clicked();
439 }
440 else
441 if (e->button() == Qt::XButton2) {
442 e->accept();
443 emit xbutton2Clicked();
444 }
445 else
446 if (e->button() == Qt::RightButton) {
447 e->accept();
448 //emit rightButtonReleased( e->globalPos() );
449 emit rightClicked();
450 }
451 else {
452 e->ignore();
453 }
454}
455
456void MplayerWindow::mouseDoubleClickEvent( QMouseEvent * e ) {
457 if (e->button() == Qt::LeftButton) {
458 e->accept();
459 if (delay_left_click) {
460 left_click_timer->stop();
461 double_clicked = true;
462 }
463 emit doubleClicked();
464 } else {
465 e->ignore();
466 }
467}
468
469void MplayerWindow::wheelEvent( QWheelEvent * e ) {
470 qDebug("MplayerWindow::wheelEvent: delta: %d", e->delta());
471 e->accept();
472
473 if (e->orientation() == Qt::Vertical) {
474 if (e->delta() >= 0)
475 emit wheelUp();
476 else
477 emit wheelDown();
478 } else {
479 qDebug("MplayerWindow::wheelEvent: horizontal event received, doing nothing");
480 }
481}
482
483bool MplayerWindow::eventFilter( QObject * object, QEvent * event ) {
484
485 if (!mouse_drag_tracking)
486 return false;
487
488 QEvent::Type type = event->type();
489 if (type != QEvent::MouseButtonPress
490 && type != QEvent::MouseButtonRelease
491 && type != QEvent::MouseMove)
492 return false;
493
494 QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
495 if (!mouseEvent)
496 return false;
497
498 if (mouseEvent->modifiers() != Qt::NoModifier) {
499 drag_state = NOT_DRAGGING;
500 return false;
501 }
502
503 if (type == QEvent::MouseButtonPress) {
504 if (mouseEvent->button() != Qt::LeftButton) {
505 drag_state = NOT_DRAGGING;
506 return false;
507 }
508
509 drag_state = START_DRAGGING;
510 start_drag = mouseEvent->globalPos();
511 // Don't filter, so others can have a look at it too
512 return false;
513 }
514
515 if (type == QEvent::MouseButtonRelease) {
516 if (drag_state != DRAGGING || mouseEvent->button() != Qt::LeftButton) {
517 drag_state = NOT_DRAGGING;
518 return false;
519 }
520
521 // Stop dragging and eat event
522 drag_state = NOT_DRAGGING;
523 event->accept();
524 return true;
525 }
526
527 // type == QEvent::MouseMove
528 if (drag_state == NOT_DRAGGING)
529 return false;
530
531 // buttons() note the s
532 if (mouseEvent->buttons() != Qt::LeftButton) {
533 drag_state = NOT_DRAGGING;
534 return false;
535 }
536
537 QPoint pos = mouseEvent->globalPos();
538 QPoint diff = pos - start_drag;
539 if (drag_state == START_DRAGGING) {
540 // Don't start dragging before moving at least DRAG_THRESHOLD pixels
541 if (abs(diff.x()) < DRAG_THRESHOLD && abs(diff.y()) < DRAG_THRESHOLD)
542 return false;
543
544 drag_state = DRAGGING;
545 }
546
547 emit mouseMovedDiff(diff);
548 start_drag = pos;
549 event->accept();
550 return true;
551}
552
553QSize MplayerWindow::sizeHint() const {
554 //qDebug("MplayerWindow::sizeHint");
555 return QSize( video_width, video_height );
556}
557
558QSize MplayerWindow::minimumSizeHint () const {
559 return QSize(0,0);
560}
561
562void MplayerWindow::setOffsetX( int d) {
563 offset_x = d;
564 mplayerlayer->move( orig_x + offset_x, mplayerlayer->y() );
565}
566
567int MplayerWindow::offsetX() { return offset_x; }
568
569void MplayerWindow::setOffsetY( int d) {
570 offset_y = d;
571 mplayerlayer->move( mplayerlayer->x(), orig_y + offset_y );
572}
573
574int MplayerWindow::offsetY() { return offset_y; }
575
576void MplayerWindow::setZoom( double d) {
577 zoom_factor = d;
578 offset_x = 0;
579 offset_y = 0;
580
581 int x = orig_x;
582 int y = orig_y;
583 int w = orig_width;
584 int h = orig_height;
585
586 if (zoom_factor != 1.0) {
587 w = w * zoom_factor;
588 h = h * zoom_factor;
589
590 // Center
591 x = (width() - w) / 2;
592 y = (height() -h) / 2;
593 }
594
595 mplayerlayer->move(x,y);
596 mplayerlayer->resize(w,h);
597}
598
599double MplayerWindow::zoom() { return zoom_factor; }
600
601void MplayerWindow::moveLayer( int offset_x, int offset_y ) {
602 int x = mplayerlayer->x();
603 int y = mplayerlayer->y();
604
605 mplayerlayer->move( x + offset_x, y + offset_y );
606}
607
608void MplayerWindow::moveLeft() {
609 if ((allow_video_movement) || (mplayerlayer->x()+mplayerlayer->width() > width() ))
610 moveLayer( -16, 0 );
611}
612
613void MplayerWindow::moveRight() {
614 if ((allow_video_movement) || ( mplayerlayer->x() < 0 ))
615 moveLayer( +16, 0 );
616}
617
618void MplayerWindow::moveUp() {
619 if ((allow_video_movement) || (mplayerlayer->y()+mplayerlayer->height() > height() ))
620 moveLayer( 0, -16 );
621}
622
623void MplayerWindow::moveDown() {
624 if ((allow_video_movement) || ( mplayerlayer->y() < 0 ))
625 moveLayer( 0, +16 );
626}
627
628void MplayerWindow::incZoom() {
629 setZoom( zoom_factor + ZOOM_STEP );
630}
631
632void MplayerWindow::decZoom() {
633 double zoom = zoom_factor - ZOOM_STEP;
634 if (zoom < ZOOM_MIN) zoom = ZOOM_MIN;
635 setZoom( zoom );
636}
637
638// Language change stuff
639void MplayerWindow::changeEvent(QEvent *e) {
640 if (e->type() == QEvent::LanguageChange) {
641 retranslateStrings();
642 } else {
643 QWidget::changeEvent(e);
644 }
645}
646
647#include "moc_mplayerwindow.cpp"
Note: See TracBrowser for help on using the repository browser.