1 /*  smplayer, GUI front-end for mplayer.
2     Copyright (C) 2006-2013 Ricardo Villalba <ricardo@smplayer.info>
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 "floatingwidget.h"
20 #include "editabletoolbar.h"
21 #include <QTimer>
22 #include <QHBoxLayout>
23 
24 #ifndef OLD_ANIMATION
25 #include <QPropertyAnimation>
26 #endif
27 
FloatingWidget(QWidget * parent)28 FloatingWidget::FloatingWidget( QWidget * parent )
29 	: QWidget( parent, Qt::Window | Qt::FramelessWindowHint |
30                        Qt::WindowStaysOnTopHint )
31 {
32 #ifndef OLD_ANIMATION
33 	animation = 0;
34 #endif
35 
36 	setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum );
37 
38 	tb = new EditableToolbar;
39 	tb->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
40 
41 	QHBoxLayout *layout = new QHBoxLayout;
42 	layout->setSpacing(2);
43 	layout->setMargin(2);
44 	layout->addWidget(tb);
45 
46 	setLayout(layout);
47 
48 	_margin = 0;
49 	_animated = false;
50 #ifdef OLD_ANIMATION
51 	animation_timer = new QTimer(this);
52 	animation_timer->setInterval(2);
53 	connect( animation_timer, SIGNAL(timeout()), this, SLOT(animate()) );
54 #endif
55 	connect( &auto_hide_timer, SIGNAL(timeout()),
56              this, SLOT(checkUnderMouse()) );
57 	setAutoHide(true);
58 }
59 
~FloatingWidget()60 FloatingWidget::~FloatingWidget() {
61 #ifndef OLD_ANIMATION
62 	if (animation) delete animation;
63 #endif
64 }
65 
66 #ifndef Q_OS_WIN
setBypassWindowManager(bool b)67 void FloatingWidget::setBypassWindowManager(bool b) {
68 	if (b) {
69 		setWindowFlags(windowFlags() | Qt::X11BypassWindowManagerHint);
70 	}
71 	else {
72 		setWindowFlags(windowFlags() & ~Qt::X11BypassWindowManagerHint);
73 	}
74 }
75 #endif
76 
setAutoHide(bool b)77 void FloatingWidget::setAutoHide(bool b) {
78 	auto_hide = b;
79 
80 	if (b)
81 		auto_hide_timer.start(5000);
82 	else
83 		auto_hide_timer.stop();
84 }
85 
86 
showOver(QWidget * widget,int size,Place place)87 void FloatingWidget::showOver(QWidget * widget, int size, Place place) {
88 	qDebug("FloatingWidget::showOver");
89 
90 	int w = widget->width() * size / 100;
91 	int h = height();
92 	resize( w, h );
93 
94 	//qDebug("widget x: %d, y: %d, h: %d, w: %d", widget->x(), widget->y(), widget->width(), widget->height());
95 
96 	int x = (widget->width() - width() ) / 2;
97 	int y;
98 	if (place == Top)
99 		y = 0 + _margin;
100 	else
101 		y = widget->height() - height() - _margin;
102 
103 	QPoint p = widget->mapToGlobal(QPoint(x, y));
104 
105 	//qDebug("FloatingWidget::showOver: x: %d, y: %d, w: %d, h: %d", x, y, w, h);
106 	//qDebug("FloatingWidget::showOver: global x: %d global y: %d", p.x(), p.y());
107 	move(p);
108 
109 	if (isAnimated()) {
110 		Movement m = Upward;
111 		if (place == Top) m = Downward;
112 		showAnimated(p, m);
113 	} else {
114 		show();
115 	}
116 }
117 
showAnimated(QPoint final_position,Movement movement)118 void FloatingWidget::showAnimated(QPoint final_position, Movement movement) {
119 #ifndef OLD_ANIMATION
120 	show();
121 	if (!animation) {
122 		animation = new QPropertyAnimation(this, "pos");
123 	}
124 	animation->setDuration(300);
125 	animation->setEasingCurve(QEasingCurve::OutBounce);
126 	animation->setEndValue(final_position);
127 	QPoint initial_position = final_position;
128 	if (movement == Upward) {
129 		initial_position.setY( initial_position.y() + height() );
130 	} else {
131 		initial_position.setY( initial_position.y() - height() );
132 	}
133 	animation->setStartValue(initial_position);
134 
135 	animation->start();
136 #else
137 	current_movement = movement;
138 	final_y = final_position.y();
139 
140 	if (movement == Upward) {
141 		current_y = final_position.y() + height();
142 	} else {
143 		current_y = final_position.y() - height();
144 	}
145 
146 	move(x(), current_y);
147 	show();
148 
149 	animation_timer->start();
150 #endif
151 }
152 
153 #ifdef OLD_ANIMATION
animate()154 void FloatingWidget::animate() {
155 	if (current_y == final_y) {
156 		animation_timer->stop();
157 	} else {
158 		if (current_movement == Upward) current_y--; else current_y++;
159 		move(x(), current_y);
160 	}
161 }
162 #endif
163 
checkUnderMouse()164 void FloatingWidget::checkUnderMouse() {
165 	if (auto_hide) {
166 		//qDebug("FloatingWidget::checkUnderMouse");
167 		if ((isVisible()) && (!underMouse())) hide();
168 	}
169 }
170 
171 #include "moc_floatingwidget.cpp"
172