source: smplayer/trunk/src/autohidewidget.cpp

Last change on this file was 188, checked in by Silvan Scherrer, 8 years ago

SMPlayer: update trunk to version 17.1.0

File size: 6.7 KB
Line 
1/* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2017 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 "autohidewidget.h"
20#include <QTimer>
21#include <QEvent>
22#include <QVBoxLayout>
23#include <QMouseEvent>
24#include <QAction>
25#include <QMenu>
26#include <QDebug>
27
28#if QT_VERSION >= 0x040600
29#include <QPropertyAnimation>
30#endif
31
32#define HANDLE_TAP_EVENT
33
34#ifdef HANDLE_TAP_EVENT
35#include <QGestureEvent>
36#endif
37
38AutohideWidget::AutohideWidget(QWidget * parent)
39 : QWidget(parent)
40 , turned_on(false)
41 , auto_hide(false)
42 , use_animation(false)
43 , spacing(0)
44 , perc_width(100)
45 , activation_area(Anywhere)
46 , internal_widget(0)
47 , timer(0)
48#if QT_VERSION >= 0x040600
49 , animation(0)
50#endif
51{
52 setBackgroundRole(QPalette::Window);
53 setAutoFillBackground(true);
54 setLayoutDirection(Qt::LeftToRight);
55
56 QWidget * widget_to_watch = parent;
57 widget_to_watch->installEventFilter(this);
58 installFilter(widget_to_watch);
59
60 timer = new QTimer(this);
61 connect(timer, SIGNAL(timeout()), this, SLOT(checkUnderMouse()));
62 timer->setInterval(3000);
63
64 QVBoxLayout *layout = new QVBoxLayout;
65 layout->setSpacing(0);
66 layout->setMargin(0);
67 setLayout(layout);
68}
69
70AutohideWidget::~AutohideWidget() {
71#if QT_VERSION >= 0x040600
72 if (animation) delete animation;
73#endif
74}
75
76void AutohideWidget::setInternalWidget(QWidget * w) {
77 //qDebug() << "AutohideWidget::setInternalWidget:" << w;
78 layout()->addWidget(w);
79 internal_widget = w;
80}
81
82void AutohideWidget::setHideDelay(int ms) {
83 timer->setInterval(ms);
84}
85
86int AutohideWidget::hideDelay() {
87 return timer->interval();
88}
89
90void AutohideWidget::installFilter(QObject *o) {
91 QObjectList children = o->children();
92 for (int n=0; n < children.count(); n++) {
93 if (children[n]->isWidgetType()) {
94 qDebug() << "AutohideWidget::installFilter: child name:" << children[n]->objectName();
95 QWidget *w = static_cast<QWidget *>(children[n]);
96 w->setMouseTracking(true);
97 w->installEventFilter(this);
98 installFilter(children[n]);
99 #ifdef HANDLE_TAP_EVENT
100 //w->grabGesture(Qt::TapGesture);
101 #endif
102 }
103 }
104}
105
106bool AutohideWidget::visiblePopups() {
107 //qDebug() << "AutohideWidget::visiblePopups: internal_widget:" << internal_widget;
108 if (!internal_widget) return false;
109
110 // Check if any of the menus in the internal widget is visible
111 QObjectList children = internal_widget->children();
112 foreach(QObject * child, children) {
113 if (child->isWidgetType()) {
114 //qDebug() << "AutohideWidget::visiblePopups:" << child << "child name:" << child->objectName();
115 QWidget *w = static_cast<QWidget *>(child);
116
117 QList<QAction *> actions = w->actions();
118 foreach(QAction * action, actions) {
119 //qDebug() << "AutohideWidget::visiblePopups: action:" << action;
120
121 QList<QWidget *> aw = action->associatedWidgets();
122 //qDebug() << "AutohideWidget::visiblePopups: aw:" << aw;
123
124 QMenu * menu = 0;
125 foreach(QWidget * widget, aw) {
126 //qDebug() << "AutohideWidget::visiblePopups: widget:" << widget;
127 if ((menu = qobject_cast<QMenu *>(widget))) {
128 //qDebug() << "AutohideWidget::visiblePopups: menu:" << menu << "visible:" << menu->isVisible();
129 if (menu->isVisible()) return true;
130 }
131 }
132
133 menu = action->menu();
134 if (menu) {
135 //qDebug() << "AutohideWidget::visiblePopups: menu:" << menu << "visible:" << menu->isVisible();
136 if (menu->isVisible()) return true;
137 }
138 }
139 }
140 }
141 return false;
142}
143
144void AutohideWidget::activate() {
145 turned_on = true;
146 timer->start();
147}
148
149void AutohideWidget::deactivate() {
150 turned_on = false;
151 timer->stop();
152 hide();
153}
154
155void AutohideWidget::show() {
156 qDebug() << "AutohideWidget::show";
157 resizeAndMove();
158
159 if (use_animation) {
160 showAnimated();
161 } else {
162 QWidget::show();
163 }
164
165 // Restart timer
166 if (timer->isActive()) timer->start();
167}
168
169void AutohideWidget::setAutoHide(bool b) {
170 auto_hide = b;
171}
172
173void AutohideWidget::checkUnderMouse() {
174 if (auto_hide) {
175 //qDebug("AutohideWidget::checkUnderMouse");
176 if (isVisible() && !underMouse() && !visiblePopups()) {
177 hide();
178 }
179 }
180}
181
182void AutohideWidget::resizeAndMove() {
183 QWidget * widget = parentWidget();
184 int w = widget->width() * perc_width / 100;
185 int h = height();
186 resize(w, h);
187
188 int x = (widget->width() - width() ) / 2;
189 int y = widget->height() - height() - spacing;
190 move(x, y);
191}
192
193bool AutohideWidget::eventFilter(QObject * obj, QEvent * event) {
194 if (turned_on) {
195 //qDebug() << "AutohideWidget::eventFilter: obj:" << obj << "type:" << event->type();
196 #ifdef HANDLE_TAP_EVENT
197 if (event->type() == QEvent::Gesture) {
198 qDebug() << "AutohideWidget::eventFilter: obj:" << obj << "gesture:" << event;
199 QGestureEvent * gesture_event = static_cast<QGestureEvent*>(event);
200 if (gesture_event->gesture(Qt::TapGesture)) {
201 qDebug() << "AutohideWidget::eventFilter: tap event detected";
202 if (!isVisible()) show(); //else hide();
203 event->setAccepted(true);
204 return true;
205 }
206 }
207 else
208 #endif
209 if (event->type() == QEvent::MouseMove) {
210 //qDebug() << "AutohideWidget::eventFilter: mouse move" << obj;
211 if (!isVisible()) {
212 if (activation_area == Anywhere) {
213 show();
214 } else {
215 QMouseEvent * mouse_event = dynamic_cast<QMouseEvent*>(event);
216 QWidget * parent = parentWidget();
217 QPoint p = parent->mapFromGlobal(mouse_event->globalPos());
218 //qDebug() << "AutohideWidget::eventFilter: y:" << p.y();
219 if (p.y() > (parent->height() - height() - spacing)) {
220 show();
221 }
222 }
223 }
224 }
225 else
226 if (event->type() == QEvent::MouseButtonRelease && obj == this) {
227 event->setAccepted(true);
228 return true;
229 }
230 }
231
232 return QWidget::eventFilter(obj, event);
233}
234
235void AutohideWidget::showAnimated() {
236#if QT_VERSION >= 0x040600
237 if (!animation) {
238 animation = new QPropertyAnimation(this, "pos");
239 }
240
241 QPoint initial_position = QPoint(pos().x(), parentWidget()->size().height());
242 QPoint final_position = pos();
243 move(initial_position);
244
245 QWidget::show();
246
247 animation->setDuration(300);
248 animation->setEasingCurve(QEasingCurve::OutBounce);
249 animation->setEndValue(final_position);
250 animation->setStartValue(initial_position);
251 animation->start();
252#else
253 QWidget::show();
254#endif
255}
256
257#include "moc_autohidewidget.cpp"
258
Note: See TracBrowser for help on using the repository browser.