6#include <QtGui/qcolor.h>
8#include <QtCore/qhash.h>
22 return d_ptr->m_position;
27 return d_ptr->m_color;
32 return d_ptr->m_model;
37 d_ptr->m_color = color;
42 d_ptr->m_position = position;
46 : d_ptr(
new QtGradientStopPrivate())
48 d_ptr->m_model = model;
58 Q_DECLARE_PUBLIC(QtGradientStopsModel)
81 return d_ptr->m_posToStop;
86 if (d_ptr->m_posToStop.contains(pos))
87 return d_ptr->m_posToStop[pos];
93 PositionStopMap gradStops = stops();
94 if (gradStops.isEmpty())
95 return QColor::fromRgbF(pos, pos, pos, 1.0);
96 if (gradStops.contains(pos))
97 return gradStops[pos]->color();
100 auto itStop = gradStops.constFind(pos);
101 if (itStop == gradStops.constBegin()) {
103 return itStop.value()->color();
105 if (itStop == --gradStops.constEnd()) {
107 return itStop.value()->color();
109 auto itPrev = itStop;
110 auto itNext = itStop;
114 double prevX = itPrev.key();
115 double nextX = itNext.key();
117 double coefX = (pos - prevX) / (nextX - prevX);
118 QColor prevCol = itPrev.value()->color();
119 QColor nextCol = itNext.value()->color();
122 newColor.setRgbF((nextCol.redF() - prevCol.redF() ) * coefX + prevCol.redF(),
123 (nextCol.greenF() - prevCol.greenF()) * coefX + prevCol.greenF(),
124 (nextCol.blueF() - prevCol.blueF() ) * coefX + prevCol.blueF(),
125 (nextCol.alphaF() - prevCol.alphaF()) * coefX + prevCol.alphaF());
131 return d_ptr->m_selection.keys();
136 return d_ptr->m_current;
141 if (d_ptr->m_selection.contains(stop))
153 if (d_ptr->m_posToStop.contains(newPos))
156 stop->setPosition(newPos);
157 stop->setColor(color);
159 d_ptr->m_posToStop[newPos] = stop;
160 d_ptr->m_stopToPos[stop] = newPos;
162 emit stopAdded(stop);
169 if (!d_ptr->m_stopToPos.contains(stop))
175 emit stopRemoved(stop);
177 qreal pos = d_ptr->m_stopToPos[stop];
178 d_ptr->m_stopToPos.remove(stop);
179 d_ptr->m_posToStop.remove(pos);
185 if (!d_ptr->m_stopToPos.contains(stop))
187 if (d_ptr->m_posToStop.contains(newPos))
192 else if (newPos < 0.0)
195 emit stopMoved(stop, newPos);
197 const qreal oldPos = stop->position();
198 stop->setPosition(newPos);
199 d_ptr->m_stopToPos[stop] = newPos;
200 d_ptr->m_posToStop.remove(oldPos);
201 d_ptr->m_posToStop[newPos] = stop;
208 if (!d_ptr->m_stopToPos.contains(stop1))
210 if (!d_ptr->m_stopToPos.contains(stop2))
213 emit stopsSwapped(stop1, stop2);
215 const qreal pos1 = stop1->position();
216 const qreal pos2 = stop2->position();
217 stop1->setPosition(pos2);
218 stop2->setPosition(pos1);
219 d_ptr->m_stopToPos[stop1] = pos2;
220 d_ptr->m_stopToPos[stop2] = pos1;
221 d_ptr->m_posToStop[pos1] = stop2;
222 d_ptr->m_posToStop[pos2] = stop1;
227 if (!d_ptr->m_stopToPos.contains(stop))
229 if (stop->color() == newColor)
232 emit stopChanged(stop, newColor);
234 stop->setColor(newColor);
239 if (!d_ptr->m_stopToPos.contains(stop))
241 bool selected = d_ptr->m_selection.contains(stop);
242 if (select == selected)
245 emit stopSelected(stop, select);
248 d_ptr->m_selection[stop] =
true;
250 d_ptr->m_selection.remove(stop);
255 if (stop && !d_ptr->m_stopToPos.contains(stop))
260 emit currentStopChanged(stop);
262 d_ptr->m_current = stop;
267 PositionStopMap stopList = stops();
268 auto itStop = stopList.cbegin();
269 while (itStop != stopList.constEnd()) {
280 PositionStopMap stopList = stops();
281 auto itStop = stopList.cend();
282 while (itStop != stopList.constBegin()) {
296 QMap<qreal, QtGradientStop *> stopsToClone = stops();
297 for (
auto it = stopsToClone.cbegin(), end = stopsToClone.cend(); it != end; ++it)
298 model->addStop(it.key(), it.value()->color());
309 double newPos = newPosition;
316 if (newPos == current->position())
319 double offset = newPos - current->position();
325 double maxOffset = 1.0 - last->position();
326 double minOffset = -first->position();
328 if (offset > maxOffset)
330 else if (offset < minOffset)
338 bool forward = (offset > 0) ?
false :
true;
340 PositionStopMap stopList;
342 const auto selected = selectedStops();
343 for (QtGradientStop *stop : selected)
344 stopList[stop->position()] = stop;
345 stopList[current->position()] = current;
347 auto itStop = forward ? stopList.cbegin() : stopList.cend();
348 while (itStop != (forward ? stopList.constEnd() : stopList.constBegin())) {
352 double pos = stop->position() + offset;
362 if (oldStop && !stopList.values().contains(oldStop))
373 const auto stopsList = stops().values();
374 for (QtGradientStop *stop : stopsList)
380 const auto stopsList = selectedStops();
381 for (QtGradientStop *stop : stopsList)
382 selectStop(stop,
false);
387 QMap<qreal, QtGradientStop *> stopsMap = stops();
388 QHash<QtGradientStop *,
bool> swappedList;
389 for (
auto itStop = stopsMap.keyValueEnd(), begin = stopsMap.keyValueBegin(); itStop != begin;) {
392 if (swappedList.contains(stop))
394 const double newPos = 1.0 - (*itStop).first;
395 if (stopsMap.contains(newPos)) {
397 swappedList[swapped] =
true;
400 moveStop(stop, newPos);
407 const auto stopsMap = stops();
408 for (
auto it = stopsMap.cbegin(), end = stopsMap.cend(); it != end; ++it)
414 const auto selected = selectedStops();
415 for (QtGradientStop *stop : selected)
QtGradientStopsModel * m_model
QtGradientStopsModel * gradientModel() const
QHash< QtGradientStop *, bool > m_selection
QtGradientStop * m_current
QHash< QtGradientStop *, qreal > m_stopToPos
void selectStop(QtGradientStop *stop, bool select)
QList< QtGradientStop * > selectedStops() const
QtGradientStopsModel * clone() const
void removeStop(QtGradientStop *stop)
void changeStop(QtGradientStop *stop, QColor newColor)
QtGradientStop * at(qreal pos) const
bool isSelected(QtGradientStop *stop) const
QtGradientStop * currentStop() const
QtGradientStop * addStop(qreal pos, QColor color)
~QtGradientStopsModel() override
QtGradientStop * firstSelected() const
void moveStops(double newPosition)
QColor color(qreal pos) const
QtGradientStopsModel(QObject *parent=nullptr)
void swapStops(QtGradientStop *stop1, QtGradientStop *stop2)
PositionStopMap stops() const
QtGradientStop * lastSelected() const
void moveStop(QtGradientStop *stop, qreal newPos)
void setCurrentStop(QtGradientStop *stop)
Combined button and popup list for selecting options.