21 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
   22 #include <QStyleOptionFrameV3> 
   24 #include <QStyleOptionFrame> 
   26 #include <QMouseEvent> 
   28 #define MARKER_WIDTH 11 
   29 #define MARKER_HEIGHT 14 
   30 #define MARKER_GAP 1.5 
   31 #define MARGIN_BOTTOM ( MARKER_HEIGHT + 2 ) 
   32 #define MARGIN_X ( MARKER_WIDTH / 2 ) 
   33 #define FRAME_MARGIN 2 
   34 #define CLICK_THRESHOLD ( MARKER_WIDTH / 2 + 3 ) 
   41   mStops = mGradient.
stops();
 
   43   if ( sOuterTriangle.isEmpty() )
 
   51   if ( sInnerTriangle.isEmpty() )
 
   60   setFocusPolicy( Qt::StrongFocus );
 
   61   setAcceptDrops( 
true );
 
   67   mStops = mGradient.
stops();
 
   76   return QSize( 200, 80 );
 
   82   QPainter painter( 
this );
 
   84   QRect frameRect( rect().x() + 
MARGIN_X, rect().y(),
 
   89   QStyleOptionFrame option;
 
   90   option.initFrom( 
this );
 
   91   option.state = hasFocus() ? QStyle::State_KeyboardFocusChange : QStyle::State_None;
 
   92   option.rect = frameRect;
 
   93   style()->drawPrimitive( QStyle::PE_Frame, &option, &painter );
 
   98     QStyleOptionFocusRect option;
 
   99     option.initFrom( 
this );
 
  100     option.state = QStyle::State_KeyboardFocusChange;
 
  101     option.rect = frameRect;
 
  102     style()->drawPrimitive( QStyle::PE_FrameFocusRect, &option, &painter );
 
  106   QBrush checkBrush = QBrush( transparentBackground() );
 
  107   painter.setBrush( checkBrush );
 
  108   painter.setPen( Qt::NoPen );
 
  114   painter.drawRect( box );
 
  117   for ( 
int i = 0; i < box.width() + 1; ++i )
 
  119     QPen pen( mGradient.
color( 
static_cast< double >( i ) / box.width() ) );
 
  120     painter.setPen( pen );
 
  121     painter.drawLine( box.left() + i, box.top(), box.left() + i, box.height() + 1 );
 
  125   int markerTop = frameRect.bottom() + 1;
 
  126   drawStopMarker( painter, QPoint( box.left(), markerTop ), mGradient.
color1(), mSelectedStop == 0 );
 
  127   drawStopMarker( painter, QPoint( box.right(), markerTop ), mGradient.
color2(), mSelectedStop == mGradient.
count() - 1 );
 
  129   const auto constMStops = mStops;
 
  132     int x = stop.offset * box.width() + box.left();
 
  133     drawStopMarker( painter, QPoint( x, markerTop ), stop.color, mSelectedStop == i );
 
  142   if ( index > 0 && index < mGradient.
count() - 1 )
 
  147     const auto constMStops = mStops;
 
  158   mSelectedStop = index;
 
  165   if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
 
  167     return mStops.at( mSelectedStop - 1 );
 
  169   else if ( mSelectedStop == 0 )
 
  181   if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
 
  183     mStops[ mSelectedStop - 1 ].color = color;
 
  186   else if ( mSelectedStop == 0 )
 
  200   if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
 
  202     mStops[ mSelectedStop - 1 ].offset = offset;
 
  211   if ( mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1 )
 
  213     mStops[ mSelectedStop - 1 ].color = color;
 
  214     mStops[ mSelectedStop - 1 ].offset = offset;
 
  217   else if ( mSelectedStop == 0 )
 
  232   if ( selectedStopIsMovable() )
 
  235     double stopOffset = mStops.at( mSelectedStop - 1 ).offset;
 
  236     mStops.removeAt( mSelectedStop - 1 );
 
  239     int closest = findClosestStop( relativePositionToPoint( stopOffset ) );
 
  263   if ( e->buttons() & Qt::LeftButton )
 
  265     if ( selectedStopIsMovable() )
 
  267       double offset = pointToRelativePosition( e->pos().x() );
 
  271       mStops[ mSelectedStop - 1 ].offset = offset;
 
  281 int QgsGradientStopEditor::findClosestStop( 
int x, 
int threshold )
 const 
  283   int closestStop = -1;
 
  284   int closestDiff = std::numeric_limits<int>::max();
 
  285   int currentDiff = std::numeric_limits<int>::max();
 
  291   const auto constStops = mGradient.
stops();
 
  294     currentDiff = std::abs( relativePositionToPoint( stop.offset ) + 1 - x );
 
  295     if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
 
  298       closestDiff = currentDiff;
 
  304   currentDiff = std::abs( relativePositionToPoint( 0.0 ) + 1 - x );
 
  305   if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
 
  308     closestDiff = currentDiff;
 
  312   currentDiff = std::abs( relativePositionToPoint( 1.0 ) + 1 - x );
 
  313   if ( ( threshold < 0 || currentDiff < threshold ) && currentDiff < closestDiff )
 
  315     closestStop = mGradient.
count() - 1;
 
  327     if ( closestStop >= 0 )
 
  338   if ( e->buttons() & Qt::LeftButton )
 
  341     double offset = pointToRelativePosition( e->pos().x() );
 
  343     mSelectedStop = mStops.length();
 
  353   if ( ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) )
 
  359   else if ( e->key() == Qt::Key_Left ||  e->key() == Qt::Key_Right )
 
  361     if ( selectedStopIsMovable() )
 
  366       if ( e->modifiers() & Qt::ShiftModifier )
 
  369       if ( e->key() == Qt::Key_Left )
 
  372       mStops[ mSelectedStop - 1 ].offset = std::clamp( mStops[ mSelectedStop - 1 ].offset + offsetDiff, 0.0, 1.0 );
 
  381   QWidget::keyPressEvent( e );
 
  384 QPixmap QgsGradientStopEditor::transparentBackground()
 
  386   static QPixmap sTranspBkgrd;
 
  388   if ( sTranspBkgrd.isNull() )
 
  394 void QgsGradientStopEditor::drawStopMarker( QPainter &painter, QPoint topMiddle, 
const QColor &color, 
bool selected )
 
  397   painter.setRenderHint( QPainter::Antialiasing );
 
  398   painter.setBrush( selected ?  QColor( 150, 150, 150 ) : Qt::white );
 
  399   painter.setPen( selected ? Qt::black : QColor( 150, 150, 150 ) );
 
  401   painter.translate( std::round( topMiddle.x() - 
MARKER_WIDTH / 2.0 ) + 0.5, topMiddle.y() + 0.5 );
 
  402   painter.drawPolygon( sOuterTriangle );
 
  405   painter.setBrush( QBrush( transparentBackground() ) );
 
  406   painter.setPen( Qt::NoPen );
 
  407   painter.drawPolygon( sInnerTriangle );
 
  410   painter.setBrush( color );
 
  411   painter.drawPolygon( sInnerTriangle );
 
  414 double QgsGradientStopEditor::pointToRelativePosition( 
int x )
 const 
  421   else if ( x >= right )
 
  424   return static_cast< double >( x - left ) / ( right - left );
 
  427 int QgsGradientStopEditor::relativePositionToPoint( 
double position )
 const 
  434   else if ( position >= 1.0 )
 
  437   return left + ( right - left ) * position;
 
  440 bool QgsGradientStopEditor::selectedStopIsMovable()
 const 
  443   return mSelectedStop > 0 && mSelectedStop < mGradient.
count() - 1;
 
  453   if ( mimeColor.isValid() )
 
  456     e->acceptProposedAction();
 
  463   bool hasAlpha = 
false;
 
  466   if ( mimeColor.isValid() )
 
  469     e->acceptProposedAction();
 
  472     double offset = pointToRelativePosition( e->pos().x() );
 
  474     mSelectedStop = mStops.length();
 
static QPixmap getThemePixmap(const QString &name, const QColor &foreColor=QColor(), const QColor &backColor=QColor(), int size=16)
Helper to get a theme icon as a pixmap.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
void setColor1(const QColor &color)
Sets the gradient start color.
void setColor2(const QColor &color)
Sets the gradient end color.
int count() const override
Returns number of defined colors, or -1 if undefined.
QColor color(double value) const override
Returns the color corresponding to a specified value.
void setStops(const QgsGradientStopsList &stops)
Sets the list of intermediate gradient stops for the ramp.
QColor color1() const
Returns the gradient start color.
QgsGradientStopsList stops() const
Returns the list of intermediate gradient stops for the ramp.
QColor color2() const
Returns the gradient end color.
void setSelectedStopOffset(double offset)
Sets the offset for the current selected stop.
void setColor2(const QColor &color)
Sets the color for the last stop.
void setSelectedStopColor(const QColor &color)
Sets the color for the current selected stop.
void changed()
Emitted when the gradient ramp is changed by a user.
void mousePressEvent(QMouseEvent *event) override
void mouseDoubleClickEvent(QMouseEvent *event) override
QgsGradientStop selectedStop() const
Returns details about the currently selected stop.
void keyPressEvent(QKeyEvent *event) override
void setSelectedStopDetails(const QColor &color, double offset)
Sets the color and offset for the current selected stop.
void deleteSelectedStop()
Deletes the current selected stop.
void paintEvent(QPaintEvent *event) override
void selectStop(int index)
Sets the currently selected stop.
QSize sizeHint() const override
void setColor1(const QColor &color)
Sets the color for the first stop.
void selectedStopChanged(const QgsGradientStop &stop)
Emitted when the current selected stop changes.
QgsGradientStopEditor(QWidget *parent=nullptr, QgsGradientColorRamp *ramp=nullptr)
Constructor for QgsGradientStopEditor.
void dropEvent(QDropEvent *e) override
void mouseMoveEvent(QMouseEvent *event) override
void setGradientRamp(const QgsGradientColorRamp &ramp)
Sets the current ramp shown in the editor.
void dragEnterEvent(QDragEnterEvent *e) override
Represents a color stop within a QgsGradientColorRamp color ramp.
Scoped object for saving and restoring a QPainter object's state.
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.