Commit 121b6cb4 authored by Thomas Hartmann's avatar Thomas Hartmann
Browse files

QmlDesigner.propertyEditor: code cleanup for property editing

Instead of duplicating the code from QmlEditorWigets we now subclass
and expose the gradient editing to qml.
The adaptor class is called GradientLineQmlAdaptor.
parent 948ca6f2
......@@ -27,7 +27,7 @@
**
**************************************************************************/
#include "colorwidget.h"
#include "colorwidgets.h"
#include <qdeclarative.h>
#include "colorbox.h"
......@@ -37,7 +37,7 @@
namespace QmlEditorWidgets {
void ColorWidget::registerDeclarativeTypes() {
void ColorWidgets::registerDeclarativeTypes() {
qmlRegisterType<QmlEditorWidgets::ColorButton>("Bauhaus",1,0,"ColorButton");
qmlRegisterType<QmlEditorWidgets::HueControl>("Bauhaus",1,0,"HueControl");
qmlRegisterType<QmlEditorWidgets::ColorBox>("Bauhaus",1,0,"ColorBox");
......
......@@ -44,7 +44,7 @@ QT_END_NAMESPACE
namespace QmlEditorWidgets {
class ColorWidget {
class QMLEDITORWIDGETS_EXPORT ColorWidgets {
public:
static void registerDeclarativeTypes();
......
......@@ -39,7 +39,6 @@
#include <QGridLayout>
#include <QToolButton>
#include <QAction>
#include "colorwidget.h"
#include "contextpanetextwidget.h"
#include "easingcontextpane.h"
#include "contextpanewidgetimage.h"
......
......@@ -49,7 +49,7 @@ void GradientLine::setGradient(const QLinearGradient &gradient)
{
m_gradient = gradient;
m_useGradient = true;
setupGradient();
readGradient();
emit gradientChanged();
}
......@@ -105,7 +105,7 @@ void GradientLine::setActiveColor(const QColor &newColor)
update();
}
void GradientLine::setupGradient()
void GradientLine::readGradient()
{
if (m_useGradient) {
m_colorList.clear();
......
......@@ -56,9 +56,6 @@ public:
QLinearGradient gradient() const { return m_gradient; }
void setGradient(const QLinearGradient &);
public slots:
void setupGradient();
signals:
void activeColorChanged();
void itemNodeChanged();
......@@ -76,6 +73,7 @@ protected:
private:
void setup();
void readGradient();
void updateGradient();
int currentColorIndex() const { return m_colorIndex; }
void setCurrentIndex(int i);
......
......@@ -19,7 +19,7 @@ HEADERS += \
contextpanewidgetimage.h \
contextpanewidget.h \
contextpanetextwidget.h \
colorwidget.h \
colorwidgets.h \
colorbutton.h \
colorbox.h \
customcolordialog.h \
......@@ -34,7 +34,7 @@ SOURCES += \
contextpanewidgetimage.cpp \
contextpanewidget.cpp \
contextpanetextwidget.cpp \
colorwidget.cpp \
colorwidgets.cpp \
colorbox.cpp \
customcolordialog.cpp \
huecontrol.cpp \
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef COLORWIDGET_H
#define COLORWIDGET_H
#include <QWeakPointer>
#include <QtGui/QWidget>
#include <QLabel>
#include <QToolButton>
#include <QMouseEvent>
#include <modelnode.h>
#include <qdeclarative.h>
#include <propertyeditorvalue.h>
#include <qmlitemnode.h>
#include <QDialog>
#include <QLinearGradient>
QT_BEGIN_NAMESPACE
class QtColorButton;
class QToolButton;
class QDoubleSpinBox;
QT_END_NAMESPACE
namespace QmlDesigner {
class ColorButton : public QToolButton {
Q_OBJECT
Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(bool noColor READ noColor WRITE setNoColor)
Q_PROPERTY(bool showArrow READ showArrow WRITE setShowArrow)
public:
ColorButton(QWidget *parent = 0) : QToolButton (parent), m_colorString("#ffffff"), m_noColor(false), m_showArrow(true) {}
void setColor(const QString &colorStr);
QString color() const { return m_colorString; }
QColor convertedColor() const;
bool noColor() const { return m_noColor; }
void setNoColor(bool f) { m_noColor = f; update(); }
bool showArrow() const { return m_showArrow; }
void setShowArrow(bool b) { m_showArrow = b; }
signals:
void colorChanged();
protected:
void paintEvent(QPaintEvent *event);
private:
QString m_colorString;
bool m_noColor;
bool m_showArrow;
};
class ColorBox : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString strColor READ strColor WRITE setStrColor NOTIFY colorChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(int hue READ hue WRITE setHue NOTIFY hueChanged)
Q_PROPERTY(int saturation READ saturation WRITE setSaturation NOTIFY saturationChanged)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(int alpha READ alpha WRITE setAlpha NOTIFY alphaChanged)
public:
ColorBox(QWidget *parent = 0) : QWidget(parent), m_color(Qt::white), m_saturatedColor(Qt::white), m_lastHue(0)
{
setFixedWidth(130);
setFixedHeight(130);
}
void setHue(int newHue);
int hue() const;
void setAlpha(int newAlpha);
int alpha() const { return m_color.alpha(); }
void setStrColor(const QString &colorStr);
void setColor(const QColor &color);
QString strColor() const;
QColor color() const { return m_color; }
int saturation() const { return m_color.hsvSaturation(); }
void setSaturation(int newsaturation);
int value() const { return m_color.value(); }
void setValue(int newvalue);
signals:
void colorChanged();
void hueChanged();
void saturationChanged();
void valueChanged();
void alphaChanged();
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void setCurrent(int x, int y);
private:
QColor m_color;
QColor m_saturatedColor;
bool m_mousePressed;
int m_lastHue;
QPixmap m_cache;
};
class HueControl : public QWidget
{
Q_OBJECT
Q_PROPERTY(qreal hue READ hue WRITE setHue NOTIFY hueChanged)
public:
HueControl(QWidget *parent = 0) : QWidget(parent), m_color(Qt::white), m_mousePressed(false)
{
setFixedWidth(28);
setFixedHeight(130);
}
void setHue(int newHue);
int hue() const { return m_color.hsvHue(); }
signals:
void hueChanged(int hue);
protected:
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void setCurrent(int y);
private:
QColor m_color;
bool m_mousePressed;
QPixmap m_cache;
};
class GradientLine : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor activeColor READ activeColor WRITE setActiveColor NOTIFY activeColorChanged)
Q_PROPERTY(QVariant itemNode READ itemNode WRITE setItemNode NOTIFY itemNodeChanged)
Q_PROPERTY(QString gradientName READ gradientName WRITE setGradientName NOTIFY gradientNameChanged)
Q_PROPERTY(bool active READ active WRITE setActive)
Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged)
public:
GradientLine(QWidget *parent = 0);
QVariant itemNode() const { return QVariant::fromValue(m_itemNode.modelNode()); }
void setItemNode(const QVariant &itemNode);
QString gradientName() const { return m_gradientName; }
void setGradientName(const QString &newName);
QColor activeColor() const { return m_activeColor; }
void setActiveColor(const QColor &newColor);
bool active() const { return m_active; }
void setActive(bool a) { m_active = a; }
QLinearGradient gradient() const { return m_gradient; }
void setGradient(const QLinearGradient &);
public slots:
void setupGradient();
void deleteGradient();
signals:
void activeColorChanged();
void itemNodeChanged();
void gradientNameChanged();
void gradientChanged();
void openColorDialog(const QPoint &pos);
protected:
bool event(QEvent *event);
void keyPressEvent(QKeyEvent * event);
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
private:
void setup();
void updateGradient();
int currentColorIndex() const { return m_colorIndex; }
void setCurrentIndex(int i);
QColor m_activeColor;
QmlItemNode m_itemNode;
QString m_gradientName;
QList<QColor> m_colorList;
QList<qreal> m_stops;
int m_colorIndex;
bool m_dragActive;
QPoint m_dragStart;
QLinearGradient m_gradient;
int m_yOffset;
bool m_create;
bool m_active;
bool m_dragOff;
bool m_useGradient;
};
class BauhausColorDialog : public QFrame {
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
BauhausColorDialog(QWidget *parent = 0);
QColor color() const { return m_color; }
void setupColor(const QColor &color);
void setColor(const QColor &color)
{
if (color == m_color)
return;
m_color = color;
setupWidgets();
emit colorChanged();
}
public slots:
void changeColor(const QColor &color) { setColor(color); }
void spinBoxChanged();
void onColorBoxChanged();
void onHueChanged(int newHue)
{
if (m_blockUpdate)
return;
if (m_color.hsvHue() == newHue)
return;
m_color.setHsv(newHue, m_color.hsvSaturation(), m_color.value());
setupWidgets();
emit colorChanged();
}
void onAccept()
{
emit accepted(m_color);
}
signals:
void colorChanged();
void accepted(const QColor &color);
void rejected();
protected:
void setupWidgets();
private:
QFrame *m_beforeColorWidget;
QFrame *m_currentColorWidget;
ColorBox *m_colorBox;
HueControl *m_hueControl;
QDoubleSpinBox *m_rSpinBox;
QDoubleSpinBox *m_gSpinBox;
QDoubleSpinBox *m_bSpinBox;
QDoubleSpinBox *m_alphaSpinBox;
QColor m_color;
bool m_blockUpdate;
};
class ColorWidget {
public:
static void registerDeclarativeTypes();
};
} //QmlDesigner
QML_DECLARE_TYPE(QmlDesigner::ColorButton)
QML_DECLARE_TYPE(QmlDesigner::HueControl)
QML_DECLARE_TYPE(QmlDesigner::ColorBox)
#endif //COLORWIDGET_H
#include "gradientlineqmladaptor.h"
#include <qdeclarative.h>
#include <QMessageBox>
#include <nodeproperty.h>
#include <nodelistproperty.h>
#include <nodemetainfo.h>
#include <abstractview.h>
#include <rewritingexception.h>
#include <variantproperty.h>
namespace QmlDesigner {
GradientLineQmlAdaptor::GradientLineQmlAdaptor(QWidget *parent) :
QmlEditorWidgets::GradientLine(parent)
{
connect(this, SIGNAL(gradientChanged()), this, SLOT(writeGradient()));
}
void GradientLineQmlAdaptor::setItemNode(const QVariant &itemNode)
{
if (!itemNode.value<ModelNode>().isValid())
return;
m_itemNode = itemNode.value<ModelNode>();
setupGradient();
emit itemNodeChanged();
}
static inline QColor normalizeColor(const QColor &color)
{
QColor newColor = QColor(color.name());
newColor.setAlpha(color.alpha());
return newColor;
}
static inline qreal roundReal(qreal real)
{
int i = real * 100;
return qreal(i) / 100;
}
void GradientLineQmlAdaptor::setupGradient()
{
ModelNode modelNode = m_itemNode.modelNode();
QLinearGradient newGradient;
QVector<QGradientStop> stops;
if (!modelNode.isValid())
return;
if (modelNode.hasProperty(gradientName())) { //gradient exists
ModelNode gradientNode = modelNode.nodeProperty(gradientName()).modelNode();
QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList();
foreach (const ModelNode &stopNode, stopList) {
QmlObjectNode stopObjectNode = stopNode;
if (stopObjectNode.isValid()) {
qreal position = stopObjectNode.instanceValue("position").toReal();
QColor color = stopObjectNode.instanceValue("color").value<QColor>();
stops.append( QPair<qreal, QColor>(position, color));
}
}
} else {
stops.append( QPair<qreal, QColor>(0, activeColor()));
stops.append( QPair<qreal, QColor>(1, QColor(Qt::black)));
}
newGradient.setStops(stops);
setGradient(newGradient);
}
void GradientLineQmlAdaptor::writeGradient()
{
if (!active())
return;
if (!m_itemNode.isValid())
return;
if (!m_itemNode.modelNode().metaInfo().hasProperty(gradientName()))
return;
try {
RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction();
ModelNode modelNode = m_itemNode.modelNode();
QString oldId;
QVector<QGradientStop> stops = gradient().stops();
if (m_itemNode.isInBaseState()) {
if (modelNode.hasProperty(gradientName())) {
oldId = modelNode.nodeProperty(gradientName()).modelNode().id();
modelNode.removeProperty(gradientName());
}
ModelNode gradientNode = modelNode.view()->createModelNode("Qt/Gradient", 4, 7);
if (!oldId.isNull())
gradientNode.setId(oldId);
for (int i = 0;i < stops.size(); i++) {
ModelNode gradientStopNode = modelNode.view()->createModelNode("Qt/GradientStop", 4, 7);
gradientStopNode.variantProperty("position") = roundReal(stops.at(i).first);
gradientStopNode.variantProperty("color") = normalizeColor(stops.at(i).second);
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
}
modelNode.nodeProperty(gradientName()).reparentHere(gradientNode);
} else { //state
if (!modelNode.hasProperty(gradientName())) {
qWarning(" GradientLine::updateGradient: no gradient in state");
return;
}
ModelNode gradientNode = modelNode.nodeProperty(gradientName()).modelNode();
QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList();
for (int i = 0;i < stops.size(); i++) {
QmlObjectNode stopObjectNode = stopList.at(i);
stopObjectNode.setVariantProperty("position", roundReal(stops.at(i).first));
stopObjectNode.setVariantProperty("color", normalizeColor(stops.at(i).second));
}
}
}
catch (RewritingException &e) {
QMessageBox::warning(0, "Error", e.description());
}
}
void GradientLineQmlAdaptor::deleteGradient()
{
if (!m_itemNode.isValid())
return;
if (!m_itemNode.modelNode().metaInfo().hasProperty(gradientName()))
return;
ModelNode modelNode = m_itemNode.modelNode();
if (m_itemNode.isInBaseState()) {
if (modelNode.hasProperty(gradientName())) {
RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction();
ModelNode gradientNode = modelNode.nodeProperty(gradientName()).modelNode();
if (QmlObjectNode(gradientNode).isValid())
QmlObjectNode(gradientNode).destroy();
}
}
}
void GradientLineQmlAdaptor::registerDeclarativeType() {
qmlRegisterType<QmlDesigner::GradientLineQmlAdaptor>("Bauhaus",1,0,"GradientLine");
}
} //QmlDesigner
#ifndef GRADIENTLINEQMLADAPTOR_H
#define GRADIENTLINEQMLADAPTOR_H
#include <qmleditorwidgets/gradientline.h>
#include <propertyeditorvalue.h>
#include <qmlitemnode.h>
namespace QmlDesigner {
class GradientLineQmlAdaptor : public QmlEditorWidgets::GradientLine
{
Q_OBJECT
Q_PROPERTY(QVariant itemNode READ itemNode WRITE setItemNode NOTIFY itemNodeChanged)
public:
explicit GradientLineQmlAdaptor(QWidget *parent = 0);
static void registerDeclarativeType();