diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp index a4f189340081348f36ab0300ab3c1d0e97e3358b..69d51201ec3bfe0575c7808ef408e74ac877fae8 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp @@ -58,7 +58,7 @@ static inline int clamp(int x, int lower, int upper) return x; } -inline QString properName(const QColor &color) +static inline QString properName(const QColor &color) { QString s; if (color.alpha() == 255) @@ -68,7 +68,7 @@ inline QString properName(const QColor &color) return s; } -inline QColor properColor(const QString &str) +static inline QColor properColor(const QString &str) { int lalpha = 255; QString lcolorStr = str; @@ -88,6 +88,27 @@ inline QColor properColor(const QString &str) return lcolor; } +static inline bool isColorString(const QString &colorString) +{ + bool ok = true; + if (colorString.size() == 9 && colorString.at(0) == QLatin1Char('#')) { + // #rgba + for (int i = 1; i < 9; ++i) { + const QChar c = colorString.at(i); + if ((c >= QLatin1Char('0') && c <= QLatin1Char('9')) + || (c >= QLatin1Char('a') && c <= QLatin1Char('f')) + || (c >= QLatin1Char('A') && c <= QLatin1Char('F'))) + continue; + ok = false; + break; + } + } else { + ok = QColor::isValidColor(colorString); + } + + return ok; +} + namespace QmlDesigner { void ColorWidget::registerDeclarativeTypes() { @@ -102,6 +123,9 @@ void ColorButton::setColor(const QString &colorStr) if (m_colorString == colorStr) return; + + setEnabled(isColorString(colorStr)); + m_colorString = colorStr; update(); emit colorChanged(); @@ -402,10 +426,19 @@ void GradientLine::setItemNode(const QVariant &itemNode) if (!itemNode.value<ModelNode>().isValid()) return; m_itemNode = itemNode.value<ModelNode>(); - setup(); + setupGradient(); emit itemNodeChanged(); } +void GradientLine::setGradient(const QLinearGradient &gradient) +{ + m_gradient = gradient; + m_useGradient = true; + setupGradient(); + emit gradientChanged(); + +} + static inline QColor invertColor(const QColor color) { QColor c = color.toHsv(); @@ -422,7 +455,8 @@ GradientLine::GradientLine(QWidget *parent) : m_yOffset(0), m_create(false), m_active(false), - m_dragOff(false) + m_dragOff(false), + m_useGradient(true) { setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); setFocusPolicy(Qt::StrongFocus); @@ -458,27 +492,36 @@ void GradientLine::setActiveColor(const QColor &newColor) void GradientLine::setupGradient() { - ModelNode modelNode = m_itemNode.modelNode(); - if (!modelNode.isValid()) - return; - m_colorList.clear(); - m_stops.clear(); - - if (modelNode.hasProperty(m_gradientName)) { //gradient exists + if (m_useGradient) { + m_colorList.clear(); + m_stops.clear(); + foreach (const QGradientStop &stop, m_gradient.stops()) { + m_stops << stop.first; + m_colorList << stop.second; + } + } else { + ModelNode modelNode = m_itemNode.modelNode(); + if (!modelNode.isValid()) + return; + m_colorList.clear(); + m_stops.clear(); - ModelNode gradientNode = modelNode.nodeProperty(m_gradientName).modelNode(); - QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList(); + if (modelNode.hasProperty(m_gradientName)) { //gradient exists - foreach (const ModelNode &stopNode, stopList) { - QmlObjectNode stopObjectNode = stopNode; - if (stopObjectNode.isValid()) { - m_stops << stopObjectNode.instanceValue("position").toReal(); - m_colorList << stopObjectNode.instanceValue("color").value<QColor>(); + ModelNode gradientNode = modelNode.nodeProperty(m_gradientName).modelNode(); + QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList(); + + foreach (const ModelNode &stopNode, stopList) { + QmlObjectNode stopObjectNode = stopNode; + if (stopObjectNode.isValid()) { + m_stops << stopObjectNode.instanceValue("position").toReal(); + m_colorList << stopObjectNode.instanceValue("color").value<QColor>(); + } } + } else { + m_colorList << m_activeColor << QColor(Qt::black); + m_stops << 0 << 1; } - } else { - m_colorList << m_activeColor << QColor(Qt::black); - m_stops << 0 << 1; } updateGradient(); @@ -534,6 +577,9 @@ void GradientLine::keyPressEvent(QKeyEvent * event) void GradientLine::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); + + if (!isEnabled()) + return; QPainter p(this); @@ -559,7 +605,7 @@ void GradientLine::paintEvent(QPaintEvent *event) QColor arrowColor(Qt::black); if (i == currentColorIndex()) { localYOffset = m_yOffset; - arrowColor = QColor(0xeeeeee); + arrowColor = QColor(0x909090); } p.setPen(arrowColor); if (i == 0 || i == (m_colorList.size() - 1)) @@ -589,6 +635,7 @@ void GradientLine::paintEvent(QPaintEvent *event) void GradientLine::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { + event->accept(); int xPos = event->pos().x(); int yPos = event->pos().y(); @@ -605,12 +652,23 @@ void GradientLine::mousePressEvent(QMouseEvent *event) setCurrentIndex(draggedIndex); update(); } + } else { + QWidget::mousePressEvent(event); } if (draggedIndex == -1) m_create = true; + } else { + QWidget::mousePressEvent(event); } setFocus(Qt::MouseFocusReason); +} + +void GradientLine::mouseDoubleClickEvent(QMouseEvent *event) +{ event->accept(); + m_dragActive = false; + m_create = false; + emit openColorDialog(event->pos()); } void GradientLine::mouseReleaseEvent(QMouseEvent *event) @@ -623,24 +681,27 @@ void GradientLine::mouseReleaseEvent(QMouseEvent *event) if ((stopPos > m_stops.at(i)) && (index == -1)) index = i +1; } - if (index != -1 && m_itemNode.isInBaseState()) { //creating of items only in base state + if (index != -1 && (m_useGradient || m_itemNode.isInBaseState())) { //creating of items only in base state m_stops.insert(index, stopPos); m_colorList.insert(index, QColor(Qt::white)); setCurrentIndex(index); updateGradient(); } } + event->accept(); } m_dragActive = false; m_yOffset = 0; update(); updateGradient(); - event->accept(); + + //QWidget::mouseReleaseEvent(event); } void GradientLine::mouseMoveEvent(QMouseEvent *event) { if (m_dragActive) { + event->accept(); int xPos = event->pos().x(); int pos = qreal((width() - 20)) * m_stops.at(currentColorIndex()) + 8; int offset = m_dragOff ? 2 : 20; @@ -652,7 +713,7 @@ void GradientLine::mouseMoveEvent(QMouseEvent *event) if ((newStop >=0) && (newStop <= 1)) m_stops[currentColorIndex()] = newStop; m_yOffset += event->pos().y() - m_dragStart.y(); - if (m_yOffset > 0 || !m_itemNode.isInBaseState()) { //deleting only in base state + if (m_yOffset > 0 || !(m_itemNode.isInBaseState() || m_useGradient)) { //deleting only in base state m_yOffset = 0; } else if ((m_yOffset < - 12) && (currentColorIndex()) != 0 && (currentColorIndex() < m_stops.size() - 1)) { m_yOffset = 0; @@ -670,7 +731,7 @@ void GradientLine::mouseMoveEvent(QMouseEvent *event) update(); } - QWidget::mouseMoveEvent(event); + //QWidget::mouseMoveEvent(event); } void GradientLine::setup() @@ -693,43 +754,52 @@ static inline qreal roundReal(qreal real) void GradientLine::updateGradient() { - if (!active()) - return; - RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(); - if (!m_itemNode.isValid()) - return; + if (m_useGradient) { + QGradientStops stops; + for (int i = 0;i < m_stops.size(); i++) { + stops.append(QPair<qreal, QColor>(m_stops.at(i), m_colorList.at(i))); + } + m_gradient.setStops(stops); + emit gradientChanged(); + } else { + if (!active()) + return; + RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(); + if (!m_itemNode.isValid()) + return; - if (!m_itemNode.modelNode().metaInfo().hasProperty(m_gradientName)) - return; + if (!m_itemNode.modelNode().metaInfo().hasProperty(m_gradientName)) + return; - ModelNode modelNode = m_itemNode.modelNode(); + ModelNode modelNode = m_itemNode.modelNode(); - if (m_itemNode.isInBaseState()) { - if (modelNode.hasProperty(m_gradientName)) { - modelNode.removeProperty(m_gradientName); - } + if (m_itemNode.isInBaseState()) { + if (modelNode.hasProperty(m_gradientName)) { + modelNode.removeProperty(m_gradientName); + } - ModelNode gradientNode = modelNode.view()->createModelNode("Qt/Gradient", 4, 7); + ModelNode gradientNode = modelNode.view()->createModelNode("Qt/Gradient", 4, 7); - for (int i = 0;i < m_stops.size(); i++) { - ModelNode gradientStopNode = modelNode.view()->createModelNode("Qt/GradientStop", 4, 7); - gradientStopNode.variantProperty("position") = roundReal(m_stops.at(i)); - gradientStopNode.variantProperty("color") = normalizeColor(m_colorList.at(i)); - gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); - } - modelNode.nodeProperty(m_gradientName).reparentHere(gradientNode); - } else { //state - if (!modelNode.hasProperty(m_gradientName)) { - qWarning(" GradientLine::updateGradient: no gradient in state"); - return; - } - ModelNode gradientNode = modelNode.nodeProperty(m_gradientName).modelNode(); - QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList(); - for (int i = 0;i < m_stops.size(); i++) { - QmlObjectNode stopObjectNode = stopList.at(i); - stopObjectNode.setVariantProperty("position", roundReal(m_stops.at(i))); - stopObjectNode.setVariantProperty("color", normalizeColor(m_colorList.at(i))); + for (int i = 0;i < m_stops.size(); i++) { + ModelNode gradientStopNode = modelNode.view()->createModelNode("Qt/GradientStop", 4, 7); + gradientStopNode.variantProperty("position") = roundReal(m_stops.at(i)); + gradientStopNode.variantProperty("color") = normalizeColor(m_colorList.at(i)); + gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); + } + modelNode.nodeProperty(m_gradientName).reparentHere(gradientNode); + } else { //state + if (!modelNode.hasProperty(m_gradientName)) { + qWarning(" GradientLine::updateGradient: no gradient in state"); + return; + } + ModelNode gradientNode = modelNode.nodeProperty(m_gradientName).modelNode(); + QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList(); + for (int i = 0;i < m_stops.size(); i++) { + QmlObjectNode stopObjectNode = stopList.at(i); + stopObjectNode.setVariantProperty("position", roundReal(m_stops.at(i))); + stopObjectNode.setVariantProperty("color", normalizeColor(m_colorList.at(i))); + } } } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h index 0a8c00ab88cc0775c8da42dfd76c3fc5bfffcc93..84517178643d9141c33cbe7be00a61fa2ae8f279 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h +++ b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h @@ -40,6 +40,7 @@ #include <propertyeditorvalue.h> #include <qmlitemnode.h> #include <QDialog> +#include <QLinearGradient> QT_BEGIN_NAMESPACE class QtColorButton; @@ -65,7 +66,7 @@ public: 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; } + void setShowArrow(bool b) { m_showArrow = b; } signals: void colorChanged(); @@ -172,6 +173,7 @@ class GradientLine : public QWidget { 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); @@ -184,6 +186,8 @@ public: 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(); @@ -193,11 +197,14 @@ 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 *); + void mousePressEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); @@ -215,10 +222,13 @@ private: 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 {