1 /*  smplayer, GUI front-end for mplayer.
2     Copyright (C) 2006-2021 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 "timeslider.h"
20 #include "helper.h"
21 
22 #include <QWheelEvent>
23 #include <QTimer>
24 #include <QToolTip>
25 #include <QStyleOption>
26 #include <QDebug>
27 
28 #define DEBUG 0
29 
TimeSlider(QWidget * parent)30 TimeSlider::TimeSlider( QWidget * parent ) : MySlider(parent)
31 	, dont_update(false)
32 	, position(0)
33 	, total_time(0)
34 {
35 	setMinimum(0);
36 #ifdef SEEKBAR_RESOLUTION
37 	setMaximum(SEEKBAR_RESOLUTION);
38 #else
39 	setMaximum(100);
40 #endif
41 
42 	setFocusPolicy( Qt::NoFocus );
43 	setSizePolicy( QSizePolicy::Expanding , QSizePolicy::Fixed );
44 
45 	connect( this, SIGNAL( sliderPressed() ), this, SLOT( stopUpdate() ) );
46 	connect( this, SIGNAL( sliderReleased() ), this, SLOT( resumeUpdate() ) );
47 	connect( this, SIGNAL( sliderReleased() ), this, SLOT( mouseReleased() ) );
48 	connect( this, SIGNAL( valueChanged(int) ), this, SLOT( valueChanged_slot(int) ) );
49 #if ENABLE_DELAYED_DRAGGING
50 	connect( this, SIGNAL(draggingPos(int) ), this, SLOT(checkDragging(int)) );
51 
52 	last_pos_to_send = -1;
53 	timer = new QTimer(this);
54 	connect( timer, SIGNAL(timeout()), this, SLOT(sendDelayedPos()) );
55 	timer->start(200);
56 #endif
57 }
58 
~TimeSlider()59 TimeSlider::~TimeSlider() {
60 }
61 
stopUpdate()62 void TimeSlider::stopUpdate() {
63 	#if DEBUG
64 	qDebug("TimeSlider::stopUpdate");
65 	#endif
66 	dont_update = true;
67 }
68 
resumeUpdate()69 void TimeSlider::resumeUpdate() {
70 	#if DEBUG
71 	qDebug("TimeSlider::resumeUpdate");
72 	#endif
73 	dont_update = false;
74 }
75 
mouseReleased()76 void TimeSlider::mouseReleased() {
77 	#if DEBUG
78 	qDebug("TimeSlider::mouseReleased");
79 	#endif
80 	emit posChanged( value() );
81 }
82 
valueChanged_slot(int v)83 void TimeSlider::valueChanged_slot(int v) {
84 	#if DEBUG
85 	qDebug("TimeSlider::changedValue_slot: %d", v);
86 	#endif
87 
88 	// Only to make things clear:
89 	bool dragging = dont_update;
90 	if (!dragging) {
91 		if (v!=position) {
92 			#if DEBUG
93 			qDebug(" emitting posChanged");
94 			#endif
95 			emit posChanged(v);
96 		}
97 	} else {
98 		#if DEBUG
99 		qDebug(" emitting draggingPos");
100 		#endif
101 		emit draggingPos(v);
102 	}
103 }
104 
105 #if ENABLE_DELAYED_DRAGGING
setDragDelay(int d)106 void TimeSlider::setDragDelay(int d) {
107 	qDebug("TimeSlider::setDragDelay: %d", d);
108 	timer->setInterval(d);
109 }
110 
dragDelay()111 int TimeSlider::dragDelay() {
112 	return timer->interval();
113 }
114 
checkDragging(int v)115 void TimeSlider::checkDragging(int v) {
116 	qDebug("TimeSlider::checkDragging: %d", v);
117 	last_pos_to_send = v;
118 }
119 
sendDelayedPos()120 void TimeSlider::sendDelayedPos() {
121 	if (last_pos_to_send != -1) {
122 		qDebug("TimeSlider::sendDelayedPos: %d", last_pos_to_send);
123 		emit delayedDraggingPos(last_pos_to_send);
124 		last_pos_to_send = -1;
125 	}
126 }
127 #endif
128 
setPos(int v)129 void TimeSlider::setPos(int v) {
130 	#if DEBUG
131 	qDebug("TimeSlider::setPos: %d", v);
132 	qDebug(" dont_update: %d", dont_update);
133 	#endif
134 
135 	if (v!=pos()) {
136 		if (!dont_update) {
137 			position = v;
138 			setValue(v);
139 		}
140 	}
141 }
142 
pos()143 int TimeSlider::pos() {
144 	return position;
145 }
146 
wheelEvent(QWheelEvent * e)147 void TimeSlider::wheelEvent(QWheelEvent * e) {
148 #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
149 	qDebug("TimeSlider::wheelEvent: delta: %d", e->angleDelta().y());
150 	e->accept();
151 	if (e->angleDelta().y() >= 0) emit wheelUp(); else emit wheelDown();
152 #else
153 	qDebug("TimeSlider::wheelEvent: delta: %d", e->delta());
154 	e->accept();
155 	if (e->orientation() == Qt::Vertical) {
156 		if (e->delta() >= 0) emit wheelUp(); else emit wheelDown();
157 	}
158 #endif
159 }
160 
event(QEvent * event)161 bool TimeSlider::event(QEvent *event) {
162 	if (event->type() == QEvent::ToolTip) {
163 		QHelpEvent * help_event = static_cast<QHelpEvent *>(event);
164 		//qDebug() << "TimeSlider::event: x:" << help_event->x() << "maximum:" << maximum() << "width:" << width() << "total_time:" << total_time;
165 
166 		QStyleOptionSlider opt;
167 		initStyleOption(&opt);
168 		const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
169 		const QPoint center = sliderRect.center() - sliderRect.topLeft();
170 
171 		int value = pixelPosToRangeValue(help_event->x() - center.x());
172 		int range = maximum() - minimum();
173 		qreal time = value * total_time / range;
174 		//qDebug() << "TimeSlider::event: value:" << value << "range:" << range << "time:" << time;
175 
176 		if (time >= 0 && time <= total_time) {
177 			QToolTip::showText(help_event->globalPos(), Helper::formatTime(time), this);
178 		} else {
179 			QToolTip::hideText();
180 			event->ignore();
181 		}
182 		return true;
183 	}
184 	return QWidget::event(event);
185 }
186 
187 #include "moc_timeslider.cpp"
188