21 #include <QStyleOptionFrameV3> 22 #include <QMouseEvent> 24 #define MARKER_WIDTH 11 25 #define MARKER_HEIGHT 14 26 #define MARKER_GAP 1.5 27 #define MARGIN_BOTTOM ( MARKER_HEIGHT + 2 ) 28 #define MARGIN_X ( MARKER_WIDTH / 2 ) 29 #define FRAME_MARGIN 2 30 #define CLICK_THRESHOLD ( MARKER_WIDTH / 2 + 3 ) 37 mStops = mGradient.
stops();
39 if ( sOuterTriangle.isEmpty() )
47 if ( sInnerTriangle.isEmpty() )
56 setFocusPolicy( Qt::StrongFocus );
57 setAcceptDrops(
true );
63 mStops = mGradient.
stops();
72 return QSize( 200, 80 );
78 QPainter painter(
this );
80 QRect frameRect( rect().x() +
MARGIN_X, rect().y(),
85 QStyleOptionFrame option;
86 option.initFrom(
this );
87 option.state = hasFocus() ? QStyle::State_KeyboardFocusChange : QStyle::State_None;
88 option.rect = frameRect;
89 style()->drawPrimitive( QStyle::PE_Frame, &option, &painter );
94 QStyleOptionFocusRect option;
95 option.initFrom(
this );
96 option.state = QStyle::State_KeyboardFocusChange;
97 option.rect = frameRect;
98 style()->drawPrimitive( QStyle::PE_FrameFocusRect, &option, &painter );
102 QBrush checkBrush = QBrush( transparentBackground() );
103 painter.setBrush( checkBrush );
104 painter.setPen( Qt::NoPen );
110 painter.drawRect( box );
113 for (
int i = 0; i < box.width() + 1; ++i )
115 QPen pen( mGradient.
color( static_cast< double >( i ) / box.width() ) );
116 painter.setPen( pen );
117 painter.drawLine( box.left() + i, box.top(), box.left() + i, box.height() + 1 );
121 int markerTop = frameRect.bottom() + 1;
122 drawStopMarker( painter, QPoint( box.left(), markerTop ), mGradient.
color1(), mSelectedStop == 0 );
123 drawStopMarker( painter, QPoint( box.right(), markerTop ), mGradient.
color2(), mSelectedStop == mGradient.
count() - 1 );
125 const auto constMStops = mStops;
128 int x = stop.offset * box.width() + box.left();
129 drawStopMarker( painter, QPoint( x, markerTop ), stop.color, mSelectedStop == i );
138 if ( index > 0 && index < mGradient.
count() - 1 )
143 const auto constMStops = mStops;
146 if ( stop == selectedStop )
154 mSelectedStop = index;
161 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
163 return mStops.at( mSelectedStop - 1 );
165 else if ( mSelectedStop == 0 )
177 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
179 mStops[ mSelectedStop - 1 ].color = color;
182 else if ( mSelectedStop == 0 )
196 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
198 mStops[ mSelectedStop - 1 ].offset = offset;
207 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
209 mStops[ mSelectedStop - 1 ].color = color;
210 mStops[ mSelectedStop - 1 ].offset = offset;
213 else if ( mSelectedStop == 0 )
228 if ( selectedStopIsMovable() )
231 double stopOffset = mStops.at( mSelectedStop - 1 ).offset;
232 mStops.removeAt( mSelectedStop - 1 );
235 int closest = findClosestStop( relativePositionToPoint( stopOffset ) );
259 if ( e->buttons() & Qt::LeftButton )
261 if ( selectedStopIsMovable() )
263 double offset = pointToRelativePosition( e->pos().x() );
267 mStops[ mSelectedStop - 1 ].offset = offset;
277 int QgsGradientStopEditor::findClosestStop(
int x,
int threshold )
const 279 int closestStop = -1;
280 int closestDiff = std::numeric_limits<int>::max();
281 int currentDiff = std::numeric_limits<int>::max();
287 const auto constStops = mGradient.
stops();
290 currentDiff = std::abs( relativePositionToPoint( stop.offset ) + 1 - x );
291 if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
294 closestDiff = currentDiff;
300 currentDiff = std::abs( relativePositionToPoint( 0.0 ) + 1 - x );
301 if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
304 closestDiff = currentDiff;
308 currentDiff = std::abs( relativePositionToPoint( 1.0 ) + 1 - x );
309 if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
311 closestStop = mGradient.
count() - 1;
323 if ( closestStop >= 0 )
334 if ( e->buttons() & Qt::LeftButton )
337 double offset = pointToRelativePosition( e->pos().x() );
339 mSelectedStop = mStops.length();
349 if ( ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) )
355 else if ( e->key() == Qt::Key_Left || e->key() == Qt::Key_Right )
357 if ( selectedStopIsMovable() )
362 if ( e->modifiers() & Qt::ShiftModifier )
365 if ( e->key() == Qt::Key_Left )
368 mStops[ mSelectedStop - 1 ].offset = qBound( 0.0, mStops[ mSelectedStop - 1 ].offset + offsetDiff, 1.0 );
377 QWidget::keyPressEvent( e );
380 QPixmap QgsGradientStopEditor::transparentBackground()
382 static QPixmap sTranspBkgrd;
384 if ( sTranspBkgrd.isNull() )
390 void QgsGradientStopEditor::drawStopMarker( QPainter &painter, QPoint topMiddle,
const QColor &color,
bool selected )
393 painter.setRenderHint( QPainter::Antialiasing );
394 painter.setBrush( selected ? QColor( 150, 150, 150 ) : Qt::white );
395 painter.setPen( selected ? Qt::black : QColor( 150, 150, 150 ) );
397 painter.translate( std::round( topMiddle.x() -
MARKER_WIDTH / 2.0 ) + 0.5, topMiddle.y() + 0.5 );
398 painter.drawPolygon( sOuterTriangle );
401 painter.setBrush( QBrush( transparentBackground() ) );
402 painter.setPen( Qt::NoPen );
403 painter.drawPolygon( sInnerTriangle );
406 painter.setBrush( color );
407 painter.drawPolygon( sInnerTriangle );
411 double QgsGradientStopEditor::pointToRelativePosition(
int x )
const 418 else if ( x >= right )
421 return static_cast< double >( x - left ) / ( right - left );
424 int QgsGradientStopEditor::relativePositionToPoint(
double position )
const 431 else if ( position >= 1.0 )
434 return left + ( right - left ) * position;
437 bool QgsGradientStopEditor::selectedStopIsMovable()
const 440 return mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1;
450 if ( mimeColor.isValid() )
453 e->acceptProposedAction();
460 bool hasAlpha =
false;
463 if ( mimeColor.isValid() )
466 e->acceptProposedAction();
469 double offset = pointToRelativePosition( e->pos().x() );
471 mSelectedStop = mStops.length();
QgsGradientStopEditor(QWidget *parent=nullptr, QgsGradientColorRamp *ramp=nullptr)
Constructor for QgsGradientStopEditor.
void setColor2(const QColor &color)
Sets the gradient end color.
Represents a color stop within a QgsGradientColorRamp color ramp.
void changed()
Emitted when the gradient ramp is changed by a user.
QColor color2() const
Returns the gradient end color.
void setSelectedStopDetails(const QColor &color, double offset)
Sets the color and offset for the current selected stop.
void setColor1(const QColor &color)
Sets the color for the first stop.
static QPixmap getThemePixmap(const QString &name)
Helper to get a theme icon as a pixmap.
void deleteSelectedStop()
Deletes the current selected stop.
void mouseMoveEvent(QMouseEvent *event) override
void setGradientRamp(const QgsGradientColorRamp &ramp)
Sets the current ramp shown in the editor.
void setStops(const QgsGradientStopsList &stops)
Sets the list of intermediate gradient stops for the ramp.
QgsGradientStopsList stops() const
Returns the list of intermediate gradient stops for the ramp.
void setColor2(const QColor &color)
Sets the color for the last stop.
void dropEvent(QDropEvent *e) override
void selectedStopChanged(const QgsGradientStop &stop)
Emitted when the current selected stop changes.
void paintEvent(QPaintEvent *event) override
void setSelectedStopColor(const QColor &color)
Sets the color for the current selected stop.
QSize sizeHint() const override
void mousePressEvent(QMouseEvent *event) override
void dragEnterEvent(QDragEnterEvent *e) override
QColor color(double value) const override
Returns the color corresponding to a specified value.
QgsGradientStop selectedStop() const
Returns details about the currently selected stop.
void mouseDoubleClickEvent(QMouseEvent *event) override
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
QColor color1() const
Returns the gradient start color.
void keyPressEvent(QKeyEvent *event) override
void setSelectedStopOffset(double offset)
Sets the offset for the current selected stop.
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
void setColor1(const QColor &color)
Sets the gradient start color.
int count() const override
Returns number of defined colors, or -1 if undefined.
void selectStop(int index)
Sets the currently selected stop.