From 2776cfd76e481f1e5cc7cfd7afd430f345a5f8f0 Mon Sep 17 00:00:00 2001
From: Thomas Hartmann <Thomas.Hartmann@nokia.com>
Date: Thu, 4 Feb 2010 14:41:04 +0100
Subject: [PATCH] QmlDesigner.propertyEditor: new color widgets

---
 .../components/propertyeditor/colorwidget.cpp | 272 +++++++-----------
 .../components/propertyeditor/colorwidget.h   | 243 +++++++++++++---
 2 files changed, 300 insertions(+), 215 deletions(-)

diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp
index 11127a80243..fccf722253c 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp
@@ -28,13 +28,11 @@
 **************************************************************************/
 
 #include "colorwidget.h"
-#include "qtcolorline.h"
-#include "qtcolorbutton.h"
 #include <QHBoxLayout>
 #include <QLabel>
 #include <QToolButton>
 #include <QGradient>
-#include <qtgradientdialog.h>
+#include <QPainter>
 #include <QtDebug>
 #include <modelnode.h>
 #include <abstractview.h>
@@ -43,217 +41,151 @@
 #include <variantproperty.h>
 #include <qmlobjectnode.h>
 
-QML_DEFINE_TYPE(Bauhaus,1,0,ColorWidget,QmlDesigner::ColorWidget);
+QML_DEFINE_TYPE(Bauhaus,1,0,ColorButton,QmlDesigner::ColorButton);
+QML_DEFINE_TYPE(Bauhaus,1,0,HueControl,QmlDesigner::HueControl);
+QML_DEFINE_TYPE(Bauhaus,1,0,ColorBox,QmlDesigner::ColorBox);
+
 
 namespace QmlDesigner {
 
-ColorWidget::ColorWidget(QWidget *parent) :
-        QWidget(parent),
-        m_label(new QLabel(this)),
-        m_colorButton(new QtColorButton(this)),
-        m_gradientButton(new QToolButton(this))
+void ColorButton::paintEvent(QPaintEvent *event)
 {
-    QHBoxLayout *horizonalBoxLayout = new QHBoxLayout(this);
-
-    m_colorButton->setFixedHeight(32);
-    m_colorButton->setStyleSheet("");
-
-    m_gradientButton->setIcon(QIcon(":/images/gradient.png"));
-
-    m_gradientButton->setFixedHeight(32);
-    m_gradientButton->setFixedWidth(100);
-    m_gradientButton->setStyleSheet("");
-
-    QFont f = m_label->font();
-    f.setBold(true);
-    m_label->setFont(f);
-    m_label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
-    horizonalBoxLayout->addWidget(m_label);
-    horizonalBoxLayout->addWidget(m_colorButton);
-    horizonalBoxLayout->addWidget(m_gradientButton);
-    horizonalBoxLayout->setSpacing(20);
-    horizonalBoxLayout->setMargin(0);
-    m_gradientButton->setCheckable(true);
-    m_gradientButton->setVisible(false);
-    connect(m_colorButton, SIGNAL(colorChanged(QColor)), this, SLOT(setColor(QColor)));
-    connect(m_gradientButton, SIGNAL(toggled(bool)), SLOT(openGradientEditor(bool)));
-}
+    QToolButton::paintEvent(event);
+    if (!isEnabled())
+        return;
 
-ColorWidget::~ColorWidget()
-{
-}
+    QColor color(m_colorString);
 
-QString ColorWidget::text() const
-{
-    if (m_label)
-        return m_label->text();
+    const int pixSize = 8;
+
+    QPainter p(this);
+
+    QRect r(0, 0, width(), height());
+    if (isEnabled())
+        p.setBrush(color);
     else
-        return QString();
+        p.setBrush(Qt::transparent);
+    p.setPen(Qt::black);
+    p.drawRect(r);
+
+    QVector<QPointF> points;
+    if (isChecked()) {
+        points.append(QPointF(2, 3));
+        points.append(QPointF(8, 3));
+        points.append(QPointF(5, 9));
+    } else {
+        points.append(QPointF(8, 6));
+        points.append(QPointF(2, 9));
+        points.append(QPointF(2, 3));
+    }
+    p.setPen("#707070");
+    p.setBrush(Qt::white);
+    p.drawPolygon(points);
 }
 
-QColor ColorWidget::color() const
-{
-    return m_color;
-}
 
-void ColorWidget::setColor(const QColor &color)
+void HueControl::setCurrent(int y)
 {
-    if (m_color == color)
-        return;
-    bool valid = m_color.isValid();
-    m_color = color;
-    m_colorButton->setColor(color);
-    if (valid)
-        emit colorChanged(color);
-}
+       QColor oldColor(m_colorString);
+       oldColor.toHsv();
+       QColor newColor;
+       newColor.setHsvF(qreal(y) / 120.0, oldColor.hsvSaturationF(), oldColor.valueF());
 
-QString ColorWidget::strColor() const
-{
-    return m_color.name();
+       QString newColorStr = QVariant(newColor).toString();
+       setColor(newColorStr);
+       setHue(qreal(y) / 120.0);
 }
 
-void ColorWidget::setText(const QString &text)
+void HueControl::paintEvent(QPaintEvent *event)
 {
-    if (m_label)
-        m_label->setText(text);
-}
+    QWidget::paintEvent(event);    
 
-ModelNode ColorWidget::gradientNode() const
-{
-    return m_gradientNode;
-}
+    QColor color(m_colorString);
+    color.toHsv();
 
-QGradient ColorWidget::gradient() const
-{
-    if (!m_gradientNode.isValid()) {
-        return QGradient();
-    }
+    QPainter p(this);
 
-    if (m_gradientNode.type() != "Qt/Gradient") {
-        qWarning() << "ColorWidget: gradient node is of wrong type";
-        return QGradient();
-    }
+    int height = 120;
 
-    QLinearGradient gradient;
+    if (m_cache.isNull()) {
+        m_cache = QPixmap(10, height);
 
-    QGradientStops oldStops;
+        QPainter cacheP(&m_cache);
 
-    //QVariantList stopList(m_modelState.nodeState(m_gradientNode).property("stops").value().toList()); /###
-    foreach (const ModelNode &stopNode, m_gradientNode.nodeListProperty("stops").toModelNodeList()) {
-            oldStops.append(QPair<qreal, QColor>(stopNode.variantProperty("position").value().toReal(), stopNode.variantProperty("color").value().value<QColor>()));
+        for (int i = 0; i < height; i++)
+        {
+            QColor c;
+            c.setHsvF(qreal(i) / 120.0, 1,1.0);
+            cacheP.fillRect(0, i, 10, i + 1, c);
         }
-    gradient.setStops(oldStops);
+    }
 
-    return gradient;
-}
+    p.drawPixmap(10, 5, m_cache);
 
-void ColorWidget::setGradientNode(const ModelNode &gradient)
-{
-    m_gradientNode = gradient;
-}
+    QVector<QPointF> points;
 
-bool ColorWidget::gradientButtonShown() const
-{
-    return m_gradientButton->isVisible();
-}
+    int y = hue() * 120 + 5;
 
-void ColorWidget::setShowGradientButton(bool showButton)
-{
-    m_gradientButton->setVisible(showButton);
-    if (showButton && layout()->children().contains(m_gradientButton))
-        layout()->removeWidget(m_gradientButton);
-    else if (showButton && !layout()->children().contains(m_gradientButton) )
-        layout()->addWidget(m_gradientButton);
-}
+    points.append(QPointF(15, y));
+    points.append(QPointF(25, y + 5));
+    points.append(QPointF(25, y - 5));
 
-void ColorWidget::openGradientEditor(bool show)
-{
-    if (show && m_gradientDialog.isNull()) {
-        m_gradientDialog = new QtGradientDialog(this);
-        m_gradientDialog->setAttribute(Qt::WA_DeleteOnClose);
-        m_gradientDialog->setGradient(gradient());
-        m_gradientDialog->show();
-        connect(m_gradientDialog.data(), SIGNAL(accepted()), SLOT(updateGradientNode()));
-        connect(m_gradientDialog.data(), SIGNAL(destroyed()), SLOT(resetGradientButton()));
-    } else {
-        delete m_gradientDialog.data();
-    }
+    p.setPen(Qt::black);
+    p.setBrush(QColor("#707070"));
+    p.drawPolygon(points);
 }
 
-void ColorWidget::updateGradientNode()
+void ColorBox::setCurrent(int x, int y)
 {
-    QGradient gradient(m_gradientDialog->gradient());
 
-    ModelNode gradientNode;
+      QColor oldColor(m_colorString);
+       oldColor.toHsv();
+       QColor newColor;
+       newColor.setHsvF(hue(), qreal(x) / 120, 1.0 - qreal(y) / 120);
 
-    if (m_modelNode.hasNodeProperty("gradient"))
-        m_gradientNode = m_modelNode.nodeProperty("gradient").modelNode();
+       QString newColorStr = QVariant(newColor).toString();
+       setColor(newColorStr);
+}
 
-    if (m_gradientNode.isValid() && m_gradientNode.type() == "Qt/Gradient") {
-        gradientNode = m_gradientNode;
-    } else {
-        if (m_modelNode.hasProperty("gradient")) {
-            m_modelNode.removeProperty("gradient");
-        }
-        gradientNode =  m_modelNode.view()->createModelNode("Qt/Gradient", 4, 6);
-        m_modelNode.nodeProperty("gradient").reparentHere(gradientNode);
-        m_gradientNode = gradientNode;
-    }
+void ColorBox::paintEvent(QPaintEvent *event)
+{
+    QWidget::paintEvent(event);
 
-    if (QmlObjectNode(m_gradientNode).isInBaseState()) {
+    QPainter p(this);
+    QColor color(m_colorString);
 
-        NodeListProperty stops(gradientNode.nodeListProperty("stops"));
+    if (m_hue != (m_lastHue) || (m_cache.isNull())) {
+        m_lastHue = m_hue;
+        m_cache = QPixmap(120, 120);
 
-        foreach (ModelNode node, stops.allSubNodes())
-            node.destroy();
+        
+        color.toHsv();
 
-        if (gradientNode.hasProperty("stops"))
-            gradientNode.removeProperty("stops");
+        int height = 120;
+        int width = 120;
 
-        foreach(const QGradientStop &stop, gradient.stops()) {
-            QList<QPair<QString, QVariant> > propertyList;
+        QPainter chacheP(&m_cache);
 
-            qreal p = stop.first * 100;
-            int ip = qRound(p);
-            p = qreal(ip) / 100;
+        if (color.hsvHueF() < 0)
+            color.setHsvF(hue(), color.hsvSaturationF(), color.valueF());
 
-            ModelNode gradientStop(gradientNode.view()->createModelNode("Qt/GradientStop", 4, 6));
-            stops.reparentHere(gradientStop);
-            gradientStop.variantProperty("position").setValue(p);
-            gradientStop.variantProperty("color").setValue(stop.second.name());
-        }
-    } else { //not in base state
-        //## TODO
+        for (int y = 0; y < height; y++)
+            for (int x = 0; x < width; x++)
+            {
+                QColor c;
+                c.setHsvF(color.hsvHueF(), qreal(x) / 120, 1.0 - qreal(y) / 120);
+                chacheP.setPen(c);
+                chacheP.drawPoint(x ,y);
+            }
     }
-}
 
-void ColorWidget::resetGradientButton()
-{
-    m_gradientButton->setChecked(false);
-}
-
-void ColorWidget::setModelNode(const ModelNode &modelNode)
-{
-    if (m_modelNode != modelNode) {
-        m_modelNode = modelNode;
-        emit modelNodeChanged();
-    }
-}
+    p.drawPixmap(5, 5, m_cache);
 
-ModelNode ColorWidget::modelNode() const
-{
-    return m_modelNode;
-}
-
-PropertyEditorNodeWrapper* ColorWidget::complexGradientNode() const
-{
-    return m_complexGradientNode;
-}
+    int x = color.hsvSaturationF() * 120 + 5;
+    int y = 120 - color.valueF() * 120 + 5;
 
-void ColorWidget::setComplexGradientNode(PropertyEditorNodeWrapper* complexNode)
-{
-    m_complexGradientNode = complexNode;
-    setModelNode(complexNode->parentModelNode());
+    p.setPen(Qt::white);
+    p.drawEllipse(x - 2, y - 2, 4, 4);
 }
 
 }
diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h
index c5080966941..413d1e04b6b 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h
@@ -33,6 +33,8 @@
 #include <QWeakPointer>
 #include <QtGui/QWidget>
 #include <QLabel>
+#include <QToolButton>
+#include <QMouseEvent>
 #include <modelnode.h>
 #include <qml.h>
 #include <propertyeditorvalue.h>
@@ -40,69 +42,220 @@
 
 class QtColorButton;
 class QToolButton;
-class QtGradientDialog;
 
 namespace QmlDesigner {
 
-class ColorWidget : public QWidget
+class ColorButton : public QToolButton {
+
+Q_OBJECT
+
+Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
+
+public:
+
+    ColorButton(QWidget *parent = 0) : QToolButton (parent), m_colorString("#ffffff")
+    {
+    }
+
+    void setColor(const QString &colorStr)
+    {
+        if (m_colorString == colorStr)
+            return;
+
+        m_colorString = colorStr;
+        update();
+        emit colorChanged();
+    }
+
+    QString color() const
+    {
+        return m_colorString;
+    }
+
+signals:
+    void colorChanged();
+
+protected:
+    void paintEvent(QPaintEvent *event);
+private:
+    QString m_colorString;
+};
+
+class ColorBox : public QWidget
 {
-    Q_OBJECT
-    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
-    Q_PROPERTY(QColor strColor READ strColor)
-    Q_PROPERTY(QString text READ text WRITE setText)
-    Q_PROPERTY(QmlDesigner::ModelNode gradient READ gradientNode WRITE setGradientNode NOTIFY gradientNodeChanged)
-    Q_PROPERTY(bool showGradientButton READ gradientButtonShown WRITE setShowGradientButton)
-    Q_PROPERTY(QmlDesigner::ModelNode modelNode READ modelNode WRITE setModelNode NOTIFY modelNodeChanged)
-    Q_PROPERTY(PropertyEditorNodeWrapper* complexGradientNode READ complexGradientNode WRITE setComplexGradientNode)
+Q_OBJECT
+
+Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
+Q_PROPERTY(qreal hue READ hue WRITE setHue NOTIFY hueChanged)
+
 public:
 
-    ColorWidget(QWidget *parent = 0);
-    ~ColorWidget();
+ColorBox(QWidget *parent = 0) : QWidget(parent), m_colorString("#ffffff"), m_hue(0), m_lastHue(0)
+{
+    setFixedWidth(130);
+    setFixedHeight(130);
+}
+
+void setHue(qreal newHue)
+{
+    if (m_hue == newHue)
+        return;
 
-    QColor color() const;
-    QString text() const;
-    QString strColor() const;
-    void setText(const QString &text);
-    ModelNode gradientNode() const;
-    bool gradientButtonShown() const;
-    void setShowGradientButton(bool showButton);
+    m_hue = newHue;
+    update();
+    emit hueChanged();
+}
 
-    void setModelNode(const ModelNode &modelNode);
-    ModelNode modelNode() const;
+qreal hue() const
+{
+    return m_hue;
+}
+
+void setColor(const QString &colorStr)
+{
+    if (m_colorString == colorStr)
+        return;
 
-    PropertyEditorNodeWrapper* complexGradientNode() const;
-    void setComplexGradientNode(PropertyEditorNodeWrapper* complexNode);
+    m_colorString = colorStr;
+    update();
+    qreal newHue = QColor(m_colorString).hsvHueF();
+    if (newHue >= 0)
+        setHue(newHue);
+    emit colorChanged();
+}
 
-public slots:
-    void setColor(const QColor &color);
-    void setGradientNode(const QmlDesigner::ModelNode &gradient);
+QString color() const
+{
+    return m_colorString;
+}
 
 signals:
-    void colorChanged(const QColor &color);
-    void gradientNodeChanged();
-    void modelStateChanged();
-    void modelNodeChanged();
+    void colorChanged();
+    void hueChanged();
 
 protected:
-    QGradient gradient() const;
+    void paintEvent(QPaintEvent *event);
+
+    void mousePressEvent(QMouseEvent *e)
+    {
+        // The current cell marker is set to the cell the mouse is pressed in
+        QPoint pos = e->pos();
+        m_mousePressed = true;
+        setCurrent(pos.x() - 5, pos.y() - 5);
+    }
+
+    void mouseReleaseEvent(QMouseEvent * /* event */)
+    {
+        m_mousePressed = false;
+    }
+
+void mouseMoveEvent(QMouseEvent *e)
+{
+    if (!m_mousePressed)
+        return;
+    QPoint pos = e->pos();
+    setCurrent(pos.x() - 5, pos.y() - 5);
+}
+
+void setCurrent(int x, int y);
+
 
-private slots:
-    void openGradientEditor(bool show);
-    void updateGradientNode();
-    void resetGradientButton();
 private:
-    QColor m_color;
-    ModelNode m_gradientNode;
-    ModelNode m_modelNode;
-    QWeakPointer<QtGradientDialog> m_gradientDialog;
-    QLabel *m_label;
-    QtColorButton *m_colorButton;
-    QToolButton *m_gradientButton;
-    PropertyEditorNodeWrapper* m_complexGradientNode;
+    QString m_colorString;
+    bool m_mousePressed;
+    qreal m_hue;
+    qreal m_lastHue;
+    QPixmap m_cache;
 };
 
+class HueControl : public QWidget
+{
+Q_OBJECT
+
+Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
+Q_PROPERTY(qreal hue READ hue WRITE setHue NOTIFY hueChanged)
+
+public:
+
+HueControl(QWidget *parent = 0) : QWidget(parent), m_colorString("#ffffff"), m_mousePressed(false), m_hue(0)
+{
+    setFixedWidth(40);
+    setFixedHeight(130);
+}
+
+void setHue(qreal newHue)
+{
+    if (m_hue == newHue)
+        return;
+
+    m_hue = newHue;
+    update();
+    emit hueChanged();
+}
+
+qreal hue() const
+{
+    return m_hue;
+}
+
+void setColor(const QString &colorStr)
+{
+    if (m_colorString == colorStr)
+        return;
+
+    m_colorString = colorStr;
+    update();
+    emit colorChanged();
+}
+
+QString color() const
+{
+    return m_colorString;
+}
+
+signals:
+    void colorChanged();
+    void hueChanged();
+
+protected:
+    void paintEvent(QPaintEvent *event);
+
+    void mousePressEvent(QMouseEvent *e)
+    {
+        // The current cell marker is set to the cell the mouse is pressed in
+        QPoint pos = e->pos();
+        m_mousePressed = true;
+        setCurrent(pos.y() - 5);
+    }
+
+    void mouseReleaseEvent(QMouseEvent * /* event */)
+    {
+        m_mousePressed = false;
+    }
+
+void mouseMoveEvent(QMouseEvent *e)
+{
+    if (!m_mousePressed)
+        return;
+    QPoint pos = e->pos();
+    setCurrent(pos.y() - 5);
 }
 
-QML_DECLARE_TYPE(QmlDesigner::ColorWidget);
+void setCurrent(int y);
+
+
+private:
+    QString m_colorString;
+    bool m_mousePressed;
+    qreal m_hue;
+    QPixmap m_cache;
+};
+
+
+QML_DECLARE_TYPE(QmlDesigner::ColorButton);
+QML_DECLARE_TYPE(QmlDesigner::HueControl);
+QML_DECLARE_TYPE(QmlDesigner::ColorBox);
+
+} //QmlDesigner
 
-#endif
+#endif //COLORWIDGET_H
-- 
GitLab