Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
QtSlideWindow.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50 //=============================================================================
51 //
52 // CLASS QtSlideWindow
53 //
54 //=============================================================================
55
56
57 //== GLOBAL DEFINITIONS=========================================================
58
59 #define BACKGROUND_RED 0xff
60 #define BACKGROUND_GREEN 0xff
61 #define BACKGROUND_BLUE 0xff
62 #define BACKGROUND_ALPHA 0xcf
63
64 #define SLIDE_DURATION 300
65 #define WAIT_UNTIL_SLIDE_DOWN 500
66
67 //== INCLUDES =================================================================
68
69 #include <OpenFlipper/common/GlobalOptions.hh>
70
71 #include <QPainter>
72 #include <QGraphicsSceneMouseEvent>
73 #include <QGraphicsScene>
74 #include <QGraphicsView>
75 #include <QDialog>
76 #include <QVBoxLayout>
77
78 #include "QtSlideWindow.hh"
79 #include "QtGraphicsButton.hh"
80
81 //== IMPLEMENTATION ==========================================================
82
83 QtSlideWindow::QtSlideWindow(QString _name, QGraphicsItem *_parent) :
84 QGraphicsProxyWidget(_parent),
85 name_(_name),
86 mainWidget_(0),
87 autohideButton_(0),
88 detachButton_(0),
89 dialog_(0),
90 down_(false),
91 animating_(false),
92 timer_(0) {
93
94 setCacheMode(QGraphicsItem::DeviceCoordinateCache);
95 setWindowFrameMargins(2, 15, 2, 2);
96 setZValue(2.0);
97
98 QImage autohide(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "button-autohide.png");
99 QImage detach(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "button-detach.png");
100
101 autohideButton_ = new QtGraphicsButton(autohide, this, 12, 12);
102 detachButton_ = new QtGraphicsButton(detach, this, 12, 12);
103
104 autohideButton_->setCheckable(true);
105 autohideButton_->setChecked(true);
106 autohideButton_->setPos(geometry().width() - 12, -13);
107 detachButton_->setPos(geometry().width() - 25, -13);
108
109 connect(detachButton_, SIGNAL(pressed()), this, SLOT(detachPressed()));
110 connect(autohideButton_, SIGNAL(pressed()), this, SLOT(autohidePressed()));
111
112 // Create animation object
113 animation_ = new QPropertyAnimation(this, "pos");
114 animation_->setDuration(SLIDE_DURATION);
115 connect(animation_, SIGNAL(finished()), this, SLOT(animationFinished()));
116
117 // Create timer
118 timer_ = new QTimer();
119 timer_->setSingleShot(true);
120
121 // Wait some milliseconds before starting the actual slide down animation
122 connect(timer_, SIGNAL(timeout()), this, SLOT(startSlideDownAnimation()));
123
124 // Hide widget
125 hide();
126
127 setAcceptHoverEvents(true);
128
129 updateParentGeometry();
130 }
131
132 //-----------------------------------------------------------------------------
133
134 void QtSlideWindow::attachWidget(QWidget *_m) {
135
136 if (!_m)
137 return;
138
139 mainWidget_ = _m;
140 mainWidget_->setParent(0);
141
142 if (autohideButton_->isChecked()) {
143 setWidget(mainWidget_);
144 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
145
146 down_ = true;
147
148 show();
149 }
150 updateGeometry();
151 }
152
153 //-----------------------------------------------------------------------------
154
155 void QtSlideWindow::detachWidget() {
156
157 setWidget(0);
158 hide();
159
160 if (mainWidget_) {
161 mainWidget_->setParent(0);
162 mainWidget_ = 0;
163 }
164
165 if (dialog_) {
166 disconnect (dialog_, SIGNAL(finished (int)), this, SLOT(dialogClosed ()));
167 dialog_->close();
168 delete dialog_;
169 dialog_ = 0;
170 }
171 }
172
173 //-----------------------------------------------------------------------------
174
175 void QtSlideWindow::paintWindowFrame(QPainter *_painter, const QStyleOptionGraphicsItem* /*_option*/, QWidget* /*_widget*/) {
176
177 int w = geometry().width();
178 int h = geometry().height();
179
180 _painter->setRenderHint(QPainter::Antialiasing, true);
181 _painter->setBrush(QBrush(QColor(BACKGROUND_RED, BACKGROUND_GREEN, BACKGROUND_BLUE, BACKGROUND_ALPHA)));
182 _painter->setPen(QColor(BACKGROUND_RED / 4, BACKGROUND_GREEN / 4, BACKGROUND_BLUE / 4, BACKGROUND_ALPHA));
183 _painter->drawRoundedRect(-2, -15, w + 4, h + 40, 4, 4);
184
185 _painter->setPen(Qt::SolidLine);
186
187 _painter->drawText(2, -13, w - 4, 11, Qt::AlignCenter, name_);
188 }
189
190 //-----------------------------------------------------------------------------
191
192 bool QtSlideWindow::windowFrameEvent(QEvent *_e) {
193
194 if(_e->type() == QEvent::GraphicsSceneMousePress || _e->type() == QEvent::GraphicsSceneMouseRelease) {
195 QGraphicsSceneMouseEvent *ge = dynamic_cast<QGraphicsSceneMouseEvent*> (_e);
196 if(windowFrameSectionAt(ge->pos()) != Qt::TopSection) {
197 _e->accept();
198 return false;
199 }
200 }
201
202 return QGraphicsProxyWidget::windowFrameEvent(_e);
203 }
204
205 //-----------------------------------------------------------------------------
206
207 Qt::WindowFrameSection QtSlideWindow::windowFrameSectionAt(const QPointF &_pos) const {
208
209 if (_pos.x() >= 2 && _pos.x() < geometry().width() - 2 - (13 * 2) && _pos.y() >= -15 && _pos.y() <= -10) {
210 return Qt::TopSection;
211 }
212
213 return Qt::NoSection;
214 }
215
216 //-----------------------------------------------------------------------------
217
218 void QtSlideWindow::hoverEnterEvent(QGraphicsSceneHoverEvent *) {
219
220 // Stop slide down action after timeout if the cursor
221 // re-enters the logger within the timeout interval
222 if(timer_->isActive()) {
223 timer_->stop();
224 return;
225 }
226
227 // Don't do anything if animation is currently in progress
228 if(animating_) return;
229
230 if (autohideButton_->isChecked() && down_) {
231 slideUp();
232 }
233 if (!mainWidget_->isVisible()) {
234 setWidget(mainWidget_);
235 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
236 show();
237 }
238 }
239
240 //-----------------------------------------------------------------------------
241
242 void QtSlideWindow::hoverLeaveEvent(QGraphicsSceneHoverEvent *) {
243
244 // Don't do anything if animation is currently in progress
245 if(animating_) return;
246
247 if (autohideButton_->isChecked() && !down_) {
248 slideDown();
249 }
250 }
251
252 //-----------------------------------------------------------------------------
253
254 void QtSlideWindow::resizeEvent(QGraphicsSceneResizeEvent *_event) {
255
256 QGraphicsProxyWidget::resizeEvent(_event);
257 }
258
259 //-----------------------------------------------------------------------------
260
261 void QtSlideWindow::moveEvent(QGraphicsSceneMoveEvent *_event) {
262
263 QGraphicsProxyWidget::moveEvent(_event);
264 }
265
266 //-----------------------------------------------------------------------------
267
268 void QtSlideWindow::detachPressed() {
269
270 setWidget(0);
271
272 dialog_ = new QDialog(0, Qt::Window);
273 dialog_->setWindowTitle(name_);
274 dialog_->setLayout(new QVBoxLayout);
275 dialog_->resize(mainWidget_->size());
276 dialog_->layout()->addWidget(mainWidget_);
277
278 if (scene() && scene()->views()[0] && scene()->views()[0]->window()) {
279 QWidget *w = scene()->views()[0]->window();
280 int x = (w->width() - mainWidget_->width()) / 2;
281 x += w->x();
282 x = qMax(0, x);
283 int y = (w->height() - mainWidget_->height()) / 2;
284 y += w->y();
285 y = qMax(0, y);
286 dialog_->move(x, y);
287 }
288
289 hide();
290
291 dialog_->show();
292 connect (dialog_, SIGNAL(finished (int)), this, SLOT(dialogClosed ()));
293 }
294
295 //-----------------------------------------------------------------------------
296
297 void QtSlideWindow::dialogClosed() {
298
299 dialog_ = 0;
300 mainWidget_->setParent(0);
301
302 setWidget(mainWidget_);
303 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
304
305 show();
306
307 updateGeometry();
308 }
309
310 //-----------------------------------------------------------------------------
311
312 void QtSlideWindow::autohidePressed() {
313
314 if(!autohideButton_->isChecked() && down_) {
315 slideUp();
316 }
317 }
318
319 //-----------------------------------------------------------------------------
320
321 void QtSlideWindow::updateParentGeometry() {
322
323 startP_.setX(10);
324 startP_.setY(parentWidget()->geometry().height() - geometry().height());
325
326 endP_.setX(10);
327 endP_.setY(parentWidget()->geometry().height() - (size().height() - geometry().height()));
328 }
329
330 //-----------------------------------------------------------------------------
331
332 void QtSlideWindow::animationFinished() {
333
334 animating_ = false;
335
336 // If we reached up position,
337 // check if the mouse is still inside (could leave in between as we block the leave event
338 // when animating to avoid flickering
339 // If mouse is not inside anymore, we start the countdown for slideDown
340 if ( !down_ && !isUnderMouse() )
341 timer_->start(WAIT_UNTIL_SLIDE_DOWN);
342 }
343
344 //-----------------------------------------------------------------------------
345
346 void QtSlideWindow::slideUp() {
347
348 if(!widget()) return;
349
350 updateParentGeometry();
351
352 down_ = false;
353 animating_ = true;
354
355 animation_->setStartValue(endP_);
356 animation_->setEndValue(startP_);
357
358 animation_->start();
359 }
360
361 //-----------------------------------------------------------------------------
362
363 void QtSlideWindow::slideDown() {
364
365 if(!widget()) return;
366
367 updateParentGeometry();
368
369 timer_->start(WAIT_UNTIL_SLIDE_DOWN);
370 }
371
372 //-----------------------------------------------------------------------------
373
374 void QtSlideWindow::startSlideDownAnimation() {
375
376 down_ = true;
377 animating_ = true;
378
379 animation_->setStartValue(startP_);
380 animation_->setEndValue(endP_);
381
382 animation_->start();
383 }
384
385 //-----------------------------------------------------------------------------
386
387 void QtSlideWindow::updateGeometry() {
388
389 if (parentWidget() && widget()) {
390
391 updateParentGeometry();
392
393 resize(parentWidget()->geometry().width() - 20, widget()->size().height());
394
395 if(down_) {
396 setPos(endP_);
397 } else {
398 setPos(startP_);
399 }
400
401 if (autohideButton_) {
402 autohideButton_->setPos(geometry().width() - 12, -13);
403 }
404 if (detachButton_) {
405 detachButton_->setPos(geometry().width() - 25, -13);
406 }
407 }
408 }
409
410 //-----------------------------------------------------------------------------
411
412 void QtSlideWindow::saveState(QSettings &_settings) {
413
414 _settings.setValue("AutoHide", autohideButton_->isChecked());
415 _settings.setValue("Detached", (dialog_ != 0));
416 _settings.setValue("WidgedGeometry", (mainWidget_) ? mainWidget_->saveGeometry() : QByteArray());
417 _settings.setValue("DialogGeometry", (dialog_) ? dialog_->saveGeometry() : QByteArray());
418 }
419
420 //-----------------------------------------------------------------------------
421
422 void QtSlideWindow::restoreState(QSettings &_settings) {
423
424 autohideButton_->setChecked(_settings.value("AutoHide", autohideButton_->isChecked()).toBool());
425
426 if (_settings.value("Detached", false).toBool() && !dialog_ && mainWidget_) {
427 detachPressed();
428 }
429
430 if (mainWidget_) {
431 mainWidget_->restoreGeometry(_settings.value("WidgedGeometry").toByteArray());
432 }
433
434 if (autohideButton_->isChecked()) {
435
436 } else {
437 if (!mainWidget_->isVisible()) {
438 setWidget(mainWidget_);
439 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
440 show();
441 }
442 }
443
444 if (dialog_)
445 dialog_->restoreGeometry(_settings.value("DialogGeometry").toByteArray());
446 }
447
448 //=============================================================================
449
QtGraphicsButton::isChecked
bool isChecked() const
returns button checked state
Definition: QtGraphicsButton.cc:139
QtSlideWindow::autohidePressed
void autohidePressed()
autohide button presed
Definition: QtSlideWindow.cc:312
QtGraphicsButton::setChecked
void setChecked(bool _value)
sets button checked state
Definition: QtGraphicsButton.cc:132
QtSlideWindow::restoreState
void restoreState(QSettings &_settings)
restores the state
Definition: QtSlideWindow.cc:422
QtGraphicsButton
Definition: QtGraphicsButton.hh:71
QtSlideWindow::updateParentGeometry
void updateParentGeometry()
Call this to correctly set start and ending positions.
Definition: QtSlideWindow.cc:321
QtSlideWindow::saveState
void saveState(QSettings &_settings)
saves the current state
Definition: QtSlideWindow.cc:412
QtGraphicsButton::setCheckable
void setCheckable(bool _value)
makes the button checkable
Definition: QtGraphicsButton.cc:125
QtSlideWindow::paintWindowFrame
virtual void paintWindowFrame(QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget=0)
paints decoration
Definition: QtSlideWindow.cc:175
QtSlideWindow::animationFinished
void animationFinished()
Slot is called whenever the animation is finished.
Definition: QtSlideWindow.cc:332
QtSlideWindow::updateGeometry
void updateGeometry()
recalculate geometry
Definition: QtSlideWindow.cc:387
QtSlideWindow::windowFrameEvent
virtual bool windowFrameEvent(QEvent *_e)
track frame events
Definition: QtSlideWindow.cc:192
QtSlideWindow::hoverEnterEvent
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *_event)
hove event tracking
Definition: QtSlideWindow.cc:218
QtSlideWindow::dialogClosed
void dialogClosed()
detached dialog closed
Definition: QtSlideWindow.cc:297
QtSlideWindow::detachWidget
void detachWidget()
detach child widget
Definition: QtSlideWindow.cc:155
QtSlideWindow::startSlideDownAnimation
void startSlideDownAnimation()
Start actual slide down.
Definition: QtSlideWindow.cc:374
QtSlideWindow::attachWidget
void attachWidget(QWidget *_m)
attach a child widget
Definition: QtSlideWindow.cc:134
QtSlideWindow::windowFrameSectionAt
virtual Qt::WindowFrameSection windowFrameSectionAt(const QPointF &_pos) const
categorize frame area
Definition: QtSlideWindow.cc:207
GlobalOptions.hh
QtSlideWindow::resizeEvent
virtual void resizeEvent(QGraphicsSceneResizeEvent *_event)
size & position event tracking
Definition: QtSlideWindow.cc:254
QtSlideWindow::detachPressed
void detachPressed()
detach button pressed
Definition: QtSlideWindow.cc:268
QtSlideWindow::slideDown
void slideDown()
Slide widget down.
Definition: QtSlideWindow.cc:363
QtSlideWindow::QtSlideWindow
QtSlideWindow(QString _name=0, QGraphicsItem *_parent=0)
Definition: QtSlideWindow.cc:83
QtSlideWindow::slideUp
void slideUp()
Slide widget up.
Definition: QtSlideWindow.cc:346