QtSlideWindow.cc

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 6850 $                                                         *
00038  *   $Author: moebius $                                                      *
00039  *   $Date: 2009-08-11 19:05:47 +0200 (Di, 11. Aug 2009) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 //=============================================================================
00044 //
00045 //  CLASS QtSlideWindow
00046 //
00047 //=============================================================================
00048 
00049 
00050 //== GLOBAL DEFINITIONS=========================================================
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 //== INCLUDES =================================================================
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 //== IMPLEMENTATION ==========================================================
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* /*_option*/,
00180                                      QWidget* /*_widget*/ )
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 

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .