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 );
127 int x = stop.
offset * box.width() + box.left();
128 drawStopMarker( painter, QPoint( x, markerTop ), stop.
color, mSelectedStop == i );
137 if ( index > 0 && index < mGradient.
count() - 1 )
144 if ( stop == selectedStop )
152 mSelectedStop = index;
159 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
161 return mStops.at( mSelectedStop - 1 );
163 else if ( mSelectedStop == 0 )
175 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
177 mStops[ mSelectedStop - 1 ].color = color;
180 else if ( mSelectedStop == 0 )
194 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
196 mStops[ mSelectedStop - 1 ].offset = offset;
205 if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
207 mStops[ mSelectedStop - 1 ].color = color;
208 mStops[ mSelectedStop - 1 ].offset = offset;
211 else if ( mSelectedStop == 0 )
226 if ( selectedStopIsMovable() )
229 double stopOffset = mStops.at( mSelectedStop - 1 ).offset;
230 mStops.removeAt( mSelectedStop - 1 );
233 int closest = findClosestStop( relativePositionToPoint( stopOffset ) );
257 if ( e->buttons() & Qt::LeftButton )
259 if ( selectedStopIsMovable() )
261 double offset = pointToRelativePosition( e->pos().x() );
265 mStops[ mSelectedStop - 1 ].offset = offset;
275 int QgsGradientStopEditor::findClosestStop(
int x,
int threshold )
const 277 int closestStop = -1;
278 int closestDiff = INT_MAX;
279 int currentDiff = INT_MAX;
287 currentDiff = std::abs( relativePositionToPoint( stop.
offset ) + 1 - x );
288 if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
291 closestDiff = currentDiff;
297 currentDiff = std::abs( relativePositionToPoint( 0.0 ) + 1 - x );
298 if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
301 closestDiff = currentDiff;
305 currentDiff = std::abs( relativePositionToPoint( 1.0 ) + 1 - x );
306 if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
308 closestStop = mGradient.
count() - 1;
320 if ( closestStop >= 0 )
331 if ( e->buttons() & Qt::LeftButton )
334 double offset = pointToRelativePosition( e->pos().x() );
336 mSelectedStop = mStops.length();
346 if ( ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) )
352 else if ( e->key() == Qt::Key_Left || e->key() == Qt::Key_Right )
354 if ( selectedStopIsMovable() )
359 if ( e->modifiers() & Qt::ShiftModifier )
362 if ( e->key() == Qt::Key_Left )
365 mStops[ mSelectedStop - 1 ].offset = qBound( 0.0, mStops[ mSelectedStop - 1 ].offset + offsetDiff, 1.0 );
374 QWidget::keyPressEvent( e );
377 QPixmap QgsGradientStopEditor::transparentBackground()
379 static QPixmap sTranspBkgrd;
381 if ( sTranspBkgrd.isNull() )
387 void QgsGradientStopEditor::drawStopMarker( QPainter &painter, QPoint topMiddle,
const QColor &color,
bool selected )
390 painter.setRenderHint( QPainter::Antialiasing );
391 painter.setBrush( selected ? QColor( 150, 150, 150 ) : Qt::white );
392 painter.setPen( selected ? Qt::black : QColor( 150, 150, 150 ) );
394 painter.translate( std::round( topMiddle.x() -
MARKER_WIDTH / 2.0 ) + 0.5, topMiddle.y() + 0.5 );
395 painter.drawPolygon( sOuterTriangle );
398 painter.setBrush( QBrush( transparentBackground() ) );
399 painter.setPen( Qt::NoPen );
400 painter.drawPolygon( sInnerTriangle );
403 painter.setBrush( color );
404 painter.drawPolygon( sInnerTriangle );
408 double QgsGradientStopEditor::pointToRelativePosition(
int x )
const 415 else if ( x >= right )
418 return static_cast< double >( x - left ) / ( right - left );
421 int QgsGradientStopEditor::relativePositionToPoint(
double position )
const 428 else if ( position >= 1.0 )
431 return left + ( right - left ) * position;
434 bool QgsGradientStopEditor::selectedStopIsMovable()
const 437 return mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1;
447 if ( mimeColor.isValid() )
450 e->acceptProposedAction();
457 bool hasAlpha =
false;
460 if ( mimeColor.isValid() )
463 e->acceptProposedAction();
466 double offset = pointToRelativePosition( e->pos().x() );
468 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.
double offset
Relative positional offset, between 0 and 1.
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.
QColor color
Gradient color at stop.
int count() const override
Returns number of defined colors, or -1 if undefined.
void selectStop(int index)
Sets the currently selected stop.