summaryrefslogtreecommitdiffstats
path: root/src/shared/qtgradienteditor
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/qtgradienteditor')
-rw-r--r--src/shared/qtgradienteditor/images/down.pngbin0 -> 594 bytes
-rw-r--r--src/shared/qtgradienteditor/images/edit.pngbin0 -> 503 bytes
-rw-r--r--src/shared/qtgradienteditor/images/editdelete.pngbin0 -> 831 bytes
-rw-r--r--src/shared/qtgradienteditor/images/minus.pngbin0 -> 250 bytes
-rw-r--r--src/shared/qtgradienteditor/images/plus.pngbin0 -> 462 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadpad.pngbin0 -> 151 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadreflect.pngbin0 -> 165 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadrepeat.pngbin0 -> 156 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typeconical.pngbin0 -> 937 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typelinear.pngbin0 -> 145 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typeradial.pngbin0 -> 583 bytes
-rw-r--r--src/shared/qtgradienteditor/images/up.pngbin0 -> 692 bytes
-rw-r--r--src/shared/qtgradienteditor/images/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--src/shared/qtgradienteditor/images/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.cpp272
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.h86
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.pri4
-rw-r--r--src/shared/qtgradienteditor/qtcolorline.cpp1122
-rw-r--r--src/shared/qtgradienteditor/qtcolorline.h124
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.cpp353
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.h87
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.ui121
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.cpp952
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.h111
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.pri33
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.qrc18
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.ui1377
-rw-r--r--src/shared/qtgradienteditor/qtgradientmanager.cpp135
-rw-r--r--src/shared/qtgradienteditor/qtgradientmanager.h92
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopscontroller.cpp724
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopscontroller.h106
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopsmodel.cpp477
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopsmodel.h121
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopswidget.cpp1154
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopswidget.h115
-rw-r--r--src/shared/qtgradienteditor/qtgradientutils.cpp420
-rw-r--r--src/shared/qtgradienteditor/qtgradientutils.h66
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.cpp292
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.h99
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.ui135
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.cpp89
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.h75
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.ui121
-rw-r--r--src/shared/qtgradienteditor/qtgradientwidget.cpp815
-rw-r--r--src/shared/qtgradienteditor/qtgradientwidget.h120
45 files changed, 9816 insertions, 0 deletions
diff --git a/src/shared/qtgradienteditor/images/down.png b/src/shared/qtgradienteditor/images/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/down.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/edit.png b/src/shared/qtgradienteditor/images/edit.png
new file mode 100644
index 000000000..4231bd9a9
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/edit.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/editdelete.png b/src/shared/qtgradienteditor/images/editdelete.png
new file mode 100644
index 000000000..df2a147d2
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/editdelete.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/minus.png b/src/shared/qtgradienteditor/images/minus.png
new file mode 100644
index 000000000..d6f233d73
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/minus.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/plus.png b/src/shared/qtgradienteditor/images/plus.png
new file mode 100644
index 000000000..40df1134f
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/plus.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadpad.png b/src/shared/qtgradienteditor/images/spreadpad.png
new file mode 100644
index 000000000..104c0a23d
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadpad.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadreflect.png b/src/shared/qtgradienteditor/images/spreadreflect.png
new file mode 100644
index 000000000..17b82b711
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadreflect.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadrepeat.png b/src/shared/qtgradienteditor/images/spreadrepeat.png
new file mode 100644
index 000000000..7aea898b1
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadrepeat.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typeconical.png b/src/shared/qtgradienteditor/images/typeconical.png
new file mode 100644
index 000000000..5479811df
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typeconical.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typelinear.png b/src/shared/qtgradienteditor/images/typelinear.png
new file mode 100644
index 000000000..dbd8a1f5a
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typelinear.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typeradial.png b/src/shared/qtgradienteditor/images/typeradial.png
new file mode 100644
index 000000000..dc5888dca
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typeradial.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/up.png b/src/shared/qtgradienteditor/images/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/up.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/zoomin.png b/src/shared/qtgradienteditor/images/zoomin.png
new file mode 100644
index 000000000..2e586fc7b
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/zoomin.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/zoomout.png b/src/shared/qtgradienteditor/images/zoomout.png
new file mode 100644
index 000000000..a736d3934
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/zoomout.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.cpp b/src/shared/qtgradienteditor/qtcolorbutton.cpp
new file mode 100644
index 000000000..96a8b26ca
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtcolorbutton.h"
+#include <QtGui/QColorDialog>
+#include <QtGui/QPainter>
+#include <QtCore/QMimeData>
+#include <QtGui/QDragEnterEvent>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorButtonPrivate
+{
+ QtColorButton *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorButton)
+public:
+ QColor m_color;
+#ifndef QT_NO_DRAGANDDROP
+ QColor m_dragColor;
+ QPoint m_dragStart;
+ bool m_dragging;
+#endif
+ bool m_backgroundCheckered;
+
+ void slotEditColor();
+ QColor shownColor() const;
+ QPixmap generatePixmap() const;
+};
+
+void QtColorButtonPrivate::slotEditColor()
+{
+ const QColor newColor = QColorDialog::getColor(m_color, q_ptr, QString(), QColorDialog::ShowAlphaChannel);
+ if (!newColor.isValid() || newColor == q_ptr->color())
+ return;
+ q_ptr->setColor(newColor);
+ emit q_ptr->colorChanged(m_color);
+}
+
+QColor QtColorButtonPrivate::shownColor() const
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (m_dragging)
+ return m_dragColor;
+#endif
+ return m_color;
+}
+
+QPixmap QtColorButtonPrivate::generatePixmap() const
+{
+ QPixmap pix(24, 24);
+
+ int pixSize = 20;
+ QBrush br(shownColor());
+
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
+ br = QBrush(pm);
+
+ QPainter p(&pix);
+ int corr = 1;
+ QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr,
+ r.width() / 2, r.height() / 2,
+ QColor(shownColor().rgb()));
+ p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
+
+ return pix;
+}
+
+///////////////
+
+QtColorButton::QtColorButton(QWidget *parent)
+ : QToolButton(parent), d_ptr(new QtColorButtonPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_dragging = false;
+ d_ptr->m_backgroundCheckered = true;
+
+ setAcceptDrops(true);
+
+ connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+}
+
+QtColorButton::~QtColorButton()
+{
+}
+
+void QtColorButton::setColor(const QColor &color)
+{
+ if (d_ptr->m_color == color)
+ return;
+ d_ptr->m_color = color;
+ update();
+}
+
+QColor QtColorButton::color() const
+{
+ return d_ptr->m_color;
+}
+
+void QtColorButton::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtColorButton::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtColorButton::paintEvent(QPaintEvent *event)
+{
+ QToolButton::paintEvent(event);
+ if (!isEnabled())
+ return;
+
+ const int pixSize = 10;
+ QBrush br(d_ptr->shownColor());
+ if (d_ptr->m_backgroundCheckered) {
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
+ br = QBrush(pm);
+ }
+
+ QPainter p(this);
+ const int corr = 4;
+ QRect r = rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ //const int adjX = qRound(r.width() / 4.0);
+ //const int adjY = qRound(r.height() / 4.0);
+ //p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
+ // QColor(d_ptr->shownColor().rgb()));
+ /*
+ p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
+ QColor(d_ptr->shownColor().rgb()));
+ p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
+ QColor(d_ptr->shownColor().rgb()));
+ */
+ /*
+ const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF - d_ptr->shownColor().alpha())));
+ p.setPen(frameColor0);
+ p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
+ */
+
+ const QColor frameColor1(0, 0, 0, 26);
+ p.setPen(frameColor1);
+ p.drawRect(r.adjusted(1, 1, -2, -2));
+ const QColor frameColor2(0, 0, 0, 51);
+ p.setPen(frameColor2);
+ p.drawRect(r.adjusted(0, 0, -1, -1));
+}
+
+void QtColorButton::mousePressEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->button() == Qt::LeftButton)
+ d_ptr->m_dragStart = event->pos();
+#endif
+ QToolButton::mousePressEvent(event);
+}
+
+void QtColorButton::mouseMoveEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->buttons() & Qt::LeftButton &&
+ (d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
+ QMimeData *mime = new QMimeData;
+ mime->setColorData(color());
+ QDrag *drg = new QDrag(this);
+ drg->setMimeData(mime);
+ drg->setPixmap(d_ptr->generatePixmap());
+ setDown(false);
+ event->accept();
+ drg->start();
+ return;
+ }
+#endif
+ QToolButton::mouseMoveEvent(event);
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QtColorButton::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ if (!mime->hasColor())
+ return;
+
+ event->accept();
+ d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
+ d_ptr->m_dragging = true;
+ update();
+}
+
+void QtColorButton::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ update();
+}
+
+void QtColorButton::dropEvent(QDropEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ if (d_ptr->m_dragColor == color())
+ return;
+ setColor(d_ptr->m_dragColor);
+ emit colorChanged(color());
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qtcolorbutton.cpp"
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.h b/src/shared/qtgradienteditor/qtcolorbutton.h
new file mode 100644
index 000000000..42fcfc113
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCOLORBUTTON_H
+#define QTCOLORBUTTON_H
+
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorButton : public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtColorButton(QWidget *parent = 0);
+ ~QtColorButton();
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ QColor color() const;
+
+public slots:
+
+ void setColor(const QColor &color);
+
+signals:
+ void colorChanged(const QColor &color);
+protected:
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+private:
+ QScopedPointer<class QtColorButtonPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorButton)
+ Q_DISABLE_COPY(QtColorButton)
+ Q_PRIVATE_SLOT(d_func(), void slotEditColor())
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.pri b/src/shared/qtgradienteditor/qtcolorbutton.pri
new file mode 100644
index 000000000..0e41068f8
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtcolorbutton.cpp
+HEADERS += $$PWD/qtcolorbutton.h
diff --git a/src/shared/qtgradienteditor/qtcolorline.cpp b/src/shared/qtgradienteditor/qtcolorline.cpp
new file mode 100644
index 000000000..f4eda3f9b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorline.cpp
@@ -0,0 +1,1122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtcolorline.h"
+#include "qdrawutil.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QStyleOption>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorLinePrivate
+{
+ QtColorLine *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorLine)
+public:
+ QtColorLinePrivate();
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+ QtColorLine::ColorComponent colorComponent() const;
+ void setColorComponent(QtColorLine::ColorComponent component);
+
+ void setIndicatorSize(int size);
+ int indicatorSize() const;
+
+ void setIndicatorSpace(int space);
+ int indicatorSpace() const;
+
+ void setFlip(bool flip);
+ bool flip() const;
+
+ void setBackgroundCheckered(bool checkered);
+ bool isBackgroundCheckered() const;
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+private:
+ void checkColor();
+ bool isMainPixmapValid() const;
+ void validate();
+ void recreateMainPixmap();
+ QSize pixmapSizeFromGeometrySize(const QSize &geometrySize) const;
+ QPixmap gradientPixmap(int size, Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
+ QPixmap gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
+ QPixmap hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped = false,
+ int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;
+ QPixmap hueGradientPixmap(Qt::Orientation orientation, bool flipped = false,
+ int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;
+
+ QVector<QRect> rects(const QPointF &point) const;
+
+ QColor colorFromPoint(const QPointF &point) const;
+ QPointF pointFromColor(const QColor &color) const;
+
+ QColor m_color;
+ QtColorLine::ColorComponent m_component;
+ bool m_flipped;
+ bool m_backgroundCheckered;
+ Qt::Orientation m_orientation;
+ bool m_dragging;
+ bool m_combiningAlpha;
+ int m_indicatorSize;
+ int m_indicatorSpace;
+ QPointF m_point;
+ QPoint m_clickOffset;
+
+ QPixmap m_mainPixmap;
+ QPixmap m_alphalessPixmap;
+ QPixmap m_semiAlphaPixmap;
+ QSize m_pixmapSize;
+
+ struct PixData {
+ QSize size;
+ QColor color;
+ QtColorLine::ColorComponent component;
+ bool flipped;
+ Qt::Orientation orientation;
+ };
+
+ PixData m_lastValidMainPixmapData;
+};
+
+QtColorLinePrivate::QtColorLinePrivate()
+ : m_color(Qt::black), m_component(QtColorLine::Value),
+ m_flipped(false), m_backgroundCheckered(true), m_orientation(Qt::Horizontal), m_dragging(false), m_combiningAlpha(false)
+{
+ m_indicatorSize = 22;
+ m_indicatorSpace = 0;
+ m_pixmapSize = QSize(0, 0);
+ m_point = pointFromColor(m_color);
+}
+
+void QtColorLinePrivate::setColor(const QColor &color)
+{
+ if (m_color == color)
+ return;
+ if (!color.isValid())
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ m_color = color;
+ checkColor();
+ QColor c = colorFromPoint(m_point);
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+QColor QtColorLinePrivate::color() const
+{
+ return m_color;
+}
+
+void QtColorLinePrivate::setColorComponent(QtColorLine::ColorComponent component)
+{
+ if (m_component == component)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ m_component = component;
+ checkColor();
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+QtColorLine::ColorComponent QtColorLinePrivate::colorComponent() const
+{
+ return m_component;
+}
+
+void QtColorLinePrivate::setIndicatorSize(int size)
+{
+ if (size <= 0)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_indicatorSize == size)
+ return;
+ m_indicatorSize = size;
+ m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
+ q_ptr->update();
+ q_ptr->updateGeometry();
+}
+
+int QtColorLinePrivate::indicatorSize() const
+{
+ return m_indicatorSize;
+}
+
+void QtColorLinePrivate::setIndicatorSpace(int space)
+{
+ if (space < 0)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_indicatorSpace == space)
+ return;
+ m_indicatorSpace = space;
+ m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
+ q_ptr->update();
+}
+
+int QtColorLinePrivate::indicatorSpace() const
+{
+ return m_indicatorSpace;
+}
+
+void QtColorLinePrivate::setFlip(bool flip)
+{
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_flipped == flip)
+ return;
+ m_flipped = flip;
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+bool QtColorLinePrivate::flip() const
+{
+ return m_flipped;
+}
+
+void QtColorLinePrivate::setBackgroundCheckered(bool checkered)
+{
+ if (m_backgroundCheckered == checkered)
+ return;
+ m_backgroundCheckered = checkered;
+ q_ptr->update();
+}
+
+bool QtColorLinePrivate::isBackgroundCheckered() const
+{
+ return m_backgroundCheckered;
+}
+
+void QtColorLinePrivate::setOrientation(Qt::Orientation orientation)
+{
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_orientation == orientation)
+ return;
+
+ m_orientation = orientation;
+ if (!q_ptr->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
+ QSizePolicy sp = q_ptr->sizePolicy();
+ sp.transpose();
+ q_ptr->setSizePolicy(sp);
+ q_ptr->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ }
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+ q_ptr->updateGeometry();
+}
+
+Qt::Orientation QtColorLinePrivate::orientation() const
+{
+ return m_orientation;
+}
+
+void QtColorLinePrivate::checkColor()
+{
+ switch (m_component) {
+ case QtColorLine::Red:
+ case QtColorLine::Green:
+ case QtColorLine::Blue:
+ if (m_color.spec() != QColor::Rgb)
+ m_color = m_color.toRgb();
+ break;
+ case QtColorLine::Hue:
+ case QtColorLine::Saturation:
+ case QtColorLine::Value:
+ if (m_color.spec() != QColor::Hsv)
+ m_color = m_color.toHsv();
+ break;
+ default:
+ break;
+ }
+ if (m_color.spec() == QColor::Hsv) {
+ if (m_color.hue() == 360 || m_color.hue() == -1) {
+ m_color.setHsvF(0.0, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
+ }
+ }
+}
+
+bool QtColorLinePrivate::isMainPixmapValid() const
+{
+ if (m_mainPixmap.isNull()) {
+ if (m_pixmapSize.isEmpty())
+ return true;
+ else
+ return false;
+ }
+ if (m_lastValidMainPixmapData.component != m_component)
+ return false;
+ if (m_lastValidMainPixmapData.size != m_pixmapSize)
+ return false;
+ if (m_lastValidMainPixmapData.flipped != m_flipped)
+ return false;
+ if (m_lastValidMainPixmapData.orientation != m_orientation)
+ return false;
+ if (m_lastValidMainPixmapData.color == m_color)
+ return true;
+ switch (m_component) {
+ case QtColorLine::Red:
+ if (m_color.green() == m_lastValidMainPixmapData.color.green() &&
+ m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Green:
+ if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
+ m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Blue:
+ if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
+ m_color.green() == m_lastValidMainPixmapData.color.green() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Hue:
+ if (m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Saturation:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Value:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Alpha:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value())
+ return true;
+ }
+ return false;
+}
+
+void QtColorLinePrivate::validate()
+{
+ if (isMainPixmapValid())
+ return;
+
+ recreateMainPixmap();
+}
+
+QPixmap QtColorLinePrivate::gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped) const
+{
+ int size = m_pixmapSize.width();
+ if (orientation == Qt::Vertical)
+ size = m_pixmapSize.height();
+ return gradientPixmap(size, orientation, begin, end, flipped);
+}
+
+QPixmap QtColorLinePrivate::gradientPixmap(int size, Qt::Orientation orientation,
+ const QColor &begin, const QColor &end, bool flipped) const
+{
+ int gradW = size;
+ int gradH = size;
+ int w = size;
+ int h = size;
+ if (orientation == Qt::Horizontal) {
+ gradH = 0;
+ h = 1;
+ } else {
+ gradW = 0;
+ w = 1;
+ }
+ QColor c1 = begin;
+ QColor c2 = end;
+ if (flipped) {
+ c1 = end;
+ c2 = begin;
+ }
+ QLinearGradient lg(0, 0, gradW, gradH);
+ lg.setColorAt(0, c1);
+ lg.setColorAt(1, c2);
+ QImage img(w, h, QImage::Format_ARGB32);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), lg);
+ return QPixmap::fromImage(img);
+}
+
+QPixmap QtColorLinePrivate::hueGradientPixmap(Qt::Orientation orientation, bool flipped,
+ int saturation, int value, int alpha) const
+{
+ int size = m_pixmapSize.width();
+ if (orientation == Qt::Vertical)
+ size = m_pixmapSize.height();
+ return hueGradientPixmap(size, orientation, flipped, saturation, value, alpha);
+}
+
+QPixmap QtColorLinePrivate::hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped,
+ int saturation, int value, int alpha) const
+{
+ int gradW = size + 1;
+ int gradH = size + 1;
+ int w = size;
+ int h = size;
+ if (orientation == Qt::Horizontal) {
+ gradH = 0;
+ h = 1;
+ } else {
+ gradW = 0;
+ w = 1;
+ }
+ QList<QColor> colorList;
+ colorList << QColor::fromHsv(0, saturation, value, alpha);
+ colorList << QColor::fromHsv(60, saturation, value, alpha);
+ colorList << QColor::fromHsv(120, saturation, value, alpha);
+ colorList << QColor::fromHsv(180, saturation, value, alpha);
+ colorList << QColor::fromHsv(240, saturation, value, alpha);
+ colorList << QColor::fromHsv(300, saturation, value, alpha);
+ colorList << QColor::fromHsv(0, saturation, value, alpha);
+ QLinearGradient lg(0, 0, gradW, gradH);
+ for (int i = 0; i <= 6; i++)
+ lg.setColorAt((double)i / 6.0, flipped ? colorList.at(6 - i) : colorList.at(i));
+ QImage img(w, h, QImage::Format_ARGB32);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), lg);
+ return QPixmap::fromImage(img);
+}
+
+void QtColorLinePrivate::recreateMainPixmap()
+{
+ m_lastValidMainPixmapData.size = m_pixmapSize;
+ m_lastValidMainPixmapData.component = m_component;
+ m_lastValidMainPixmapData.color = m_color;
+ m_lastValidMainPixmapData.flipped = m_flipped;
+ m_lastValidMainPixmapData.orientation = m_orientation;
+
+ if (m_pixmapSize.isEmpty()) {
+ m_mainPixmap = QPixmap();
+ m_alphalessPixmap = QPixmap();
+ m_semiAlphaPixmap = QPixmap();
+ return;
+ }
+
+ if (m_mainPixmap.size() != m_pixmapSize) {
+ m_mainPixmap = QPixmap(m_pixmapSize);
+ m_alphalessPixmap = QPixmap(m_pixmapSize);
+ m_semiAlphaPixmap = QPixmap(m_pixmapSize);
+ }
+
+ Qt::Orientation orient = m_orientation;
+ const bool flip = m_flipped;
+
+ const int r = m_color.red();
+ const int g = m_color.green();
+ const int b = m_color.blue();
+ const int h = m_color.hue();
+ const int s = m_color.saturation();
+ const int v = m_color.value();
+ const int a = m_color.alpha();
+ const double coef = 0.5;
+ const int semi = qRound(a * coef + 0xFF * (1.0 - coef));
+
+ if (m_component == QtColorLine::Hue) {
+ m_alphalessPixmap = hueGradientPixmap(orient, flip, s, v, 0xFF);
+ if (m_combiningAlpha) {
+ m_mainPixmap = hueGradientPixmap(orient, flip, s, v, a);
+ m_semiAlphaPixmap = hueGradientPixmap(orient, flip, s, v, semi);
+ }
+ } else if (m_component == QtColorLine::Saturation) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, 0xFF), QColor::fromHsv(h, 0xFF, v, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, a), QColor::fromHsv(h, 0xFF, v, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, semi), QColor::fromHsv(h, 0xFF, v, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Value) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, 0xFF), QColor::fromHsv(h, s, 0xFF, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, a), QColor::fromHsv(h, s, 0xFF, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, semi), QColor::fromHsv(h, s, 0xFF, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Red) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, 0xFF), QColor::fromRgb(0xFF, g, b, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, a), QColor::fromRgb(0xFF, g, b, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, semi), QColor::fromRgb(0xFF, g, b, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Green) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, 0xFF), QColor::fromRgb(r, 0xFF, b, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, a), QColor::fromRgb(r, 0xFF, b, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, semi), QColor::fromRgb(r, 0xFF, b, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Blue) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, 0xFF), QColor::fromRgb(r, g, 0xFF, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, a), QColor::fromRgb(r, g, 0xFF, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, semi), QColor::fromRgb(r, g, 0xFF, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Alpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0), QColor::fromRgb(r, g, b, 0xFF), flip);
+
+// m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0xFF), QColor::fromRgb(r, g, b, 0xFF), flip);
+// m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, semi), QColor::fromRgb(r, g, b, semi), flip);
+ }
+ if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
+ m_mainPixmap = m_alphalessPixmap;
+}
+
+QSize QtColorLinePrivate::pixmapSizeFromGeometrySize(
+ const QSize &geometrySize) const
+{
+ QSize size(m_indicatorSize + 2 * m_indicatorSpace - 1,
+ m_indicatorSize + 2 * m_indicatorSpace - 1);
+ if (m_orientation == Qt::Horizontal)
+ size.setHeight(0);
+ else
+ size.setWidth(0);
+ return geometrySize - size;
+}
+
+QColor QtColorLinePrivate::colorFromPoint(const QPointF &point) const
+{
+ QPointF p = point;
+ if (p.x() < 0)
+ p.setX(0.0);
+ else if (p.x() > 1)
+ p.setX(1.0);
+ if (p.y() < 0)
+ p.setY(0.0);
+ else if (p.y() > 1)
+ p.setY(1.0);
+
+ double pos = p.x();
+ if (m_orientation == Qt::Vertical)
+ pos = p.y();
+ if (m_flipped)
+ pos = 1.0 - pos;
+ QColor c;
+ qreal hue;
+ switch (m_component) {
+ case QtColorLine::Red:
+ c.setRgbF(pos, m_color.greenF(), m_color.blueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Green:
+ c.setRgbF(m_color.redF(), pos, m_color.blueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Blue:
+ c.setRgbF(m_color.redF(), m_color.greenF(), pos, m_color.alphaF());
+ break;
+ case QtColorLine::Hue:
+ hue = pos;
+ hue *= 35999.0 / 36000.0;
+ c.setHsvF(hue, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Saturation:
+ c.setHsvF(m_color.hueF(), pos, m_color.valueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Value:
+ c.setHsvF(m_color.hueF(), m_color.saturationF(), pos, m_color.alphaF());
+ break;
+ case QtColorLine::Alpha:
+ c.setHsvF(m_color.hueF(), m_color.saturationF(), m_color.valueF(), pos);
+ break;
+ }
+ return c;
+}
+
+QPointF QtColorLinePrivate::pointFromColor(const QColor &color) const
+{
+ qreal hue = color.hueF();
+ if (color.hue() == 360)
+ hue = 0.0;
+ else
+ hue *= 36000.0 / 35999.0;
+
+ double pos = 0.0;
+ switch (m_component) {
+ case QtColorLine::Red:
+ pos = color.redF();
+ break;
+ case QtColorLine::Green:
+ pos = color.greenF();
+ break;
+ case QtColorLine::Blue:
+ pos = color.blueF();
+ break;
+ case QtColorLine::Hue:
+ pos = hue;
+ break;
+ case QtColorLine::Saturation:
+ pos = color.saturationF();
+ break;
+ case QtColorLine::Value:
+ pos = color.valueF();
+ break;
+ case QtColorLine::Alpha:
+ pos = color.alphaF();
+ break;
+ }
+ if (m_flipped)
+ pos = 1.0 - pos;
+ QPointF p(pos, pos);
+ if (m_orientation == Qt::Horizontal)
+ p.setY(0);
+ else
+ p.setX(0);
+ return p;
+}
+
+QVector<QRect> QtColorLinePrivate::rects(const QPointF &point) const
+{
+ QRect r = q_ptr->geometry();
+ r.moveTo(0, 0);
+
+ int x1 = (int)((r.width() - m_indicatorSize - 2 * m_indicatorSpace) * point.x() + 0.5);
+ int x2 = x1 + m_indicatorSize + 2 * m_indicatorSpace;
+ int y1 = (int)((r.height() - m_indicatorSize - 2 * m_indicatorSpace) * point.y() + 0.5);
+ int y2 = y1 + m_indicatorSize + 2 * m_indicatorSpace;
+
+ QVector<QRect> rects;
+ if (m_orientation == Qt::Horizontal) {
+ // r0 r1 r2
+ QRect r0(0, 0, x1, r.height());
+ QRect r1(x1 + m_indicatorSpace, 0, m_indicatorSize, r.height());
+ QRect r2(x2, 0, r.width() - x2, r.height());
+
+ rects << r0 << r1 << r2;
+ } else {
+ // r0
+ // r1
+ // r2
+ QRect r0(0, 0, r.width(), y1);
+ QRect r1(0, y1 + m_indicatorSpace, r.width(), m_indicatorSize);
+ QRect r2(0, y2, r.width(), r.height() - y2);
+
+ rects << r0 << r1 << r2;
+ }
+ return rects;
+}
+
+void QtColorLinePrivate::resizeEvent(QResizeEvent *event)
+{
+ m_pixmapSize = pixmapSizeFromGeometrySize(event->size());
+}
+
+void QtColorLinePrivate::paintEvent(QPaintEvent *)
+{
+ QRect rect = q_ptr->rect();
+
+ QVector<QRect> r = rects(m_point);
+
+ QColor cBack = q_ptr->palette().color(QPalette::Active, QPalette::Window);
+ QColor c = colorFromPoint(m_point);
+ if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
+ c.setAlpha(0xFF);
+
+ QPainter p(q_ptr);
+ if (q_ptr->isEnabled()) {
+ if (m_backgroundCheckered) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+ pmp.end();
+
+ p.setBrushOrigin((rect.width() % pixSize + pixSize) / 2, (rect.height() % pixSize + pixSize) / 2);
+ p.setClipRect(r[1].adjusted(4, 4, -4, -4));
+ p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 0, rect.bottom())), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(r[1].right() - 0, rect.top()), rect.bottomRight()), Qt::UniteClip);
+ p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 0)), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 0), rect.bottomRight()), Qt::UniteClip);
+ /*
+ p.setClipRect(r[1].adjusted(3, 3, -3, -3));
+ p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 1, rect.bottom())), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(r[1].right() - 1, rect.top()), rect.bottomRight()), Qt::UniteClip);
+ p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 1)), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 1), rect.bottomRight()), Qt::UniteClip);
+ */
+ p.fillRect(rect, pm);
+ p.setBrushOrigin(0, 0);
+ p.setClipping(false);
+ }
+
+ validate();
+
+ QSize fieldSize = pixmapSizeFromGeometrySize(q_ptr->geometry().size());
+
+ QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
+ int x = posOnField.x();
+ int y = posOnField.y();
+ int w = fieldSize.width();
+ int h = fieldSize.height();
+
+ QRect r0, r2;
+ if (m_orientation == Qt::Horizontal) {
+ r0 = QRect(0, 0, x, m_pixmapSize.height());
+ r2 = QRect(x + 1, 0, w - x - 1, m_pixmapSize.height());
+ } else {
+ r0 = QRect(0, 0, m_pixmapSize.width(), y);
+ r2 = QRect(0, y + 1, m_pixmapSize.width(), h - y - 1);
+ }
+
+ p.setBrush(m_mainPixmap);
+ p.setPen(Qt::NoPen);
+ if (r[0].isValid()) {
+ p.drawRect(r[0]);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ p.drawRect(r[2]);
+ }
+ if (m_indicatorSpace) {
+ p.setBrush(c);
+ if (m_orientation == Qt::Horizontal) {
+ p.drawRect(r[1].adjusted(-m_indicatorSpace, 0, -r[1].width(), 0));
+ p.drawRect(r[1].adjusted(r[1].width(), 0, m_indicatorSpace, 0));
+ } else {
+ p.drawRect(r[1].adjusted(0, -m_indicatorSpace, 0, -r[1].height()));
+ p.drawRect(r[1].adjusted(0, r[1].height(), 0, m_indicatorSpace));
+ }
+ }
+
+ QPen pen(c);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ if (r[1].isValid()) {
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+ }
+ double coef = 9.0 / 10;
+ p.setPen(Qt::NoPen);
+ if (m_component != QtColorLine::Alpha && m_combiningAlpha) {
+ p.setBrush(m_alphalessPixmap);
+ if (r[0].isValid()) {
+ p.setBrushOrigin(QPoint(0, 0));
+ QRect thinRect1 = r[0];
+ QRect thinRect2 = r[0];
+ QRect thinRect = r[0];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ QRect thinRect1 = r[2];
+ QRect thinRect2 = r[2];
+ QRect thinRect = r[2];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ /*
+
+*/
+
+
+
+
+
+ p.setPen(Qt::NoPen);
+
+ p.setBrush(m_semiAlphaPixmap);
+ if (r[0].isValid()) {
+ p.setBrushOrigin(QPoint(0, 0));
+ QRect thinRect1 = r[0];
+ QRect thinRect2 = r[0];
+ QRect thinRect = r[0];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
+ thinRect1.setBottom(thinRect1.top());
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
+ thinRect2.setTop(thinRect2.bottom());
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
+ thinRect1.setRight(thinRect1.left());
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
+ thinRect2.setLeft(thinRect2.right());
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ QRect thinRect1 = r[2];
+ QRect thinRect2 = r[2];
+ QRect thinRect = r[2];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
+ thinRect1.setBottom(thinRect1.top());
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
+ thinRect2.setTop(thinRect2.bottom());
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
+ thinRect1.setRight(thinRect1.left());
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
+ thinRect2.setLeft(thinRect2.right());
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ p.setBrush(m_alphalessPixmap);
+ if (m_orientation == Qt::Horizontal) {
+ p.setClipRect(r[1].adjusted(0, qRound(r[1].height() * coef), 0, 0));
+ p.setClipRect(r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef)), Qt::UniteClip);
+ } else {
+ p.setClipRect(r[1].adjusted(qRound(r[1].width() * coef), 0, 0, 0));
+ p.setClipRect(r[1].adjusted(0, 0, -qRound(r[1].width() * coef), 0), Qt::UniteClip);
+ }
+ p.setBrush(Qt::NoBrush);
+ p.setPen(QPen(QColor(c.rgb())));
+
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+/*
+ p.setBrush(m_semiAlphaPixmap);
+ if (m_orientation == Qt::Horizontal) {
+ QRect top = r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef) + 1);
+ top.setTop(top.bottom());
+ QRect bottom = r[1].adjusted(0, qRound(r[1].height() * coef) - 1, 0, 0);
+ top.setBottom(bottom.top());
+ p.setClipRect(top);
+ p.setClipRect(bottom, Qt::UniteClip);
+ } else {
+
+ }
+ QColor semiColor(c.rgb());
+ semiColor.setAlpha((c.alpha() + 0xFF) / 2);
+ p.setPen(QPen(semiColor));
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+*/
+ p.setClipping(false);
+ }
+ }
+
+ p.setBrush(Qt::NoBrush);
+ int lw = 4;
+ //int br = 1;
+ int br = 0;
+ r[1].adjust(br, br, -br, -br);
+ if (r[1].adjusted(lw, lw, -lw, -lw).isValid()) {
+ QStyleOptionFrame opt;
+ opt.init(q_ptr);
+ opt.rect = r[1];
+ opt.lineWidth = 2;
+ opt.midLineWidth = 1;
+ if (m_dragging)
+ opt.state |= QStyle::State_Sunken;
+ else
+ opt.state |= QStyle::State_Raised;
+ q_ptr->style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, q_ptr);
+ QRect colorRect = r[1].adjusted(lw, lw, -lw, -lw);
+ if (q_ptr->isEnabled()) {
+ p.fillRect(colorRect, c);
+ const QColor frameColor(0, 0, 0, 38);
+ p.setPen(frameColor);
+ p.drawRect(colorRect.adjusted(0, 0, -1, -1));
+ /*
+ p.fillRect(colorRect.width() / 4 + colorRect.left(),
+ colorRect.height() / 4 + colorRect.top(),
+ colorRect.width() / 2,
+ colorRect.height() / 2,
+ QColor(c.rgb()));
+ */
+ /*
+ if (m_component != QtColorLine::Alpha) {
+ p.fillRect(colorRect.adjusted(0, colorRect.height() * 4 / 5, 0, 0), QColor(c.rgb()));
+ p.fillRect(colorRect.adjusted(0, 0, 0, -colorRect.height() * 4 / 5), QColor(c.rgb()));
+ }
+ */
+ }
+ }
+}
+
+void QtColorLinePrivate::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ QVector<QRect> r = rects(m_point);
+ QPoint clickPos = event->pos();
+
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+ QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
+ m_clickOffset = posOnField - clickPos;
+
+ if (!r[1].contains(clickPos))
+ return;
+ m_dragging = true;
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!m_dragging)
+ return;
+ QPoint newPos = event->pos();
+
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+ QPoint newPosOnField = newPos + m_clickOffset;
+ if (newPosOnField.x() < 0)
+ newPosOnField.setX(0);
+ else if (newPosOnField.x() > fieldSize.width())
+ newPosOnField.setX(fieldSize.width());
+ if (newPosOnField.y() < 0)
+ newPosOnField.setY(0);
+ else if (newPosOnField.y() > fieldSize.height())
+ newPosOnField.setY(fieldSize.height());
+
+ double x = (double)newPosOnField.x() / fieldSize.width();
+ double y = (double)newPosOnField.y() / fieldSize.height();
+ m_point = QPointF(x, y);
+ QColor color = colorFromPoint(m_point);
+ if (m_color == color)
+ return;
+ m_color = color;
+ emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+ m_dragging = false;
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ QVector<QRect> r = rects(m_point);
+ QPoint clickPos = event->pos();
+ if (!r[0].contains(clickPos) && !r[2].contains(clickPos))
+ return;
+ QPoint newPosOnField = clickPos;
+ if (r[2].contains(clickPos))
+ newPosOnField -= QPoint(m_indicatorSize + 2 * m_indicatorSpace - 2, m_indicatorSize + 2 * m_indicatorSpace - 2);
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+
+ double x = (double)newPosOnField.x() / fieldSize.width();
+ double y = (double)newPosOnField.y() / fieldSize.height();
+ m_point = QPointF(x, y);
+ QColor color = colorFromPoint(m_point);
+ if (m_color == color)
+ return;
+ m_color = color;
+ emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
+ q_ptr->update();
+}
+
+////////////////////////////////////////////////////
+
+QtColorLine::QtColorLine(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtColorLinePrivate)
+{
+ d_ptr->q_ptr = this;
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+}
+
+QtColorLine::~QtColorLine()
+{
+}
+
+QSize QtColorLine::minimumSizeHint() const
+{
+ return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
+}
+
+QSize QtColorLine::sizeHint() const
+{
+ return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
+}
+
+void QtColorLine::setColor(const QColor &color)
+{
+ d_ptr->setColor(color);
+}
+
+QColor QtColorLine::color() const
+{
+ return d_ptr->color();
+}
+
+void QtColorLine::setColorComponent(QtColorLine::ColorComponent component)
+{
+ d_ptr->setColorComponent(component);
+}
+
+QtColorLine::ColorComponent QtColorLine::colorComponent() const
+{
+ return d_ptr->colorComponent();
+}
+
+void QtColorLine::setIndicatorSize(int size)
+{
+ d_ptr->setIndicatorSize(size);
+}
+
+int QtColorLine::indicatorSize() const
+{
+ return d_ptr->indicatorSize();
+}
+
+void QtColorLine::setIndicatorSpace(int space)
+{
+ d_ptr->setIndicatorSpace(space);
+}
+
+int QtColorLine::indicatorSpace() const
+{
+ return d_ptr->indicatorSpace();
+}
+
+void QtColorLine::setFlip(bool flip)
+{
+ d_ptr->setFlip(flip);
+}
+
+bool QtColorLine::flip() const
+{
+ return d_ptr->flip();
+}
+
+void QtColorLine::setBackgroundCheckered(bool checkered)
+{
+ d_ptr->setBackgroundCheckered(checkered);
+}
+
+bool QtColorLine::isBackgroundCheckered() const
+{
+ return d_ptr->isBackgroundCheckered();
+}
+
+void QtColorLine::setOrientation(Qt::Orientation orientation)
+{
+ d_ptr->setOrientation(orientation);
+}
+
+Qt::Orientation QtColorLine::orientation() const
+{
+ return d_ptr->orientation();
+}
+void QtColorLine::resizeEvent(QResizeEvent *event)
+{
+ d_ptr->resizeEvent(event);
+}
+
+void QtColorLine::paintEvent(QPaintEvent *event)
+{
+ d_ptr->paintEvent(event);
+}
+
+void QtColorLine::mousePressEvent(QMouseEvent *event)
+{
+ d_ptr->mousePressEvent(event);
+}
+
+void QtColorLine::mouseMoveEvent(QMouseEvent *event)
+{
+ d_ptr->mouseMoveEvent(event);
+}
+
+void QtColorLine::mouseReleaseEvent(QMouseEvent *event)
+{
+ d_ptr->mouseReleaseEvent(event);
+}
+
+void QtColorLine::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ d_ptr->mouseDoubleClickEvent(event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtcolorline.h b/src/shared/qtgradienteditor/qtcolorline.h
new file mode 100644
index 000000000..8d04a7ca7
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorline.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCOLORLINE_H
+#define QTCOLORLINE_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorLine : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ color WRITE setColor)
+ Q_PROPERTY(int indicatorSpace READ indicatorSpace WRITE setIndicatorSpace)
+ Q_PROPERTY(int indicatorSize READ indicatorSize WRITE setIndicatorSize)
+ Q_PROPERTY(bool flip READ flip WRITE setFlip)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(ColorComponent colorComponent READ colorComponent WRITE setColorComponent)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_ENUMS(ColorComponent)
+public:
+
+ enum ColorComponent {
+ Red,
+ Green,
+ Blue,
+ Hue,
+ Saturation,
+ Value,
+ Alpha
+ };
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ QtColorLine(QWidget *parent = 0);
+ ~QtColorLine();
+
+ QColor color() const;
+
+ void setIndicatorSize(int size);
+ int indicatorSize() const;
+
+ void setIndicatorSpace(int space);
+ int indicatorSpace() const;
+
+ void setFlip(bool flip);
+ bool flip() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void setColorComponent(ColorComponent component);
+ ColorComponent colorComponent() const;
+
+public slots:
+
+ void setColor(const QColor &color);
+
+signals:
+
+ void colorChanged(const QColor &color);
+
+protected:
+
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+
+private:
+
+ QScopedPointer<class QtColorLinePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorLine)
+ Q_DISABLE_COPY(QtColorLine)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.cpp b/src/shared/qtgradienteditor/qtgradientdialog.cpp
new file mode 100644
index 000000000..dbeeb1f20
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.cpp
@@ -0,0 +1,353 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientdialog.h"
+#include "ui_qtgradientdialog.h"
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientDialogPrivate
+{
+ QtGradientDialog *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientDialog)
+public:
+
+ void slotAboutToShowDetails(bool details, int extensionWidthHint);
+
+ Ui::QtGradientDialog m_ui;
+};
+
+void QtGradientDialogPrivate::slotAboutToShowDetails(bool details, int extensionWidthHint)
+{
+ if (details) {
+ q_ptr->resize(q_ptr->size() + QSize(extensionWidthHint, 0));
+ } else {
+ q_ptr->setMinimumSize(1, 1);
+ q_ptr->resize(q_ptr->size() - QSize(extensionWidthHint, 0));
+ q_ptr->setMinimumSize(0, 0);
+ }
+}
+
+/*!
+ \class QtGradientDialog
+
+ \brief The QtGradientDialog class provides a dialog for specifying gradients.
+
+ The gradient dialog's function is to allow users to edit gradients.
+ For example, you might use this in a drawing program to allow the user to set the brush gradient.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialog.png
+ \o \inlineimage qtgradientdialogextension.png
+ \header
+ \o Details extension hidden
+ \o Details extension visible
+ \endtable
+
+ Starting from the top of the dialog there are several buttons:
+
+ \image qtgradientdialogtopbuttons.png
+
+ The first three buttons allow for changing a type of the gradient (QGradient::Type), while the second three allow for
+ changing spread of the gradient (QGradient::Spread). The last button shows or hides the details extension of the dialog.
+ Conceptually the default view with hidden details provides the full functional control over gradient editing.
+ The additional extension with details allows to set gradient's parameters more precisely. The visibility
+ of extension can be controlled by detailsVisible property. Moreover, if you don't want the user to
+ switch on or off the visibility of extension you can set the detailsButtonVisible property to false.
+
+ Below top buttons there is an area where edited gradient is interactively previewed.
+ In addition the user can edit gradient type's specific parameters directly in this area by dragging
+ appropriate handles.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialoglineareditor.png
+ \o \inlineimage qtgradientdialogradialeditor.png
+ \o \inlineimage qtgradientdialogconicaleditor.png
+ \header
+ \o Editing linear type
+ \o Editing radial type
+ \o Editing conical type
+ \row
+ \o The user can change the start and final point positions by dragging the circular handles.
+ \o The user can change the center and focal point positions by dragging the circular handles
+ and can change the gradient's radius by dragging horizontal or vertical line.
+ \o The user can change the center point by dragging the circular handle
+ and can change the gradient's angle by dragging the big wheel.
+ \endtable
+
+ In the middle of the dialog there is an area where the user can edit gradient stops.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogstops.png
+ \o \inlineimage qtgradientdialogstopszoomed.png
+ \endtable
+
+ The top part of this area contains stop handles, and bottom part shows the preview of gradient stops path.
+ In order to create a new gradient stop double click inside the view over the desired position.
+ If you double click on existing stop handle in the top part of the view, clicked handle will be duplicated
+ (duplicate will contain the same color).
+ The stop can be activated by clicking on its handle. You can activate previous or next stop by pressing
+ left or right key respectively. To jump to the first or last stop press home or end key respectively.
+ The gradient stops editor supports multiselection.
+ Clicking a handle holding the shift modifier key down will select a range of stops between
+ the active stop and clicked one. Clicking a handle holding control modifier key down will remove from or
+ add to selection the clicked stop depending if it was or wasn't already selected respectively.
+ Multiselection can also be created using rubberband (by pressing the left mouse button outside
+ of any handle and dragging).
+ Sometimes it's hard to select a stop because its handle can be partially covered by other handle.
+ In that case the user can zoom in the view by spinning mouse wheel.
+ The selected stop handles can be moved by drag & drop. In order to remove selected stops press delete key.
+ For convenience context menu is provided with the following actions:
+
+ \list
+ \o New Stop - creates a new gradient stop
+ \o Delete - removes the active and all selected stops
+ \o Flip All - mirrors all stops
+ \o Select All - selects all stops
+ \o Zoom In - zooms in
+ \o Zoom Out - zooms out
+ \o Zoom All - goes back to original 100% zoom
+ \endlist
+
+ The bottom part of the QtGradientDialog contains a set of widgets allowing to control the color of
+ the active and selected stops.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogcolorhsv.png
+ \o \inlineimage qtgradientdialogcolorrgb.png
+ \endtable
+
+
+ The color button shows the color of the active gradient stop. It also allows for choosing
+ a color from standard color dialog and applying it to the
+ active stop and all selected stops. It's also possible to drag a color directly from the color button
+ and to drop it in gradient stops editor at desired position (it will create new stop with dragged color)
+ or at desired stop handle (it will change the color of that handle).
+
+ To the right of color button there is a set of 2 radio buttons which allows to switch between
+ HVS and RGB color spec.
+
+ Finally there are 4 color sliders working either in HSVA (hue saturation value alpha) or
+ RGBA (red green blue alpha) mode, depending on which radio button is chosen. The radio buttons
+ can be controlled programatically by spec() and setSpec() methods. The sliders show the
+ color of the active stop. By double clicking inside color slider you can set directly the desired color.
+ Changes of slider's are applied to stop selection in the way that the color
+ component being changed is applied to stops in selection only, while other components
+ remain unchanged in selected stops (e.g. when the user is changing the saturation,
+ new saturation is applied to selected stops preventing original hue, value and alpha in multiselection).
+
+ The convenient static functions getGradient() provide modal gradient dialogs, e.g.:
+
+ \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 0
+
+ In order to have more control over the properties of QtGradientDialog use
+ standard QDialog::exec() method:
+
+ \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 1
+
+ \sa {Gradient View Example}
+*/
+
+/*!
+ Constructs a gradient dialog with \a parent as parent widget.
+*/
+
+QtGradientDialog::QtGradientDialog(QWidget *parent)
+ : QDialog(parent), d_ptr(new QtGradientDialogPrivate())
+{
+// setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ d_ptr->q_ptr = this;
+ d_ptr->m_ui.setupUi(this);
+ QPushButton *button = d_ptr->m_ui.buttonBox->button(QDialogButtonBox::Ok);
+ if (button)
+ button->setAutoDefault(false);
+ button = d_ptr->m_ui.buttonBox->button(QDialogButtonBox::Cancel);
+ if (button)
+ button->setAutoDefault(false);
+ connect(d_ptr->m_ui.gradientEditor, SIGNAL(aboutToShowDetails(bool,int)),
+ this, SLOT(slotAboutToShowDetails(bool,int)));
+}
+
+/*!
+ Destroys the gradient dialog
+*/
+
+QtGradientDialog::~QtGradientDialog()
+{
+}
+
+/*!
+ \property QtGradientDialog::gradient
+ \brief the gradient of the dialog
+*/
+void QtGradientDialog::setGradient(const QGradient &gradient)
+{
+ d_ptr->m_ui.gradientEditor->setGradient(gradient);
+}
+
+QGradient QtGradientDialog::gradient() const
+{
+ return d_ptr->m_ui.gradientEditor->gradient();
+}
+
+/*!
+ \property QtGradientDialog::backgroundCheckered
+ \brief whether the background of widgets able to show the colors with alpha channel is checkered.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogbackgroundcheckered.png
+ \o \inlineimage qtgradientdialogbackgroundtransparent.png
+ \row
+ \o \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 2
+ \o \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 3
+ \endtable
+
+ When this property is set to true (the default) widgets inside gradient dialog like color button,
+ color sliders, gradient stops editor and gradient editor will show checkered background
+ in case of transparent colors. Otherwise the background of these widgets is transparent.
+*/
+
+bool QtGradientDialog::isBackgroundCheckered() const
+{
+ return d_ptr->m_ui.gradientEditor->isBackgroundCheckered();
+}
+
+void QtGradientDialog::setBackgroundCheckered(bool checkered)
+{
+ d_ptr->m_ui.gradientEditor->setBackgroundCheckered(checkered);
+}
+
+/*!
+ \property QtGradientDialog::detailsVisible
+ \brief whether details extension is visible.
+
+ When this property is set to true the details extension is visible. By default
+ this property is set to false and the details extension is hidden.
+
+ \sa detailsButtonVisible
+*/
+bool QtGradientDialog::detailsVisible() const
+{
+ return d_ptr->m_ui.gradientEditor->detailsVisible();
+}
+
+void QtGradientDialog::setDetailsVisible(bool visible)
+{
+ d_ptr->m_ui.gradientEditor->setDetailsVisible(visible);
+}
+
+/*!
+ \property QtGradientDialog::detailsButtonVisible
+ \brief whether the details button allowing for showing and hiding details extension is visible.
+
+ When this property is set to true (the default) the details button is visible and the user
+ can show and hide details extension interactively. Otherwise the button is hidden and the details
+ extension is always visible or hidded depending on the value of detailsVisible property.
+
+ \sa detailsVisible
+*/
+bool QtGradientDialog::isDetailsButtonVisible() const
+{
+ return d_ptr->m_ui.gradientEditor->isDetailsButtonVisible();
+}
+
+void QtGradientDialog::setDetailsButtonVisible(bool visible)
+{
+ d_ptr->m_ui.gradientEditor->setDetailsButtonVisible(visible);
+}
+
+/*!
+ Returns the current QColor::Spec used for the color sliders in the dialog.
+*/
+QColor::Spec QtGradientDialog::spec() const
+{
+ return d_ptr->m_ui.gradientEditor->spec();
+}
+
+/*!
+ Sets the current QColor::Spec to \a spec used for the color sliders in the dialog.
+*/
+void QtGradientDialog::setSpec(QColor::Spec spec)
+{
+ d_ptr->m_ui.gradientEditor->setSpec(spec);
+}
+
+/*!
+ Executes a modal gradient dialog, lets the user to specify a gradient, and returns that gradient.
+
+ If the user clicks \gui OK, the gradient specified by the user is returned. If the user clicks \gui Cancel, the \a initial gradient is returned.
+
+ The dialog is constructed with the given \a parent. \a caption is shown as the window title of the dialog and
+ \a initial is the initial gradient shown in the dialog. If the \a ok parameter is not-null,
+ the value it refers to is set to true if the user clicks \gui OK, and set to false if the user clicks \gui Cancel.
+*/
+QGradient QtGradientDialog::getGradient(bool *ok, const QGradient &initial, QWidget *parent, const QString &caption)
+{
+ QtGradientDialog dlg(parent);
+ if (!caption.isEmpty())
+ dlg.setWindowTitle(caption);
+ dlg.setGradient(initial);
+ const int res = dlg.exec();
+ if (ok) {
+ *ok = (res == QDialog::Accepted) ? true : false;
+ }
+ if (res == QDialog::Accepted)
+ return dlg.gradient();
+ return initial;
+}
+
+/*!
+ This method calls getGradient(ok, QLinearGradient(), parent, caption).
+*/
+QGradient QtGradientDialog::getGradient(bool *ok, QWidget *parent, const QString &caption)
+{
+ return getGradient(ok, QLinearGradient(), parent, caption);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientdialog.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.h b/src/shared/qtgradienteditor/qtgradientdialog.h
new file mode 100644
index 000000000..c6330d164
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTDIALOG_H
+#define QTGRADIENTDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientDialog : public QDialog
+{
+ Q_OBJECT
+ Q_PROPERTY(QGradient gradient READ gradient WRITE setGradient)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(bool detailsVisible READ detailsVisible WRITE setDetailsVisible)
+ Q_PROPERTY(bool detailsButtonVisible READ isDetailsButtonVisible WRITE setDetailsButtonVisible)
+public:
+ QtGradientDialog(QWidget *parent = 0);
+ ~QtGradientDialog();
+
+ void setGradient(const QGradient &gradient);
+ QGradient gradient() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ bool detailsVisible() const;
+ void setDetailsVisible(bool visible);
+
+ bool isDetailsButtonVisible() const;
+ void setDetailsButtonVisible(bool visible);
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+ static QGradient getGradient(bool *ok, const QGradient &initial, QWidget *parent = 0, const QString &caption = QString());
+ static QGradient getGradient(bool *ok, QWidget *parent = 0, const QString &caption = QString());
+
+private:
+ QScopedPointer<class QtGradientDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientDialog)
+ Q_DISABLE_COPY(QtGradientDialog)
+ Q_PRIVATE_SLOT(d_func(), void slotAboutToShowDetails(bool details, int extensionWidthHint))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.ui b/src/shared/qtgradienteditor/qtgradientdialog.ui
new file mode 100644
index 000000000..0652c1636
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.ui
@@ -0,0 +1,121 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientDialog</class>
+ <widget class="QDialog" name="QtGradientDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>178</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Edit Gradient</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QtGradientEditor" name="gradientEditor" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtGradientEditor</class>
+ <extends>QFrame</extends>
+ <header>qtgradienteditor.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtGradientDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>224</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>21</x>
+ <y>243</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtGradientDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>168</x>
+ <y>233</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>152</x>
+ <y>251</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.cpp b/src/shared/qtgradienteditor/qtgradienteditor.cpp
new file mode 100644
index 000000000..2855389d2
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.cpp
@@ -0,0 +1,952 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradienteditor.h"
+#include "qtgradientstopscontroller.h"
+#include "ui_qtgradienteditor.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientEditorPrivate
+{
+ QtGradientEditor *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientEditor)
+public:
+ QtGradientEditorPrivate() : m_gradient(QLinearGradient()) {}
+
+ void slotGradientStopsChanged(const QGradientStops &stops);
+ void slotTypeChanged(int type);
+ void slotSpreadChanged(int spread);
+ void slotStartLinearXChanged(double value);
+ void slotStartLinearYChanged(double value);
+ void slotEndLinearXChanged(double value);
+ void slotEndLinearYChanged(double value);
+ void slotCentralRadialXChanged(double value);
+ void slotCentralRadialYChanged(double value);
+ void slotFocalRadialXChanged(double value);
+ void slotFocalRadialYChanged(double value);
+ void slotRadiusRadialChanged(double value);
+ void slotCentralConicalXChanged(double value);
+ void slotCentralConicalYChanged(double value);
+ void slotAngleConicalChanged(double value);
+
+ void slotDetailsChanged(bool details);
+
+ void startLinearChanged(const QPointF &point);
+ void endLinearChanged(const QPointF &point);
+ void centralRadialChanged(const QPointF &point);
+ void focalRadialChanged(const QPointF &point);
+ void radiusRadialChanged(qreal radius);
+ void centralConicalChanged(const QPointF &point);
+ void angleConicalChanged(qreal angle);
+
+ void setStartLinear(const QPointF &point);
+ void setEndLinear(const QPointF &point);
+ void setCentralRadial(const QPointF &point);
+ void setFocalRadial(const QPointF &point);
+ void setRadiusRadial(qreal radius);
+ void setCentralConical(const QPointF &point);
+ void setAngleConical(qreal angle);
+
+ void setType(QGradient::Type type);
+ void showDetails(bool details);
+
+ void setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max = 1.0, double step = 0.01, int decimals = 3);
+ void reset();
+ void setLayout(bool details);
+ void layoutDetails(bool details);
+ bool row4Visible() const;
+ bool row5Visible() const;
+ int extensionWidthHint() const;
+
+ void setCombos(bool combos);
+
+ QGradient gradient() const;
+ void updateGradient(bool emitSignal);
+
+ Ui::QtGradientEditor m_ui;
+ QtGradientStopsController *m_gradientStopsController;
+
+ QDoubleSpinBox *startLinearXSpinBox;
+ QDoubleSpinBox *startLinearYSpinBox;
+ QDoubleSpinBox *endLinearXSpinBox;
+ QDoubleSpinBox *endLinearYSpinBox;
+ QDoubleSpinBox *centralRadialXSpinBox;
+ QDoubleSpinBox *centralRadialYSpinBox;
+ QDoubleSpinBox *focalRadialXSpinBox;
+ QDoubleSpinBox *focalRadialYSpinBox;
+ QDoubleSpinBox *radiusRadialSpinBox;
+ QDoubleSpinBox *centralConicalXSpinBox;
+ QDoubleSpinBox *centralConicalYSpinBox;
+ QDoubleSpinBox *angleConicalSpinBox;
+
+ QButtonGroup *m_typeGroup;
+ QButtonGroup *m_spreadGroup;
+
+ QGradient::Type m_type;
+
+ QGridLayout *m_gridLayout;
+ QWidget *m_hiddenWidget;
+ QGridLayout *m_hiddenLayout;
+ bool m_details;
+ bool m_detailsButtonVisible;
+ bool m_backgroundCheckered;
+
+ QGradient m_gradient;
+
+ bool m_combos;
+};
+
+QGradient QtGradientEditorPrivate::gradient() const
+{
+ QGradient *gradient = 0;
+ switch (m_ui.gradientWidget->gradientType()) {
+ case QGradient::LinearGradient:
+ gradient = new QLinearGradient(m_ui.gradientWidget->startLinear(),
+ m_ui.gradientWidget->endLinear());
+ break;
+ case QGradient::RadialGradient:
+ gradient = new QRadialGradient(m_ui.gradientWidget->centralRadial(),
+ m_ui.gradientWidget->radiusRadial(),
+ m_ui.gradientWidget->focalRadial());
+ break;
+ case QGradient::ConicalGradient:
+ gradient = new QConicalGradient(m_ui.gradientWidget->centralConical(),
+ m_ui.gradientWidget->angleConical());
+ break;
+ default:
+ break;
+ }
+ if (!gradient)
+ return QGradient();
+ gradient->setStops(m_ui.gradientWidget->gradientStops());
+ gradient->setSpread(m_ui.gradientWidget->gradientSpread());
+ gradient->setCoordinateMode(QGradient::StretchToDeviceMode);
+ QGradient gr = *gradient;
+ delete gradient;
+ return gr;
+}
+
+void QtGradientEditorPrivate::updateGradient(bool emitSignal)
+{
+ QGradient grad = gradient();
+ if (m_gradient == grad)
+ return;
+
+ m_gradient = grad;
+ if (emitSignal)
+ emit q_ptr->gradientChanged(m_gradient);
+}
+
+void QtGradientEditorPrivate::setCombos(bool combos)
+{
+ if (m_combos == combos)
+ return;
+
+ m_combos = combos;
+ m_ui.linearButton->setVisible(!m_combos);
+ m_ui.radialButton->setVisible(!m_combos);
+ m_ui.conicalButton->setVisible(!m_combos);
+ m_ui.padButton->setVisible(!m_combos);
+ m_ui.repeatButton->setVisible(!m_combos);
+ m_ui.reflectButton->setVisible(!m_combos);
+ m_ui.typeComboBox->setVisible(m_combos);
+ m_ui.spreadComboBox->setVisible(m_combos);
+}
+
+void QtGradientEditorPrivate::setLayout(bool details)
+{
+ QHBoxLayout *hboxLayout = new QHBoxLayout();
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->addWidget(m_ui.typeComboBox);
+ hboxLayout->addWidget(m_ui.spreadComboBox);
+ QHBoxLayout *typeLayout = new QHBoxLayout();
+ typeLayout->setSpacing(0);
+ typeLayout->addWidget(m_ui.linearButton);
+ typeLayout->addWidget(m_ui.radialButton);
+ typeLayout->addWidget(m_ui.conicalButton);
+ hboxLayout->addLayout(typeLayout);
+ QHBoxLayout *spreadLayout = new QHBoxLayout();
+ spreadLayout->setSpacing(0);
+ spreadLayout->addWidget(m_ui.padButton);
+ spreadLayout->addWidget(m_ui.repeatButton);
+ spreadLayout->addWidget(m_ui.reflectButton);
+ hboxLayout->addLayout(spreadLayout);
+ hboxLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ hboxLayout->addWidget(m_ui.detailsButton);
+ m_gridLayout->addLayout(hboxLayout, 0, 0, 1, 2);
+ int span = 1;
+ if (details)
+ span = 7;
+ m_gridLayout->addWidget(m_ui.frame, 1, 0, span, 2);
+ int row = 2;
+ if (details) {
+ row = 8;
+ span = 4;
+ }
+ m_gridLayout->addWidget(m_ui.gradientStopsWidget, row, 0, span, 2);
+ QHBoxLayout *hboxLayout1 = new QHBoxLayout();
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
+ hboxLayout1->addWidget(m_ui.colorLabel);
+ hboxLayout1->addWidget(m_ui.colorButton);
+ hboxLayout1->addWidget(m_ui.hsvRadioButton);
+ hboxLayout1->addWidget(m_ui.rgbRadioButton);
+ hboxLayout1->addItem(new QSpacerItem(16, 23, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ int addRow = 0;
+ if (details)
+ addRow = 9;
+ m_gridLayout->addLayout(hboxLayout1, 3 + addRow, 0, 1, 2);
+ m_gridLayout->addWidget(m_ui.hLabel, 4 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_2, 4 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.sLabel, 5 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_5, 5 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.vLabel, 6 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_3, 6 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.aLabel, 7 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_4, 7 + addRow, 1, 1, 1);
+
+ if (details) {
+ layoutDetails(details);
+ }
+}
+
+void QtGradientEditorPrivate::layoutDetails(bool details)
+{
+ QGridLayout *gridLayout = m_gridLayout;
+ int col = 2;
+ if (!details) {
+ col = 0;
+ if (!m_hiddenWidget) {
+ m_hiddenWidget = new QWidget();
+ m_hiddenLayout = new QGridLayout(m_hiddenWidget);
+ m_hiddenLayout->setContentsMargins(0, 0, 0, 0);
+ m_hiddenLayout->setSizeConstraint(QLayout::SetFixedSize);
+ }
+ gridLayout = m_hiddenLayout;
+ }
+ gridLayout->addWidget(m_ui.label1, 1, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox1, 1, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label2, 2, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox2, 2, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label3, 3, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox3, 3, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label4, 4, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox4, 4, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label5, 5, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox5, 5, col + 1, 1, 1);
+ gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 6, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.line1Widget, 7, col + 0, 1, 2);
+ gridLayout->addWidget(m_ui.zoomLabel, 8, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.zoomWidget, 8, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.zoomButtonsWidget, 9, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.zoomAllButton, 9, col + 1, 1, 1);
+ gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Preferred), 10, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.line2Widget, 11, col + 0, 1, 2);
+ gridLayout->addWidget(m_ui.positionLabel, 12, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.positionWidget, 12, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.hueLabel, 13, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.hueWidget, 13, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.saturationLabel, 14, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.saturationWidget, 14, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.valueLabel, 15, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.valueWidget, 15, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.alphaLabel, 16, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.alphaWidget, 16, col + 1, 1, 1);
+
+ if (details) {
+ if (m_hiddenLayout) {
+ delete m_hiddenLayout;
+ m_hiddenLayout = 0;
+ }
+ if (m_hiddenWidget) {
+ delete m_hiddenWidget;
+ m_hiddenWidget = 0;
+ }
+ }
+}
+
+int QtGradientEditorPrivate::extensionWidthHint() const
+{
+ if (m_details)
+ return q_ptr->size().width() - m_ui.gradientStopsWidget->size().width();
+
+ const int space = m_ui.spinBox1->geometry().left() - m_ui.label1->geometry().right();
+
+ return m_hiddenLayout->minimumSize().width() + space;
+}
+
+void QtGradientEditorPrivate::slotDetailsChanged(bool details)
+{
+ showDetails(details);
+}
+
+bool QtGradientEditorPrivate::row4Visible() const
+{
+ if (m_type == QGradient::ConicalGradient)
+ return false;
+ return true;
+}
+
+bool QtGradientEditorPrivate::row5Visible() const
+{
+ if (m_type == QGradient::RadialGradient)
+ return true;
+ return false;
+}
+
+void QtGradientEditorPrivate::showDetails(bool details)
+{
+ if (m_details == details)
+ return;
+
+ bool blocked = m_ui.detailsButton->signalsBlocked();
+ m_ui.detailsButton->blockSignals(true);
+ m_ui.detailsButton->setChecked(details);
+ m_ui.detailsButton->blockSignals(blocked);
+
+ bool updates = q_ptr->updatesEnabled();
+ q_ptr->setUpdatesEnabled(false);
+
+ if (m_gridLayout) {
+ m_gridLayout->setEnabled(false);
+ delete m_gridLayout;
+ m_gridLayout = 0;
+ }
+
+ if (!details) {
+ layoutDetails(details);
+ }
+
+ emit q_ptr->aboutToShowDetails(details, extensionWidthHint());
+ m_details = details;
+
+ m_gridLayout = new QGridLayout(q_ptr);
+ m_gridLayout->setEnabled(false);
+ m_gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ m_gridLayout->setContentsMargins(0, 0, 0, 0);
+
+ m_ui.label4->setVisible(row4Visible());
+ m_ui.label5->setVisible(row5Visible());
+ m_ui.spinBox4->setVisible(row4Visible());
+ m_ui.spinBox5->setVisible(row5Visible());
+
+ setLayout(details);
+ m_gridLayout->setEnabled(true);
+
+ q_ptr->setUpdatesEnabled(updates);
+ q_ptr->update();
+}
+
+void QtGradientEditorPrivate::setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max, double step, int decimals)
+{
+ bool blocked = spinBox->signalsBlocked();
+ spinBox->blockSignals(true);
+ spinBox->setDecimals(decimals);
+ spinBox->setMaximum(max);
+ spinBox->setSingleStep(step);
+ spinBox->blockSignals(blocked);
+ QObject::connect(spinBox, SIGNAL(valueChanged(double)), q_ptr, slot);
+}
+
+void QtGradientEditorPrivate::reset()
+{
+ startLinearXSpinBox = 0;
+ startLinearYSpinBox = 0;
+ endLinearXSpinBox = 0;
+ endLinearYSpinBox = 0;
+ centralRadialXSpinBox = 0;
+ centralRadialYSpinBox = 0;
+ focalRadialXSpinBox = 0;
+ focalRadialYSpinBox = 0;
+ radiusRadialSpinBox = 0;
+ centralConicalXSpinBox = 0;
+ centralConicalYSpinBox = 0;
+ angleConicalSpinBox = 0;
+}
+
+void QtGradientEditorPrivate::setType(QGradient::Type type)
+{
+ if (m_type == type)
+ return;
+
+ m_type = type;
+ m_ui.spinBox1->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox2->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox3->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox4->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox5->disconnect(SIGNAL(valueChanged(double)));
+
+ reset();
+
+ bool ena = true;
+
+ if (m_gridLayout) {
+ ena = m_gridLayout->isEnabled();
+ m_gridLayout->setEnabled(false);
+ }
+
+ bool spreadEnabled = true;
+
+ if (type == QGradient::LinearGradient) {
+ startLinearXSpinBox = m_ui.spinBox1;
+ setSpinBox(startLinearXSpinBox, SLOT(slotStartLinearXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Start X", 0, QApplication::UnicodeUTF8));
+
+ startLinearYSpinBox = m_ui.spinBox2;
+ setSpinBox(startLinearYSpinBox, SLOT(slotStartLinearYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Start Y", 0, QApplication::UnicodeUTF8));
+
+ endLinearXSpinBox = m_ui.spinBox3;
+ setSpinBox(endLinearXSpinBox, SLOT(slotEndLinearXChanged(double)));
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Final X", 0, QApplication::UnicodeUTF8));
+
+ endLinearYSpinBox = m_ui.spinBox4;
+ setSpinBox(endLinearYSpinBox, SLOT(slotEndLinearYChanged(double)));
+ m_ui.label4->setText(QApplication::translate("QtGradientEditor", "Final Y", 0, QApplication::UnicodeUTF8));
+
+ setStartLinear(m_ui.gradientWidget->startLinear());
+ setEndLinear(m_ui.gradientWidget->endLinear());
+ } else if (type == QGradient::RadialGradient) {
+ centralRadialXSpinBox = m_ui.spinBox1;
+ setSpinBox(centralRadialXSpinBox, SLOT(slotCentralRadialXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Central X", 0, QApplication::UnicodeUTF8));
+
+ centralRadialYSpinBox = m_ui.spinBox2;
+ setSpinBox(centralRadialYSpinBox, SLOT(slotCentralRadialYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Central Y", 0, QApplication::UnicodeUTF8));
+
+ focalRadialXSpinBox = m_ui.spinBox3;
+ setSpinBox(focalRadialXSpinBox, SLOT(slotFocalRadialXChanged(double)));
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Focal X", 0, QApplication::UnicodeUTF8));
+
+ focalRadialYSpinBox = m_ui.spinBox4;
+ setSpinBox(focalRadialYSpinBox, SLOT(slotFocalRadialYChanged(double)));
+ m_ui.label4->setText(QApplication::translate("QtGradientEditor", "Focal Y", 0, QApplication::UnicodeUTF8));
+
+ radiusRadialSpinBox = m_ui.spinBox5;
+ setSpinBox(radiusRadialSpinBox, SLOT(slotRadiusRadialChanged(double)), 2.0);
+ m_ui.label5->setText(QApplication::translate("QtGradientEditor", "Radius", 0, QApplication::UnicodeUTF8));
+
+ setCentralRadial(m_ui.gradientWidget->centralRadial());
+ setFocalRadial(m_ui.gradientWidget->focalRadial());
+ setRadiusRadial(m_ui.gradientWidget->radiusRadial());
+ } else if (type == QGradient::ConicalGradient) {
+ centralConicalXSpinBox = m_ui.spinBox1;
+ setSpinBox(centralConicalXSpinBox, SLOT(slotCentralConicalXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Central X", 0, QApplication::UnicodeUTF8));
+
+ centralConicalYSpinBox = m_ui.spinBox2;
+ setSpinBox(centralConicalYSpinBox, SLOT(slotCentralConicalYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Central Y", 0, QApplication::UnicodeUTF8));
+
+ angleConicalSpinBox = m_ui.spinBox3;
+ setSpinBox(angleConicalSpinBox, SLOT(slotAngleConicalChanged(double)), 360.0, 1.0, 1);
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Angle", 0, QApplication::UnicodeUTF8));
+
+ setCentralConical(m_ui.gradientWidget->centralConical());
+ setAngleConical(m_ui.gradientWidget->angleConical());
+
+ spreadEnabled = false;
+ }
+ m_ui.spreadComboBox->setEnabled(spreadEnabled);
+ m_ui.padButton->setEnabled(spreadEnabled);
+ m_ui.repeatButton->setEnabled(spreadEnabled);
+ m_ui.reflectButton->setEnabled(spreadEnabled);
+
+ m_ui.label4->setVisible(row4Visible());
+ m_ui.spinBox4->setVisible(row4Visible());
+ m_ui.label5->setVisible(row5Visible());
+ m_ui.spinBox5->setVisible(row5Visible());
+
+ if (m_gridLayout) {
+ m_gridLayout->setEnabled(ena);
+ }
+}
+
+void QtGradientEditorPrivate::slotGradientStopsChanged(const QGradientStops &stops)
+{
+ m_ui.gradientWidget->setGradientStops(stops);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotTypeChanged(int idx)
+{
+ QGradient::Type type = QGradient::NoGradient;
+ if (idx == 0)
+ type = QGradient::LinearGradient;
+ else if (idx == 1)
+ type = QGradient::RadialGradient;
+ else if (idx == 2)
+ type = QGradient::ConicalGradient;
+ setType(type);
+ m_ui.typeComboBox->setCurrentIndex(idx);
+ m_typeGroup->button(idx)->setChecked(true);
+ m_ui.gradientWidget->setGradientType(type);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotSpreadChanged(int spread)
+{
+ if (spread == 0) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::PadSpread);
+ } else if (spread == 1) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::RepeatSpread);
+ } else if (spread == 2) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::ReflectSpread);
+ }
+ m_ui.spreadComboBox->setCurrentIndex(spread);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotStartLinearXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->startLinear();
+ point.setX(value);
+ m_ui.gradientWidget->setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotStartLinearYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->startLinear();
+ point.setY(value);
+ m_ui.gradientWidget->setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotEndLinearXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->endLinear();
+ point.setX(value);
+ m_ui.gradientWidget->setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotEndLinearYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->endLinear();
+ point.setY(value);
+ m_ui.gradientWidget->setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralRadialXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralRadial();
+ point.setX(value);
+ m_ui.gradientWidget->setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralRadialYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralRadial();
+ point.setY(value);
+ m_ui.gradientWidget->setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotFocalRadialXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->focalRadial();
+ point.setX(value);
+ m_ui.gradientWidget->setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotFocalRadialYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->focalRadial();
+ point.setY(value);
+ m_ui.gradientWidget->setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotRadiusRadialChanged(double value)
+{
+ m_ui.gradientWidget->setRadiusRadial(value);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralConicalXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralConical();
+ point.setX(value);
+ m_ui.gradientWidget->setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralConicalYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralConical();
+ point.setY(value);
+ m_ui.gradientWidget->setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotAngleConicalChanged(double value)
+{
+ m_ui.gradientWidget->setAngleConical(value);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::startLinearChanged(const QPointF &point)
+{
+ setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::endLinearChanged(const QPointF &point)
+{
+ setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::centralRadialChanged(const QPointF &point)
+{
+ setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::focalRadialChanged(const QPointF &point)
+{
+ setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::radiusRadialChanged(qreal radius)
+{
+ setRadiusRadial(radius);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::centralConicalChanged(const QPointF &point)
+{
+ setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::angleConicalChanged(qreal angle)
+{
+ setAngleConical(angle);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::setStartLinear(const QPointF &point)
+{
+ if (startLinearXSpinBox)
+ startLinearXSpinBox->setValue(point.x());
+ if (startLinearYSpinBox)
+ startLinearYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setEndLinear(const QPointF &point)
+{
+ if (endLinearXSpinBox)
+ endLinearXSpinBox->setValue(point.x());
+ if (endLinearYSpinBox)
+ endLinearYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setCentralRadial(const QPointF &point)
+{
+ if (centralRadialXSpinBox)
+ centralRadialXSpinBox->setValue(point.x());
+ if (centralRadialYSpinBox)
+ centralRadialYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setFocalRadial(const QPointF &point)
+{
+ if (focalRadialXSpinBox)
+ focalRadialXSpinBox->setValue(point.x());
+ if (focalRadialYSpinBox)
+ focalRadialYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setRadiusRadial(qreal radius)
+{
+ if (radiusRadialSpinBox)
+ radiusRadialSpinBox->setValue(radius);
+}
+
+void QtGradientEditorPrivate::setCentralConical(const QPointF &point)
+{
+ if (centralConicalXSpinBox)
+ centralConicalXSpinBox->setValue(point.x());
+ if (centralConicalYSpinBox)
+ centralConicalYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setAngleConical(qreal angle)
+{
+ if (angleConicalSpinBox)
+ angleConicalSpinBox->setValue(angle);
+}
+
+QtGradientEditor::QtGradientEditor(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtGradientEditorPrivate())
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_type = QGradient::RadialGradient;
+ d_ptr->m_ui.setupUi(this);
+ d_ptr->m_gridLayout = 0;
+ d_ptr->m_hiddenLayout = 0;
+ d_ptr->m_hiddenWidget = 0;
+ bool detailsDefault = false;
+ d_ptr->m_details = !detailsDefault;
+ d_ptr->m_detailsButtonVisible = true;
+ bool checkeredDefault = true;
+ d_ptr->m_backgroundCheckered = !checkeredDefault;
+ d_ptr->m_gradientStopsController = new QtGradientStopsController(this);
+ d_ptr->m_gradientStopsController->setUi(&d_ptr->m_ui);
+ d_ptr->reset();
+ d_ptr->setType(QGradient::LinearGradient);
+ d_ptr->m_combos = true;
+ d_ptr->setCombos(!d_ptr->m_combos);
+
+ d_ptr->showDetails(detailsDefault);
+ setBackgroundCheckered(checkeredDefault);
+
+ d_ptr->setStartLinear(QPointF(0, 0));
+ d_ptr->setEndLinear(QPointF(1, 1));
+ d_ptr->setCentralRadial(QPointF(0.5, 0.5));
+ d_ptr->setFocalRadial(QPointF(0.5, 0.5));
+ d_ptr->setRadiusRadial(0.5);
+ d_ptr->setCentralConical(QPointF(0.5, 0.5));
+ d_ptr->setAngleConical(0);
+
+ QIcon icon;
+ icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowRight), QIcon::Normal, QIcon::Off);
+ icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowLeft), QIcon::Normal, QIcon::On);
+ d_ptr->m_ui.detailsButton->setIcon(icon);
+
+ connect(d_ptr->m_ui.detailsButton, SIGNAL(clicked(bool)), this, SLOT(slotDetailsChanged(bool)));
+ connect(d_ptr->m_gradientStopsController, SIGNAL(gradientStopsChanged(QGradientStops)),
+ this, SLOT(slotGradientStopsChanged(QGradientStops)));
+
+ QIcon iconLinear(QLatin1String(":/trolltech/qtgradienteditor/images/typelinear.png"));
+ QIcon iconRadial(QLatin1String(":/trolltech/qtgradienteditor/images/typeradial.png"));
+ QIcon iconConical(QLatin1String(":/trolltech/qtgradienteditor/images/typeconical.png"));
+
+ d_ptr->m_ui.typeComboBox->addItem(iconLinear, tr("Linear"));
+ d_ptr->m_ui.typeComboBox->addItem(iconRadial, tr("Radial"));
+ d_ptr->m_ui.typeComboBox->addItem(iconConical, tr("Conical"));
+
+ d_ptr->m_ui.linearButton->setIcon(iconLinear);
+ d_ptr->m_ui.radialButton->setIcon(iconRadial);
+ d_ptr->m_ui.conicalButton->setIcon(iconConical);
+
+ d_ptr->m_typeGroup = new QButtonGroup(this);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.linearButton, 0);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.radialButton, 1);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.conicalButton, 2);
+
+ connect(d_ptr->m_typeGroup, SIGNAL(buttonClicked(int)),
+ this, SLOT(slotTypeChanged(int)));
+ connect(d_ptr->m_ui.typeComboBox, SIGNAL(activated(int)),
+ this, SLOT(slotTypeChanged(int)));
+
+ QIcon iconPad(QLatin1String(":/trolltech/qtgradienteditor/images/spreadpad.png"));
+ QIcon iconRepeat(QLatin1String(":/trolltech/qtgradienteditor/images/spreadrepeat.png"));
+ QIcon iconReflect(QLatin1String(":/trolltech/qtgradienteditor/images/spreadreflect.png"));
+
+ d_ptr->m_ui.spreadComboBox->addItem(iconPad, tr("Pad"));
+ d_ptr->m_ui.spreadComboBox->addItem(iconRepeat, tr("Repeat"));
+ d_ptr->m_ui.spreadComboBox->addItem(iconReflect, tr("Reflect"));
+
+ d_ptr->m_ui.padButton->setIcon(iconPad);
+ d_ptr->m_ui.repeatButton->setIcon(iconRepeat);
+ d_ptr->m_ui.reflectButton->setIcon(iconReflect);
+
+ d_ptr->m_spreadGroup = new QButtonGroup(this);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.padButton, 0);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.repeatButton, 1);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.reflectButton, 2);
+ connect(d_ptr->m_spreadGroup, SIGNAL(buttonClicked(int)),
+ this, SLOT(slotSpreadChanged(int)));
+ connect(d_ptr->m_ui.spreadComboBox, SIGNAL(activated(int)),
+ this, SLOT(slotSpreadChanged(int)));
+
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(startLinearChanged(QPointF)),
+ this, SLOT(startLinearChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(endLinearChanged(QPointF)),
+ this, SLOT(endLinearChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralRadialChanged(QPointF)),
+ this, SLOT(centralRadialChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(focalRadialChanged(QPointF)),
+ this, SLOT(focalRadialChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(radiusRadialChanged(qreal)),
+ this, SLOT(radiusRadialChanged(qreal)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralConicalChanged(QPointF)),
+ this, SLOT(centralConicalChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(angleConicalChanged(qreal)),
+ this, SLOT(angleConicalChanged(qreal)));
+
+ QGradientStops stops = gradient().stops();
+ d_ptr->m_gradientStopsController->setGradientStops(stops);
+ d_ptr->m_ui.gradientWidget->setGradientStops(stops);
+}
+
+QtGradientEditor::~QtGradientEditor()
+{
+ if (d_ptr->m_hiddenWidget)
+ delete d_ptr->m_hiddenWidget;
+}
+
+void QtGradientEditor::setGradient(const QGradient &grad)
+{
+ if (grad == gradient())
+ return;
+
+ QGradient::Type type = grad.type();
+ int idx = 0;
+ switch (type) {
+ case QGradient::LinearGradient: idx = 0; break;
+ case QGradient::RadialGradient: idx = 1; break;
+ case QGradient::ConicalGradient: idx = 2; break;
+ default: return;
+ }
+ d_ptr->setType(type);
+ d_ptr->m_ui.typeComboBox->setCurrentIndex(idx);
+ d_ptr->m_ui.gradientWidget->setGradientType(type);
+ d_ptr->m_typeGroup->button(idx)->setChecked(true);
+
+ QGradient::Spread spread = grad.spread();
+ switch (spread) {
+ case QGradient::PadSpread: idx = 0; break;
+ case QGradient::RepeatSpread: idx = 1; break;
+ case QGradient::ReflectSpread: idx = 2; break;
+ default: idx = 0; break;
+ }
+ d_ptr->m_ui.spreadComboBox->setCurrentIndex(idx);
+ d_ptr->m_ui.gradientWidget->setGradientSpread(spread);
+ d_ptr->m_spreadGroup->button(idx)->setChecked(true);
+
+ if (type == QGradient::LinearGradient) {
+ QLinearGradient *gr = (QLinearGradient *)(&grad);
+ d_ptr->setStartLinear(gr->start());
+ d_ptr->setEndLinear(gr->finalStop());
+ d_ptr->m_ui.gradientWidget->setStartLinear(gr->start());
+ d_ptr->m_ui.gradientWidget->setEndLinear(gr->finalStop());
+ } else if (type == QGradient::RadialGradient) {
+ QRadialGradient *gr = (QRadialGradient *)(&grad);
+ d_ptr->setCentralRadial(gr->center());
+ d_ptr->setFocalRadial(gr->focalPoint());
+ d_ptr->setRadiusRadial(gr->radius());
+ d_ptr->m_ui.gradientWidget->setCentralRadial(gr->center());
+ d_ptr->m_ui.gradientWidget->setFocalRadial(gr->focalPoint());
+ d_ptr->m_ui.gradientWidget->setRadiusRadial(gr->radius());
+ } else if (type == QGradient::ConicalGradient) {
+ QConicalGradient *gr = (QConicalGradient *)(&grad);
+ d_ptr->setCentralConical(gr->center());
+ d_ptr->setAngleConical(gr->angle());
+ d_ptr->m_ui.gradientWidget->setCentralConical(gr->center());
+ d_ptr->m_ui.gradientWidget->setAngleConical(gr->angle());
+ }
+
+ d_ptr->m_gradientStopsController->setGradientStops(grad.stops());
+ d_ptr->m_ui.gradientWidget->setGradientStops(grad.stops());
+ d_ptr->updateGradient(false);
+}
+
+QGradient QtGradientEditor::gradient() const
+{
+ return d_ptr->m_gradient;
+}
+
+bool QtGradientEditor::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientEditor::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+
+ d_ptr->m_backgroundCheckered = checkered;
+ d_ptr->m_ui.hueColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.saturationColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.valueColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.alphaColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.gradientWidget->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.gradientStopsWidget->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.colorButton->setBackgroundCheckered(checkered);
+}
+
+bool QtGradientEditor::detailsVisible() const
+{
+ return d_ptr->m_details;
+}
+
+void QtGradientEditor::setDetailsVisible(bool visible)
+{
+ d_ptr->showDetails(visible);
+}
+
+bool QtGradientEditor::isDetailsButtonVisible() const
+{
+ return d_ptr->m_detailsButtonVisible;
+}
+
+void QtGradientEditor::setDetailsButtonVisible(bool visible)
+{
+ if (d_ptr->m_detailsButtonVisible == visible)
+ return;
+
+ d_ptr->m_detailsButtonVisible = visible;
+ d_ptr->m_ui.detailsButton->setVisible(visible);
+}
+
+QColor::Spec QtGradientEditor::spec() const
+{
+ return d_ptr->m_gradientStopsController->spec();
+}
+
+void QtGradientEditor::setSpec(QColor::Spec spec)
+{
+ d_ptr->m_gradientStopsController->setSpec(spec);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradienteditor.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.h b/src/shared/qtgradienteditor/qtgradienteditor.h
new file mode 100644
index 000000000..77e1d3470
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTEDITOR_H
+#define QTGRADIENTEDITOR_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientEditor : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QGradient gradient READ gradient WRITE setGradient)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(bool detailsVisible READ detailsVisible WRITE setDetailsVisible)
+ Q_PROPERTY(bool detailsButtonVisible READ isDetailsButtonVisible WRITE setDetailsButtonVisible)
+public:
+ QtGradientEditor(QWidget *parent = 0);
+ ~QtGradientEditor();
+
+ void setGradient(const QGradient &gradient);
+ QGradient gradient() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ bool detailsVisible() const;
+ void setDetailsVisible(bool visible);
+
+ bool isDetailsButtonVisible() const;
+ void setDetailsButtonVisible(bool visible);
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+signals:
+
+ void gradientChanged(const QGradient &gradient);
+ void aboutToShowDetails(bool details, int extenstionWidthHint);
+
+private:
+ QScopedPointer<class QtGradientEditorPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientEditor)
+ Q_DISABLE_COPY(QtGradientEditor)
+ Q_PRIVATE_SLOT(d_func(), void slotGradientStopsChanged(const QGradientStops &stops))
+ Q_PRIVATE_SLOT(d_func(), void slotTypeChanged(int type))
+ Q_PRIVATE_SLOT(d_func(), void slotSpreadChanged(int type))
+ Q_PRIVATE_SLOT(d_func(), void slotStartLinearXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotStartLinearYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotEndLinearXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotEndLinearYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralRadialXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralRadialYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotFocalRadialXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotFocalRadialYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotRadiusRadialChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralConicalXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralConicalYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotAngleConicalChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotDetailsChanged(bool details))
+ Q_PRIVATE_SLOT(d_func(), void startLinearChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void endLinearChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void centralRadialChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void focalRadialChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void radiusRadialChanged(qreal))
+ Q_PRIVATE_SLOT(d_func(), void centralConicalChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void angleConicalChanged(qreal))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.pri b/src/shared/qtgradienteditor/qtgradienteditor.pri
new file mode 100644
index 000000000..4cf059e1f
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.pri
@@ -0,0 +1,33 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+FORMS += $$PWD/qtgradienteditor.ui \
+ $$PWD/qtgradientdialog.ui \
+ $$PWD/qtgradientview.ui \
+ $$PWD/qtgradientviewdialog.ui
+SOURCES += $$PWD/qtgradientstopsmodel.cpp \
+ $$PWD/qtgradientstopswidget.cpp \
+ $$PWD/qtgradientstopscontroller.cpp \
+ $$PWD/qtgradientwidget.cpp \
+ $$PWD/qtgradienteditor.cpp \
+ $$PWD/qtgradientdialog.cpp \
+ $$PWD/qtcolorbutton.cpp \
+ $$PWD/qtcolorline.cpp \
+ $$PWD/qtgradientview.cpp \
+ $$PWD/qtgradientviewdialog.cpp \
+ $$PWD/qtgradientmanager.cpp \
+ $$PWD/qtgradientutils.cpp
+HEADERS += $$PWD/qtgradientstopsmodel.h \
+ $$PWD/qtgradientstopswidget.h \
+ $$PWD/qtgradientstopscontroller.h \
+ $$PWD/qtgradientwidget.h \
+ $$PWD/qtgradienteditor.h \
+ $$PWD/qtgradientdialog.h \
+ $$PWD/qtcolorbutton.h \
+ $$PWD/qtcolorline.h \
+ $$PWD/qtgradientview.h \
+ $$PWD/qtgradientviewdialog.h \
+ $$PWD/qtgradientmanager.h \
+ $$PWD/qtgradientutils.h
+RESOURCES += $$PWD/qtgradienteditor.qrc
+
+QT += xml
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.qrc b/src/shared/qtgradienteditor/qtgradienteditor.qrc
new file mode 100644
index 000000000..cce7ba622
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.qrc
@@ -0,0 +1,18 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/trolltech/qtgradienteditor">
+ <file>images/edit.png</file>
+ <file>images/zoomin.png</file>
+ <file>images/zoomout.png</file>
+ <file>images/up.png</file>
+ <file>images/down.png</file>
+ <file>images/plus.png</file>
+ <file>images/minus.png</file>
+ <file>images/editdelete.png</file>
+ <file>images/spreadpad.png</file>
+ <file>images/spreadrepeat.png</file>
+ <file>images/spreadreflect.png</file>
+ <file>images/typelinear.png</file>
+ <file>images/typeradial.png</file>
+ <file>images/typeconical.png</file>
+ </qresource>
+</RCC>
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.ui b/src/shared/qtgradienteditor/qtgradienteditor.ui
new file mode 100644
index 000000000..5a842ffe4
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.ui
@@ -0,0 +1,1377 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientEditor</class>
+ <widget class="QWidget" name="QtGradientEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>364</width>
+ <height>518</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <widget class="QFrame" name="frame" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>69</y>
+ <width>193</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtGradientWidget" native="1" name="gradientWidget" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Gradient Editor</string>
+ </property>
+ <property name="whatsThis" >
+ <string>This area shows a preview of the gradient being edited. It also allows you to edit parameters specific to the gradient's type such as start and final point, radius, etc. by drag &amp; drop.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="label1" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>69</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox1" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>69</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label2" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>99</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>2</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox2" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>99</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label3" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>129</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>3</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox3" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>129</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label4" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>159</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>4</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox4" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>159</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label5" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>189</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>5</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox5" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>189</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QtGradientStopsWidget" native="1" name="gradientStopsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>225</y>
+ <width>193</width>
+ <height>67</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Gradient Stops Editor</string>
+ </property>
+ <property name="whatsThis" >
+ <string>This area allows you to edit gradient stops. Double click on the existing stop handle to duplicate it. Double click outside of the existing stop handles to create a new stop. Drag &amp; drop the handle to reposition it. Use right mouse button to popup context menu with extra actions.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="zoomLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>231</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Zoom</string>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="zoomAllButton" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>260</y>
+ <width>72</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Reset Zoom</string>
+ </property>
+ <property name="text" >
+ <string>Reset Zoom</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="positionLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>304</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Position</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="hLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>335</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Hue</string>
+ </property>
+ <property name="text" >
+ <string>H</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_2" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>333</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="hueColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Hue</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="hueLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>335</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Hue</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="sLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>364</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Saturation</string>
+ </property>
+ <property name="text" >
+ <string>S</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_5" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>362</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="saturationColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Saturation</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="saturationLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>364</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Sat</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="vLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>393</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Value</string>
+ </property>
+ <property name="text" >
+ <string>V</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_3" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>391</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="valueColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Value</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="valueLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>393</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Val</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="aLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>422</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Alpha</string>
+ </property>
+ <property name="text" >
+ <string>A</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_4" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>420</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="alphaColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Alpha</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="alphaLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>422</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Alpha</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" name="typeComboBox" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>40</y>
+ <width>79</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Type</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" name="spreadComboBox" >
+ <property name="geometry" >
+ <rect>
+ <x>96</x>
+ <y>40</y>
+ <width>72</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Spread</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="colorLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>298</y>
+ <width>32</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Color</string>
+ </property>
+ </widget>
+ <widget class="QtColorButton" name="colorButton" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>300</y>
+ <width>26</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Current stop's color</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="hsvRadioButton" >
+ <property name="geometry" >
+ <rect>
+ <x>80</x>
+ <y>301</y>
+ <width>49</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Show HSV specification</string>
+ </property>
+ <property name="text" >
+ <string>HSV</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="rgbRadioButton" >
+ <property name="geometry" >
+ <rect>
+ <x>135</x>
+ <y>301</y>
+ <width>49</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Show RGB specification</string>
+ </property>
+ <property name="text" >
+ <string>RGB</string>
+ </property>
+ </widget>
+ <widget class="QWidget" native="1" name="positionWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>304</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QDoubleSpinBox" name="positionSpinBox" >
+ <property name="toolTip" >
+ <string>Current stop's position</string>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="minimum" >
+ <double>0.000000000000000</double>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="hueWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>333</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="hueSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>359</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="saturationWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>362</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="saturationSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="valueWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>391</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="valueSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="alphaWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>420</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="alphaSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="zoomWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>231</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="zoomSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="minimum" >
+ <number>100</number>
+ </property>
+ <property name="maximum" >
+ <number>10000</number>
+ </property>
+ <property name="singleStep" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="line1Widget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>219</y>
+ <width>143</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Line" name="line1" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="line2Widget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>292</y>
+ <width>143</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Line" name="line2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="zoomButtonsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>260</y>
+ <width>64</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="zoomInButton" >
+ <property name="toolTip" >
+ <string>Zoom In</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="zoomOutButton" >
+ <property name="toolTip" >
+ <string>Zoom Out</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QToolButton" name="detailsButton" >
+ <property name="geometry" >
+ <rect>
+ <x>176</x>
+ <y>40</y>
+ <width>25</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Ignored" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Toggle details extension</string>
+ </property>
+ <property name="text" >
+ <string>></string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="linearButton" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Linear Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="radialButton" >
+ <property name="geometry" >
+ <rect>
+ <x>40</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Radial Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="conicalButton" >
+ <property name="geometry" >
+ <rect>
+ <x>70</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Conical Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="padButton" >
+ <property name="geometry" >
+ <rect>
+ <x>110</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Pad Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="repeatButton" >
+ <property name="geometry" >
+ <rect>
+ <x>140</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Repeat Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="reflectButton" >
+ <property name="geometry" >
+ <rect>
+ <x>170</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Reflect Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtColorButton</class>
+ <extends>QToolButton</extends>
+ <header>qtcolorbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QtColorLine</class>
+ <extends>QWidget</extends>
+ <header>qtcolorline.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QtGradientStopsWidget</class>
+ <extends>QWidget</extends>
+ <header>qtgradientstopswidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QtGradientWidget</class>
+ <extends>QWidget</extends>
+ <header>qtgradientwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>typeComboBox</tabstop>
+ <tabstop>spreadComboBox</tabstop>
+ <tabstop>detailsButton</tabstop>
+ <tabstop>spinBox1</tabstop>
+ <tabstop>spinBox2</tabstop>
+ <tabstop>spinBox3</tabstop>
+ <tabstop>spinBox4</tabstop>
+ <tabstop>spinBox5</tabstop>
+ <tabstop>zoomSpinBox</tabstop>
+ <tabstop>zoomInButton</tabstop>
+ <tabstop>zoomOutButton</tabstop>
+ <tabstop>zoomAllButton</tabstop>
+ <tabstop>colorButton</tabstop>
+ <tabstop>hsvRadioButton</tabstop>
+ <tabstop>rgbRadioButton</tabstop>
+ <tabstop>positionSpinBox</tabstop>
+ <tabstop>hueSpinBox</tabstop>
+ <tabstop>saturationSpinBox</tabstop>
+ <tabstop>valueSpinBox</tabstop>
+ <tabstop>alphaSpinBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientmanager.cpp b/src/shared/qtgradienteditor/qtgradientmanager.cpp
new file mode 100644
index 000000000..afa26c042
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientmanager.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientmanager.h"
+#include <QtGui/QPixmap>
+#include <QtCore/QMetaEnum>
+
+QT_BEGIN_NAMESPACE
+
+QtGradientManager::QtGradientManager(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QMap<QString, QGradient> QtGradientManager::gradients() const
+{
+ return m_idToGradient;
+}
+
+QString QtGradientManager::uniqueId(const QString &id) const
+{
+ if (!m_idToGradient.contains(id))
+ return id;
+
+ QString base = id;
+ while (base.count() > 0 && base.at(base.count() - 1).isDigit())
+ base = base.left(base.count() - 1);
+ QString newId = base;
+ int counter = 0;
+ while (m_idToGradient.contains(newId)) {
+ ++counter;
+ newId = base + QString::number(counter);
+ }
+ return newId;
+}
+
+QString QtGradientManager::addGradient(const QString &id, const QGradient &gradient)
+{
+ QString newId = uniqueId(id);
+
+ m_idToGradient[newId] = gradient;
+
+ emit gradientAdded(newId, gradient);
+
+ return newId;
+}
+
+void QtGradientManager::removeGradient(const QString &id)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ emit gradientRemoved(id);
+
+ m_idToGradient.remove(id);
+}
+
+void QtGradientManager::renameGradient(const QString &id, const QString &newId)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ if (newId == id)
+ return;
+
+ QString changedId = uniqueId(newId);
+ QGradient gradient = m_idToGradient.value(id);
+
+ emit gradientRenamed(id, changedId);
+
+ m_idToGradient.remove(id);
+ m_idToGradient[changedId] = gradient;
+}
+
+void QtGradientManager::changeGradient(const QString &id, const QGradient &newGradient)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ if (m_idToGradient.value(id) == newGradient)
+ return;
+
+ emit gradientChanged(id, newGradient);
+
+ m_idToGradient[id] = newGradient;
+}
+
+void QtGradientManager::clear()
+{
+ QMap<QString, QGradient> grads = gradients();
+ QMapIterator<QString, QGradient> itGrad(grads);
+ while (itGrad.hasNext()) {
+ removeGradient(itGrad.next().key());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientmanager.h b/src/shared/qtgradienteditor/qtgradientmanager.h
new file mode 100644
index 000000000..c0ad6c2b9
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientmanager.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTMANAGER_H
+#define GRADIENTMANAGER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QSize>
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomElement>
+#include <QtGui/QGradient>
+
+QT_BEGIN_NAMESPACE
+
+class QGradient;
+class QPixmap;
+class QColor;
+
+class QtGradientManager : public QObject
+{
+ Q_OBJECT
+public:
+ QtGradientManager(QObject *parent = 0);
+
+ QMap<QString, QGradient> gradients() const;
+
+ QString uniqueId(const QString &id) const;
+
+public slots:
+
+ QString addGradient(const QString &id, const QGradient &gradient);
+ void renameGradient(const QString &id, const QString &newId);
+ void changeGradient(const QString &id, const QGradient &newGradient);
+ void removeGradient(const QString &id);
+
+ //utils
+ void clear();
+
+signals:
+
+ void gradientAdded(const QString &id, const QGradient &gradient);
+ void gradientRenamed(const QString &id, const QString &newId);
+ void gradientChanged(const QString &id, const QGradient &newGradient);
+ void gradientRemoved(const QString &id);
+
+private:
+
+ QMap<QString, QGradient> m_idToGradient;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
new file mode 100644
index 000000000..0e65e015c
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
@@ -0,0 +1,724 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopscontroller.h"
+#include "ui_qtgradienteditor.h"
+#include "qtgradientstopsmodel.h"
+
+#include <QtCore/QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsControllerPrivate
+{
+ QtGradientStopsController *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsController)
+public:
+ typedef QMap<qreal, QColor> PositionColorMap;
+ typedef QMap<qreal, QtGradientStop *> PositionStopMap;
+
+ void slotHsvClicked();
+ void slotRgbClicked();
+
+ void slotCurrentStopChanged(QtGradientStop *stop);
+ void slotStopMoved(QtGradientStop *stop, qreal newPos);
+ void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void slotStopChanged(QtGradientStop *stop, const QColor &newColor);
+ void slotStopSelected(QtGradientStop *stop, bool selected);
+ void slotStopAdded(QtGradientStop *stop);
+ void slotStopRemoved(QtGradientStop *stop);
+ void slotUpdatePositionSpinBox();
+
+ void slotChangeColor(const QColor &color);
+ void slotChangeHue(const QColor &color);
+ void slotChangeSaturation(const QColor &color);
+ void slotChangeValue(const QColor &color);
+ void slotChangeAlpha(const QColor &color);
+ void slotChangeHue(int color);
+ void slotChangeSaturation(int color);
+ void slotChangeValue(int color);
+ void slotChangeAlpha(int color);
+ void slotChangePosition(double value);
+
+ void slotChangeZoom(int value);
+ void slotZoomIn();
+ void slotZoomOut();
+ void slotZoomAll();
+ void slotZoomChanged(double zoom);
+
+ void enableCurrent(bool enable);
+ void setColorSpinBoxes(const QColor &color);
+ PositionColorMap stopsData(const PositionStopMap &stops) const;
+ QGradientStops makeGradientStops(const PositionColorMap &data) const;
+ void updateZoom(double zoom);
+
+ QtGradientStopsModel *m_model;
+ QColor::Spec m_spec;
+
+ Ui::QtGradientEditor *m_ui;
+};
+
+void QtGradientStopsControllerPrivate::enableCurrent(bool enable)
+{
+ m_ui->positionLabel->setEnabled(enable);
+ m_ui->colorLabel->setEnabled(enable);
+ m_ui->hLabel->setEnabled(enable);
+ m_ui->sLabel->setEnabled(enable);
+ m_ui->vLabel->setEnabled(enable);
+ m_ui->aLabel->setEnabled(enable);
+ m_ui->hueLabel->setEnabled(enable);
+ m_ui->saturationLabel->setEnabled(enable);
+ m_ui->valueLabel->setEnabled(enable);
+ m_ui->alphaLabel->setEnabled(enable);
+
+ m_ui->positionSpinBox->setEnabled(enable);
+ m_ui->colorButton->setEnabled(enable);
+
+ m_ui->hueColorLine->setEnabled(enable);
+ m_ui->saturationColorLine->setEnabled(enable);
+ m_ui->valueColorLine->setEnabled(enable);
+ m_ui->alphaColorLine->setEnabled(enable);
+
+ m_ui->hueSpinBox->setEnabled(enable);
+ m_ui->saturationSpinBox->setEnabled(enable);
+ m_ui->valueSpinBox->setEnabled(enable);
+ m_ui->alphaSpinBox->setEnabled(enable);
+}
+
+QtGradientStopsControllerPrivate::PositionColorMap QtGradientStopsControllerPrivate::stopsData(const PositionStopMap &stops) const
+{
+ PositionColorMap data;
+ PositionStopMap::ConstIterator itStop = stops.constBegin();
+ while (itStop != stops.constEnd()) {
+ QtGradientStop *stop = itStop.value();
+ data[stop->position()] = stop->color();
+
+ ++itStop;
+ }
+ return data;
+}
+
+QGradientStops QtGradientStopsControllerPrivate::makeGradientStops(const PositionColorMap &data) const
+{
+ QGradientStops stops;
+ PositionColorMap::ConstIterator itData = data.constBegin();
+ while (itData != data.constEnd()) {
+ stops << QPair<qreal, QColor>(itData.key(), itData.value());
+
+ ++itData;
+ }
+ return stops;
+}
+
+void QtGradientStopsControllerPrivate::updateZoom(double zoom)
+{
+ m_ui->gradientStopsWidget->setZoom(zoom);
+ m_ui->zoomSpinBox->blockSignals(true);
+ m_ui->zoomSpinBox->setValue(qRound(zoom * 100));
+ m_ui->zoomSpinBox->blockSignals(false);
+ bool zoomInEnabled = true;
+ bool zoomOutEnabled = true;
+ bool zoomAllEnabled = true;
+ if (zoom <= 1) {
+ zoomAllEnabled = false;
+ zoomOutEnabled = false;
+ } else if (zoom >= 100) {
+ zoomInEnabled = false;
+ }
+ m_ui->zoomInButton->setEnabled(zoomInEnabled);
+ m_ui->zoomOutButton->setEnabled(zoomOutEnabled);
+ m_ui->zoomAllButton->setEnabled(zoomAllEnabled);
+}
+
+void QtGradientStopsControllerPrivate::slotHsvClicked()
+{
+ QString h = QApplication::translate("qdesigner_internal::QtGradientStopsController", "H", 0, QApplication::UnicodeUTF8);
+ QString s = QApplication::translate("qdesigner_internal::QtGradientStopsController", "S", 0, QApplication::UnicodeUTF8);
+ QString v = QApplication::translate("qdesigner_internal::QtGradientStopsController", "V", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setText(h);
+ m_ui->sLabel->setText(s);
+ m_ui->vLabel->setText(v);
+
+ h = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Hue", 0, QApplication::UnicodeUTF8);
+ s = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Sat", 0, QApplication::UnicodeUTF8);
+ v = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Val", 0, QApplication::UnicodeUTF8);
+
+ const QString hue = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Hue", 0, QApplication::UnicodeUTF8);
+ const QString saturation = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Saturation", 0, QApplication::UnicodeUTF8);
+ const QString value = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Value", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setToolTip(hue);
+ m_ui->hueLabel->setText(h);
+ m_ui->hueColorLine->setToolTip(hue);
+ m_ui->hueColorLine->setColorComponent(QtColorLine::Hue);
+
+ m_ui->sLabel->setToolTip(saturation);
+ m_ui->saturationLabel->setText(s);
+ m_ui->saturationColorLine->setToolTip(saturation);
+ m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation);
+
+ m_ui->vLabel->setToolTip(value);
+ m_ui->valueLabel->setText(v);
+ m_ui->valueColorLine->setToolTip(value);
+ m_ui->valueColorLine->setColorComponent(QtColorLine::Value);
+
+ setColorSpinBoxes(m_ui->colorButton->color());
+}
+
+void QtGradientStopsControllerPrivate::slotRgbClicked()
+{
+ QString r = QApplication::translate("qdesigner_internal::QtGradientStopsController", "R", 0, QApplication::UnicodeUTF8);
+ QString g = QApplication::translate("qdesigner_internal::QtGradientStopsController", "G", 0, QApplication::UnicodeUTF8);
+ QString b = QApplication::translate("qdesigner_internal::QtGradientStopsController", "B", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setText(r);
+ m_ui->sLabel->setText(g);
+ m_ui->vLabel->setText(b);
+
+ QString red = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Red", 0, QApplication::UnicodeUTF8);
+ QString green = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Green", 0, QApplication::UnicodeUTF8);
+ QString blue = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Blue", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setToolTip(red);
+ m_ui->hueLabel->setText(red);
+ m_ui->hueColorLine->setToolTip(red);
+ m_ui->hueColorLine->setColorComponent(QtColorLine::Red);
+
+ m_ui->sLabel->setToolTip(green);
+ m_ui->saturationLabel->setText(green);
+ m_ui->saturationColorLine->setToolTip(green);
+ m_ui->saturationColorLine->setColorComponent(QtColorLine::Green);
+
+ m_ui->vLabel->setToolTip(blue);
+ m_ui->valueLabel->setText(blue);
+ m_ui->valueColorLine->setToolTip(blue);
+ m_ui->valueColorLine->setColorComponent(QtColorLine::Blue);
+
+ setColorSpinBoxes(m_ui->colorButton->color());
+}
+
+void QtGradientStopsControllerPrivate::setColorSpinBoxes(const QColor &color)
+{
+ m_ui->hueSpinBox->blockSignals(true);
+ m_ui->saturationSpinBox->blockSignals(true);
+ m_ui->valueSpinBox->blockSignals(true);
+ m_ui->alphaSpinBox->blockSignals(true);
+ if (m_ui->hsvRadioButton->isChecked()) {
+ if (m_ui->hueSpinBox->maximum() != 359)
+ m_ui->hueSpinBox->setMaximum(359);
+ if (m_ui->hueSpinBox->value() != color.hue())
+ m_ui->hueSpinBox->setValue(color.hue());
+ if (m_ui->saturationSpinBox->value() != color.saturation())
+ m_ui->saturationSpinBox->setValue(color.saturation());
+ if (m_ui->valueSpinBox->value() != color.value())
+ m_ui->valueSpinBox->setValue(color.value());
+ } else {
+ if (m_ui->hueSpinBox->maximum() != 255)
+ m_ui->hueSpinBox->setMaximum(255);
+ if (m_ui->hueSpinBox->value() != color.red())
+ m_ui->hueSpinBox->setValue(color.red());
+ if (m_ui->saturationSpinBox->value() != color.green())
+ m_ui->saturationSpinBox->setValue(color.green());
+ if (m_ui->valueSpinBox->value() != color.blue())
+ m_ui->valueSpinBox->setValue(color.blue());
+ }
+ m_ui->alphaSpinBox->setValue(color.alpha());
+ m_ui->hueSpinBox->blockSignals(false);
+ m_ui->saturationSpinBox->blockSignals(false);
+ m_ui->valueSpinBox->blockSignals(false);
+ m_ui->alphaSpinBox->blockSignals(false);
+}
+
+void QtGradientStopsControllerPrivate::slotCurrentStopChanged(QtGradientStop *stop)
+{
+ if (!stop) {
+ enableCurrent(false);
+ return;
+ }
+ enableCurrent(true);
+
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ m_ui->colorButton->setColor(stop->color());
+ m_ui->hueColorLine->setColor(stop->color());
+ m_ui->saturationColorLine->setColor(stop->color());
+ m_ui->valueColorLine->setColor(stop->color());
+ m_ui->alphaColorLine->setColor(stop->color());
+ setColorSpinBoxes(stop->color());
+}
+
+void QtGradientStopsControllerPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos)
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops.remove(stop->position());
+ stops[newPos] = stop->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ const qreal pos1 = stop1->position();
+ const qreal pos2 = stop2->position();
+ stops[pos1] = stop2->color();
+ stops[pos2] = stop1->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopAdded(QtGradientStop *stop)
+{
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops[stop->position()] = stop->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopRemoved(QtGradientStop *stop)
+{
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops.remove(stop->position());
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor)
+{
+ if (m_model->currentStop() == stop) {
+ m_ui->colorButton->setColor(newColor);
+ m_ui->hueColorLine->setColor(newColor);
+ m_ui->saturationColorLine->setColor(newColor);
+ m_ui->valueColorLine->setColor(newColor);
+ m_ui->alphaColorLine->setColor(newColor);
+ setColorSpinBoxes(newColor);
+ }
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops[stop->position()] = newColor;
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopSelected(QtGradientStop *stop, bool selected)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(selected)
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+}
+
+void QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox()
+{
+ QtGradientStop *current = m_model->currentStop();
+ if (!current)
+ return;
+
+ qreal min = 0.0;
+ qreal max = 1.0;
+ const qreal pos = current->position();
+
+ QtGradientStop *first = m_model->firstSelected();
+ QtGradientStop *last = m_model->lastSelected();
+
+ if (first && last) {
+ const qreal minPos = pos - first->position() - 0.0004999;
+ const qreal maxPos = pos + 1.0 - last->position() + 0.0004999;
+
+ if (max > maxPos)
+ max = maxPos;
+ if (min < minPos)
+ min = minPos;
+
+ if (first->position() == 0.0)
+ min = pos;
+ if (last->position() == 1.0)
+ max = pos;
+ }
+
+ const int spinMin = qRound(m_ui->positionSpinBox->minimum() * 1000);
+ const int spinMax = qRound(m_ui->positionSpinBox->maximum() * 1000);
+
+ const int newMin = qRound(min * 1000);
+ const int newMax = qRound(max * 1000);
+
+ m_ui->positionSpinBox->blockSignals(true);
+ if (spinMin != newMin || spinMax != newMax) {
+ m_ui->positionSpinBox->setRange((double)newMin / 1000, (double)newMax / 1000);
+ }
+ if (m_ui->positionSpinBox->value() != pos)
+ m_ui->positionSpinBox->setValue(pos);
+ m_ui->positionSpinBox->blockSignals(false);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeColor(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop)
+ m_model->changeStop(s, color);
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeHue(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(color.hueF(), c.saturationF(), c.valueF(), c.alphaF());
+ else
+ c.setRgbF(color.redF(), c.greenF(), c.blueF(), c.alphaF());
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeHue(int color)
+{
+ QColor c = m_ui->hueColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF((qreal)color / 360.0, c.saturationF(), c.valueF(), c.alphaF());
+ else
+ c.setRed(color);
+ slotChangeHue(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeSaturation(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), color.saturationF(), c.valueF(), c.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), color.greenF(), c.blueF(), c.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeSaturation(int color)
+{
+ QColor c = m_ui->saturationColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), (qreal)color / 255, c.valueF(), c.alphaF());
+ else
+ c.setGreen(color);
+ slotChangeSaturation(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeValue(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), c.saturationF(), color.valueF(), c.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), c.greenF(), color.blueF(), c.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeValue(int color)
+{
+ QColor c = m_ui->valueColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), c.saturationF(), (qreal)color / 255, c.alphaF());
+ else
+ c.setBlue(color);
+ slotChangeValue(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeAlpha(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), c.saturationF(), c.valueF(), color.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), c.greenF(), c.blueF(), color.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeAlpha(int color)
+{
+ QColor c = m_ui->alphaColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), c.saturationF(), c.valueF(), (qreal)color / 255);
+ else
+ c.setAlpha(color);
+ slotChangeAlpha(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangePosition(double value)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+
+ m_model->moveStops(value);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeZoom(int value)
+{
+ updateZoom(value / 100.0);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomIn()
+{
+ double newZoom = m_ui->gradientStopsWidget->zoom() * 2;
+ if (newZoom > 100)
+ newZoom = 100;
+ updateZoom(newZoom);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomOut()
+{
+ double newZoom = m_ui->gradientStopsWidget->zoom() / 2;
+ if (newZoom < 1)
+ newZoom = 1;
+ updateZoom(newZoom);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomAll()
+{
+ updateZoom(1);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomChanged(double zoom)
+{
+ updateZoom(zoom);
+}
+
+QtGradientStopsController::QtGradientStopsController(QObject *parent)
+ : QObject(parent), d_ptr(new QtGradientStopsControllerPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_spec = QColor::Hsv;
+}
+
+void QtGradientStopsController::setUi(Ui::QtGradientEditor *ui)
+{
+ d_ptr->m_ui = ui;
+
+ d_ptr->m_ui->hueColorLine->setColorComponent(QtColorLine::Hue);
+ d_ptr->m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation);
+ d_ptr->m_ui->valueColorLine->setColorComponent(QtColorLine::Value);
+ d_ptr->m_ui->alphaColorLine->setColorComponent(QtColorLine::Alpha);
+
+ d_ptr->m_model = new QtGradientStopsModel(this);
+ d_ptr->m_ui->gradientStopsWidget->setGradientStopsModel(d_ptr->m_model);
+ connect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ connect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ connect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ connect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+
+ connect(d_ptr->m_ui->hueColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeHue(QColor)));
+ connect(d_ptr->m_ui->saturationColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeSaturation(QColor)));
+ connect(d_ptr->m_ui->valueColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeValue(QColor)));
+ connect(d_ptr->m_ui->alphaColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeAlpha(QColor)));
+ connect(d_ptr->m_ui->colorButton, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeColor(QColor)));
+
+ connect(d_ptr->m_ui->hueSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeHue(int)));
+ connect(d_ptr->m_ui->saturationSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeSaturation(int)));
+ connect(d_ptr->m_ui->valueSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeValue(int)));
+ connect(d_ptr->m_ui->alphaSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeAlpha(int)));
+
+ connect(d_ptr->m_ui->positionSpinBox, SIGNAL(valueChanged(double)),
+ this, SLOT(slotChangePosition(double)));
+
+ connect(d_ptr->m_ui->zoomSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeZoom(int)));
+ connect(d_ptr->m_ui->zoomInButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomIn()));
+ connect(d_ptr->m_ui->zoomOutButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomOut()));
+ connect(d_ptr->m_ui->zoomAllButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomAll()));
+ connect(d_ptr->m_ui->gradientStopsWidget, SIGNAL(zoomChanged(double)),
+ this, SLOT(slotZoomChanged(double)));
+
+ connect(d_ptr->m_ui->hsvRadioButton, SIGNAL(clicked()),
+ this, SLOT(slotHsvClicked()));
+ connect(d_ptr->m_ui->rgbRadioButton, SIGNAL(clicked()),
+ this, SLOT(slotRgbClicked()));
+
+ d_ptr->enableCurrent(false);
+ d_ptr->m_ui->zoomInButton->setIcon(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/zoomin.png")));
+ d_ptr->m_ui->zoomOutButton->setIcon(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/zoomout.png")));
+ d_ptr->updateZoom(1);
+}
+
+QtGradientStopsController::~QtGradientStopsController()
+{
+}
+
+void QtGradientStopsController::setGradientStops(const QGradientStops &stops)
+{
+ d_ptr->m_model->clear();
+ QVectorIterator<QPair<qreal, QColor> > it(stops);
+ QtGradientStop *first = 0;
+ while (it.hasNext()) {
+ QPair<qreal, QColor> pair = it.next();
+ QtGradientStop *stop = d_ptr->m_model->addStop(pair.first, pair.second);
+ if (!first)
+ first = stop;
+ }
+ if (first)
+ d_ptr->m_model->setCurrentStop(first);
+}
+
+QGradientStops QtGradientStopsController::gradientStops() const
+{
+ QGradientStops stops;
+ QList<QtGradientStop *> stopsList = d_ptr->m_model->stops().values();
+ QListIterator<QtGradientStop *> itStop(stopsList);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+ stops << QPair<qreal, QColor>(stop->position(), stop->color());
+ }
+ return stops;
+}
+
+QColor::Spec QtGradientStopsController::spec() const
+{
+ return d_ptr->m_spec;
+}
+
+void QtGradientStopsController::setSpec(QColor::Spec spec)
+{
+ if (d_ptr->m_spec == spec)
+ return;
+
+ d_ptr->m_spec = spec;
+ if (d_ptr->m_spec == QColor::Rgb) {
+ d_ptr->m_ui->rgbRadioButton->setChecked(true);
+ d_ptr->slotRgbClicked();
+ } else {
+ d_ptr->m_ui->hsvRadioButton->setChecked(true);
+ d_ptr->slotHsvClicked();
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientstopscontroller.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientstopscontroller.h b/src/shared/qtgradienteditor/qtgradientstopscontroller.h
new file mode 100644
index 000000000..1ae96aafe
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopscontroller.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSCONTROLLER_H
+#define QTGRADIENTSTOPSCONTROLLER_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class QtGradientEditor;
+}
+
+class QtGradientStopsController : public QObject
+{
+ Q_OBJECT
+public:
+ QtGradientStopsController(QObject *parent = 0);
+ ~QtGradientStopsController();
+
+ void setUi(Ui::QtGradientEditor *editor);
+
+ void setGradientStops(const QGradientStops &stops);
+ QGradientStops gradientStops() const;
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+signals:
+
+ void gradientStopsChanged(const QGradientStops &stops);
+
+private:
+ QScopedPointer<class QtGradientStopsControllerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsController)
+ Q_DISABLE_COPY(QtGradientStopsController)
+ Q_PRIVATE_SLOT(d_func(), void slotHsvClicked())
+ Q_PRIVATE_SLOT(d_func(), void slotRgbClicked())
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentStopChanged(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopMoved(QtGradientStop *stop, qreal newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2))
+ Q_PRIVATE_SLOT(d_func(), void slotStopChanged(QtGradientStop *stop, const QColor &newColor))
+ Q_PRIVATE_SLOT(d_func(), void slotStopSelected(QtGradientStop *stop, bool selected))
+ Q_PRIVATE_SLOT(d_func(), void slotStopAdded(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopRemoved(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotUpdatePositionSpinBox())
+ Q_PRIVATE_SLOT(d_func(), void slotChangeColor(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeHue(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeSaturation(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeValue(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeAlpha(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeHue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeSaturation(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeAlpha(int))
+ //Q_PRIVATE_SLOT(d_func(), void slotChangePosition(double newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotChangePosition(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeZoom(int value))
+ Q_PRIVATE_SLOT(d_func(), void slotZoomIn())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomOut())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomAll())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomChanged(double))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
new file mode 100644
index 000000000..427e6eed3
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
@@ -0,0 +1,477 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopsmodel.h"
+#include <QtGui/QColor>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopPrivate
+{
+public:
+ qreal m_position;
+ QColor m_color;
+ QtGradientStopsModel *m_model;
+};
+
+qreal QtGradientStop::position() const
+{
+ return d_ptr->m_position;
+}
+
+QColor QtGradientStop::color() const
+{
+ return d_ptr->m_color;
+}
+
+QtGradientStopsModel *QtGradientStop::gradientModel() const
+{
+ return d_ptr->m_model;
+}
+
+void QtGradientStop::setColor(const QColor &color)
+{
+ d_ptr->m_color = color;
+}
+
+void QtGradientStop::setPosition(qreal position)
+{
+ d_ptr->m_position = position;
+}
+
+QtGradientStop::QtGradientStop(QtGradientStopsModel *model)
+ : d_ptr(new QtGradientStopPrivate())
+{
+ d_ptr->m_position = 0;
+ d_ptr->m_color = Qt::white;
+ d_ptr->m_model = model;
+}
+
+QtGradientStop::~QtGradientStop()
+{
+}
+
+class QtGradientStopsModelPrivate
+{
+ QtGradientStopsModel *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsModel)
+public:
+ QMap<qreal, QtGradientStop *> m_posToStop;
+ QMap<QtGradientStop *, qreal> m_stopToPos;
+ QMap<QtGradientStop *, bool> m_selection;
+ QtGradientStop *m_current;
+};
+
+
+
+QtGradientStopsModel::QtGradientStopsModel(QObject *parent)
+ : QObject(parent), d_ptr(new QtGradientStopsModelPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_current = 0;
+}
+
+QtGradientStopsModel::~QtGradientStopsModel()
+{
+ clear();
+}
+
+QtGradientStopsModel::PositionStopMap QtGradientStopsModel::stops() const
+{
+ return d_ptr->m_posToStop;
+}
+
+QtGradientStop *QtGradientStopsModel::at(qreal pos) const
+{
+ if (d_ptr->m_posToStop.contains(pos))
+ return d_ptr->m_posToStop[pos];
+ return 0;
+}
+
+QColor QtGradientStopsModel::color(qreal pos) const
+{
+ PositionStopMap gradStops = stops();
+ if (gradStops.isEmpty())
+ return QColor::fromRgbF(pos, pos, pos, 1.0);
+ if (gradStops.contains(pos))
+ return gradStops[pos]->color();
+
+ gradStops[pos] = 0;
+ PositionStopMap::ConstIterator itStop = gradStops.constFind(pos);
+ if (itStop == gradStops.constBegin()) {
+ ++itStop;
+ return itStop.value()->color();
+ }
+ if (itStop == --gradStops.constEnd()) {
+ --itStop;
+ return itStop.value()->color();
+ }
+ PositionStopMap::ConstIterator itPrev = itStop;
+ PositionStopMap::ConstIterator itNext = itStop;
+ --itPrev;
+ ++itNext;
+
+ double prevX = itPrev.key();
+ double nextX = itNext.key();
+
+ double coefX = (pos - prevX) / (nextX - prevX);
+ QColor prevCol = itPrev.value()->color();
+ QColor nextCol = itNext.value()->color();
+
+ QColor newColor;
+ newColor.setRgbF((nextCol.redF() - prevCol.redF() ) * coefX + prevCol.redF(),
+ (nextCol.greenF() - prevCol.greenF()) * coefX + prevCol.greenF(),
+ (nextCol.blueF() - prevCol.blueF() ) * coefX + prevCol.blueF(),
+ (nextCol.alphaF() - prevCol.alphaF()) * coefX + prevCol.alphaF());
+ return newColor;
+}
+
+QList<QtGradientStop *> QtGradientStopsModel::selectedStops() const
+{
+ return d_ptr->m_selection.keys();
+}
+
+QtGradientStop *QtGradientStopsModel::currentStop() const
+{
+ return d_ptr->m_current;
+}
+
+bool QtGradientStopsModel::isSelected(QtGradientStop *stop) const
+{
+ if (d_ptr->m_selection.contains(stop))
+ return true;
+ return false;
+}
+
+QtGradientStop *QtGradientStopsModel::addStop(qreal pos, const QColor &color)
+{
+ qreal newPos = pos;
+ if (pos < 0.0)
+ newPos = 0.0;
+ if (pos > 1.0)
+ newPos = 1.0;
+ if (d_ptr->m_posToStop.contains(newPos))
+ return 0;
+ QtGradientStop *stop = new QtGradientStop();
+ stop->setPosition(newPos);
+ stop->setColor(color);
+
+ d_ptr->m_posToStop[newPos] = stop;
+ d_ptr->m_stopToPos[stop] = newPos;
+
+ emit stopAdded(stop);
+
+ return stop;
+}
+
+void QtGradientStopsModel::removeStop(QtGradientStop *stop)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (currentStop() == stop)
+ setCurrentStop(0);
+ selectStop(stop, false);
+
+ emit stopRemoved(stop);
+
+ qreal pos = d_ptr->m_stopToPos[stop];
+ d_ptr->m_stopToPos.remove(stop);
+ d_ptr->m_posToStop.remove(pos);
+ delete stop;
+}
+
+void QtGradientStopsModel::moveStop(QtGradientStop *stop, qreal newPos)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (d_ptr->m_posToStop.contains(newPos))
+ return;
+
+ if (newPos > 1.0)
+ newPos = 1.0;
+ else if (newPos < 0.0)
+ newPos = 0.0;
+
+ emit stopMoved(stop, newPos);
+
+ const qreal oldPos = stop->position();
+ stop->setPosition(newPos);
+ d_ptr->m_stopToPos[stop] = newPos;
+ d_ptr->m_posToStop.remove(oldPos);
+ d_ptr->m_posToStop[newPos] = stop;
+}
+
+void QtGradientStopsModel::swapStops(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ if (stop1 == stop2)
+ return;
+ if (!d_ptr->m_stopToPos.contains(stop1))
+ return;
+ if (!d_ptr->m_stopToPos.contains(stop2))
+ return;
+
+ emit stopsSwapped(stop1, stop2);
+
+ const qreal pos1 = stop1->position();
+ const qreal pos2 = stop2->position();
+ stop1->setPosition(pos2);
+ stop2->setPosition(pos1);
+ d_ptr->m_stopToPos[stop1] = pos2;
+ d_ptr->m_stopToPos[stop2] = pos1;
+ d_ptr->m_posToStop[pos1] = stop2;
+ d_ptr->m_posToStop[pos2] = stop1;
+}
+
+void QtGradientStopsModel::changeStop(QtGradientStop *stop, const QColor &newColor)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (stop->color() == newColor)
+ return;
+
+ emit stopChanged(stop, newColor);
+
+ stop->setColor(newColor);
+}
+
+void QtGradientStopsModel::selectStop(QtGradientStop *stop, bool select)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ bool selected = d_ptr->m_selection.contains(stop);
+ if (select == selected)
+ return;
+
+ emit stopSelected(stop, select);
+
+ if (select)
+ d_ptr->m_selection[stop] = true;
+ else
+ d_ptr->m_selection.remove(stop);
+}
+
+void QtGradientStopsModel::setCurrentStop(QtGradientStop *stop)
+{
+ if (stop && !d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (stop == currentStop())
+ return;
+
+ emit currentStopChanged(stop);
+
+ d_ptr->m_current = stop;
+}
+
+QtGradientStop *QtGradientStopsModel::firstSelected() const
+{
+ PositionStopMap stopList = stops();
+ PositionStopMap::ConstIterator itStop = stopList.constBegin();
+ while (itStop != stopList.constEnd()) {
+ QtGradientStop *stop = itStop.value();
+ if (isSelected(stop))
+ return stop;
+ ++itStop;
+ };
+ return 0;
+}
+
+QtGradientStop *QtGradientStopsModel::lastSelected() const
+{
+ PositionStopMap stopList = stops();
+ PositionStopMap::ConstIterator itStop = stopList.constEnd();
+ while (itStop != stopList.constBegin()) {
+ --itStop;
+
+ QtGradientStop *stop = itStop.value();
+ if (isSelected(stop))
+ return stop;
+ };
+ return 0;
+}
+
+QtGradientStopsModel *QtGradientStopsModel::clone() const
+{
+ QtGradientStopsModel *model = new QtGradientStopsModel();
+
+ QMap<qreal, QtGradientStop *> stopsToClone = stops();
+ QMapIterator<qreal, QtGradientStop *> it(stopsToClone);
+ while (it.hasNext()) {
+ it.next();
+ model->addStop(it.key(), it.value()->color());
+ }
+ // clone selection and current also
+ return model;
+}
+
+void QtGradientStopsModel::moveStops(double newPosition)
+{
+ QtGradientStop *current = currentStop();
+ if (!current)
+ return;
+
+ double newPos = newPosition;
+
+ if (newPos > 1)
+ newPos = 1;
+ else if (newPos < 0)
+ newPos = 0;
+
+ if (newPos == current->position())
+ return;
+
+ double offset = newPos - current->position();
+
+ QtGradientStop *first = firstSelected();
+ QtGradientStop *last = lastSelected();
+
+ if (first && last) { // multiselection
+ double maxOffset = 1.0 - last->position();
+ double minOffset = -first->position();
+
+ if (offset > maxOffset)
+ offset = maxOffset;
+ else if (offset < minOffset)
+ offset = minOffset;
+
+ }
+
+ if (offset == 0)
+ return;
+
+ bool forward = (offset > 0) ? false : true;
+
+ PositionStopMap stopList;
+
+ QList<QtGradientStop *> selected = selectedStops();
+ QListIterator<QtGradientStop *> it(selected);
+ while (it.hasNext()) {
+ QtGradientStop *stop = it.next();
+ stopList[stop->position()] = stop;
+ }
+ stopList[current->position()] = current;
+
+ PositionStopMap::ConstIterator itStop = forward ? stopList.constBegin() : stopList.constEnd();
+ while (itStop != (forward ? stopList.constEnd() : stopList.constBegin())) {
+ if (!forward)
+ --itStop;
+ QtGradientStop *stop = itStop.value();
+ double pos = stop->position() + offset;
+ if (pos > 1)
+ pos = 1;
+ if (pos < 0)
+ pos = 0;
+
+ if (current == stop)
+ pos = newPos;
+
+ QtGradientStop *oldStop = at(pos);
+ if (oldStop && !stopList.values().contains(oldStop))
+ removeStop(oldStop);
+ moveStop(stop, pos);
+
+ if (forward)
+ ++itStop;
+ }
+}
+
+void QtGradientStopsModel::clear()
+{
+ QList<QtGradientStop *> stopsList = stops().values();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ removeStop(it.next());
+}
+
+void QtGradientStopsModel::clearSelection()
+{
+ QList<QtGradientStop *> stopsList = selectedStops();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ selectStop(it.next(), false);
+}
+
+void QtGradientStopsModel::flipAll()
+{
+ QMap<qreal, QtGradientStop *> stopsMap = stops();
+ QMapIterator<qreal, QtGradientStop *> itStop(stopsMap);
+ itStop.toBack();
+
+ QMap<QtGradientStop *, bool> swappedList;
+
+ while (itStop.hasPrevious()) {
+ itStop.previous();
+
+ QtGradientStop *stop = itStop.value();
+ if (swappedList.contains(stop))
+ continue;
+ const double newPos = 1.0 - itStop.key();
+ if (stopsMap.contains(newPos)) {
+ QtGradientStop *swapped = stopsMap.value(newPos);
+ swappedList[swapped] = true;
+ swapStops(stop, swapped);
+ } else {
+ moveStop(stop, newPos);
+ }
+ }
+}
+
+void QtGradientStopsModel::selectAll()
+{
+ QList<QtGradientStop *> stopsList = stops().values();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ selectStop(it.next(), true);
+}
+
+void QtGradientStopsModel::deleteStops()
+{
+ QList<QtGradientStop *> selected = selectedStops();
+ QListIterator<QtGradientStop *> itSel(selected);
+ while (itSel.hasNext()) {
+ QtGradientStop *stop = itSel.next();
+ removeStop(stop);
+ }
+ QtGradientStop *current = currentStop();
+ if (current)
+ removeStop(current);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientstopsmodel.h b/src/shared/qtgradienteditor/qtgradientstopsmodel.h
new file mode 100644
index 000000000..fac7d5642
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopsmodel.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSMODEL_H
+#define QTGRADIENTSTOPSMODEL_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QColor;
+
+class QtGradientStopsModel;
+
+class QtGradientStop
+{
+public:
+ qreal position() const;
+ QColor color() const;
+ QtGradientStopsModel *gradientModel() const;
+
+private:
+ void setColor(const QColor &color);
+ void setPosition(qreal position);
+ friend class QtGradientStopsModel;
+ QtGradientStop(QtGradientStopsModel *model = 0);
+ ~QtGradientStop();
+ QScopedPointer<class QtGradientStopPrivate> d_ptr;
+};
+
+class QtGradientStopsModel : public QObject
+{
+ Q_OBJECT
+public:
+ typedef QMap<qreal, QtGradientStop *> PositionStopMap;
+
+ QtGradientStopsModel(QObject *parent = 0);
+ ~QtGradientStopsModel();
+
+ PositionStopMap stops() const;
+ QtGradientStop *at(qreal pos) const;
+ QColor color(qreal pos) const; // calculated between points
+ QList<QtGradientStop *> selectedStops() const;
+ QtGradientStop *currentStop() const;
+ bool isSelected(QtGradientStop *stop) const;
+ QtGradientStop *firstSelected() const;
+ QtGradientStop *lastSelected() const;
+ QtGradientStopsModel *clone() const;
+
+ QtGradientStop *addStop(qreal pos, const QColor &color);
+ void removeStop(QtGradientStop *stop);
+ void moveStop(QtGradientStop *stop, qreal newPos);
+ void swapStops(QtGradientStop *stop1, QtGradientStop *stop2);
+ void changeStop(QtGradientStop *stop, const QColor &newColor);
+ void selectStop(QtGradientStop *stop, bool select);
+ void setCurrentStop(QtGradientStop *stop);
+
+ void moveStops(double newPosition); // moves current stop to newPos and all selected stops are moved accordingly
+ void clear();
+ void clearSelection();
+ void flipAll();
+ void selectAll();
+ void deleteStops();
+
+signals:
+ void stopAdded(QtGradientStop *stop);
+ void stopRemoved(QtGradientStop *stop);
+ void stopMoved(QtGradientStop *stop, qreal newPos);
+ void stopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void stopChanged(QtGradientStop *stop, const QColor &newColor);
+ void stopSelected(QtGradientStop *stop, bool selected);
+ void currentStopChanged(QtGradientStop *stop);
+
+private:
+ QScopedPointer<class QtGradientStopsModelPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsModel)
+ Q_DISABLE_COPY(QtGradientStopsModel)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopswidget.cpp b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
new file mode 100644
index 000000000..a4104327b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
@@ -0,0 +1,1154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopswidget.h"
+#include "qtgradientstopsmodel.h"
+
+#include <QtCore/QMap>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QRubberBand>
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsWidgetPrivate
+{
+ QtGradientStopsWidget *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsWidget)
+public:
+ typedef QMap<qreal, QColor> PositionColorMap;
+ typedef QMap<QtGradientStop *, qreal> StopPositionMap;
+
+ void slotStopAdded(QtGradientStop *stop);
+ void slotStopRemoved(QtGradientStop *stop);
+ void slotStopMoved(QtGradientStop *stop, qreal newPos);
+ void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void slotStopChanged(QtGradientStop *stop, const QColor &newColor);
+ void slotStopSelected(QtGradientStop *stop, bool selected);
+ void slotCurrentStopChanged(QtGradientStop *stop);
+ void slotNewStop();
+ void slotDelete();
+ void slotFlipAll();
+ void slotSelectAll();
+ void slotZoomIn();
+ void slotZoomOut();
+ void slotResetZoom();
+
+ double fromViewport(int x) const;
+ double toViewport(double x) const;
+ QtGradientStop *stopAt(const QPoint &viewportPos) const;
+ QList<QtGradientStop *> stopsAt(const QPoint &viewportPos) const;
+ void setupMove(QtGradientStop *stop, int x);
+ void ensureVisible(double x); // x = stop position
+ void ensureVisible(QtGradientStop *stop);
+ QtGradientStop *newStop(const QPoint &viewportPos);
+
+ bool m_backgroundCheckered;
+ QtGradientStopsModel *m_model;
+ double m_handleSize;
+ int m_scaleFactor;
+ double m_zoom;
+
+#ifndef QT_NO_DRAGANDDROP
+ QtGradientStop *m_dragStop;
+ QtGradientStop *m_changedStop;
+ QtGradientStop *m_clonedStop;
+ QtGradientStopsModel *m_dragModel;
+ QColor m_dragColor;
+ void clearDrag();
+ void removeClonedStop();
+ void restoreChangedStop();
+ void changeStop(qreal pos);
+ void cloneStop(qreal pos);
+#endif
+
+ QRubberBand *m_rubber;
+ QPoint m_clickPos;
+
+ QList<QtGradientStop *> m_stops;
+
+ bool m_moving;
+ int m_moveOffset;
+ StopPositionMap m_moveStops;
+
+ PositionColorMap m_moveOriginal;
+};
+
+double QtGradientStopsWidgetPrivate::fromViewport(int x) const
+{
+ QSize size = q_ptr->viewport()->size();
+ int w = size.width();
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int val = q_ptr->horizontalScrollBar()->value();
+ return ((double)x * m_scaleFactor + w * val) / (w * (m_scaleFactor + max));
+}
+
+double QtGradientStopsWidgetPrivate::toViewport(double x) const
+{
+ QSize size = q_ptr->viewport()->size();
+ int w = size.width();
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int val = q_ptr->horizontalScrollBar()->value();
+ return w * (x * (m_scaleFactor + max) - val) / m_scaleFactor;
+}
+
+QtGradientStop *QtGradientStopsWidgetPrivate::stopAt(const QPoint &viewportPos) const
+{
+ double posY = m_handleSize / 2;
+ QListIterator<QtGradientStop *> itStop(m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+
+ double posX = toViewport(stop->position());
+
+ double x = viewportPos.x() - posX;
+ double y = viewportPos.y() - posY;
+
+ if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
+ return stop;
+ }
+ return 0;
+}
+
+QList<QtGradientStop *> QtGradientStopsWidgetPrivate::stopsAt(const QPoint &viewportPos) const
+{
+ QList<QtGradientStop *> stops;
+ double posY = m_handleSize / 2;
+ QListIterator<QtGradientStop *> itStop(m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+
+ double posX = toViewport(stop->position());
+
+ double x = viewportPos.x() - posX;
+ double y = viewportPos.y() - posY;
+
+ if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
+ stops.append(stop);
+ }
+ return stops;
+}
+
+void QtGradientStopsWidgetPrivate::setupMove(QtGradientStop *stop, int x)
+{
+ m_model->setCurrentStop(stop);
+
+ int viewportX = qRound(toViewport(stop->position()));
+ m_moveOffset = x - viewportX;
+
+ QList<QtGradientStop *> stops = m_stops;
+ m_stops.clear();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (m_model->isSelected(s) || s == stop) {
+ m_moveStops[s] = s->position() - stop->position();
+ m_stops.append(s);
+ } else {
+ m_moveOriginal[s->position()] = s->color();
+ }
+ }
+ itStop.toFront();
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (!m_model->isSelected(s))
+ m_stops.append(s);
+ }
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+}
+
+void QtGradientStopsWidgetPrivate::ensureVisible(double x)
+{
+ double viewX = toViewport(x);
+ if (viewX < 0 || viewX > q_ptr->viewport()->size().width()) {
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int newVal = qRound(x * (max + m_scaleFactor) - m_scaleFactor / 2);
+ q_ptr->horizontalScrollBar()->setValue(newVal);
+ }
+}
+
+void QtGradientStopsWidgetPrivate::ensureVisible(QtGradientStop *stop)
+{
+ if (!stop)
+ return;
+ ensureVisible(stop->position());
+}
+
+QtGradientStop *QtGradientStopsWidgetPrivate::newStop(const QPoint &viewportPos)
+{
+ QtGradientStop *copyStop = stopAt(viewportPos);
+ double posX = fromViewport(viewportPos.x());
+ QtGradientStop *stop = m_model->at(posX);
+ if (!stop) {
+ QColor newColor;
+ if (copyStop)
+ newColor = copyStop->color();
+ else
+ newColor = m_model->color(posX);
+ if (!newColor.isValid())
+ newColor = Qt::white;
+ stop = m_model->addStop(posX, newColor);
+ }
+ return stop;
+}
+
+void QtGradientStopsWidgetPrivate::slotStopAdded(QtGradientStop *stop)
+{
+ m_stops.append(stop);
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopRemoved(QtGradientStop *stop)
+{
+ m_stops.removeAll(stop);
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(newPos)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ Q_UNUSED(stop1)
+ Q_UNUSED(stop2)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(newColor)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopSelected(QtGradientStop *stop, bool selected)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(selected)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotCurrentStopChanged(QtGradientStop *stop)
+{
+ Q_UNUSED(stop)
+
+ if (!m_model)
+ return;
+ q_ptr->viewport()->update();
+ if (stop) {
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+ }
+}
+
+void QtGradientStopsWidgetPrivate::slotNewStop()
+{
+ if (!m_model)
+ return;
+
+ QtGradientStop *stop = newStop(m_clickPos);
+
+ if (!stop)
+ return;
+
+ m_model->clearSelection();
+ m_model->selectStop(stop, true);
+ m_model->setCurrentStop(stop);
+}
+
+void QtGradientStopsWidgetPrivate::slotDelete()
+{
+ if (!m_model)
+ return;
+
+ m_model->deleteStops();
+}
+
+void QtGradientStopsWidgetPrivate::slotFlipAll()
+{
+ if (!m_model)
+ return;
+
+ m_model->flipAll();
+}
+
+void QtGradientStopsWidgetPrivate::slotSelectAll()
+{
+ if (!m_model)
+ return;
+
+ m_model->selectAll();
+}
+
+void QtGradientStopsWidgetPrivate::slotZoomIn()
+{
+ double newZoom = q_ptr->zoom() * 2;
+ if (newZoom > 100)
+ newZoom = 100;
+ if (newZoom == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(newZoom);
+ emit q_ptr->zoomChanged(q_ptr->zoom());
+}
+
+void QtGradientStopsWidgetPrivate::slotZoomOut()
+{
+ double newZoom = q_ptr->zoom() / 2;
+ if (newZoom < 1)
+ newZoom = 1;
+ if (newZoom == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(newZoom);
+ emit q_ptr->zoomChanged(q_ptr->zoom());
+}
+
+void QtGradientStopsWidgetPrivate::slotResetZoom()
+{
+ if (1 == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(1);
+ emit q_ptr->zoomChanged(1);
+}
+
+QtGradientStopsWidget::QtGradientStopsWidget(QWidget *parent)
+ : QAbstractScrollArea(parent), d_ptr(new QtGradientStopsWidgetPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_backgroundCheckered = true;
+ d_ptr->m_model = 0;
+ d_ptr->m_handleSize = 25.0;
+ d_ptr->m_scaleFactor = 1000;
+ d_ptr->m_moving = false;
+ d_ptr->m_zoom = 1;
+ d_ptr->m_rubber = new QRubberBand(QRubberBand::Rectangle, this);
+#ifndef QT_NO_DRAGANDDROP
+ d_ptr->m_dragStop = 0;
+ d_ptr->m_changedStop = 0;
+ d_ptr->m_clonedStop = 0;
+ d_ptr->m_dragModel = 0;
+#endif
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ horizontalScrollBar()->setRange(0, (int)(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1) + 0.5));
+ horizontalScrollBar()->setPageStep(d_ptr->m_scaleFactor);
+ horizontalScrollBar()->setSingleStep(4);
+ viewport()->setAutoFillBackground(false);
+
+ setAcceptDrops(true);
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
+}
+
+QtGradientStopsWidget::~QtGradientStopsWidget()
+{
+}
+
+QSize QtGradientStopsWidget::sizeHint() const
+{
+ return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->sizeHint().height());
+}
+
+QSize QtGradientStopsWidget::minimumSizeHint() const
+{
+ return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->minimumSizeHint().height());
+}
+
+void QtGradientStopsWidget::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtGradientStopsWidget::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientStopsWidget::setGradientStopsModel(QtGradientStopsModel *model)
+{
+ if (d_ptr->m_model == model)
+ return;
+
+ if (d_ptr->m_model) {
+ disconnect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ disconnect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ disconnect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ disconnect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+
+ d_ptr->m_stops.clear();
+ }
+
+ d_ptr->m_model = model;
+
+ if (d_ptr->m_model) {
+ connect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ connect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ connect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ connect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+
+ QList<QtGradientStop *> stops = d_ptr->m_model->stops().values();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext())
+ d_ptr->slotStopAdded(itStop.next());
+
+ QList<QtGradientStop *> selected = d_ptr->m_model->selectedStops();
+ QListIterator<QtGradientStop *> itSelect(selected);
+ while (itSelect.hasNext())
+ d_ptr->slotStopSelected(itSelect.next(), true);
+
+ d_ptr->slotCurrentStopChanged(d_ptr->m_model->currentStop());
+ }
+}
+
+void QtGradientStopsWidget::mousePressEvent(QMouseEvent *e)
+{
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ d_ptr->m_moving = true;
+
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+ d_ptr->m_clickPos = e->pos();
+ QtGradientStop *stop = d_ptr->stopAt(e->pos());
+ if (stop) {
+ if (e->modifiers() & Qt::ControlModifier) {
+ d_ptr->m_model->selectStop(stop, !d_ptr->m_model->isSelected(stop));
+ } else if (e->modifiers() & Qt::ShiftModifier) {
+ QtGradientStop *oldCurrent = d_ptr->m_model->currentStop();
+ if (oldCurrent) {
+ PositionStopMap stops = d_ptr->m_model->stops();
+ PositionStopMap::ConstIterator itSt = stops.constFind(oldCurrent->position());
+ if (itSt != stops.constEnd()) {
+ while (itSt != stops.constFind(stop->position())) {
+ d_ptr->m_model->selectStop(itSt.value(), true);
+ if (oldCurrent->position() < stop->position())
+ ++itSt;
+ else
+ --itSt;
+ }
+ }
+ }
+ d_ptr->m_model->selectStop(stop, true);
+ } else {
+ if (!d_ptr->m_model->isSelected(stop)) {
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(stop, true);
+ }
+ }
+ d_ptr->setupMove(stop, e->pos().x());
+ } else {
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_rubber->setGeometry(QRect(d_ptr->m_clickPos, QSize()));
+ d_ptr->m_rubber->show();
+ }
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ d_ptr->m_moving = false;
+ d_ptr->m_rubber->hide();
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+}
+
+void QtGradientStopsWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ typedef QtGradientStopsWidgetPrivate::PositionColorMap PositionColorMap;
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ typedef QtGradientStopsWidgetPrivate::StopPositionMap StopPositionMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (!(e->buttons() & Qt::LeftButton))
+ return;
+
+ if (!d_ptr->m_moving)
+ return;
+
+ if (!d_ptr->m_moveStops.isEmpty()) {
+ double maxOffset = 0.0;
+ double minOffset = 0.0;
+ bool first = true;
+ StopPositionMap::ConstIterator itStop = d_ptr->m_moveStops.constBegin();
+ while (itStop != d_ptr->m_moveStops.constEnd()) {
+ double offset = itStop.value();
+
+ if (first) {
+ maxOffset = offset;
+ minOffset = offset;
+ first = false;
+ } else {
+ if (maxOffset < offset)
+ maxOffset = offset;
+ else if (minOffset > offset)
+ minOffset = offset;
+ }
+ ++itStop;
+ }
+
+ double viewportMin = d_ptr->toViewport(-minOffset);
+ double viewportMax = d_ptr->toViewport(1.0 - maxOffset);
+
+ PositionStopMap newPositions;
+
+ int viewportX = e->pos().x() - d_ptr->m_moveOffset;
+
+ if (viewportX > viewport()->size().width())
+ viewportX = viewport()->size().width();
+ else if (viewportX < 0)
+ viewportX = 0;
+
+ double posX = d_ptr->fromViewport(viewportX);
+
+ if (viewportX > viewportMax)
+ posX = 1.0 - maxOffset;
+ else if (viewportX < viewportMin)
+ posX = -minOffset;
+
+ itStop = d_ptr->m_moveStops.constBegin();
+ while (itStop != d_ptr->m_moveStops.constEnd()) {
+ QtGradientStop *stop = itStop.key();
+
+ newPositions[posX + itStop.value()] = stop;
+
+ ++itStop;
+ }
+
+ bool forward = true;
+ PositionStopMap::ConstIterator itNewPos = newPositions.constBegin();
+ if (itNewPos.value()->position() < itNewPos.key())
+ forward = false;
+
+ itNewPos = forward ? newPositions.constBegin() : newPositions.constEnd();
+ while (itNewPos != (forward ? newPositions.constEnd() : newPositions.constBegin())) {
+ if (!forward)
+ --itNewPos;
+ QtGradientStop *stop = itNewPos.value();
+ double newPos = itNewPos.key();
+ if (newPos > 1)
+ newPos = 1;
+ else if (newPos < 0)
+ newPos = 0;
+
+ QtGradientStop *existingStop = d_ptr->m_model->at(newPos);
+ if (existingStop && !d_ptr->m_moveStops.contains(existingStop))
+ d_ptr->m_model->removeStop(existingStop);
+ d_ptr->m_model->moveStop(stop, newPos);
+
+ if (forward)
+ ++itNewPos;
+ }
+
+ PositionColorMap::ConstIterator itOld = d_ptr->m_moveOriginal.constBegin();
+ while (itOld != d_ptr->m_moveOriginal.constEnd()) {
+ double position = itOld.key();
+ if (!d_ptr->m_model->at(position))
+ d_ptr->m_model->addStop(position, itOld.value());
+
+ ++itOld;
+ }
+
+ } else {
+ QRect r(QRect(d_ptr->m_clickPos, e->pos()).normalized());
+ r.translate(1, 0);
+ d_ptr->m_rubber->setGeometry(r);
+ //d_ptr->m_model->clearSelection();
+
+ int xv1 = d_ptr->m_clickPos.x();
+ int xv2 = e->pos().x();
+ if (xv1 > xv2) {
+ int temp = xv1;
+ xv1 = xv2;
+ xv2 = temp;
+ }
+ int yv1 = d_ptr->m_clickPos.y();
+ int yv2 = e->pos().y();
+ if (yv1 > yv2) {
+ int temp = yv1;
+ yv1 = yv2;
+ yv2 = temp;
+ }
+
+ QPoint p1, p2;
+
+ if (yv2 < d_ptr->m_handleSize / 2) {
+ p1 = QPoint(xv1, yv2);
+ p2 = QPoint(xv2, yv2);
+ } else if (yv1 > d_ptr->m_handleSize / 2) {
+ p1 = QPoint(xv1, yv1);
+ p2 = QPoint(xv2, yv1);
+ } else {
+ p1 = QPoint(xv1, qRound(d_ptr->m_handleSize / 2));
+ p2 = QPoint(xv2, qRound(d_ptr->m_handleSize / 2));
+ }
+
+ QList<QtGradientStop *> beginList = d_ptr->stopsAt(p1);
+ QList<QtGradientStop *> endList = d_ptr->stopsAt(p2);
+
+ double x1 = d_ptr->fromViewport(xv1);
+ double x2 = d_ptr->fromViewport(xv2);
+
+ QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+ if ((stop->position() >= x1 && stop->position() <= x2) ||
+ beginList.contains(stop) || endList.contains(stop))
+ d_ptr->m_model->selectStop(stop, true);
+ else
+ d_ptr->m_model->selectStop(stop, false);
+ }
+ }
+}
+
+void QtGradientStopsWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ if (d_ptr->m_clickPos != e->pos()) {
+ mousePressEvent(e);
+ return;
+ }
+ d_ptr->m_moving = true;
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+
+ QtGradientStop *stop = d_ptr->newStop(e->pos());
+
+ if (!stop)
+ return;
+
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(stop, true);
+
+ d_ptr->setupMove(stop, e->pos().x());
+
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::keyPressEvent(QKeyEvent *e)
+{
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
+ d_ptr->m_model->deleteStops();
+ } else if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right ||
+ e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
+ PositionStopMap stops = d_ptr->m_model->stops();
+ if (stops.isEmpty())
+ return;
+ QtGradientStop *newCurrent = 0;
+ QtGradientStop *current = d_ptr->m_model->currentStop();
+ if (!current || e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
+ if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Home)
+ newCurrent = stops.constBegin().value();
+ else if (e->key() == Qt::Key_Right || e->key() == Qt::Key_End)
+ newCurrent = (--stops.constEnd()).value();
+ } else {
+ PositionStopMap::ConstIterator itStop = stops.constBegin();
+ while (itStop.value() != current)
+ ++itStop;
+ if (e->key() == Qt::Key_Left && itStop != stops.constBegin())
+ --itStop;
+ else if (e->key() == Qt::Key_Right && itStop != --stops.constEnd())
+ ++itStop;
+ newCurrent = itStop.value();
+ }
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(newCurrent, true);
+ d_ptr->m_model->setCurrentStop(newCurrent);
+ d_ptr->ensureVisible(newCurrent);
+ } else if (e->key() == Qt::Key_A) {
+ if (e->modifiers() & Qt::ControlModifier)
+ d_ptr->m_model->selectAll();
+ }
+}
+
+void QtGradientStopsWidget::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e)
+ if (!d_ptr->m_model)
+ return;
+
+ QtGradientStopsModel *model = d_ptr->m_model;
+#ifndef QT_NO_DRAGANDDROP
+ if (d_ptr->m_dragModel)
+ model = d_ptr->m_dragModel;
+#endif
+
+ QSize size = viewport()->size();
+ int w = size.width();
+ double h = size.height() - d_ptr->m_handleSize;
+ if (w <= 0)
+ return;
+
+ QPixmap pix(size);
+ QPainter p;
+
+ if (d_ptr->m_backgroundCheckered) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+
+ p.begin(&pix);
+ p.setBrushOrigin((size.width() % pixSize + pixSize) / 2, (size.height() % pixSize + pixSize) / 2);
+ p.fillRect(viewport()->rect(), pm);
+ p.setBrushOrigin(0, 0);
+ } else {
+ p.begin(viewport());
+ }
+
+ double viewBegin = (double)w * horizontalScrollBar()->value() / d_ptr->m_scaleFactor;
+
+ int val = horizontalScrollBar()->value();
+ int max = horizontalScrollBar()->maximum();
+
+ double begin = (double)val / (d_ptr->m_scaleFactor + max);
+ double end = (double)(val + d_ptr->m_scaleFactor) / (d_ptr->m_scaleFactor + max);
+ double width = end - begin;
+
+ if (h > 0) {
+ QLinearGradient lg(0, 0, w, 0);
+ QMap<qreal, QtGradientStop *> stops = model->stops();
+ QMapIterator<qreal, QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next().value();
+ double pos = stop->position();
+ if (pos >= begin && pos <= end) {
+ double gradPos = (pos - begin) / width;
+ QColor c = stop->color();
+ lg.setColorAt(gradPos, c);
+ }
+ //lg.setColorAt(stop->position(), stop->color());
+ }
+ lg.setColorAt(0, model->color(begin));
+ lg.setColorAt(1, model->color(end));
+ QImage img(w, 1, QImage::Format_ARGB32_Premultiplied);
+ QPainter p1(&img);
+ p1.setCompositionMode(QPainter::CompositionMode_Source);
+
+ /*
+ if (viewBegin != 0)
+ p1.translate(-viewBegin, 0);
+ if (d_ptr->m_zoom != 1)
+ p1.scale(d_ptr->m_zoom, 1);
+ */
+ p1.fillRect(0, 0, w, 1, lg);
+
+ p.fillRect(QRectF(0, d_ptr->m_handleSize, w, h), QPixmap::fromImage(img));
+ }
+
+
+ double handleWidth = d_ptr->m_handleSize * d_ptr->m_scaleFactor / (w * (d_ptr->m_scaleFactor + max));
+
+ QColor insideColor = QColor::fromRgb(0x20, 0x20, 0x20, 0xFF);
+ QColor borderColor = QColor(Qt::white);
+ QColor drawColor;
+ QColor back1 = QColor(Qt::lightGray);
+ QColor back2 = QColor(Qt::darkGray);
+ QColor back = QColor::fromRgb((back1.red() + back2.red()) / 2,
+ (back1.green() + back2.green()) / 2,
+ (back1.blue() + back2.blue()) / 2);
+
+ QPen pen;
+ p.setRenderHint(QPainter::Antialiasing);
+ QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
+ itStop.toBack();
+ while (itStop.hasPrevious()) {
+ QtGradientStop *stop = itStop.previous();
+ double x = stop->position();
+ if (x >= begin - handleWidth / 2 && x <= end + handleWidth / 2) {
+ double viewX = x * w * (d_ptr->m_scaleFactor + max) / d_ptr->m_scaleFactor - viewBegin;
+ p.save();
+ QColor c = stop->color();
+#ifndef QT_NO_DRAGANDDROP
+ if (stop == d_ptr->m_dragStop)
+ c = d_ptr->m_dragColor;
+#endif
+ if ((0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF()) * c.alphaF() +
+ (0.3 * back.redF() + 0.59 * back.greenF() + 0.11 * back.blueF()) * (1.0 - c.alphaF()) < 0.5) {
+ drawColor = QColor::fromRgb(0xC0, 0xC0, 0xC0, 0xB0);
+ } else {
+ drawColor = QColor::fromRgb(0x40, 0x40, 0x40, 0x80);
+ }
+ QRectF rect(viewX - d_ptr->m_handleSize / 2, 0, d_ptr->m_handleSize, d_ptr->m_handleSize);
+ rect.adjust(0.5, 0.5, -0.5, -0.5);
+ if (h > 0) {
+ pen.setWidthF(1);
+ QLinearGradient lg(0, d_ptr->m_handleSize, 0, d_ptr->m_handleSize + h / 2);
+ lg.setColorAt(0, drawColor);
+ QColor alphaZero = drawColor;
+ alphaZero.setAlpha(0);
+ lg.setColorAt(1, alphaZero);
+ pen.setBrush(lg);
+ p.setPen(pen);
+ p.drawLine(QPointF(viewX, d_ptr->m_handleSize), QPointF(viewX, d_ptr->m_handleSize + h / 2));
+
+ pen.setWidthF(1);
+ pen.setBrush(drawColor);
+ p.setPen(pen);
+ QRectF r1 = rect.adjusted(0.5, 0.5, -0.5, -0.5);
+ QRectF r2 = rect.adjusted(1.5, 1.5, -1.5, -1.5);
+ QColor inColor = QColor::fromRgb(0x80, 0x80, 0x80, 0x80);
+ if (!d_ptr->m_model->isSelected(stop)) {
+ p.setBrush(c);
+ p.drawEllipse(rect);
+ } else {
+ pen.setBrush(insideColor);
+ pen.setWidthF(2);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ p.drawEllipse(r1);
+
+ pen.setBrush(inColor);
+ pen.setWidthF(1);
+ p.setPen(pen);
+ p.setBrush(c);
+ p.drawEllipse(r2);
+ }
+
+ if (d_ptr->m_model->currentStop() == stop) {
+ p.setBrush(Qt::NoBrush);
+ pen.setWidthF(5);
+ pen.setBrush(drawColor);
+ int corr = 4;
+ if (!d_ptr->m_model->isSelected(stop)) {
+ corr = 3;
+ pen.setWidthF(7);
+ }
+ p.setPen(pen);
+ p.drawEllipse(rect.adjusted(corr, corr, -corr, -corr));
+ }
+
+ }
+ p.restore();
+ }
+ }
+ if (d_ptr->m_backgroundCheckered) {
+ p.end();
+ p.begin(viewport());
+ p.drawPixmap(0, 0, pix);
+ }
+ p.end();
+}
+
+void QtGradientStopsWidget::focusInEvent(QFocusEvent *e)
+{
+ Q_UNUSED(e)
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::focusOutEvent(QFocusEvent *e)
+{
+ Q_UNUSED(e)
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::contextMenuEvent(QContextMenuEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ d_ptr->m_clickPos = e->pos();
+
+ QMenu menu(this);
+ QAction *newStopAction = new QAction(tr("New Stop"), &menu);
+ QAction *deleteAction = new QAction(tr("Delete"), &menu);
+ QAction *flipAllAction = new QAction(tr("Flip All"), &menu);
+ QAction *selectAllAction = new QAction(tr("Select All"), &menu);
+ QAction *zoomInAction = new QAction(tr("Zoom In"), &menu);
+ QAction *zoomOutAction = new QAction(tr("Zoom Out"), &menu);
+ QAction *zoomAllAction = new QAction(tr("Reset Zoom"), &menu);
+ if (d_ptr->m_model->selectedStops().isEmpty() && !d_ptr->m_model->currentStop())
+ deleteAction->setEnabled(false);
+ if (zoom() <= 1) {
+ zoomOutAction->setEnabled(false);
+ zoomAllAction->setEnabled(false);
+ } else if (zoom() >= 100) {
+ zoomInAction->setEnabled(false);
+ }
+ connect(newStopAction, SIGNAL(triggered()), this, SLOT(slotNewStop()));
+ connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotDelete()));
+ connect(flipAllAction, SIGNAL(triggered()), this, SLOT(slotFlipAll()));
+ connect(selectAllAction, SIGNAL(triggered()), this, SLOT(slotSelectAll()));
+ connect(zoomInAction, SIGNAL(triggered()), this, SLOT(slotZoomIn()));
+ connect(zoomOutAction, SIGNAL(triggered()), this, SLOT(slotZoomOut()));
+ connect(zoomAllAction, SIGNAL(triggered()), this, SLOT(slotResetZoom()));
+ menu.addAction(newStopAction);
+ menu.addAction(deleteAction);
+ menu.addAction(flipAllAction);
+ menu.addAction(selectAllAction);
+ menu.addSeparator();
+ menu.addAction(zoomInAction);
+ menu.addAction(zoomOutAction);
+ menu.addAction(zoomAllAction);
+ menu.exec(e->globalPos());
+}
+
+void QtGradientStopsWidget::wheelEvent(QWheelEvent *e)
+{
+ int numDegrees = e->delta() / 8;
+ int numSteps = numDegrees / 15;
+
+ int shift = numSteps;
+ if (shift < 0)
+ shift = -shift;
+ int pow = 1 << shift;
+ //const double c = 0.7071067; // 2 steps per doubled value
+ const double c = 0.5946036; // 4 steps pre doubled value
+ // in general c = pow(2, 1 / n) / 2; where n is the step
+ double factor = pow * c;
+
+ double newZoom = zoom();
+ if (numSteps < 0)
+ newZoom /= factor;
+ else
+ newZoom *= factor;
+ if (newZoom > 100)
+ newZoom = 100;
+ if (newZoom < 1)
+ newZoom = 1;
+
+ if (newZoom == zoom())
+ return;
+
+ setZoom(newZoom);
+ emit zoomChanged(zoom());
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QtGradientStopsWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ if (!mime->hasColor())
+ return;
+ event->accept();
+ d_ptr->m_dragModel = d_ptr->m_model->clone();
+
+ d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
+ update();
+}
+
+void QtGradientStopsWidget::dragMoveEvent(QDragMoveEvent *event)
+{
+ QRectF rect = viewport()->rect();
+ rect.adjust(0, d_ptr->m_handleSize, 0, 0);
+ double x = d_ptr->fromViewport(event->pos().x());
+ QtGradientStop *dragStop = d_ptr->stopAt(event->pos());
+ if (dragStop) {
+ event->accept();
+ d_ptr->removeClonedStop();
+ d_ptr->changeStop(dragStop->position());
+ } else if (rect.contains(event->pos())) {
+ event->accept();
+ if (d_ptr->m_model->at(x)) {
+ d_ptr->removeClonedStop();
+ d_ptr->changeStop(x);
+ } else {
+ d_ptr->restoreChangedStop();
+ d_ptr->cloneStop(x);
+ }
+ } else {
+ event->ignore();
+ d_ptr->removeClonedStop();
+ d_ptr->restoreChangedStop();
+ }
+
+ update();
+}
+
+void QtGradientStopsWidget::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ event->accept();
+ d_ptr->clearDrag();
+ update();
+}
+
+void QtGradientStopsWidget::dropEvent(QDropEvent *event)
+{
+ event->accept();
+ if (!d_ptr->m_dragModel)
+ return;
+
+ if (d_ptr->m_changedStop)
+ d_ptr->m_model->changeStop(d_ptr->m_model->at(d_ptr->m_changedStop->position()), d_ptr->m_dragColor);
+ else if (d_ptr->m_clonedStop)
+ d_ptr->m_model->addStop(d_ptr->m_clonedStop->position(), d_ptr->m_dragColor);
+
+ d_ptr->clearDrag();
+ update();
+}
+
+void QtGradientStopsWidgetPrivate::clearDrag()
+{
+ removeClonedStop();
+ restoreChangedStop();
+ delete m_dragModel;
+ m_dragModel = 0;
+}
+
+void QtGradientStopsWidgetPrivate::removeClonedStop()
+{
+ if (!m_clonedStop)
+ return;
+ m_dragModel->removeStop(m_clonedStop);
+ m_clonedStop = 0;
+}
+
+void QtGradientStopsWidgetPrivate::restoreChangedStop()
+{
+ if (!m_changedStop)
+ return;
+ m_dragModel->changeStop(m_changedStop, m_model->at(m_changedStop->position())->color());
+ m_changedStop = 0;
+ m_dragStop = 0;
+}
+
+void QtGradientStopsWidgetPrivate::changeStop(qreal pos)
+{
+ QtGradientStop *stop = m_dragModel->at(pos);
+ if (!stop)
+ return;
+
+ m_dragModel->changeStop(stop, m_dragColor);
+ m_changedStop = stop;
+ m_dragStop = m_model->at(stop->position());
+}
+
+void QtGradientStopsWidgetPrivate::cloneStop(qreal pos)
+{
+ if (m_clonedStop) {
+ m_dragModel->moveStop(m_clonedStop, pos);
+ return;
+ }
+ QtGradientStop *stop = m_dragModel->at(pos);
+ if (stop)
+ return;
+
+ m_clonedStop = m_dragModel->addStop(pos, m_dragColor);
+}
+
+#endif
+
+void QtGradientStopsWidget::setZoom(double zoom)
+{
+ double z = zoom;
+ if (z < 1)
+ z = 1;
+ else if (z > 100)
+ z = 100;
+
+ if (d_ptr->m_zoom == z)
+ return;
+
+ d_ptr->m_zoom = z;
+ int oldMax = horizontalScrollBar()->maximum();
+ int oldVal = horizontalScrollBar()->value();
+ horizontalScrollBar()->setRange(0, qRound(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1)));
+ int newMax = horizontalScrollBar()->maximum();
+ double newVal = (oldVal + (double)d_ptr->m_scaleFactor / 2) * (newMax + d_ptr->m_scaleFactor)
+ / (oldMax + d_ptr->m_scaleFactor) - (double)d_ptr->m_scaleFactor / 2;
+ horizontalScrollBar()->setValue(qRound(newVal));
+ viewport()->update();
+}
+
+double QtGradientStopsWidget::zoom() const
+{
+ return d_ptr->m_zoom;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientstopswidget.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientstopswidget.h b/src/shared/qtgradienteditor/qtgradientstopswidget.h
new file mode 100644
index 000000000..a6893c07b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopswidget.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSWIDGET_H
+#define QTGRADIENTSTOPSWIDGET_H
+
+#include <QtGui/QAbstractScrollArea>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsModel;
+class QtGradientStopsWidgetPrivate;
+
+class QtGradientStopsWidget : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtGradientStopsWidget(QWidget *parent = 0);
+ ~QtGradientStopsWidget();
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ void setGradientStopsModel(QtGradientStopsModel *model);
+
+ void setZoom(double zoom);
+ double zoom() const;
+
+signals:
+
+ void zoomChanged(double zoom);
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void contextMenuEvent(QContextMenuEvent *e);
+ void wheelEvent(QWheelEvent *e);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+
+private:
+ QScopedPointer<QtGradientStopsWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsWidget)
+ Q_DISABLE_COPY(QtGradientStopsWidget)
+ Q_PRIVATE_SLOT(d_func(), void slotStopAdded(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopRemoved(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopMoved(QtGradientStop *stop, qreal newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2))
+ Q_PRIVATE_SLOT(d_func(), void slotStopChanged(QtGradientStop *stop, const QColor &newColor))
+ Q_PRIVATE_SLOT(d_func(), void slotStopSelected(QtGradientStop *stop, bool selected))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentStopChanged(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotNewStop())
+ Q_PRIVATE_SLOT(d_func(), void slotDelete())
+ Q_PRIVATE_SLOT(d_func(), void slotFlipAll())
+ Q_PRIVATE_SLOT(d_func(), void slotSelectAll())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomIn())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomOut())
+ Q_PRIVATE_SLOT(d_func(), void slotResetZoom())
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientutils.cpp b/src/shared/qtgradienteditor/qtgradientutils.cpp
new file mode 100644
index 000000000..cfc4c25b8
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientutils.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientutils.h"
+#include "qtgradientmanager.h"
+#include <QtGui/QLinearGradient>
+#include <QtGui/QRadialGradient>
+#include <QtGui/QConicalGradient>
+#include <QtXml/QDomDocument>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static QString gradientTypeToString(QGradient::Type type)
+{
+ if (type == QGradient::LinearGradient)
+ return QLatin1String("LinearGradient");
+ if (type == QGradient::RadialGradient)
+ return QLatin1String("RadialGradient");
+ if (type == QGradient::ConicalGradient)
+ return QLatin1String("ConicalGradient");
+ return QLatin1String("NoGradient");
+}
+
+static QGradient::Type stringToGradientType(const QString &name)
+{
+ if (name == QLatin1String("LinearGradient"))
+ return QGradient::LinearGradient;
+ if (name == QLatin1String("RadialGradient"))
+ return QGradient::RadialGradient;
+ if (name == QLatin1String("ConicalGradient"))
+ return QGradient::ConicalGradient;
+ return QGradient::NoGradient;
+}
+
+static QString gradientSpreadToString(QGradient::Spread spread)
+{
+ if (spread == QGradient::PadSpread)
+ return QLatin1String("PadSpread");
+ if (spread == QGradient::RepeatSpread)
+ return QLatin1String("RepeatSpread");
+ if (spread == QGradient::ReflectSpread)
+ return QLatin1String("ReflectSpread");
+ return QLatin1String("PadSpread");
+}
+
+static QGradient::Spread stringToGradientSpread(const QString &name)
+{
+ if (name == QLatin1String("PadSpread"))
+ return QGradient::PadSpread;
+ if (name == QLatin1String("RepeatSpread"))
+ return QGradient::RepeatSpread;
+ if (name == QLatin1String("ReflectSpread"))
+ return QGradient::ReflectSpread;
+ return QGradient::PadSpread;
+}
+
+static QString gradientCoordinateModeToString(QGradient::CoordinateMode mode)
+{
+ if (mode == QGradient::LogicalMode)
+ return QLatin1String("LogicalMode");
+ if (mode == QGradient::StretchToDeviceMode)
+ return QLatin1String("StretchToDeviceMode");
+ if (mode == QGradient::ObjectBoundingMode)
+ return QLatin1String("ObjectBoundingMode");
+ return QLatin1String("StretchToDeviceMode");
+}
+
+static QGradient::CoordinateMode stringToGradientCoordinateMode(const QString &name)
+{
+ if (name == QLatin1String("LogicalMode"))
+ return QGradient::LogicalMode;
+ if (name == QLatin1String("StretchToDeviceMode"))
+ return QGradient::StretchToDeviceMode;
+ if (name == QLatin1String("ObjectBoundingMode"))
+ return QGradient::ObjectBoundingMode;
+ return QGradient::StretchToDeviceMode;
+}
+
+static QDomElement saveColor(QDomDocument &doc, const QColor &color)
+{
+ QDomElement colorElem = doc.createElement(QLatin1String("colorData"));
+
+ colorElem.setAttribute(QLatin1String("r"), QString::number(color.red()));
+ colorElem.setAttribute(QLatin1String("g"), QString::number(color.green()));
+ colorElem.setAttribute(QLatin1String("b"), QString::number(color.blue()));
+ colorElem.setAttribute(QLatin1String("a"), QString::number(color.alpha()));
+
+ return colorElem;
+}
+
+static QDomElement saveGradientStop(QDomDocument &doc, const QGradientStop &stop)
+{
+ QDomElement stopElem = doc.createElement(QLatin1String("stopData"));
+
+ stopElem.setAttribute(QLatin1String("position"), QString::number(stop.first));
+
+ const QDomElement colorElem = saveColor(doc, stop.second);
+ stopElem.appendChild(colorElem);
+
+ return stopElem;
+}
+
+static QDomElement saveGradient(QDomDocument &doc, const QGradient &gradient)
+{
+ QDomElement gradElem = doc.createElement(QLatin1String("gradientData"));
+
+ const QGradient::Type type = gradient.type();
+ gradElem.setAttribute(QLatin1String("type"), gradientTypeToString(type));
+ gradElem.setAttribute(QLatin1String("spread"), gradientSpreadToString(gradient.spread()));
+ gradElem.setAttribute(QLatin1String("coordinateMode"), gradientCoordinateModeToString(gradient.coordinateMode()));
+
+ QGradientStops stops = gradient.stops();
+ QVectorIterator<QGradientStop > it(stops);
+ while (it.hasNext())
+ gradElem.appendChild(saveGradientStop(doc, it.next()));
+
+ if (type == QGradient::LinearGradient) {
+ const QLinearGradient &g = *static_cast<const QLinearGradient *>(&gradient);
+ gradElem.setAttribute(QLatin1String("startX"), QString::number(g.start().x()));
+ gradElem.setAttribute(QLatin1String("startY"), QString::number(g.start().y()));
+ gradElem.setAttribute(QLatin1String("endX"), QString::number(g.finalStop().x()));
+ gradElem.setAttribute(QLatin1String("endY"), QString::number(g.finalStop().y()));
+ } else if (type == QGradient::RadialGradient) {
+ const QRadialGradient &g = *static_cast<const QRadialGradient *>(&gradient);
+ gradElem.setAttribute(QLatin1String("centerX"), QString::number(g.center().x()));
+ gradElem.setAttribute(QLatin1String("centerY"), QString::number(g.center().y()));
+ gradElem.setAttribute(QLatin1String("focalX"), QString::number(g.focalPoint().x()));
+ gradElem.setAttribute(QLatin1String("focalY"), QString::number(g.focalPoint().y()));
+ gradElem.setAttribute(QLatin1String("radius"), QString::number(g.radius()));
+ } else if (type == QGradient::ConicalGradient) {
+ const QConicalGradient &g = *static_cast<const QConicalGradient*>(&gradient);
+ gradElem.setAttribute(QLatin1String("centerX"), QString::number(g.center().x()));
+ gradElem.setAttribute(QLatin1String("centerY"), QString::number(g.center().y()));
+ gradElem.setAttribute(QLatin1String("angle"), QString::number(g.angle()));
+ }
+
+ return gradElem;
+}
+
+static QColor loadColor(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("colorData"))
+ return QColor();
+
+ return QColor(elem.attribute(QLatin1String("r")).toInt(),
+ elem.attribute(QLatin1String("g")).toInt(),
+ elem.attribute(QLatin1String("b")).toInt(),
+ elem.attribute(QLatin1String("a")).toInt());
+}
+
+static QGradientStop loadGradientStop(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("stopData"))
+ return QGradientStop();
+
+ const qreal pos = static_cast<qreal>(elem.attribute(QLatin1String("position")).toDouble());
+ return qMakePair(pos, loadColor(elem.firstChild().toElement()));
+}
+
+static QGradient loadGradient(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("gradientData"))
+ return QLinearGradient();
+
+ const QGradient::Type type = stringToGradientType(elem.attribute(QLatin1String("type")));
+ const QGradient::Spread spread = stringToGradientSpread(elem.attribute(QLatin1String("spread")));
+ const QGradient::CoordinateMode mode = stringToGradientCoordinateMode(elem.attribute(QLatin1String("coordinateMode")));
+
+ QGradient gradient = QLinearGradient();
+
+ if (type == QGradient::LinearGradient) {
+ QLinearGradient g;
+ g.setStart(elem.attribute(QLatin1String("startX")).toDouble(), elem.attribute(QLatin1String("startY")).toDouble());
+ g.setFinalStop(elem.attribute(QLatin1String("endX")).toDouble(), elem.attribute(QLatin1String("endY")).toDouble());
+ gradient = g;
+ } else if (type == QGradient::RadialGradient) {
+ QRadialGradient g;
+ g.setCenter(elem.attribute(QLatin1String("centerX")).toDouble(), elem.attribute(QLatin1String("centerY")).toDouble());
+ g.setFocalPoint(elem.attribute(QLatin1String("focalX")).toDouble(), elem.attribute(QLatin1String("focalY")).toDouble());
+ g.setRadius(elem.attribute(QLatin1String("radius")).toDouble());
+ gradient = g;
+ } else if (type == QGradient::ConicalGradient) {
+ QConicalGradient g;
+ g.setCenter(elem.attribute(QLatin1String("centerX")).toDouble(), elem.attribute(QLatin1String("centerY")).toDouble());
+ g.setAngle(elem.attribute(QLatin1String("angle")).toDouble());
+ gradient = g;
+ }
+
+ QDomElement stopElem = elem.firstChildElement();
+ while (!stopElem.isNull()) {
+ QGradientStop stop = loadGradientStop(stopElem);
+
+ gradient.setColorAt(stop.first, stop.second);
+
+ stopElem = stopElem.nextSiblingElement();
+ }
+
+ gradient.setSpread(spread);
+ gradient.setCoordinateMode(mode);
+
+ return gradient;
+}
+
+QString QtGradientUtils::saveState(const QtGradientManager *manager)
+{
+ QDomDocument doc;
+
+ QDomElement rootElem = doc.createElement(QLatin1String("gradients"));
+
+ QMap<QString, QGradient> grads = manager->gradients();
+ QMapIterator<QString, QGradient> itGrad(grads);
+ while (itGrad.hasNext()) {
+ itGrad.next();
+ QDomElement idElem = doc.createElement(QLatin1String("gradient"));
+ idElem.setAttribute(QLatin1String("name"), itGrad.key());
+ QDomElement gradElem = saveGradient(doc, itGrad.value());
+ idElem.appendChild(gradElem);
+
+ rootElem.appendChild(idElem);
+ }
+
+ doc.appendChild(rootElem);
+
+ return doc.toString();
+}
+
+void QtGradientUtils::restoreState(QtGradientManager *manager, const QString &state)
+{
+ manager->clear();
+
+ QDomDocument doc;
+ doc.setContent(state);
+
+ QDomElement rootElem = doc.documentElement();
+
+ QDomElement gradElem = rootElem.firstChildElement();
+ while (!gradElem.isNull()) {
+ const QString name = gradElem.attribute(QLatin1String("name"));
+ const QGradient gradient = loadGradient(gradElem.firstChildElement());
+
+ manager->addGradient(name, gradient);
+ gradElem = gradElem.nextSiblingElement();
+ }
+}
+
+QPixmap QtGradientUtils::gradientPixmap(const QGradient &gradient, const QSize &size, bool checkeredBackground)
+{
+ QImage image(size, QImage::Format_ARGB32);
+ QPainter p(&image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+
+ if (checkeredBackground) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
+
+ p.setBrushOrigin((size.width() % pixSize + pixSize) / 2, (size.height() % pixSize + pixSize) / 2);
+ p.fillRect(0, 0, size.width(), size.height(), pm);
+ p.setBrushOrigin(0, 0);
+ p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ }
+
+ const qreal scaleFactor = 0.999999;
+ p.scale(scaleFactor, scaleFactor);
+ QGradient grad = gradient;
+ grad.setCoordinateMode(QGradient::StretchToDeviceMode);
+ p.fillRect(QRect(0, 0, size.width(), size.height()), grad);
+ p.drawRect(QRect(0, 0, size.width() - 1, size.height() - 1));
+
+ return QPixmap::fromImage(image);
+}
+
+static QString styleSheetFillName(const QGradient &gradient)
+{
+ QString result;
+
+ switch (gradient.type()) {
+ case QGradient::LinearGradient:
+ result += QLatin1String("qlineargradient");
+ break;
+ case QGradient::RadialGradient:
+ result += QLatin1String("qradialgradient");
+ break;
+ case QGradient::ConicalGradient:
+ result += QLatin1String("qconicalgradient");
+ break;
+ default:
+ qWarning() << "QtGradientUtils::styleSheetFillName(): gradient type" << gradient.type() << "not supported!";
+ break;
+ }
+
+ return result;
+}
+
+static QStringList styleSheetParameters(const QGradient &gradient)
+{
+ QStringList result;
+
+ if (gradient.type() != QGradient::ConicalGradient) {
+ QString spread;
+ switch (gradient.spread()) {
+ case QGradient::PadSpread:
+ spread = QLatin1String("pad");
+ break;
+ case QGradient::ReflectSpread:
+ spread = QLatin1String("reflect");
+ break;
+ case QGradient::RepeatSpread:
+ spread = QLatin1String("repeat");
+ break;
+ default:
+ qWarning() << "QtGradientUtils::styleSheetParameters(): gradient spread" << gradient.spread() << "not supported!";
+ break;
+ }
+ result << QLatin1String("spread:") + spread;
+ }
+
+ switch (gradient.type()) {
+ case QGradient::LinearGradient: {
+ const QLinearGradient *linearGradient = static_cast<const QLinearGradient*>(&gradient);
+ result << QLatin1String("x1:") + QString::number(linearGradient->start().x())
+ << QLatin1String("y1:") + QString::number(linearGradient->start().y())
+ << QLatin1String("x2:") + QString::number(linearGradient->finalStop().x())
+ << QLatin1String("y2:") + QString::number(linearGradient->finalStop().y());
+ break;
+ }
+ case QGradient::RadialGradient: {
+ const QRadialGradient *radialGradient = static_cast<const QRadialGradient*>(&gradient);
+ result << QLatin1String("cx:") + QString::number(radialGradient->center().x())
+ << QLatin1String("cy:") + QString::number(radialGradient->center().y())
+ << QLatin1String("radius:") + QString::number(radialGradient->radius())
+ << QLatin1String("fx:") + QString::number(radialGradient->focalPoint().x())
+ << QLatin1String("fy:") + QString::number(radialGradient->focalPoint().y());
+ break;
+ }
+ case QGradient::ConicalGradient: {
+ const QConicalGradient *conicalGradient = static_cast<const QConicalGradient*>(&gradient);
+ result << QLatin1String("cx:") + QString::number(conicalGradient->center().x())
+ << QLatin1String("cy:") + QString::number(conicalGradient->center().y())
+ << QLatin1String("angle:") + QString::number(conicalGradient->angle());
+ break;
+ }
+ default:
+ qWarning() << "QtGradientUtils::styleSheetParameters(): gradient type" << gradient.type() << "not supported!";
+ break;
+ }
+
+ return result;
+}
+
+static QStringList styleSheetStops(const QGradient &gradient)
+{
+ QStringList result;
+ foreach (const QGradientStop &stop, gradient.stops()) {
+ const QColor color = stop.second;
+
+ const QString stopDescription = QLatin1String("stop:") + QString::number(stop.first) + QLatin1String(" rgba(")
+ + QString::number(color.red()) + QLatin1String(", ")
+ + QString::number(color.green()) + QLatin1String(", ")
+ + QString::number(color.blue()) + QLatin1String(", ")
+ + QString::number(color.alpha()) + QLatin1Char(')');
+ result << stopDescription;
+ }
+
+ return result;
+}
+
+QString QtGradientUtils::styleSheetCode(const QGradient &gradient)
+{
+ QStringList gradientParameters;
+ gradientParameters << styleSheetParameters(gradient) << styleSheetStops(gradient);
+
+ return styleSheetFillName(gradient) + QLatin1Char('(') + gradientParameters.join(QLatin1String(", ")) + QLatin1Char(')');
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientutils.h b/src/shared/qtgradienteditor/qtgradientutils.h
new file mode 100644
index 000000000..6c0d75e60
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientutils.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTUTILS_H
+#define GRADIENTUTILS_H
+
+#include <QtGui/QGradient>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+
+class QtGradientUtils
+{
+public:
+ static QString styleSheetCode(const QGradient &gradient);
+ // utils methods, they could be outside of this class
+ static QString saveState(const QtGradientManager *manager);
+ static void restoreState(QtGradientManager *manager, const QString &state);
+
+ static QPixmap gradientPixmap(const QGradient &gradient, const QSize &size = QSize(64, 64), bool checkeredBackground = false);
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientview.cpp b/src/shared/qtgradienteditor/qtgradientview.cpp
new file mode 100644
index 000000000..a3d17950d
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientview.h"
+#include "qtgradientmanager.h"
+#include "qtgradientdialog.h"
+#include "qtgradientutils.h"
+#include <QtGui/QPainter>
+#include <QtGui/QMessageBox>
+#include <QtGui/QClipboard>
+
+QT_BEGIN_NAMESPACE
+
+void QtGradientView::slotGradientAdded(const QString &id, const QGradient &gradient)
+{
+ QListWidgetItem *item = new QListWidgetItem(QtGradientUtils::gradientPixmap(gradient), id, m_ui.listWidget);
+ item->setToolTip(id);
+ item->setSizeHint(QSize(72, 84));
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+
+ m_idToItem[id] = item;
+ m_itemToId[item] = id;
+}
+
+void QtGradientView::slotGradientRenamed(const QString &id, const QString &newId)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ item->setText(newId);
+ item->setToolTip(newId);
+ m_itemToId[item] = newId;
+ m_idToItem.remove(id);
+ m_idToItem[newId] = item;
+}
+
+void QtGradientView::slotGradientChanged(const QString &id, const QGradient &newGradient)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ item->setIcon(QtGradientUtils::gradientPixmap(newGradient));
+}
+
+void QtGradientView::slotGradientRemoved(const QString &id)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ delete item;
+ m_itemToId.remove(item);
+ m_idToItem.remove(id);
+}
+
+void QtGradientView::slotNewGradient()
+{
+ bool ok;
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ QGradient grad = QLinearGradient();
+ if (item)
+ grad = m_manager->gradients().value(m_itemToId.value(item));
+ QGradient gradient = QtGradientDialog::getGradient(&ok, grad, this);
+ if (!ok)
+ return;
+
+ QString id = m_manager->addGradient(tr("Grad"), gradient);
+ m_ui.listWidget->setCurrentItem(m_idToItem.value(id));
+}
+
+void QtGradientView::slotEditGradient()
+{
+ bool ok;
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ QGradient grad = m_manager->gradients().value(id);
+ QGradient gradient = QtGradientDialog::getGradient(&ok, grad, this);
+ if (!ok)
+ return;
+
+ m_manager->changeGradient(id, gradient);
+}
+
+void QtGradientView::slotRemoveGradient()
+{
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ if (QMessageBox::question(this, tr("Remove Gradient"),
+ tr("Are you sure you want to remove the selected gradient?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ m_manager->removeGradient(id);
+}
+
+void QtGradientView::slotRenameGradient()
+{
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ m_ui.listWidget->editItem(item);
+}
+
+void QtGradientView::slotRenameGradient(QListWidgetItem *item)
+{
+ if (!item)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ m_manager->renameGradient(id, item->text());
+}
+
+void QtGradientView::slotCurrentItemChanged(QListWidgetItem *item)
+{
+ m_editAction->setEnabled(item);
+ m_renameAction->setEnabled(item);
+ m_removeAction->setEnabled(item);
+ emit currentGradientChanged(m_itemToId.value(item));
+}
+
+void QtGradientView::slotGradientActivated(QListWidgetItem *item)
+{
+ const QString id = m_itemToId.value(item);
+ if (!id.isEmpty())
+ emit gradientActivated(id);
+}
+
+QtGradientView::QtGradientView(QWidget *parent)
+ : QWidget(parent)
+{
+ m_manager = 0;
+
+ m_ui.setupUi(this);
+
+ m_ui.listWidget->setViewMode(QListView::IconMode);
+ m_ui.listWidget->setMovement(QListView::Static);
+ m_ui.listWidget->setTextElideMode(Qt::ElideRight);
+ m_ui.listWidget->setResizeMode(QListWidget::Adjust);
+ m_ui.listWidget->setIconSize(QSize(64, 64));
+ m_ui.listWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ QPalette pal = m_ui.listWidget->viewport()->palette();
+ int pixSize = 18;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QColor c1 = palette().color(QPalette::Midlight);
+ QColor c2 = palette().color(QPalette::Dark);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, c1);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, c1);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, c2);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, c2);
+
+ pal.setBrush(QPalette::Base, QBrush(pm));
+ m_ui.listWidget->viewport()->setPalette(pal);
+
+ connect(m_ui.listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotGradientActivated(QListWidgetItem*)));
+ connect(m_ui.listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(slotRenameGradient(QListWidgetItem*)));
+ connect(m_ui.listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(slotCurrentItemChanged(QListWidgetItem*)));
+
+ m_newAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/plus.png")), tr("New..."), this);
+ m_editAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/edit.png")), tr("Edit..."), this);
+ m_renameAction = new QAction(tr("Rename"), this);
+ m_removeAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/minus.png")), tr("Remove"), this);
+
+ connect(m_newAction, SIGNAL(triggered()), this, SLOT(slotNewGradient()));
+ connect(m_editAction, SIGNAL(triggered()), this, SLOT(slotEditGradient()));
+ connect(m_removeAction, SIGNAL(triggered()), this, SLOT(slotRemoveGradient()));
+ connect(m_renameAction, SIGNAL(triggered()), this, SLOT(slotRenameGradient()));
+
+ m_ui.listWidget->addAction(m_newAction);
+ m_ui.listWidget->addAction(m_editAction);
+ m_ui.listWidget->addAction(m_renameAction);
+ m_ui.listWidget->addAction(m_removeAction);
+
+ m_ui.newButton->setDefaultAction(m_newAction);
+ m_ui.editButton->setDefaultAction(m_editAction);
+ m_ui.renameButton->setDefaultAction(m_renameAction);
+ m_ui.removeButton->setDefaultAction(m_removeAction);
+
+ m_ui.listWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
+}
+
+void QtGradientView::setGradientManager(QtGradientManager *manager)
+{
+ if (m_manager == manager)
+ return;
+
+ if (m_manager) {
+ disconnect(m_manager, SIGNAL(gradientAdded(QString,QGradient)),
+ this, SLOT(slotGradientAdded(QString,QGradient)));
+ disconnect(m_manager, SIGNAL(gradientRenamed(QString,QString)),
+ this, SLOT(slotGradientRenamed(QString,QString)));
+ disconnect(m_manager, SIGNAL(gradientChanged(QString,QGradient)),
+ this, SLOT(slotGradientChanged(QString,QGradient)));
+ disconnect(m_manager, SIGNAL(gradientRemoved(QString)),
+ this, SLOT(slotGradientRemoved(QString)));
+
+ m_ui.listWidget->clear();
+ m_idToItem.clear();
+ m_itemToId.clear();
+ }
+
+ m_manager = manager;
+
+ if (!m_manager)
+ return;
+
+ QMap<QString, QGradient> gradients = m_manager->gradients();
+ QMapIterator<QString, QGradient> itGrad(gradients);
+ while (itGrad.hasNext()) {
+ itGrad.next();
+ slotGradientAdded(itGrad.key(), itGrad.value());
+ }
+
+ connect(m_manager, SIGNAL(gradientAdded(QString,QGradient)),
+ this, SLOT(slotGradientAdded(QString,QGradient)));
+ connect(m_manager, SIGNAL(gradientRenamed(QString,QString)),
+ this, SLOT(slotGradientRenamed(QString,QString)));
+ connect(m_manager, SIGNAL(gradientChanged(QString,QGradient)),
+ this, SLOT(slotGradientChanged(QString,QGradient)));
+ connect(m_manager, SIGNAL(gradientRemoved(QString)),
+ this, SLOT(slotGradientRemoved(QString)));
+}
+
+QtGradientManager *QtGradientView::gradientManager() const
+{
+ return m_manager;
+}
+
+void QtGradientView::setCurrentGradient(const QString &id)
+{
+ QListWidgetItem *item = m_idToItem.value(id);
+ if (!item)
+ return;
+
+ m_ui.listWidget->setCurrentItem(item);
+}
+
+QString QtGradientView::currentGradient() const
+{
+ return m_itemToId.value(m_ui.listWidget->currentItem());
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientview.h b/src/shared/qtgradienteditor/qtgradientview.h
new file mode 100644
index 000000000..8a45ecfcb
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTVIEW_H
+#define GRADIENTVIEW_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QMap>
+#include "ui_qtgradientview.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+class QListViewItem;
+class QAction;
+
+class QtGradientView : public QWidget
+{
+ Q_OBJECT
+public:
+ QtGradientView(QWidget *parent = 0);
+
+ void setGradientManager(QtGradientManager *manager);
+ QtGradientManager *gradientManager() const;
+
+ void setCurrentGradient(const QString &id);
+ QString currentGradient() const;
+
+signals:
+ void currentGradientChanged(const QString &id);
+ void gradientActivated(const QString &id);
+
+private slots:
+ void slotGradientAdded(const QString &id, const QGradient &gradient);
+ void slotGradientRenamed(const QString &id, const QString &newId);
+ void slotGradientChanged(const QString &id, const QGradient &newGradient);
+ void slotGradientRemoved(const QString &id);
+ void slotNewGradient();
+ void slotEditGradient();
+ void slotRemoveGradient();
+ void slotRenameGradient();
+ void slotRenameGradient(QListWidgetItem *item);
+ void slotCurrentItemChanged(QListWidgetItem *item);
+ void slotGradientActivated(QListWidgetItem *item);
+
+private:
+ QMap<QString, QListWidgetItem *> m_idToItem;
+ QMap<QListWidgetItem *, QString> m_itemToId;
+
+ QAction *m_newAction;
+ QAction *m_editAction;
+ QAction *m_renameAction;
+ QAction *m_removeAction;
+
+ QtGradientManager *m_manager;
+ Ui::QtGradientView m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientview.ui b/src/shared/qtgradienteditor/qtgradientview.ui
new file mode 100644
index 000000000..af7267ea2
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.ui
@@ -0,0 +1,135 @@
+<ui version="4.0" >
+ <class>QtGradientView</class>
+ <widget class="QWidget" name="QtGradientView" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>484</width>
+ <height>228</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Gradient View</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QToolButton" name="newButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>New...</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="editButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Edit...</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="renameButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Rename</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>71</width>
+ <height>26</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" />
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>listWidget</tabstop>
+ <tabstop>newButton</tabstop>
+ <tabstop>editButton</tabstop>
+ <tabstop>renameButton</tabstop>
+ <tabstop>removeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.cpp b/src/shared/qtgradienteditor/qtgradientviewdialog.cpp
new file mode 100644
index 000000000..260641d32
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientviewdialog.h"
+#include "qtgradientmanager.h"
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+QtGradientViewDialog::QtGradientViewDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ m_ui.setupUi(this);
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ connect(m_ui.gradientView, SIGNAL(currentGradientChanged(QString)),
+ this, SLOT(slotGradientSelected(QString)));
+ connect(m_ui.gradientView, SIGNAL(gradientActivated(QString)),
+ this, SLOT(slotGradientActivated(QString)));
+}
+
+void QtGradientViewDialog::setGradientManager(QtGradientManager *manager)
+{
+ m_ui.gradientView->setGradientManager(manager);
+}
+
+QGradient QtGradientViewDialog::getGradient(bool *ok, QtGradientManager *manager, QWidget *parent, const QString &caption)
+{
+ QtGradientViewDialog dlg(parent);
+ dlg.setGradientManager(manager);
+ dlg.setWindowTitle(caption);
+ QGradient grad = QLinearGradient();
+ const int res = dlg.exec();
+ if (res == QDialog::Accepted)
+ grad = dlg.m_ui.gradientView->gradientManager()->gradients().value(dlg.m_ui.gradientView->currentGradient());
+ if (ok)
+ *ok = res == QDialog::Accepted;
+ return grad;
+}
+
+void QtGradientViewDialog::slotGradientSelected(const QString &id)
+{
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!id.isEmpty());
+}
+
+void QtGradientViewDialog::slotGradientActivated(const QString &id)
+{
+ Q_UNUSED(id)
+ accept();
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.h b/src/shared/qtgradienteditor/qtgradientviewdialog.h
new file mode 100644
index 000000000..66cfeea40
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTVIEWDIALOG_H
+#define GRADIENTVIEWDIALOG_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QMap>
+#include "ui_qtgradientviewdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+
+class QtGradientViewDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ QtGradientViewDialog(QWidget *parent = 0);
+
+ void setGradientManager(QtGradientManager *manager);
+ QtGradientManager *gradientManager() const;
+
+ static QGradient getGradient(bool *ok, QtGradientManager *manager, QWidget *parent = 0, const QString &caption = tr("Select Gradient", 0));
+
+private slots:
+ void slotGradientSelected(const QString &id);
+ void slotGradientActivated(const QString &id);
+
+private:
+ Ui::QtGradientViewDialog m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.ui b/src/shared/qtgradienteditor/qtgradientviewdialog.ui
new file mode 100644
index 000000000..1aa32a323
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.ui
@@ -0,0 +1,121 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientViewDialog</class>
+ <widget class="QDialog" name="QtGradientViewDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>178</width>
+ <height>72</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Select Gradient</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QtGradientView" name="gradientView" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtGradientView</class>
+ <extends>QFrame</extends>
+ <header>qtgradientview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtGradientViewDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>224</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>21</x>
+ <y>243</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtGradientViewDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>168</x>
+ <y>233</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>152</x>
+ <y>251</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientwidget.cpp b/src/shared/qtgradienteditor/qtgradientwidget.cpp
new file mode 100644
index 000000000..d9056a703
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientwidget.cpp
@@ -0,0 +1,815 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientwidget.h"
+#include <QtCore/QMap>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMouseEvent>
+
+#define _USE_MATH_DEFINES
+
+
+#include "math.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientWidgetPrivate
+{
+ QtGradientWidget *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientWidget)
+public:
+ QPointF fromViewport(const QPointF &point) const;
+ QPointF toViewport(const QPointF &point) const;
+// void setupDrag(QtGradientStop *stop, int x);
+
+ QPointF checkRange(const QPointF &point) const;
+ QRectF pointRect(const QPointF &point, double size) const;
+
+ double correctAngle(double angle) const;
+ void setAngleConical(double angle);
+
+ void paintPoint(QPainter *painter, const QPointF &point, double size) const;
+
+ double m_handleSize;
+ bool m_backgroundCheckered;
+
+ QGradientStops m_gradientStops;
+ QGradient::Type m_gradientType;
+ QGradient::Spread m_gradientSpread;
+ QPointF m_startLinear;
+ QPointF m_endLinear;
+ QPointF m_centralRadial;
+ QPointF m_focalRadial;
+ qreal m_radiusRadial;
+ QPointF m_centralConical;
+ qreal m_angleConical;
+
+ enum Handle {
+ NoHandle,
+ StartLinearHandle,
+ EndLinearHandle,
+ CentralRadialHandle,
+ FocalRadialHandle,
+ RadiusRadialHandle,
+ CentralConicalHandle,
+ AngleConicalHandle
+ };
+
+ Handle m_dragHandle;
+ QPointF m_dragOffset;
+ //double m_radiusOffset;
+ double m_radiusFactor;
+ double m_dragRadius;
+ double m_angleOffset;
+ double m_dragAngle;
+};
+
+double QtGradientWidgetPrivate::correctAngle(double angle) const
+{
+ double a = angle;
+ while (a >= 360)
+ a -= 360;
+ while (a < 0)
+ a += 360;
+ return a;
+}
+
+void QtGradientWidgetPrivate::setAngleConical(double angle)
+{
+ double a = correctAngle(angle);
+ if (m_angleConical == a)
+ return;
+ m_angleConical = a;
+ emit q_ptr->angleConicalChanged(m_angleConical);
+}
+
+QRectF QtGradientWidgetPrivate::pointRect(const QPointF &point, double size) const
+{
+ return QRectF(point.x() - size / 2, point.y() - size / 2, size, size);
+}
+
+QPointF QtGradientWidgetPrivate::checkRange(const QPointF &point) const
+{
+ QPointF p = point;
+ if (p.x() > 1)
+ p.setX(1);
+ else if (p.x() < 0)
+ p.setX(0);
+ if (p.y() > 1)
+ p.setY(1);
+ else if (p.y() < 0)
+ p.setY(0);
+ return p;
+}
+
+QPointF QtGradientWidgetPrivate::fromViewport(const QPointF &point) const
+{
+ QSize size = q_ptr->size();
+ return QPointF(point.x() / size.width(), point.y() / size.height());
+}
+
+QPointF QtGradientWidgetPrivate::toViewport(const QPointF &point) const
+{
+ QSize size = q_ptr->size();
+ return QPointF(point.x() * size.width(), point.y() * size.height());
+}
+
+void QtGradientWidgetPrivate::paintPoint(QPainter *painter, const QPointF &point, double size) const
+{
+ QPointF pf = toViewport(point);
+ QRectF rf = pointRect(pf, size);
+
+ QPen pen;
+ pen.setWidthF(1);
+ QColor alphaZero = Qt::white;
+ alphaZero.setAlpha(0);
+
+ painter->save();
+ painter->drawEllipse(rf);
+
+ /*
+ painter->save();
+
+ QLinearGradient lgV(0, rf.top(), 0, rf.bottom());
+ lgV.setColorAt(0, alphaZero);
+ lgV.setColorAt(0.25, Qt::white);
+ lgV.setColorAt(0.25, Qt::white);
+ lgV.setColorAt(1, alphaZero);
+ pen.setBrush(lgV);
+ painter->setPen(pen);
+
+ painter->drawLine(QPointF(pf.x(), rf.top()), QPointF(pf.x(), rf.bottom()));
+
+ QLinearGradient lgH(rf.left(), 0, rf.right(), 0);
+ lgH.setColorAt(0, alphaZero);
+ lgH.setColorAt(0.5, Qt::white);
+ lgH.setColorAt(1, alphaZero);
+ pen.setBrush(lgH);
+ painter->setPen(pen);
+
+ painter->drawLine(QPointF(rf.left(), pf.y()), QPointF(rf.right(), pf.y()));
+
+ painter->restore();
+ */
+
+ painter->restore();
+}
+
+/*
+void QtGradientWidgetPrivate::setupDrag(QtGradientStop *stop, int x)
+{
+ m_model->setCurrentStop(stop);
+
+ int viewportX = qRound(toViewport(stop->position()));
+ m_dragOffset = x - viewportX;
+
+ QList<QtGradientStop *> stops = m_stops;
+ m_stops.clear();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (m_model->isSelected(s) || s == stop) {
+ m_dragStops[s] = s->position() - stop->position();
+ m_stops.append(s);
+ } else {
+ m_dragOriginal[s->position()] = s->color();
+ }
+ }
+ itStop.toFront();
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (!m_model->isSelected(s))
+ m_stops.append(s);
+ }
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+}
+*/
+////////////////////////////
+
+QtGradientWidget::QtGradientWidget(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtGradientWidgetPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_backgroundCheckered = true;
+ d_ptr->m_handleSize = 20.0;
+ d_ptr->m_gradientType = QGradient::LinearGradient;
+ d_ptr->m_startLinear = QPointF(0, 0);
+ d_ptr->m_endLinear = QPointF(1, 1);
+ d_ptr->m_centralRadial = QPointF(0.5, 0.5);
+ d_ptr->m_focalRadial = QPointF(0.5, 0.5);
+ d_ptr->m_radiusRadial = 0.5;
+ d_ptr->m_centralConical = QPointF(0.5, 0.5);
+ d_ptr->m_angleConical = 0;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+}
+
+QtGradientWidget::~QtGradientWidget()
+{
+}
+
+QSize QtGradientWidget::sizeHint() const
+{
+ return QSize(176, 176);
+}
+
+QSize QtGradientWidget::minimumSizeHint() const
+{
+ return QSize(128, 128);
+}
+
+int QtGradientWidget::heightForWidth(int w) const
+{
+ return w;
+}
+
+void QtGradientWidget::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtGradientWidget::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientWidget::mousePressEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ QPoint p = e->pos();
+ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
+ QPointF startPoint = d_ptr->toViewport(d_ptr->m_startLinear);
+ double x = p.x() - startPoint.x();
+ double y = p.y() - startPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::StartLinearHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF endPoint = d_ptr->toViewport(d_ptr->m_endLinear);
+ x = p.x() - endPoint.x();
+ y = p.y() - endPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::EndLinearHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
+ QPointF focalPoint = d_ptr->toViewport(d_ptr->m_focalRadial);
+ double x = p.x() - focalPoint.x();
+ double y = p.y() - focalPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 9) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::FocalRadialHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
+ x = p.x() - centralPoint.x();
+ y = p.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralRadialHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
+ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
+ QRectF r1(0, r.y(), size().width(), r.height());
+ QRectF r2(r.x(), 0, r.width(), r.y());
+ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
+ QPointF pF(p.x(), p.y());
+ if (r1.contains(pF) || r2.contains(pF) || r3.contains(pF)) {
+ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
+ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
+ double clickRadius = sqrt(x * x + y * y);
+ //d_ptr->m_radiusOffset = d_ptr->m_radiusRadial - clickRadius;
+ d_ptr->m_radiusFactor = d_ptr->m_radiusRadial / clickRadius;
+ if (d_ptr->m_radiusFactor == 0)
+ d_ptr->m_radiusFactor = 1;
+ d_ptr->m_dragRadius = d_ptr->m_radiusRadial;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::RadiusRadialHandle;
+ mouseMoveEvent(e);
+ update();
+ return;
+ }
+ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
+ double x = p.x() - centralPoint.x();
+ double y = p.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralConicalHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+ double radius = size().width();
+ if (size().height() < radius)
+ radius = size().height();
+ radius /= 2;
+ double corr = d_ptr->m_handleSize / 3;
+ radius -= corr;
+ QPointF vp = d_ptr->toViewport(d_ptr->m_centralConical);
+ x = p.x() - vp.x();
+ y = p.y() - vp.y();
+ if (((radius - corr) * (radius - corr) < (x * x + y * y)) &&
+ ((radius + corr) * (radius + corr) > (x * x + y * y))) {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF current(e->pos().x(), e->pos().y());
+ x = current.x() - central.x();
+ y = current.y() - central.y();
+ x /= size().width() / 2;
+ y /= size().height() / 2;
+ double r = sqrt(x * x + y * y);
+
+ double arcSin = asin(y / r);
+ double arcCos = acos(x / r);
+
+ double angle = arcCos * 180 / M_PI;
+ if (arcSin > 0) {
+ angle = -angle;
+ }
+
+ d_ptr->m_angleOffset = d_ptr->m_angleConical - angle;
+ d_ptr->m_dragAngle = d_ptr->m_angleConical;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::AngleConicalHandle;
+ update();
+ return;
+ }
+ }
+}
+
+void QtGradientWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_UNUSED(e)
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
+ update();
+}
+
+void QtGradientWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::NoHandle)
+ return;
+
+ QPointF newPos = QPointF((double)e->pos().x() - d_ptr->m_dragOffset.x(),
+ (double)e->pos().y() - d_ptr->m_dragOffset.y());
+ QPointF newPoint = d_ptr->fromViewport(newPos);
+ if (newPoint.x() < 0)
+ newPoint.setX(0);
+ else if (newPoint.x() > 1)
+ newPoint.setX(1);
+ if (newPoint.y() < 0)
+ newPoint.setY(0);
+ else if (newPoint.y() > 1)
+ newPoint.setY(1);
+
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle) {
+ d_ptr->m_startLinear = newPoint;
+ emit startLinearChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle) {
+ d_ptr->m_endLinear = newPoint;
+ emit endLinearChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle) {
+ d_ptr->m_centralRadial = newPoint;
+ emit centralRadialChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle) {
+ d_ptr->m_focalRadial = newPoint;
+ emit focalRadialChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
+ QPointF pF(e->pos().x(), e->pos().y());
+ double x = pF.x() - centralPoint.x();
+ double y = pF.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ if (d_ptr->m_radiusRadial != d_ptr->m_dragRadius) {
+ d_ptr->m_radiusRadial = d_ptr->m_dragRadius;
+ emit radiusRadialChanged(d_ptr->m_radiusRadial);
+ }
+ } else {
+ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
+ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
+ double moveRadius = sqrt(x * x + y * y);
+ //double newRadius = moveRadius + d_ptr->m_radiusOffset;
+ double newRadius = moveRadius * d_ptr->m_radiusFactor;
+ if (newRadius > 2)
+ newRadius = 2;
+ d_ptr->m_radiusRadial = newRadius;
+ emit radiusRadialChanged(d_ptr->m_radiusRadial);
+ }
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle) {
+ d_ptr->m_centralConical = newPoint;
+ emit centralConicalChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF pF(e->pos().x(), e->pos().y());
+ double x = pF.x() - centralPoint.x();
+ double y = pF.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ if (d_ptr->m_angleConical != d_ptr->m_dragAngle) {
+ d_ptr->m_angleConical = d_ptr->m_dragAngle;
+ emit angleConicalChanged(d_ptr->m_angleConical);
+ }
+ } else {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF current = pF;
+ x = current.x() - central.x();
+ y = current.y() - central.y();
+ x /= size().width() / 2;
+ y /= size().height() / 2;
+ double r = sqrt(x * x + y * y);
+
+ double arcSin = asin(y / r);
+ double arcCos = acos(x / r);
+
+ double angle = arcCos * 180 / M_PI;
+ if (arcSin > 0) {
+ angle = -angle;
+ }
+
+ angle += d_ptr->m_angleOffset;
+
+ d_ptr->setAngleConical(angle);
+ }
+ }
+ update();
+}
+
+void QtGradientWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ mousePressEvent(e);
+}
+
+void QtGradientWidget::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e)
+
+ QPainter p(this);
+
+ if (d_ptr->m_backgroundCheckered) {
+ int pixSize = 40;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+
+ p.setBrushOrigin((size().width() % pixSize + pixSize) / 2, (size().height() % pixSize + pixSize) / 2);
+ p.fillRect(rect(), pm);
+ p.setBrushOrigin(0, 0);
+ }
+
+ QGradient *gradient = 0;
+ switch (d_ptr->m_gradientType) {
+ case QGradient::LinearGradient:
+ gradient = new QLinearGradient(d_ptr->m_startLinear, d_ptr->m_endLinear);
+ break;
+ case QGradient::RadialGradient:
+ gradient = new QRadialGradient(d_ptr->m_centralRadial, d_ptr->m_radiusRadial, d_ptr->m_focalRadial);
+ break;
+ case QGradient::ConicalGradient:
+ gradient = new QConicalGradient(d_ptr->m_centralConical, d_ptr->m_angleConical);
+ break;
+ default:
+ break;
+ }
+ if (!gradient)
+ return;
+
+ gradient->setStops(d_ptr->m_gradientStops);
+ gradient->setSpread(d_ptr->m_gradientSpread);
+
+ p.save();
+ p.scale(size().width(), size().height());
+ p.fillRect(QRect(0, 0, 1, 1), *gradient);
+ p.restore();
+
+ p.setRenderHint(QPainter::Antialiasing);
+
+ QColor c = QColor::fromRgbF(0.5, 0.5, 0.5, 0.5);
+ QBrush br(c);
+ p.setBrush(br);
+ QPen pen(Qt::white);
+ pen.setWidthF(1);
+ p.setPen(pen);
+ QPen dragPen = pen;
+ dragPen.setWidthF(2);
+ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_startLinear, d_ptr->m_handleSize);
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_endLinear, d_ptr->m_handleSize);
+ p.restore();
+ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
+
+ p.save();
+ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
+ QRectF r1(0, r.y(), size().width(), r.height());
+ QRectF r2(r.x(), 0, r.width(), r.y());
+ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
+ p.fillRect(r1, c);
+ p.fillRect(r2, c);
+ p.fillRect(r3, c);
+ p.setBrush(Qt::NoBrush);
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_centralRadial, d_ptr->m_handleSize);
+ p.restore();
+
+ QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial * size().width(),
+ central.y() - d_ptr->m_radiusRadial * size().height(),
+ 2 * d_ptr->m_radiusRadial * size().width(),
+ 2 * d_ptr->m_radiusRadial * size().height());
+ p.setClipRect(r1);
+ p.setClipRect(r2, Qt::UniteClip);
+ p.setClipRect(r3, Qt::UniteClip);
+ p.drawEllipse(rect);
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
+ p.save();
+ p.setPen(dragPen);
+ QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
+ central.y() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height(),
+ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
+ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height());
+ p.drawEllipse(rect);
+
+ p.restore();
+ }
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_focalRadial, 2 * d_ptr->m_handleSize / 3);
+ p.restore();
+ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
+ double radius = size().width();
+ if (size().height() < radius)
+ radius = size().height();
+ radius /= 2;
+ double corr = d_ptr->m_handleSize / 3;
+ radius -= corr;
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+
+ p.save();
+ p.setBrush(Qt::NoBrush);
+ QPen pen2(c);
+ pen2.setWidthF(2 * d_ptr->m_handleSize / 3);
+ p.setPen(pen2);
+ p.drawEllipse(d_ptr->pointRect(central, 2 * radius));
+ p.restore();
+
+ p.save();
+ p.setBrush(Qt::NoBrush);
+ int pointCount = 2;
+ for (int i = 0; i < pointCount; i++) {
+ QPointF ang(cos(M_PI * (i * 180.0 / pointCount + d_ptr->m_angleConical) / 180) * size().width() / 2,
+ -sin(M_PI * (i * 180.0 / pointCount + d_ptr->m_angleConical) / 180) * size().height() / 2);
+ double mod = sqrt(ang.x() * ang.x() + ang.y() * ang.y());
+ p.drawLine(QPointF(central.x() + ang.x() * (radius - corr) / mod,
+ central.y() + ang.y() * (radius - corr) / mod),
+ QPointF(central.x() + ang.x() * (radius + corr) / mod,
+ central.y() + ang.y() * (radius + corr) / mod));
+ p.drawLine(QPointF(central.x() - ang.x() * (radius - corr) / mod,
+ central.y() - ang.y() * (radius - corr) / mod),
+ QPointF(central.x() - ang.x() * (radius + corr) / mod,
+ central.y() - ang.y() * (radius + corr) / mod));
+ }
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
+ p.save();
+ p.setPen(dragPen);
+ QPointF ang(cos(M_PI * (d_ptr->m_angleConical - d_ptr->m_angleOffset) / 180) * size().width() / 2,
+ -sin(M_PI * (d_ptr->m_angleConical - d_ptr->m_angleOffset) / 180) * size().height() / 2);
+ double mod = sqrt(ang.x() * ang.x() + ang.y() * ang.y());
+ p.drawLine(QPointF(central.x() + ang.x() * (radius - corr) / mod,
+ central.y() + ang.y() * (radius - corr) / mod),
+ QPointF(central.x() + ang.x() * (radius + corr) / mod,
+ central.y() + ang.y() * (radius + corr) / mod));
+ p.restore();
+ }
+
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_centralConical, d_ptr->m_handleSize);
+ p.restore();
+
+ }
+
+ delete gradient;
+}
+
+void QtGradientWidget::setGradientStops(const QGradientStops &stops)
+{
+ d_ptr->m_gradientStops = stops;
+ update();
+}
+
+QGradientStops QtGradientWidget::gradientStops() const
+{
+ return d_ptr->m_gradientStops;
+}
+
+void QtGradientWidget::setGradientType(QGradient::Type type)
+{
+ if (type == QGradient::NoGradient)
+ return;
+ if (d_ptr->m_gradientType == type)
+ return;
+
+ d_ptr->m_gradientType = type;
+ update();
+}
+
+QGradient::Type QtGradientWidget::gradientType() const
+{
+ return d_ptr->m_gradientType;
+}
+
+void QtGradientWidget::setGradientSpread(QGradient::Spread spread)
+{
+ if (d_ptr->m_gradientSpread == spread)
+ return;
+
+ d_ptr->m_gradientSpread = spread;
+ update();
+}
+
+QGradient::Spread QtGradientWidget::gradientSpread() const
+{
+ return d_ptr->m_gradientSpread;
+}
+
+void QtGradientWidget::setStartLinear(const QPointF &point)
+{
+ if (d_ptr->m_startLinear == point)
+ return;
+
+ d_ptr->m_startLinear = d_ptr->checkRange(point);
+ update();
+}
+
+QPointF QtGradientWidget::startLinear() const
+{
+ return d_ptr->m_startLinear;
+}
+
+void QtGradientWidget::setEndLinear(const QPointF &point)
+{
+ if (d_ptr->m_endLinear == point)
+ return;
+
+ d_ptr->m_endLinear = d_ptr->checkRange(point);
+ update();
+}
+
+QPointF QtGradientWidget::endLinear() const
+{
+ return d_ptr->m_endLinear;
+}
+
+void QtGradientWidget::setCentralRadial(const QPointF &point)
+{
+ if (d_ptr->m_centralRadial == point)
+ return;
+
+ d_ptr->m_centralRadial = point;
+ update();
+}
+
+QPointF QtGradientWidget::centralRadial() const
+{
+ return d_ptr->m_centralRadial;
+}
+
+void QtGradientWidget::setFocalRadial(const QPointF &point)
+{
+ if (d_ptr->m_focalRadial == point)
+ return;
+
+ d_ptr->m_focalRadial = point;
+ update();
+}
+
+QPointF QtGradientWidget::focalRadial() const
+{
+ return d_ptr->m_focalRadial;
+}
+
+void QtGradientWidget::setRadiusRadial(qreal radius)
+{
+ if (d_ptr->m_radiusRadial == radius)
+ return;
+
+ d_ptr->m_radiusRadial = radius;
+ update();
+}
+
+qreal QtGradientWidget::radiusRadial() const
+{
+ return d_ptr->m_radiusRadial;
+}
+
+void QtGradientWidget::setCentralConical(const QPointF &point)
+{
+ if (d_ptr->m_centralConical == point)
+ return;
+
+ d_ptr->m_centralConical = point;
+ update();
+}
+
+QPointF QtGradientWidget::centralConical() const
+{
+ return d_ptr->m_centralConical;
+}
+
+void QtGradientWidget::setAngleConical(qreal angle)
+{
+ if (d_ptr->m_angleConical == angle)
+ return;
+
+ d_ptr->m_angleConical = angle;
+ update();
+}
+
+qreal QtGradientWidget::angleConical() const
+{
+ return d_ptr->m_angleConical;
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientwidget.h b/src/shared/qtgradienteditor/qtgradientwidget.h
new file mode 100644
index 000000000..ee866feb9
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientwidget.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTWIDGET_H
+#define QTGRADIENTWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtGradientWidget(QWidget *parent = 0);
+ ~QtGradientWidget();
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+ int heightForWidth(int w) const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ QGradientStops gradientStops() const;
+
+ void setGradientType(QGradient::Type type);
+ QGradient::Type gradientType() const;
+
+ void setGradientSpread(QGradient::Spread spread);
+ QGradient::Spread gradientSpread() const;
+
+ void setStartLinear(const QPointF &point);
+ QPointF startLinear() const;
+
+ void setEndLinear(const QPointF &point);
+ QPointF endLinear() const;
+
+ void setCentralRadial(const QPointF &point);
+ QPointF centralRadial() const;
+
+ void setFocalRadial(const QPointF &point);
+ QPointF focalRadial() const;
+
+ void setRadiusRadial(qreal radius);
+ qreal radiusRadial() const;
+
+ void setCentralConical(const QPointF &point);
+ QPointF centralConical() const;
+
+ void setAngleConical(qreal angle);
+ qreal angleConical() const;
+
+public slots:
+ void setGradientStops(const QGradientStops &stops);
+signals:
+
+ void startLinearChanged(const QPointF &point);
+ void endLinearChanged(const QPointF &point);
+ void centralRadialChanged(const QPointF &point);
+ void focalRadialChanged(const QPointF &point);
+ void radiusRadialChanged(qreal radius);
+ void centralConicalChanged(const QPointF &point);
+ void angleConicalChanged(qreal angle);
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+
+private:
+ QScopedPointer<class QtGradientWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientWidget)
+ Q_DISABLE_COPY(QtGradientWidget)
+};
+
+QT_END_NAMESPACE
+
+#endif