00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define BACKGROUND_RED 0xff
00053 #define BACKGROUND_GREEN 0xff
00054 #define BACKGROUND_BLUE 0xff
00055 #define BACKGROUND_ALPHA 0xcf
00056
00057 #define SLIDE_DURATION 400
00058
00059
00060
00061
00062
00063 #include <OpenFlipper/common/GlobalOptions.hh>
00064
00065 #include <QPainter>
00066 #include <QGraphicsSceneMouseEvent>
00067 #include <QTimeLine>
00068 #include <QGraphicsItemAnimation>
00069 #include <QGraphicsScene>
00070 #include <QGraphicsView>
00071 #include <QDialog>
00072 #include <QVBoxLayout>
00073
00074 #include "QtSlideWindow.hh"
00075 #include "QtGraphicsButton.hh"
00076
00077
00078
00079
00080 QtSlideWindow::QtSlideWindow(QString _name, QGraphicsItem *_parent) :
00081 QGraphicsProxyWidget(_parent),
00082 name_(_name),
00083 mainWidget_(0),
00084 autohideButton_(0),
00085 detachButton_(0),
00086 hideAnimation_(0),
00087 dialog_(0),
00088 tempWidget_(new QWidget)
00089 {
00090 setCacheMode (QGraphicsItem::DeviceCoordinateCache);
00091 setWindowFrameMargins (2, 15, 2, 2);
00092 setZValue (2.0);
00093
00094 QImage autohide (OpenFlipper::Options::iconDirStr () + OpenFlipper::Options::dirSeparator () + "button-autohide.png");
00095 QImage detach (OpenFlipper::Options::iconDirStr () + OpenFlipper::Options::dirSeparator () + "button-detach.png");
00096
00097 autohideButton_ = new QtGraphicsButton (autohide, this, 12, 12);
00098 detachButton_ = new QtGraphicsButton (detach, this, 12, 12);
00099
00100 autohideButton_->setCheckable (true);
00101 autohideButton_->setChecked (true);
00102 autohideButton_->setPos (geometry().width() - 12, -13);
00103 detachButton_->setPos (geometry().width() - 25, -13);
00104
00105 connect (detachButton_, SIGNAL(pressed ()), this, SLOT(detachPressed ()));
00106 connect (autohideButton_, SIGNAL(pressed ()), this, SLOT(autohidePressed ()));
00107
00108 hideTimeLine_ = new QTimeLine (SLIDE_DURATION);
00109 hideTimeLine_->setFrameRange (0, 100);
00110
00111 hideAnimation_ = new QGraphicsItemAnimation;
00112 hideAnimation_->setItem (this);
00113 hideAnimation_->setTimeLine (hideTimeLine_);
00114
00115 hideAnimation_->setTranslationAt (0.0, 0, geometry ().height ());
00116 for (int i = 0; i < geometry ().height (); ++i)
00117 hideAnimation_->setTranslationAt (0.25 + (i / (geometry ().height () * 2.0)), 0, geometry ().height () - i);
00118 hideAnimation_->setTranslationAt (1.0, 0, 0);
00119
00120 hide ();
00121 connect (hideTimeLine_, SIGNAL(finished()), this, SLOT(timelineFinished()));
00122
00123 setAcceptsHoverEvents (true);
00124 }
00125
00126
00127
00128 void QtSlideWindow::attachWidget (QWidget *_m)
00129 {
00130 if (!_m)
00131 return;
00132
00133 mainWidget_ = _m;
00134 mainWidget_->setParent(0);
00135
00136 if (autohideButton_->isChecked ())
00137 {
00138 tempWidget_->setGeometry (mainWidget_->geometry ());
00139 setWidget (tempWidget_);
00140 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
00141
00142 show ();
00143 hideTimeLine_->setCurrentTime (0);
00144 hideAnimation_->setStep (0.0);
00145 }
00146 else
00147 {
00148 setWidget (mainWidget_);
00149 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
00150
00151 show ();
00152 hideTimeLine_->setCurrentTime (SLIDE_DURATION);
00153 hideAnimation_->setStep (1.0);
00154 }
00155 updateGeometry ();
00156 }
00157
00158
00159
00160 void QtSlideWindow::detachWidget ()
00161 {
00162 setWidget (0);
00163 hide ();
00164 mainWidget_->setParent(0);
00165 mainWidget_ = 0;
00166
00167 if (dialog_)
00168 {
00169 disconnect (dialog_, SIGNAL(finished (int)), this, SLOT(dialogClosed ()));
00170 dialog_->close ();
00171 delete dialog_;
00172 dialog_ = 0;
00173 }
00174 }
00175
00176
00177
00178 void QtSlideWindow::paintWindowFrame(QPainter *_painter,
00179 const QStyleOptionGraphicsItem* ,
00180 QWidget* )
00181 {
00182 int w = geometry().width();
00183 int h = geometry().height();
00184
00185 _painter->setRenderHint(QPainter::Antialiasing, true);
00186 _painter->setBrush(QBrush(QColor(BACKGROUND_RED,
00187 BACKGROUND_GREEN,
00188 BACKGROUND_BLUE,
00189 BACKGROUND_ALPHA)));
00190 _painter->setPen(QColor(BACKGROUND_RED / 4,
00191 BACKGROUND_GREEN / 4,
00192 BACKGROUND_BLUE / 4,
00193 BACKGROUND_ALPHA));
00194 _painter->drawRoundedRect(-2, -15, w + 4, h + 40, 4, 4);
00195
00196 _painter->setPen(Qt::SolidLine);
00197
00198 _painter->drawText(2,-13,w - 4, 11, Qt::AlignCenter, name_);
00199
00200 }
00201
00202
00203
00204 bool QtSlideWindow::windowFrameEvent(QEvent *_e)
00205 {
00206 if (_e->type() == QEvent::GraphicsSceneMousePress ||
00207 _e->type() == QEvent::GraphicsSceneMouseRelease)
00208 {
00209 QGraphicsSceneMouseEvent *ge = dynamic_cast<QGraphicsSceneMouseEvent*>(_e);
00210 if (windowFrameSectionAt(ge->pos()) != Qt::TopSection)
00211 {
00212 _e->accept();
00213 return false;
00214 }
00215 }
00216 return QGraphicsProxyWidget::windowFrameEvent(_e);
00217 }
00218
00219
00220
00221 Qt::WindowFrameSection QtSlideWindow::windowFrameSectionAt(const QPointF &_pos) const
00222 {
00223 if (_pos.x() >= 2 && _pos.x() < geometry().width() - 2 - (13 * 2) &&
00224 _pos.y() >= -15 && _pos.y() <= -10)
00225 {
00226 return Qt::TopSection;
00227 }
00228 return Qt::NoSection;
00229 }
00230
00231
00232
00233 void QtSlideWindow::hoverEnterEvent (QGraphicsSceneHoverEvent *)
00234 {
00235 if (autohideButton_->isChecked () && hideTimeLine_->currentTime() != SLIDE_DURATION)
00236 {
00237 hideTimeLine_->setDirection (QTimeLine::Forward);
00238 if (hideTimeLine_->state () == QTimeLine::NotRunning)
00239 hideTimeLine_->start ();
00240 }
00241 if (!mainWidget_->isVisible ())
00242 {
00243 mainWidget_->setGeometry (tempWidget_->geometry ());
00244 setWidget (mainWidget_);
00245 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
00246 show ();
00247 }
00248 }
00249
00250
00251
00252 void QtSlideWindow::hoverLeaveEvent (QGraphicsSceneHoverEvent *)
00253 {
00254 if (autohideButton_->isChecked () &&
00255 (!scene ()->mouseGrabberItem () || !childItems ().contains (scene ()->mouseGrabberItem ())))
00256 {
00257 hideTimeLine_->setDirection (QTimeLine::Backward);
00258 if (hideTimeLine_->state () == QTimeLine::NotRunning)
00259 hideTimeLine_->start ();
00260 }
00261 }
00262
00263
00264
00265 void QtSlideWindow::resizeEvent (QGraphicsSceneResizeEvent *_event)
00266 {
00267 QGraphicsProxyWidget::resizeEvent (_event);
00268 if (hideAnimation_)
00269 {
00270 hideAnimation_->clear ();
00271 hideAnimation_->setTranslationAt (0.0, 0, geometry ().height ());
00272 for (int i = 0; i < geometry ().height (); ++i)
00273 hideAnimation_->setTranslationAt (0.25 + (i / (geometry ().height () * 2.0)), 0, geometry ().height () - i);
00274 hideAnimation_->setTranslationAt (1.0, 0, 0);
00275 }
00276 }
00277
00278
00279
00280 void QtSlideWindow::moveEvent (QGraphicsSceneMoveEvent *_event)
00281 {
00282 QGraphicsProxyWidget::moveEvent (_event);
00283 if (hideAnimation_)
00284 {
00285 hideAnimation_->clear ();
00286 hideAnimation_->setTranslationAt (0.0, 0, geometry ().height ());
00287 for (int i = 0; i < geometry ().height (); ++i)
00288 hideAnimation_->setTranslationAt (0.25 + (i / (geometry ().height () * 2.0)), 0, geometry ().height () - i);
00289 hideAnimation_->setTranslationAt (1.0, 0, 0);
00290 }
00291 }
00292
00293
00294
00295 void QtSlideWindow::detachPressed ()
00296 {
00297 setWidget (0);
00298 dialog_ = new QDialog(0, Qt::Window);
00299 dialog_->setWindowTitle (name_);
00300 dialog_->setLayout (new QVBoxLayout);
00301 dialog_->resize (mainWidget_->size ());
00302 dialog_->layout ()->addWidget (mainWidget_);
00303 if (scene () && scene ()->views ()[0] && scene ()->views ()[0]->window ())
00304 {
00305 QWidget *w = scene ()->views ()[0]->window ();
00306 int x = (w->width () - mainWidget_->width ()) / 2;
00307 x += w->x ();
00308 x = qMax (0, x);
00309 int y = (w->height () - mainWidget_->height ()) / 2;
00310 y += w->y ();
00311 y = qMax (0, y);
00312 dialog_->move (x, y);
00313 }
00314 hide ();
00315 dialog_->show ();
00316 mainWidget_->setAttribute(Qt::WA_DeleteOnClose, false);
00317 connect (dialog_, SIGNAL(finished (int)), this, SLOT(dialogClosed ()));
00318
00319 }
00320
00321
00322
00323 void QtSlideWindow::dialogClosed ()
00324 {
00325 dialog_ = 0;
00326 mainWidget_->setParent(0);
00327 setWidget (mainWidget_);
00328 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
00329 mainWidget_->setAttribute(Qt::WA_DeleteOnClose, true);
00330 show ();
00331 if (autohideButton_->isChecked ())
00332 {
00333 hideTimeLine_->setCurrentTime (0);
00334 hideAnimation_->setStep (0.0);
00335 }
00336 else
00337 {
00338 hideTimeLine_->setCurrentTime (SLIDE_DURATION);
00339 hideAnimation_->setStep (1.0);
00340 }
00341 updateGeometry ();
00342
00343 }
00344
00345
00346
00347 void QtSlideWindow::autohidePressed ()
00348 {
00349 if (!autohideButton_->isChecked ())
00350 {
00351 hideTimeLine_->setDirection (QTimeLine::Forward);
00352 if (hideTimeLine_->state () == QTimeLine::NotRunning &&
00353 hideTimeLine_->currentTime () != SLIDE_DURATION)
00354 hideTimeLine_->start ();
00355 }
00356 }
00357
00358
00359
00360 void QtSlideWindow::updateGeometry ()
00361 {
00362 if (parentWidget () && widget ())
00363 {
00364 setPos (8, parentWidget ()->geometry ().height () - geometry ().height ());
00365 resize (parentWidget ()->geometry ().width () - 20,
00366 widget ()->size ().height ());
00367 if (autohideButton_)
00368 autohideButton_->setPos (geometry().width() - 12, -13);
00369 if (detachButton_)
00370 detachButton_->setPos (geometry().width() - 25, -13);
00371 }
00372 }
00373
00374
00375
00376 void QtSlideWindow::saveState (QSettings &_settings)
00377 {
00378 _settings.setValue ("AutoHide", autohideButton_->isChecked ());
00379 _settings.setValue ("Detached", (dialog_ != 0));
00380 _settings.setValue ("WidgedGeometry", (mainWidget_) ? mainWidget_->saveGeometry (): QByteArray());
00381 _settings.setValue ("DialogGeometry", (dialog_) ? dialog_->saveGeometry (): QByteArray());
00382 }
00383
00384
00385
00386 void QtSlideWindow::restoreState (QSettings &_settings)
00387 {
00388 autohideButton_->setChecked (_settings.value ("AutoHide", autohideButton_->isChecked ()).toBool ());
00389
00390 if (_settings.value ("Detached", false).toBool () && !dialog_ && mainWidget_)
00391 {
00392 detachPressed ();
00393 }
00394
00395 if (mainWidget_)
00396 {
00397 mainWidget_->restoreGeometry (_settings.value ("WidgedGeometry").toByteArray ());
00398 if (hideAnimation_)
00399 {
00400 hideAnimation_->clear ();
00401 hideAnimation_->setTranslationAt (0.0, 0, geometry ().height ());
00402 for (int i = 0; i < geometry ().height (); ++i)
00403 hideAnimation_->setTranslationAt (0.25 + (i / (geometry ().height () * 2.0)), 0, geometry ().height () - i);
00404 hideAnimation_->setTranslationAt (1.0, 0, 0);
00405 }
00406 }
00407
00408 if (autohideButton_->isChecked ())
00409 {
00410 hideTimeLine_->setCurrentTime (0);
00411 hideAnimation_->setStep (0.0);
00412 }
00413 else
00414 {
00415 hideTimeLine_->setCurrentTime (SLIDE_DURATION);
00416 hideAnimation_->setStep (1.0);
00417 if (!mainWidget_->isVisible ())
00418 {
00419 mainWidget_->setGeometry (tempWidget_->geometry ());
00420 setWidget (mainWidget_);
00421 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
00422 show ();
00423 }
00424 }
00425
00426 if (dialog_)
00427 dialog_->restoreGeometry (_settings.value ("DialogGeometry").toByteArray ());
00428 }
00429
00430
00431
00432 void QtSlideWindow::timelineFinished ()
00433 {
00434 if (hideTimeLine_->currentValue () == 0.0)
00435 {
00436 tempWidget_->setGeometry (mainWidget_->geometry ());
00437 setWidget (tempWidget_);
00438 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
00439 mainWidget_->setParent (0);
00440 mainWidget_->hide ();
00441 show ();
00442 }
00443 }
00444
00445
00446
00447