2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2023-01-04 08:52:22 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2010-08-12 15:43:13 +02:00
|
|
|
|
|
|
|
|
#include "gradientline.h"
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QPainter>
|
|
|
|
|
#include <QMouseEvent>
|
2010-08-12 15:43:13 +02:00
|
|
|
|
|
|
|
|
static inline QPixmap tilePixMap(int size)
|
|
|
|
|
{
|
|
|
|
|
const int checkerbordSize= size;
|
|
|
|
|
QPixmap tilePixmap(checkerbordSize * 2, checkerbordSize * 2);
|
|
|
|
|
tilePixmap.fill(Qt::white);
|
|
|
|
|
QPainter tilePainter(&tilePixmap);
|
|
|
|
|
QColor color(220, 220, 220);
|
|
|
|
|
tilePainter.fillRect(0, 0, checkerbordSize, checkerbordSize, color);
|
|
|
|
|
tilePainter.fillRect(checkerbordSize, checkerbordSize, checkerbordSize, checkerbordSize, color);
|
|
|
|
|
return tilePixmap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace QmlEditorWidgets {
|
|
|
|
|
|
|
|
|
|
void GradientLine::setGradient(const QLinearGradient &gradient)
|
|
|
|
|
{
|
|
|
|
|
m_gradient = gradient;
|
|
|
|
|
m_useGradient = true;
|
2010-12-16 17:46:38 +01:00
|
|
|
readGradient();
|
2010-08-12 15:43:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GradientLine::GradientLine(QWidget *parent) :
|
|
|
|
|
QWidget(parent),
|
|
|
|
|
m_activeColor(Qt::black),
|
2012-12-02 22:07:04 +02:00
|
|
|
m_gradientName(QLatin1String("gradient")),
|
2010-08-12 15:43:13 +02:00
|
|
|
m_colorIndex(0),
|
|
|
|
|
m_dragActive(false),
|
|
|
|
|
m_yOffset(0),
|
|
|
|
|
m_create(false),
|
|
|
|
|
m_active(false),
|
|
|
|
|
m_dragOff(false),
|
|
|
|
|
m_useGradient(true)
|
|
|
|
|
{
|
|
|
|
|
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
|
|
|
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
|
|
|
setFixedHeight(50);
|
|
|
|
|
setMinimumWidth(160);
|
|
|
|
|
resize(160, 50);
|
|
|
|
|
m_colorList << m_activeColor << QColor(Qt::white);
|
|
|
|
|
m_stops << 0 << 1;
|
|
|
|
|
updateGradient();
|
|
|
|
|
setCurrentIndex(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::setGradientName(const QString &newName)
|
|
|
|
|
{
|
|
|
|
|
if (newName == m_gradientName)
|
|
|
|
|
return;
|
|
|
|
|
m_gradientName = newName;
|
|
|
|
|
setup();
|
|
|
|
|
emit gradientNameChanged();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::setActiveColor(const QColor &newColor)
|
|
|
|
|
{
|
|
|
|
|
if (newColor.name() == m_activeColor.name() && newColor.alpha() == m_activeColor.alpha())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_activeColor = newColor;
|
|
|
|
|
m_colorList.removeAt(currentColorIndex());
|
|
|
|
|
m_colorList.insert(currentColorIndex(), m_activeColor);
|
|
|
|
|
updateGradient();
|
2011-03-04 14:10:33 +01:00
|
|
|
emit gradientChanged();
|
|
|
|
|
emit activeColorChanged();
|
2010-08-12 15:43:13 +02:00
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-16 17:46:38 +01:00
|
|
|
void GradientLine::readGradient()
|
2010-08-12 15:43:13 +02:00
|
|
|
{
|
|
|
|
|
if (m_useGradient) {
|
|
|
|
|
m_colorList.clear();
|
|
|
|
|
m_stops.clear();
|
2022-12-19 13:23:53 +01:00
|
|
|
const QGradientStops stops = m_gradient.stops();
|
|
|
|
|
for (const QGradientStop &stop : stops) {
|
2010-08-12 15:43:13 +02:00
|
|
|
m_stops << stop.first;
|
|
|
|
|
m_colorList << stop.second;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
updateGradient();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GradientLine::event(QEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (event->type() == QEvent::ShortcutOverride)
|
|
|
|
|
if (static_cast<QKeyEvent*>(event)->matches(QKeySequence::Delete)) {
|
|
|
|
|
event->accept();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QWidget::event(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::keyPressEvent(QKeyEvent * event)
|
|
|
|
|
{
|
|
|
|
|
if (event->matches(QKeySequence::Delete)) {
|
|
|
|
|
if ((currentColorIndex()) != 0 && (currentColorIndex() < m_stops.size() - 1)) {
|
|
|
|
|
m_dragActive = false;
|
|
|
|
|
m_stops.removeAt(currentColorIndex());
|
|
|
|
|
m_colorList.removeAt(currentColorIndex());
|
|
|
|
|
updateGradient();
|
2011-03-04 14:10:33 +01:00
|
|
|
emit gradientChanged();
|
2010-08-12 15:43:13 +02:00
|
|
|
setCurrentIndex(0);
|
|
|
|
|
//delete item
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
QWidget::keyPressEvent(event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::paintEvent(QPaintEvent *event)
|
|
|
|
|
{
|
|
|
|
|
QWidget::paintEvent(event);
|
|
|
|
|
|
|
|
|
|
QPainter p(this);
|
|
|
|
|
|
|
|
|
|
if (!isEnabled()) {
|
|
|
|
|
p.setBrush(Qt::NoBrush);
|
|
|
|
|
p.setPen(QColor(0x444444));
|
|
|
|
|
p.drawRect(9, 31, width() - 14, height() - 32);
|
|
|
|
|
|
|
|
|
|
p.drawTiledPixmap(10, 32, width() - 16, height() - 34, tilePixMap(8));
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
QLinearGradient linearGradient(QPointF(0, 0), QPointF(width(), 0));
|
|
|
|
|
|
|
|
|
|
for (int i =0; i < m_stops.size(); i++)
|
|
|
|
|
linearGradient.setColorAt(m_stops.at(i), m_colorList.at(i));
|
|
|
|
|
|
|
|
|
|
p.setBrush(Qt::NoBrush);
|
|
|
|
|
p.setPen(QColor(0x444444));
|
|
|
|
|
p.drawRect(9, 31, width() - 14, height() - 32);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p.drawTiledPixmap(9, 31, width() - 16, height() - 34, tilePixMap(8));
|
|
|
|
|
|
|
|
|
|
p.setBrush(linearGradient);
|
|
|
|
|
p.setPen(QColor(0x222222));
|
|
|
|
|
p.drawRect(8, 30, width() - 14, height() - 32);
|
|
|
|
|
p.setPen(QColor(255, 255, 255, 40));
|
|
|
|
|
p.drawRect(9, 31, width() - 16, height() - 34);
|
|
|
|
|
|
|
|
|
|
p.setPen(Qt::black);
|
|
|
|
|
|
|
|
|
|
for (int i =0; i < m_colorList.size(); i++) {
|
|
|
|
|
int localYOffset = 0;
|
|
|
|
|
QColor arrowColor(Qt::black);
|
|
|
|
|
if (i == currentColorIndex()) {
|
|
|
|
|
localYOffset = m_yOffset;
|
|
|
|
|
arrowColor = QColor(0x909090);
|
|
|
|
|
}
|
|
|
|
|
p.setPen(arrowColor);
|
|
|
|
|
if (i == 0 || i == (m_colorList.size() - 1))
|
|
|
|
|
localYOffset = 0;
|
|
|
|
|
|
|
|
|
|
int pos = qreal((width() - 16)) * m_stops.at(i) + 9;
|
|
|
|
|
p.setBrush(arrowColor);
|
|
|
|
|
QVector<QPointF> points;
|
2010-11-10 11:34:26 +01:00
|
|
|
if (localYOffset < -8)
|
|
|
|
|
p.setOpacity(0.5);
|
2010-08-12 15:43:13 +02:00
|
|
|
points.append(QPointF(pos + 0.5, 28.5 + localYOffset)); //triangle
|
|
|
|
|
points.append(QPointF(pos - 3.5, 22.5 + localYOffset));
|
|
|
|
|
points.append(QPointF(pos + 4.5, 22.5 + localYOffset));
|
|
|
|
|
p.setRenderHint(QPainter::Antialiasing, true);
|
|
|
|
|
p.drawPolygon(points);
|
|
|
|
|
p.setRenderHint(QPainter::Antialiasing, false);
|
|
|
|
|
p.setBrush(Qt::NoBrush);
|
|
|
|
|
p.setPen(QColor(0x424242));
|
|
|
|
|
p.drawRect(pos - 4, 9 + localYOffset, 10, 11);
|
|
|
|
|
|
|
|
|
|
p.drawTiledPixmap(pos - 4, 9 + localYOffset, 9, 10, tilePixMap(5));
|
|
|
|
|
p.setPen(QColor(0x424242));
|
|
|
|
|
p.setBrush(m_colorList.at(i));
|
|
|
|
|
p.drawRect(pos - 5, 8 + localYOffset, 10, 11);
|
|
|
|
|
p.setBrush(Qt::NoBrush);
|
|
|
|
|
p.setPen(QColor(255, 255, 255, 30));
|
|
|
|
|
p.drawRect(pos - 4, 9 + localYOffset, 8, 9);
|
2010-11-10 11:34:26 +01:00
|
|
|
p.setOpacity(1);
|
2010-08-12 15:43:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::mousePressEvent(QMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (event->button() == Qt::LeftButton) {
|
|
|
|
|
event->accept();
|
|
|
|
|
int xPos = event->pos().x();
|
|
|
|
|
int yPos = event->pos().y();
|
2010-11-10 11:34:26 +01:00
|
|
|
m_dragStart = event->pos();
|
2010-08-12 15:43:13 +02:00
|
|
|
|
|
|
|
|
int draggedIndex = -1;
|
|
|
|
|
m_create = false;
|
|
|
|
|
m_dragActive = false;
|
|
|
|
|
if ((yPos > 10) && (yPos < 30))
|
|
|
|
|
for (int i =0; i < m_stops.size(); i++) {
|
|
|
|
|
int pos = qreal((width() - 16)) * m_stops.at(i) + 9;
|
2010-11-10 11:34:26 +01:00
|
|
|
if (((xPos + 8) > pos) && ((xPos - 8) < pos)) {
|
2010-08-12 15:43:13 +02:00
|
|
|
draggedIndex = i;
|
|
|
|
|
m_dragActive = true;
|
|
|
|
|
setCurrentIndex(draggedIndex);
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (draggedIndex == -1)
|
|
|
|
|
m_create = true;
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
if (event->button() == Qt::LeftButton) {
|
|
|
|
|
event->accept();
|
2010-11-10 11:34:26 +01:00
|
|
|
|
|
|
|
|
if (m_dragActive) {
|
|
|
|
|
m_yOffset += event->pos().y() - 14;
|
|
|
|
|
if (m_yOffset > 0) {
|
|
|
|
|
m_yOffset = 0;
|
|
|
|
|
} else if ((m_yOffset < - 8) && (currentColorIndex()) != 0 && (currentColorIndex() < m_stops.size() - 1)) {
|
|
|
|
|
m_yOffset = 0;
|
|
|
|
|
m_dragActive = false;
|
|
|
|
|
m_stops.removeAt(currentColorIndex());
|
|
|
|
|
m_colorList.removeAt(currentColorIndex());
|
|
|
|
|
updateGradient();
|
2011-03-04 14:10:33 +01:00
|
|
|
emit gradientChanged();
|
2010-11-10 11:34:26 +01:00
|
|
|
setCurrentIndex(0);
|
|
|
|
|
//delete item
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-12 15:43:13 +02:00
|
|
|
if (m_dragActive == false && m_create) {
|
|
|
|
|
qreal stopPos = qreal(event->pos().x() - 9) / qreal((width() - 15));
|
|
|
|
|
int index = -1;
|
|
|
|
|
for (int i =0; i < m_stops.size() - 1; i++) {
|
|
|
|
|
if ((stopPos > m_stops.at(i)) && (index == -1))
|
|
|
|
|
index = i +1;
|
|
|
|
|
}
|
2010-11-10 11:34:26 +01:00
|
|
|
if (index != -1 && (m_useGradient) && abs(m_dragStart.x() - event->pos().x()) < 10) { //creating of items only in base state
|
2010-08-12 15:43:13 +02:00
|
|
|
m_stops.insert(index, stopPos);
|
|
|
|
|
m_colorList.insert(index, QColor(Qt::white));
|
|
|
|
|
setCurrentIndex(index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_dragActive = false;
|
|
|
|
|
m_yOffset = 0;
|
|
|
|
|
updateGradient();
|
2011-03-04 14:10:33 +01:00
|
|
|
emit gradientChanged();
|
2010-08-12 15:43:13 +02:00
|
|
|
update();
|
|
|
|
|
setFocus(Qt::MouseFocusReason);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (m_dragActive) {
|
|
|
|
|
event->accept();
|
|
|
|
|
int pos = qreal((width() - 20)) * m_stops.at(currentColorIndex()) + 8;
|
2010-11-10 11:34:26 +01:00
|
|
|
|
|
|
|
|
m_dragOff = false;
|
|
|
|
|
int xDistance = event->pos().x() - pos;
|
|
|
|
|
qreal distance = qreal(xDistance) / qreal((width() - 20));
|
|
|
|
|
qreal newStopPosition = m_stops.at(currentColorIndex()) + distance;
|
|
|
|
|
if (newStopPosition > 0.98) //snap to 1
|
|
|
|
|
newStopPosition = 1;
|
|
|
|
|
if (newStopPosition < 0.02) //snap to 0
|
|
|
|
|
newStopPosition = 0;
|
|
|
|
|
if ((newStopPosition >=0) && (newStopPosition <= 1))
|
|
|
|
|
m_stops[currentColorIndex()] = newStopPosition;
|
|
|
|
|
m_yOffset += event->pos().y() - 14;
|
|
|
|
|
if (m_yOffset > 0)
|
|
|
|
|
m_yOffset = 0;
|
|
|
|
|
else if ((m_yOffset < - 10))
|
|
|
|
|
m_yOffset = -10;
|
|
|
|
|
|
2010-08-12 15:43:13 +02:00
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::setup()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::updateGradient()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
} else {
|
|
|
|
|
if (!active())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GradientLine::setCurrentIndex(int i)
|
|
|
|
|
{
|
|
|
|
|
if (i == m_colorIndex)
|
|
|
|
|
return;
|
|
|
|
|
m_colorIndex = i;
|
|
|
|
|
m_activeColor = m_colorList.at(i);
|
|
|
|
|
emit activeColorChanged();
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} //QmlEditorWidgets
|