tools/shared/qtgradienteditor/qtgradientstopswidget.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the tools applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qtgradientstopswidget.h"
       
    43 #include "qtgradientstopsmodel.h"
       
    44 
       
    45 #include <QtCore/QMap>
       
    46 #include <QtGui/QImage>
       
    47 #include <QtGui/QPainter>
       
    48 #include <QtGui/QScrollBar>
       
    49 #include <QtGui/QMouseEvent>
       
    50 #include <QtGui/QRubberBand>
       
    51 #include <QtGui/QMenu>
       
    52 
       
    53 QT_BEGIN_NAMESPACE
       
    54 
       
    55 class QtGradientStopsWidgetPrivate
       
    56 {
       
    57     QtGradientStopsWidget *q_ptr;
       
    58     Q_DECLARE_PUBLIC(QtGradientStopsWidget)
       
    59 public:
       
    60     typedef QMap<qreal, QColor> PositionColorMap;
       
    61     typedef QMap<QtGradientStop *, qreal> StopPositionMap;
       
    62 
       
    63     void slotStopAdded(QtGradientStop *stop);
       
    64     void slotStopRemoved(QtGradientStop *stop);
       
    65     void slotStopMoved(QtGradientStop *stop, qreal newPos);
       
    66     void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
       
    67     void slotStopChanged(QtGradientStop *stop, const QColor &newColor);
       
    68     void slotStopSelected(QtGradientStop *stop, bool selected);
       
    69     void slotCurrentStopChanged(QtGradientStop *stop);
       
    70     void slotNewStop();
       
    71     void slotDelete();
       
    72     void slotFlipAll();
       
    73     void slotSelectAll();
       
    74     void slotZoomIn();
       
    75     void slotZoomOut();
       
    76     void slotResetZoom();
       
    77 
       
    78     double fromViewport(int x) const;
       
    79     double toViewport(double x) const;
       
    80     QtGradientStop *stopAt(const QPoint &viewportPos) const;
       
    81     QList<QtGradientStop *> stopsAt(const QPoint &viewportPos) const;
       
    82     void setupMove(QtGradientStop *stop, int x);
       
    83     void ensureVisible(double x); // x = stop position
       
    84     void ensureVisible(QtGradientStop *stop);
       
    85     QtGradientStop *newStop(const QPoint &viewportPos);
       
    86 
       
    87     bool m_backgroundCheckered;
       
    88     QtGradientStopsModel *m_model;
       
    89     double m_handleSize;
       
    90     int m_scaleFactor;
       
    91     double m_zoom;
       
    92 
       
    93 #ifndef QT_NO_DRAGANDDROP
       
    94     QtGradientStop *m_dragStop;
       
    95     QtGradientStop *m_changedStop;
       
    96     QtGradientStop *m_clonedStop;
       
    97     QtGradientStopsModel *m_dragModel;
       
    98     QColor m_dragColor;
       
    99     void clearDrag();
       
   100     void removeClonedStop();
       
   101     void restoreChangedStop();
       
   102     void changeStop(qreal pos);
       
   103     void cloneStop(qreal pos);
       
   104 #endif
       
   105 
       
   106     QRubberBand *m_rubber;
       
   107     QPoint m_clickPos;
       
   108 
       
   109     QList<QtGradientStop *> m_stops;
       
   110 
       
   111     bool m_moving;
       
   112     int m_moveOffset;
       
   113     StopPositionMap m_moveStops;
       
   114 
       
   115     PositionColorMap m_moveOriginal;
       
   116 };
       
   117 
       
   118 double QtGradientStopsWidgetPrivate::fromViewport(int x) const
       
   119 {
       
   120     QSize size = q_ptr->viewport()->size();
       
   121     int w = size.width();
       
   122     int max = q_ptr->horizontalScrollBar()->maximum();
       
   123     int val = q_ptr->horizontalScrollBar()->value();
       
   124     return ((double)x * m_scaleFactor + w * val) / (w * (m_scaleFactor + max));
       
   125 }
       
   126 
       
   127 double QtGradientStopsWidgetPrivate::toViewport(double x) const
       
   128 {
       
   129     QSize size = q_ptr->viewport()->size();
       
   130     int w = size.width();
       
   131     int max = q_ptr->horizontalScrollBar()->maximum();
       
   132     int val = q_ptr->horizontalScrollBar()->value();
       
   133     return w * (x * (m_scaleFactor + max) - val) / m_scaleFactor;
       
   134 }
       
   135 
       
   136 QtGradientStop *QtGradientStopsWidgetPrivate::stopAt(const QPoint &viewportPos) const
       
   137 {
       
   138     double posY = m_handleSize / 2;
       
   139     QListIterator<QtGradientStop *> itStop(m_stops);
       
   140     while (itStop.hasNext()) {
       
   141         QtGradientStop *stop = itStop.next();
       
   142 
       
   143         double posX = toViewport(stop->position());
       
   144 
       
   145         double x = viewportPos.x() - posX;
       
   146         double y = viewportPos.y() - posY;
       
   147 
       
   148         if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
       
   149             return stop;
       
   150     }
       
   151     return 0;
       
   152 }
       
   153 
       
   154 QList<QtGradientStop *> QtGradientStopsWidgetPrivate::stopsAt(const QPoint &viewportPos) const
       
   155 {
       
   156     QList<QtGradientStop *> stops;
       
   157     double posY = m_handleSize / 2;
       
   158     QListIterator<QtGradientStop *> itStop(m_stops);
       
   159     while (itStop.hasNext()) {
       
   160         QtGradientStop *stop = itStop.next();
       
   161 
       
   162         double posX = toViewport(stop->position());
       
   163 
       
   164         double x = viewportPos.x() - posX;
       
   165         double y = viewportPos.y() - posY;
       
   166 
       
   167         if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
       
   168             stops.append(stop);
       
   169     }
       
   170     return stops;
       
   171 }
       
   172 
       
   173 void QtGradientStopsWidgetPrivate::setupMove(QtGradientStop *stop, int x)
       
   174 {
       
   175     m_model->setCurrentStop(stop);
       
   176 
       
   177     int viewportX = qRound(toViewport(stop->position()));
       
   178     m_moveOffset = x - viewportX;
       
   179 
       
   180     QList<QtGradientStop *> stops = m_stops;
       
   181     m_stops.clear();
       
   182     QListIterator<QtGradientStop *> itStop(stops);
       
   183     while (itStop.hasNext()) {
       
   184         QtGradientStop *s = itStop.next();
       
   185         if (m_model->isSelected(s) || s == stop) {
       
   186             m_moveStops[s] = s->position() - stop->position();
       
   187             m_stops.append(s);
       
   188         } else {
       
   189             m_moveOriginal[s->position()] = s->color();
       
   190         }
       
   191     }
       
   192     itStop.toFront();
       
   193     while (itStop.hasNext()) {
       
   194         QtGradientStop *s = itStop.next();
       
   195         if (!m_model->isSelected(s))
       
   196             m_stops.append(s);
       
   197     }
       
   198     m_stops.removeAll(stop);
       
   199     m_stops.prepend(stop);
       
   200 }
       
   201 
       
   202 void QtGradientStopsWidgetPrivate::ensureVisible(double x)
       
   203 {
       
   204     double viewX = toViewport(x);
       
   205     if (viewX < 0 || viewX > q_ptr->viewport()->size().width()) {
       
   206         int max = q_ptr->horizontalScrollBar()->maximum();
       
   207         int newVal = qRound(x * (max + m_scaleFactor) - m_scaleFactor / 2);
       
   208         q_ptr->horizontalScrollBar()->setValue(newVal);
       
   209     }
       
   210 }
       
   211 
       
   212 void QtGradientStopsWidgetPrivate::ensureVisible(QtGradientStop *stop)
       
   213 {
       
   214     if (!stop)
       
   215         return;
       
   216     ensureVisible(stop->position());
       
   217 }
       
   218 
       
   219 QtGradientStop *QtGradientStopsWidgetPrivate::newStop(const QPoint &viewportPos)
       
   220 {
       
   221     QtGradientStop *copyStop = stopAt(viewportPos);
       
   222     double posX = fromViewport(viewportPos.x());
       
   223     QtGradientStop *stop = m_model->at(posX);
       
   224     if (!stop) {
       
   225         QColor newColor;
       
   226         if (copyStop)
       
   227             newColor = copyStop->color();
       
   228         else
       
   229             newColor = m_model->color(posX);
       
   230         if (!newColor.isValid())
       
   231             newColor = Qt::white;
       
   232         stop = m_model->addStop(posX, newColor);
       
   233     }
       
   234     return stop;
       
   235 }
       
   236 
       
   237 void QtGradientStopsWidgetPrivate::slotStopAdded(QtGradientStop *stop)
       
   238 {
       
   239     m_stops.append(stop);
       
   240     q_ptr->viewport()->update();
       
   241 }
       
   242 
       
   243 void QtGradientStopsWidgetPrivate::slotStopRemoved(QtGradientStop *stop)
       
   244 {
       
   245     m_stops.removeAll(stop);
       
   246     q_ptr->viewport()->update();
       
   247 }
       
   248 
       
   249 void QtGradientStopsWidgetPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos)
       
   250 {
       
   251     Q_UNUSED(stop)
       
   252     Q_UNUSED(newPos)
       
   253     q_ptr->viewport()->update();
       
   254 }
       
   255 
       
   256 void QtGradientStopsWidgetPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2)
       
   257 {
       
   258     Q_UNUSED(stop1)
       
   259     Q_UNUSED(stop2)
       
   260     q_ptr->viewport()->update();
       
   261 }
       
   262 
       
   263 void QtGradientStopsWidgetPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor)
       
   264 {
       
   265     Q_UNUSED(stop)
       
   266     Q_UNUSED(newColor)
       
   267     q_ptr->viewport()->update();
       
   268 }
       
   269 
       
   270 void QtGradientStopsWidgetPrivate::slotStopSelected(QtGradientStop *stop, bool selected)
       
   271 {
       
   272     Q_UNUSED(stop)
       
   273     Q_UNUSED(selected)
       
   274     q_ptr->viewport()->update();
       
   275 }
       
   276 
       
   277 void QtGradientStopsWidgetPrivate::slotCurrentStopChanged(QtGradientStop *stop)
       
   278 {
       
   279     Q_UNUSED(stop)
       
   280 
       
   281     if (!m_model)
       
   282         return;
       
   283     q_ptr->viewport()->update();
       
   284     if (stop) {
       
   285         m_stops.removeAll(stop);
       
   286         m_stops.prepend(stop);
       
   287     }
       
   288 }
       
   289 
       
   290 void QtGradientStopsWidgetPrivate::slotNewStop()
       
   291 {
       
   292     if (!m_model)
       
   293         return;
       
   294 
       
   295     QtGradientStop *stop = newStop(m_clickPos);
       
   296 
       
   297     if (!stop)
       
   298         return;
       
   299 
       
   300     m_model->clearSelection();
       
   301     m_model->selectStop(stop, true);
       
   302     m_model->setCurrentStop(stop);
       
   303 }
       
   304 
       
   305 void QtGradientStopsWidgetPrivate::slotDelete()
       
   306 {
       
   307     if (!m_model)
       
   308         return;
       
   309 
       
   310     m_model->deleteStops();
       
   311 }
       
   312 
       
   313 void QtGradientStopsWidgetPrivate::slotFlipAll()
       
   314 {
       
   315     if (!m_model)
       
   316         return;
       
   317 
       
   318     m_model->flipAll();
       
   319 }
       
   320 
       
   321 void QtGradientStopsWidgetPrivate::slotSelectAll()
       
   322 {
       
   323     if (!m_model)
       
   324         return;
       
   325 
       
   326     m_model->selectAll();
       
   327 }
       
   328 
       
   329 void QtGradientStopsWidgetPrivate::slotZoomIn()
       
   330 {
       
   331     double newZoom = q_ptr->zoom() * 2;
       
   332     if (newZoom > 100)
       
   333         newZoom = 100;
       
   334     if (newZoom == q_ptr->zoom())
       
   335         return;
       
   336 
       
   337     q_ptr->setZoom(newZoom);
       
   338     emit q_ptr->zoomChanged(q_ptr->zoom());
       
   339 }
       
   340 
       
   341 void QtGradientStopsWidgetPrivate::slotZoomOut()
       
   342 {
       
   343     double newZoom = q_ptr->zoom() / 2;
       
   344     if (newZoom < 1)
       
   345         newZoom = 1;
       
   346     if (newZoom == q_ptr->zoom())
       
   347         return;
       
   348 
       
   349     q_ptr->setZoom(newZoom);
       
   350     emit q_ptr->zoomChanged(q_ptr->zoom());
       
   351 }
       
   352 
       
   353 void QtGradientStopsWidgetPrivate::slotResetZoom()
       
   354 {
       
   355     if (1 == q_ptr->zoom())
       
   356         return;
       
   357 
       
   358     q_ptr->setZoom(1);
       
   359     emit q_ptr->zoomChanged(1);
       
   360 }
       
   361 
       
   362 QtGradientStopsWidget::QtGradientStopsWidget(QWidget *parent)
       
   363     : QAbstractScrollArea(parent), d_ptr(new QtGradientStopsWidgetPrivate)
       
   364 {
       
   365     d_ptr->q_ptr = this;
       
   366     d_ptr->m_backgroundCheckered = true;
       
   367     d_ptr->m_model = 0;
       
   368     d_ptr->m_handleSize = 25.0;
       
   369     d_ptr->m_scaleFactor = 1000;
       
   370     d_ptr->m_moving = false;
       
   371     d_ptr->m_zoom = 1;
       
   372     d_ptr->m_rubber = new QRubberBand(QRubberBand::Rectangle, this);
       
   373 #ifndef QT_NO_DRAGANDDROP
       
   374     d_ptr->m_dragStop = 0;
       
   375     d_ptr->m_changedStop = 0;
       
   376     d_ptr->m_clonedStop = 0;
       
   377     d_ptr->m_dragModel = 0;
       
   378 #endif
       
   379     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
   380     setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
       
   381     horizontalScrollBar()->setRange(0, (int)(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1) + 0.5));
       
   382     horizontalScrollBar()->setPageStep(d_ptr->m_scaleFactor);
       
   383     horizontalScrollBar()->setSingleStep(4);
       
   384     viewport()->setAutoFillBackground(false);
       
   385 
       
   386     setAcceptDrops(true);
       
   387 
       
   388     setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
       
   389 }
       
   390 
       
   391 QtGradientStopsWidget::~QtGradientStopsWidget()
       
   392 {
       
   393 }
       
   394 
       
   395 QSize QtGradientStopsWidget::sizeHint() const
       
   396 {
       
   397     return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->sizeHint().height());
       
   398 }
       
   399 
       
   400 QSize QtGradientStopsWidget::minimumSizeHint() const
       
   401 {
       
   402     return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->minimumSizeHint().height());
       
   403 }
       
   404 
       
   405 void QtGradientStopsWidget::setBackgroundCheckered(bool checkered)
       
   406 {
       
   407     if (d_ptr->m_backgroundCheckered == checkered)
       
   408         return;
       
   409     d_ptr->m_backgroundCheckered = checkered;
       
   410     update();
       
   411 }
       
   412 
       
   413 bool QtGradientStopsWidget::isBackgroundCheckered() const
       
   414 {
       
   415     return d_ptr->m_backgroundCheckered;
       
   416 }
       
   417 
       
   418 void QtGradientStopsWidget::setGradientStopsModel(QtGradientStopsModel *model)
       
   419 {
       
   420     if (d_ptr->m_model == model)
       
   421         return;
       
   422 
       
   423     if (d_ptr->m_model) {
       
   424         disconnect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop *)),
       
   425                     this, SLOT(slotStopAdded(QtGradientStop *)));
       
   426         disconnect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop *)),
       
   427                     this, SLOT(slotStopRemoved(QtGradientStop *)));
       
   428         disconnect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop *, qreal)),
       
   429                     this, SLOT(slotStopMoved(QtGradientStop *, qreal)));
       
   430         disconnect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop *, QtGradientStop *)),
       
   431                     this, SLOT(slotStopsSwapped(QtGradientStop *, QtGradientStop *)));
       
   432         disconnect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop *, const QColor &)),
       
   433                     this, SLOT(slotStopChanged(QtGradientStop *, const QColor &)));
       
   434         disconnect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop *, bool)),
       
   435                     this, SLOT(slotStopSelected(QtGradientStop *, bool)));
       
   436         disconnect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop *)),
       
   437                     this, SLOT(slotCurrentStopChanged(QtGradientStop *)));
       
   438 
       
   439         d_ptr->m_stops.clear();
       
   440     }
       
   441 
       
   442     d_ptr->m_model = model;
       
   443 
       
   444     if (d_ptr->m_model) {
       
   445         connect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop *)),
       
   446                     this, SLOT(slotStopAdded(QtGradientStop *)));
       
   447         connect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop *)),
       
   448                     this, SLOT(slotStopRemoved(QtGradientStop *)));
       
   449         connect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop *, qreal)),
       
   450                     this, SLOT(slotStopMoved(QtGradientStop *, qreal)));
       
   451         connect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop *, QtGradientStop *)),
       
   452                     this, SLOT(slotStopsSwapped(QtGradientStop *, QtGradientStop *)));
       
   453         connect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop *, const QColor &)),
       
   454                     this, SLOT(slotStopChanged(QtGradientStop *, const QColor &)));
       
   455         connect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop *, bool)),
       
   456                     this, SLOT(slotStopSelected(QtGradientStop *, bool)));
       
   457         connect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop *)),
       
   458                     this, SLOT(slotCurrentStopChanged(QtGradientStop *)));
       
   459 
       
   460         QList<QtGradientStop *> stops = d_ptr->m_model->stops().values();
       
   461         QListIterator<QtGradientStop *> itStop(stops);
       
   462         while (itStop.hasNext())
       
   463             d_ptr->slotStopAdded(itStop.next());
       
   464 
       
   465         QList<QtGradientStop *> selected = d_ptr->m_model->selectedStops();
       
   466         QListIterator<QtGradientStop *> itSelect(selected);
       
   467         while (itSelect.hasNext())
       
   468             d_ptr->slotStopSelected(itSelect.next(), true);
       
   469 
       
   470         d_ptr->slotCurrentStopChanged(d_ptr->m_model->currentStop());
       
   471     }
       
   472 }
       
   473 
       
   474 void QtGradientStopsWidget::mousePressEvent(QMouseEvent *e)
       
   475 {
       
   476     typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
       
   477     if (!d_ptr->m_model)
       
   478         return;
       
   479 
       
   480     if (e->button() != Qt::LeftButton)
       
   481         return;
       
   482 
       
   483     d_ptr->m_moving = true;
       
   484 
       
   485     d_ptr->m_moveStops.clear();
       
   486     d_ptr->m_moveOriginal.clear();
       
   487     d_ptr->m_clickPos = e->pos();
       
   488     QtGradientStop *stop = d_ptr->stopAt(e->pos());
       
   489     if (stop) {
       
   490         if (e->modifiers() & Qt::ControlModifier) {
       
   491             d_ptr->m_model->selectStop(stop, !d_ptr->m_model->isSelected(stop));
       
   492         } else if (e->modifiers() & Qt::ShiftModifier) {
       
   493             QtGradientStop *oldCurrent = d_ptr->m_model->currentStop();
       
   494             if (oldCurrent) {
       
   495                 PositionStopMap stops = d_ptr->m_model->stops();
       
   496                 PositionStopMap::ConstIterator itSt = stops.constFind(oldCurrent->position());
       
   497                 if (itSt != stops.constEnd()) {
       
   498                     while (itSt != stops.constFind(stop->position())) {
       
   499                         d_ptr->m_model->selectStop(itSt.value(), true);
       
   500                         if (oldCurrent->position() < stop->position())
       
   501                             ++itSt;
       
   502                         else
       
   503                             --itSt;
       
   504                     }
       
   505                 }
       
   506             }
       
   507             d_ptr->m_model->selectStop(stop, true);
       
   508         } else {
       
   509             if (!d_ptr->m_model->isSelected(stop)) {
       
   510                 d_ptr->m_model->clearSelection();
       
   511                 d_ptr->m_model->selectStop(stop, true);
       
   512             }
       
   513         }
       
   514         d_ptr->setupMove(stop, e->pos().x());
       
   515     } else {
       
   516         d_ptr->m_model->clearSelection();
       
   517         d_ptr->m_rubber->setGeometry(QRect(d_ptr->m_clickPos, QSize()));
       
   518         d_ptr->m_rubber->show();
       
   519     }
       
   520     viewport()->update();
       
   521 }
       
   522 
       
   523 void QtGradientStopsWidget::mouseReleaseEvent(QMouseEvent *e)
       
   524 {
       
   525     if (!d_ptr->m_model)
       
   526         return;
       
   527 
       
   528     if (e->button() != Qt::LeftButton)
       
   529         return;
       
   530 
       
   531     d_ptr->m_moving = false;
       
   532     d_ptr->m_rubber->hide();
       
   533     d_ptr->m_moveStops.clear();
       
   534     d_ptr->m_moveOriginal.clear();
       
   535 }
       
   536 
       
   537 void QtGradientStopsWidget::mouseMoveEvent(QMouseEvent *e)
       
   538 {
       
   539     typedef QtGradientStopsWidgetPrivate::PositionColorMap PositionColorMap;
       
   540     typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
       
   541     typedef QtGradientStopsWidgetPrivate::StopPositionMap StopPositionMap;
       
   542     if (!d_ptr->m_model)
       
   543         return;
       
   544 
       
   545     if (!(e->buttons() & Qt::LeftButton))
       
   546         return;
       
   547 
       
   548     if (!d_ptr->m_moving)
       
   549         return;
       
   550 
       
   551     if (!d_ptr->m_moveStops.isEmpty()) {
       
   552         double maxOffset = 0.0;
       
   553         double minOffset = 0.0;
       
   554         bool first = true;
       
   555         StopPositionMap::ConstIterator itStop = d_ptr->m_moveStops.constBegin();
       
   556         while (itStop != d_ptr->m_moveStops.constEnd()) {
       
   557             double offset = itStop.value();
       
   558 
       
   559             if (first) {
       
   560                 maxOffset = offset;
       
   561                 minOffset = offset;
       
   562                 first = false;
       
   563             } else {
       
   564                 if (maxOffset < offset)
       
   565                     maxOffset = offset;
       
   566                 else if (minOffset > offset)
       
   567                     minOffset = offset;
       
   568             }
       
   569             ++itStop;
       
   570         }
       
   571 
       
   572         double viewportMin = d_ptr->toViewport(-minOffset);
       
   573         double viewportMax = d_ptr->toViewport(1.0 - maxOffset);
       
   574 
       
   575         PositionStopMap newPositions;
       
   576 
       
   577         int viewportX = e->pos().x() - d_ptr->m_moveOffset;
       
   578 
       
   579         if (viewportX > viewport()->size().width())
       
   580             viewportX = viewport()->size().width();
       
   581         else if (viewportX < 0)
       
   582             viewportX = 0;
       
   583 
       
   584         double posX = d_ptr->fromViewport(viewportX);
       
   585 
       
   586         if (viewportX > viewportMax)
       
   587             posX = 1.0 - maxOffset;
       
   588         else if (viewportX < viewportMin)
       
   589             posX = -minOffset;
       
   590 
       
   591         itStop = d_ptr->m_moveStops.constBegin();
       
   592         while (itStop != d_ptr->m_moveStops.constEnd()) {
       
   593             QtGradientStop *stop = itStop.key();
       
   594 
       
   595             newPositions[posX + itStop.value()] = stop;
       
   596 
       
   597             ++itStop;
       
   598         }
       
   599 
       
   600         bool forward = true;
       
   601         PositionStopMap::ConstIterator itNewPos = newPositions.constBegin();
       
   602         if (itNewPos.value()->position() < itNewPos.key())
       
   603             forward = false;
       
   604 
       
   605         itNewPos = forward ? newPositions.constBegin() : newPositions.constEnd();
       
   606         while (itNewPos != (forward ? newPositions.constEnd() : newPositions.constBegin())) {
       
   607             if (!forward)
       
   608                 --itNewPos;
       
   609             QtGradientStop *stop = itNewPos.value();
       
   610             double newPos = itNewPos.key();
       
   611             if (newPos > 1)
       
   612                 newPos = 1;
       
   613             else if (newPos < 0)
       
   614                 newPos = 0;
       
   615 
       
   616             QtGradientStop *existingStop = d_ptr->m_model->at(newPos);
       
   617             if (existingStop && !d_ptr->m_moveStops.contains(existingStop))
       
   618                     d_ptr->m_model->removeStop(existingStop);
       
   619             d_ptr->m_model->moveStop(stop, newPos);
       
   620 
       
   621             if (forward)
       
   622                 ++itNewPos;
       
   623         }
       
   624 
       
   625         PositionColorMap::ConstIterator itOld = d_ptr->m_moveOriginal.constBegin();
       
   626         while (itOld != d_ptr->m_moveOriginal.constEnd()) {
       
   627             double position = itOld.key();
       
   628             if (!d_ptr->m_model->at(position))
       
   629                 d_ptr->m_model->addStop(position, itOld.value());
       
   630 
       
   631             ++itOld;
       
   632         }
       
   633 
       
   634     } else {
       
   635         QRect r(QRect(d_ptr->m_clickPos, e->pos()).normalized());
       
   636         r.translate(1, 0);
       
   637         d_ptr->m_rubber->setGeometry(r);
       
   638         //d_ptr->m_model->clearSelection();
       
   639 
       
   640         int xv1 = d_ptr->m_clickPos.x();
       
   641         int xv2 = e->pos().x();
       
   642         if (xv1 > xv2) {
       
   643             int temp = xv1;
       
   644             xv1 = xv2;
       
   645             xv2 = temp;
       
   646         }
       
   647         int yv1 = d_ptr->m_clickPos.y();
       
   648         int yv2 = e->pos().y();
       
   649         if (yv1 > yv2) {
       
   650             int temp = yv1;
       
   651             yv1 = yv2;
       
   652             yv2 = temp;
       
   653         }
       
   654 
       
   655         QPoint p1, p2;
       
   656 
       
   657         if (yv2 < d_ptr->m_handleSize / 2) {
       
   658             p1 = QPoint(xv1, yv2);
       
   659             p2 = QPoint(xv2, yv2);
       
   660         } else if (yv1 > d_ptr->m_handleSize / 2) {
       
   661             p1 = QPoint(xv1, yv1);
       
   662             p2 = QPoint(xv2, yv1);
       
   663         } else {
       
   664             p1 = QPoint(xv1, qRound(d_ptr->m_handleSize / 2));
       
   665             p2 = QPoint(xv2, qRound(d_ptr->m_handleSize / 2));
       
   666         }
       
   667 
       
   668         QList<QtGradientStop *> beginList = d_ptr->stopsAt(p1);
       
   669         QList<QtGradientStop *> endList = d_ptr->stopsAt(p2);
       
   670 
       
   671         double x1 = d_ptr->fromViewport(xv1);
       
   672         double x2 = d_ptr->fromViewport(xv2);
       
   673 
       
   674         QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
       
   675         while (itStop.hasNext()) {
       
   676             QtGradientStop *stop = itStop.next();
       
   677             if ((stop->position() >= x1 && stop->position() <= x2) ||
       
   678                         beginList.contains(stop) || endList.contains(stop))
       
   679                 d_ptr->m_model->selectStop(stop, true);
       
   680             else
       
   681                 d_ptr->m_model->selectStop(stop, false);
       
   682         }
       
   683     }
       
   684 }
       
   685 
       
   686 void QtGradientStopsWidget::mouseDoubleClickEvent(QMouseEvent *e)
       
   687 {
       
   688     if (!d_ptr->m_model)
       
   689         return;
       
   690 
       
   691     if (e->button() != Qt::LeftButton)
       
   692         return;
       
   693 
       
   694     if (d_ptr->m_clickPos != e->pos()) {
       
   695         mousePressEvent(e);
       
   696         return;
       
   697     }
       
   698     d_ptr->m_moving = true;
       
   699     d_ptr->m_moveStops.clear();
       
   700     d_ptr->m_moveOriginal.clear();
       
   701 
       
   702     QtGradientStop *stop = d_ptr->newStop(e->pos());
       
   703 
       
   704     if (!stop)
       
   705         return;
       
   706 
       
   707     d_ptr->m_model->clearSelection();
       
   708     d_ptr->m_model->selectStop(stop, true);
       
   709 
       
   710     d_ptr->setupMove(stop, e->pos().x());
       
   711 
       
   712     viewport()->update();
       
   713 }
       
   714 
       
   715 void QtGradientStopsWidget::keyPressEvent(QKeyEvent *e)
       
   716 {
       
   717     typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
       
   718     if (!d_ptr->m_model)
       
   719         return;
       
   720 
       
   721     if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
       
   722         d_ptr->m_model->deleteStops();
       
   723     } else if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right ||
       
   724                 e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
       
   725         PositionStopMap stops = d_ptr->m_model->stops();
       
   726         if (stops.isEmpty())
       
   727             return;
       
   728         QtGradientStop *newCurrent = 0;
       
   729         QtGradientStop *current = d_ptr->m_model->currentStop();
       
   730         if (!current || e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
       
   731             if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Home)
       
   732                 newCurrent = stops.constBegin().value();
       
   733             else if (e->key() == Qt::Key_Right || e->key() == Qt::Key_End)
       
   734                 newCurrent = (--stops.constEnd()).value();
       
   735         } else {
       
   736             PositionStopMap::ConstIterator itStop = stops.constBegin();
       
   737             while (itStop.value() != current)
       
   738                 ++itStop;
       
   739             if (e->key() == Qt::Key_Left && itStop != stops.constBegin())
       
   740                 --itStop;
       
   741             else if (e->key() == Qt::Key_Right && itStop != --stops.constEnd())
       
   742                 ++itStop;
       
   743             newCurrent = itStop.value();
       
   744         }
       
   745         d_ptr->m_model->clearSelection();
       
   746         d_ptr->m_model->selectStop(newCurrent, true);
       
   747         d_ptr->m_model->setCurrentStop(newCurrent);
       
   748         d_ptr->ensureVisible(newCurrent);
       
   749     } else if (e->key() == Qt::Key_A) {
       
   750         if (e->modifiers() & Qt::ControlModifier)
       
   751             d_ptr->m_model->selectAll();
       
   752     }
       
   753 }
       
   754 
       
   755 void QtGradientStopsWidget::paintEvent(QPaintEvent *e)
       
   756 {
       
   757     Q_UNUSED(e)
       
   758     if (!d_ptr->m_model)
       
   759         return;
       
   760 
       
   761     QtGradientStopsModel *model = d_ptr->m_model;
       
   762 #ifndef QT_NO_DRAGANDDROP
       
   763     if (d_ptr->m_dragModel)
       
   764         model = d_ptr->m_dragModel;
       
   765 #endif
       
   766 
       
   767     QSize size = viewport()->size();
       
   768     int w = size.width();
       
   769     double h = size.height() - d_ptr->m_handleSize;
       
   770     if (w <= 0)
       
   771         return;
       
   772 
       
   773     QPixmap pix(size);
       
   774     QPainter p;
       
   775 
       
   776     if (d_ptr->m_backgroundCheckered) {
       
   777         int pixSize = 20;
       
   778         QPixmap pm(2 * pixSize, 2 * pixSize);
       
   779         QPainter pmp(&pm);
       
   780         pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
       
   781         pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
       
   782         pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
       
   783         pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
       
   784 
       
   785         p.begin(&pix);
       
   786         p.setBrushOrigin((size.width() % pixSize + pixSize) / 2, (size.height() % pixSize + pixSize) / 2);
       
   787         p.fillRect(viewport()->rect(), pm);
       
   788         p.setBrushOrigin(0, 0);
       
   789     } else {
       
   790         p.begin(viewport());
       
   791     }
       
   792 
       
   793     double viewBegin = (double)w * horizontalScrollBar()->value() / d_ptr->m_scaleFactor;
       
   794 
       
   795     int val = horizontalScrollBar()->value();
       
   796     int max = horizontalScrollBar()->maximum();
       
   797 
       
   798     double begin = (double)val / (d_ptr->m_scaleFactor + max);
       
   799     double end = (double)(val + d_ptr->m_scaleFactor) / (d_ptr->m_scaleFactor + max);
       
   800     double width = end - begin;
       
   801 
       
   802     if (h > 0) {
       
   803         QLinearGradient lg(0, 0, w, 0);
       
   804         QMap<qreal, QtGradientStop *> stops = model->stops();
       
   805         QMapIterator<qreal, QtGradientStop *> itStop(stops);
       
   806         while (itStop.hasNext()) {
       
   807             QtGradientStop *stop = itStop.next().value();
       
   808             double pos = stop->position();
       
   809             if (pos >= begin && pos <= end) {
       
   810                 double gradPos = (pos - begin) / width;
       
   811                 QColor c = stop->color();
       
   812                 lg.setColorAt(gradPos, c);
       
   813             }
       
   814             //lg.setColorAt(stop->position(), stop->color());
       
   815         }
       
   816         lg.setColorAt(0, model->color(begin));
       
   817         lg.setColorAt(1, model->color(end));
       
   818         QImage img(w, 1, QImage::Format_ARGB32_Premultiplied);
       
   819         QPainter p1(&img);
       
   820         p1.setCompositionMode(QPainter::CompositionMode_Source);
       
   821 
       
   822         /*
       
   823         if (viewBegin != 0)
       
   824             p1.translate(-viewBegin, 0);
       
   825         if (d_ptr->m_zoom != 1)
       
   826             p1.scale(d_ptr->m_zoom, 1);
       
   827             */
       
   828         p1.fillRect(0, 0, w, 1, lg);
       
   829 
       
   830         p.fillRect(QRectF(0, d_ptr->m_handleSize, w, h), QPixmap::fromImage(img));
       
   831     }
       
   832 
       
   833 
       
   834     double handleWidth = d_ptr->m_handleSize * d_ptr->m_scaleFactor / (w * (d_ptr->m_scaleFactor + max));
       
   835 
       
   836     QColor insideColor = QColor::fromRgb(0x20, 0x20, 0x20, 0xFF);
       
   837     QColor borderColor = QColor(Qt::white);
       
   838     QColor drawColor;
       
   839     QColor back1 = QColor(Qt::lightGray);
       
   840     QColor back2 = QColor(Qt::darkGray);
       
   841     QColor back = QColor::fromRgb((back1.red() + back2.red()) / 2,
       
   842             (back1.green() + back2.green()) / 2,
       
   843             (back1.blue() + back2.blue()) / 2);
       
   844 
       
   845     QPen pen;
       
   846     p.setRenderHint(QPainter::Antialiasing);
       
   847     QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
       
   848     itStop.toBack();
       
   849     while (itStop.hasPrevious()) {
       
   850         QtGradientStop *stop = itStop.previous();
       
   851         double x = stop->position();
       
   852         if (x >= begin - handleWidth / 2 && x <= end + handleWidth / 2) {
       
   853             double viewX = x * w * (d_ptr->m_scaleFactor + max) / d_ptr->m_scaleFactor - viewBegin;
       
   854             p.save();
       
   855             QColor c = stop->color();
       
   856 #ifndef QT_NO_DRAGANDDROP
       
   857             if (stop == d_ptr->m_dragStop)
       
   858                 c = d_ptr->m_dragColor;
       
   859 #endif
       
   860             if ((0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF()) * c.alphaF() +
       
   861                 (0.3 * back.redF() + 0.59 * back.greenF() + 0.11 * back.blueF()) * (1.0 - c.alphaF()) < 0.5) {
       
   862                 drawColor = QColor::fromRgb(0xC0, 0xC0, 0xC0, 0xB0);
       
   863             } else {
       
   864                 drawColor = QColor::fromRgb(0x40, 0x40, 0x40, 0x80);
       
   865             }
       
   866             QRectF rect(viewX - d_ptr->m_handleSize / 2, 0, d_ptr->m_handleSize, d_ptr->m_handleSize);
       
   867             rect.adjust(0.5, 0.5, -0.5, -0.5);
       
   868             if (h > 0) {
       
   869                 pen.setWidthF(1);
       
   870                 QLinearGradient lg(0, d_ptr->m_handleSize, 0, d_ptr->m_handleSize + h / 2);
       
   871                 lg.setColorAt(0, drawColor);
       
   872                 QColor alphaZero = drawColor;
       
   873                 alphaZero.setAlpha(0);
       
   874                 lg.setColorAt(1, alphaZero);
       
   875                 pen.setBrush(lg);
       
   876                 p.setPen(pen);
       
   877                 p.drawLine(QPointF(viewX, d_ptr->m_handleSize), QPointF(viewX, d_ptr->m_handleSize + h / 2));
       
   878 
       
   879                 pen.setWidthF(1);
       
   880                 pen.setBrush(drawColor);
       
   881                 p.setPen(pen);
       
   882                 QRectF r1 = rect.adjusted(0.5, 0.5, -0.5, -0.5);
       
   883                 QRectF r2 = rect.adjusted(1.5, 1.5, -1.5, -1.5);
       
   884                 QColor inColor = QColor::fromRgb(0x80, 0x80, 0x80, 0x80);
       
   885                 if (!d_ptr->m_model->isSelected(stop)) {
       
   886                     p.setBrush(c);
       
   887                     p.drawEllipse(rect);
       
   888                 } else {
       
   889                     pen.setBrush(insideColor);
       
   890                     pen.setWidthF(2);
       
   891                     p.setPen(pen);
       
   892                     p.setBrush(Qt::NoBrush);
       
   893                     p.drawEllipse(r1);
       
   894 
       
   895                     pen.setBrush(inColor);
       
   896                     pen.setWidthF(1);
       
   897                     p.setPen(pen);
       
   898                     p.setBrush(c);
       
   899                     p.drawEllipse(r2);
       
   900                 }
       
   901 
       
   902                 if (d_ptr->m_model->currentStop() == stop) {
       
   903                     p.setBrush(Qt::NoBrush);
       
   904                     pen.setWidthF(5);
       
   905                     pen.setBrush(drawColor);
       
   906                     int corr = 4;
       
   907                     if (!d_ptr->m_model->isSelected(stop)) {
       
   908                         corr = 3;
       
   909                         pen.setWidthF(7);
       
   910                     }
       
   911                     p.setPen(pen);
       
   912                     p.drawEllipse(rect.adjusted(corr, corr, -corr, -corr));
       
   913                 }
       
   914 
       
   915             }
       
   916             p.restore();
       
   917         }
       
   918     }
       
   919     if (d_ptr->m_backgroundCheckered) {
       
   920         p.end();
       
   921         p.begin(viewport());
       
   922         p.drawPixmap(0, 0, pix);
       
   923     }
       
   924     p.end();
       
   925 }
       
   926 
       
   927 void QtGradientStopsWidget::focusInEvent(QFocusEvent *e)
       
   928 {
       
   929     Q_UNUSED(e)
       
   930     viewport()->update();
       
   931 }
       
   932 
       
   933 void QtGradientStopsWidget::focusOutEvent(QFocusEvent *e)
       
   934 {
       
   935     Q_UNUSED(e)
       
   936     viewport()->update();
       
   937 }
       
   938 
       
   939 void QtGradientStopsWidget::contextMenuEvent(QContextMenuEvent *e)
       
   940 {
       
   941     if (!d_ptr->m_model)
       
   942         return;
       
   943 
       
   944     d_ptr->m_clickPos = e->pos();
       
   945 
       
   946     QMenu menu(this);
       
   947     QAction *newStopAction = new QAction(tr("New Stop"), &menu);
       
   948     QAction *deleteAction = new QAction(tr("Delete"), &menu);
       
   949     QAction *flipAllAction = new QAction(tr("Flip All"), &menu);
       
   950     QAction *selectAllAction = new QAction(tr("Select All"), &menu);
       
   951     QAction *zoomInAction = new QAction(tr("Zoom In"), &menu);
       
   952     QAction *zoomOutAction = new QAction(tr("Zoom Out"), &menu);
       
   953     QAction *zoomAllAction = new QAction(tr("Reset Zoom"), &menu);
       
   954     if (d_ptr->m_model->selectedStops().isEmpty() && !d_ptr->m_model->currentStop())
       
   955         deleteAction->setEnabled(false);
       
   956     if (zoom() <= 1) {
       
   957         zoomOutAction->setEnabled(false);
       
   958         zoomAllAction->setEnabled(false);
       
   959     } else if (zoom() >= 100) {
       
   960         zoomInAction->setEnabled(false);
       
   961     }
       
   962     connect(newStopAction, SIGNAL(triggered()), this, SLOT(slotNewStop()));
       
   963     connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotDelete()));
       
   964     connect(flipAllAction, SIGNAL(triggered()), this, SLOT(slotFlipAll()));
       
   965     connect(selectAllAction, SIGNAL(triggered()), this, SLOT(slotSelectAll()));
       
   966     connect(zoomInAction, SIGNAL(triggered()), this, SLOT(slotZoomIn()));
       
   967     connect(zoomOutAction, SIGNAL(triggered()), this, SLOT(slotZoomOut()));
       
   968     connect(zoomAllAction, SIGNAL(triggered()), this, SLOT(slotResetZoom()));
       
   969     menu.addAction(newStopAction);
       
   970     menu.addAction(deleteAction);
       
   971     menu.addAction(flipAllAction);
       
   972     menu.addAction(selectAllAction);
       
   973     menu.addSeparator();
       
   974     menu.addAction(zoomInAction);
       
   975     menu.addAction(zoomOutAction);
       
   976     menu.addAction(zoomAllAction);
       
   977     menu.exec(e->globalPos());
       
   978 }
       
   979 
       
   980 void QtGradientStopsWidget::wheelEvent(QWheelEvent *e)
       
   981 {
       
   982     int numDegrees = e->delta() / 8;
       
   983     int numSteps = numDegrees / 15;
       
   984 
       
   985     int shift = numSteps;
       
   986     if (shift < 0)
       
   987         shift = -shift;
       
   988     int pow = 1 << shift;
       
   989     //const double c = 0.7071067; // 2 steps per doubled value
       
   990     const double c = 0.5946036; // 4 steps pre doubled value
       
   991     // in general c = pow(2, 1 / n) / 2; where n is the step
       
   992     double factor = pow * c;
       
   993 
       
   994     double newZoom = zoom();
       
   995     if (numSteps < 0)
       
   996         newZoom /= factor;
       
   997     else
       
   998         newZoom *= factor;
       
   999     if (newZoom > 100)
       
  1000         newZoom = 100;
       
  1001     if (newZoom < 1)
       
  1002         newZoom = 1;
       
  1003 
       
  1004     if (newZoom == zoom())
       
  1005         return;
       
  1006 
       
  1007     setZoom(newZoom);
       
  1008     emit zoomChanged(zoom());
       
  1009 }
       
  1010 
       
  1011 #ifndef QT_NO_DRAGANDDROP
       
  1012 void QtGradientStopsWidget::dragEnterEvent(QDragEnterEvent *event)
       
  1013 {
       
  1014     const QMimeData *mime = event->mimeData();
       
  1015     if (!mime->hasColor())
       
  1016         return;
       
  1017     event->accept();
       
  1018     d_ptr->m_dragModel = d_ptr->m_model->clone();
       
  1019 
       
  1020     d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
       
  1021     update();
       
  1022 }
       
  1023 
       
  1024 void QtGradientStopsWidget::dragMoveEvent(QDragMoveEvent *event)
       
  1025 {
       
  1026     QRectF rect = viewport()->rect();
       
  1027     rect.adjust(0, d_ptr->m_handleSize, 0, 0);
       
  1028     double x = d_ptr->fromViewport(event->pos().x());
       
  1029     QtGradientStop *dragStop = d_ptr->stopAt(event->pos());
       
  1030     if (dragStop) {
       
  1031         event->accept();
       
  1032         d_ptr->removeClonedStop();
       
  1033         d_ptr->changeStop(dragStop->position());
       
  1034     } else if (rect.contains(event->pos())) {
       
  1035         event->accept();
       
  1036         if (d_ptr->m_model->at(x)) {
       
  1037             d_ptr->removeClonedStop();
       
  1038             d_ptr->changeStop(x);
       
  1039         } else {
       
  1040             d_ptr->restoreChangedStop();
       
  1041             d_ptr->cloneStop(x);
       
  1042         }
       
  1043     } else {
       
  1044         event->ignore();
       
  1045         d_ptr->removeClonedStop();
       
  1046         d_ptr->restoreChangedStop();
       
  1047     }
       
  1048 
       
  1049     update();
       
  1050 }
       
  1051 
       
  1052 void QtGradientStopsWidget::dragLeaveEvent(QDragLeaveEvent *event)
       
  1053 {
       
  1054     event->accept();
       
  1055     d_ptr->clearDrag();
       
  1056     update();
       
  1057 }
       
  1058 
       
  1059 void QtGradientStopsWidget::dropEvent(QDropEvent *event)
       
  1060 {
       
  1061     event->accept();
       
  1062     if (!d_ptr->m_dragModel)
       
  1063         return;
       
  1064 
       
  1065     if (d_ptr->m_changedStop)
       
  1066         d_ptr->m_model->changeStop(d_ptr->m_model->at(d_ptr->m_changedStop->position()), d_ptr->m_dragColor);
       
  1067     else if (d_ptr->m_clonedStop)
       
  1068         d_ptr->m_model->addStop(d_ptr->m_clonedStop->position(), d_ptr->m_dragColor);
       
  1069 
       
  1070     d_ptr->clearDrag();
       
  1071     update();
       
  1072 }
       
  1073 
       
  1074 void QtGradientStopsWidgetPrivate::clearDrag()
       
  1075 {
       
  1076     removeClonedStop();
       
  1077     restoreChangedStop();
       
  1078     delete m_dragModel;
       
  1079     m_dragModel = 0;
       
  1080 }
       
  1081 
       
  1082 void QtGradientStopsWidgetPrivate::removeClonedStop()
       
  1083 {
       
  1084     if (!m_clonedStop)
       
  1085         return;
       
  1086     m_dragModel->removeStop(m_clonedStop);
       
  1087     m_clonedStop = 0;
       
  1088 }
       
  1089 
       
  1090 void QtGradientStopsWidgetPrivate::restoreChangedStop()
       
  1091 {
       
  1092     if (!m_changedStop)
       
  1093         return;
       
  1094     m_dragModel->changeStop(m_changedStop, m_model->at(m_changedStop->position())->color());
       
  1095     m_changedStop = 0;
       
  1096     m_dragStop = 0;
       
  1097 }
       
  1098 
       
  1099 void QtGradientStopsWidgetPrivate::changeStop(qreal pos)
       
  1100 {
       
  1101     QtGradientStop *stop = m_dragModel->at(pos);
       
  1102     if (!stop)
       
  1103         return;
       
  1104 
       
  1105     m_dragModel->changeStop(stop, m_dragColor);
       
  1106     m_changedStop = stop;
       
  1107     m_dragStop = m_model->at(stop->position());
       
  1108 }
       
  1109 
       
  1110 void QtGradientStopsWidgetPrivate::cloneStop(qreal pos)
       
  1111 {
       
  1112     if (m_clonedStop) {
       
  1113         m_dragModel->moveStop(m_clonedStop, pos);
       
  1114         return;
       
  1115     }
       
  1116     QtGradientStop *stop = m_dragModel->at(pos);
       
  1117     if (stop)
       
  1118         return;
       
  1119 
       
  1120     m_clonedStop = m_dragModel->addStop(pos, m_dragColor);
       
  1121 }
       
  1122 
       
  1123 #endif
       
  1124 
       
  1125 void QtGradientStopsWidget::setZoom(double zoom)
       
  1126 {
       
  1127     double z = zoom;
       
  1128     if (z < 1)
       
  1129         z = 1;
       
  1130     else if (z > 100)
       
  1131         z = 100;
       
  1132 
       
  1133     if (d_ptr->m_zoom == z)
       
  1134         return;
       
  1135 
       
  1136     d_ptr->m_zoom = z;
       
  1137     int oldMax = horizontalScrollBar()->maximum();
       
  1138     int oldVal = horizontalScrollBar()->value();
       
  1139     horizontalScrollBar()->setRange(0, qRound(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1)));
       
  1140     int newMax = horizontalScrollBar()->maximum();
       
  1141     double newVal = (oldVal + (double)d_ptr->m_scaleFactor / 2) * (newMax + d_ptr->m_scaleFactor)
       
  1142                 / (oldMax + d_ptr->m_scaleFactor) - (double)d_ptr->m_scaleFactor / 2;
       
  1143     horizontalScrollBar()->setValue(qRound(newVal));
       
  1144     viewport()->update();
       
  1145 }
       
  1146 
       
  1147 double QtGradientStopsWidget::zoom() const
       
  1148 {
       
  1149     return d_ptr->m_zoom;
       
  1150 }
       
  1151 
       
  1152 QT_END_NAMESPACE
       
  1153 
       
  1154 #include "moc_qtgradientstopswidget.cpp"