23#include <QColorDialog> 
   25#include <QInputDialog> 
   27#include <QTableWidget> 
   31#include <qwt_global.h> 
   32#include <qwt_plot_canvas.h> 
   34#include <qwt_plot_curve.h> 
   35#include <qwt_plot_grid.h> 
   36#include <qwt_plot_marker.h> 
   37#include <qwt_plot_picker.h> 
   38#include <qwt_picker_machine.h> 
   39#include <qwt_plot_layout.h> 
   40#include <qwt_symbol.h> 
   41#include <qwt_legend.h> 
   42#include <qwt_scale_div.h> 
   43#include <qwt_scale_map.h> 
   48  , mCurrentPlotColorComponent( -1 )
 
   49  , mCurrentPlotMarkerIndex( 0 )
 
   54  mColorWidget->setColorModelEditable( 
false );
 
   56  mStopColorSpec->addItem( tr( 
"RGB" ), 
static_cast< int >( QColor::Spec::Rgb ) );
 
   57  mStopColorSpec->addItem( tr( 
"HSV" ), 
static_cast< int >( QColor::Spec::Hsv ) );
 
   58  mStopColorSpec->addItem( tr( 
"HSL" ), 
static_cast< int >( QColor::Spec::Hsl ) );
 
   59  mStopColorSpec->addItem( tr( 
"CMYK" ), 
static_cast< int >( QColor::Spec::Cmyk ) );
 
   60  mStopColorSpec->setCurrentIndex( mStopColorSpec->findData( 
static_cast< int >( 
ramp.
colorSpec() ) ) );
 
   64  mStopDirection->setCurrentIndex( mStopColorSpec->findData( 
static_cast< int >( 
ramp.
direction() ) ) );
 
   66  mStopDirection->setEnabled( hasDirection( 
static_cast< QColor::Spec
>( mStopColorSpec->currentData().toInt() ) ) );
 
   68  connect( mStopColorSpec, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, [ = ]
 
   70    const QColor::Spec colorSpec = 
static_cast< QColor::Spec
>( mStopColorSpec->currentData().toInt() );
 
   71    mStopDirection->setEnabled( hasDirection( colorSpec ) );
 
   73    if ( colorSpec != mColorWidget->color().spec() )
 
   75      mColorWidget->setColor( mColorWidget->color().convertTo( colorSpec ) );
 
   81    mStopEditor->setSelectedStopColorSpec( colorSpec );
 
   84  connect( mStopDirection, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, [ = ]
 
   89    mStopEditor->setSelectedStopDirection( 
static_cast< Qgis::AngularDirection >( mStopDirection->currentData().toInt() ) );
 
   92  connect( cboType, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsGradientColorRampDialog::cboType_currentIndexChanged );
 
   93  connect( btnInformation, &QPushButton::pressed, 
this, &QgsGradientColorRampDialog::btnInformation_pressed );
 
   94  connect( mPositionSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsGradientColorRampDialog::mPositionSpinBox_valueChanged );
 
   95  connect( mPlotHueCheckbox, &QCheckBox::toggled, 
this, &QgsGradientColorRampDialog::mPlotHueCheckbox_toggled );
 
   96  connect( mPlotLightnessCheckbox, &QCheckBox::toggled, 
this, &QgsGradientColorRampDialog::mPlotLightnessCheckbox_toggled );
 
   97  connect( mPlotSaturationCheckbox, &QCheckBox::toggled, 
this, &QgsGradientColorRampDialog::mPlotSaturationCheckbox_toggled );
 
   98  connect( mPlotAlphaCheckbox, &QCheckBox::toggled, 
this, &QgsGradientColorRampDialog::mPlotAlphaCheckbox_toggled );
 
  100  setWindowModality( Qt::WindowModal );
 
  103  mPositionSpinBox->setShowClearButton( 
false );
 
  104  btnColor1->setAllowOpacity( 
true );
 
  105  btnColor1->setColorDialogTitle( tr( 
"Select Ramp Color" ) );
 
  106  btnColor1->setContext( QStringLiteral( 
"symbology" ) );
 
  107  btnColor1->setShowNoColor( 
true );
 
  108  btnColor1->setNoColorString( tr( 
"Transparent" ) );
 
  109  btnColor2->setAllowOpacity( 
true );
 
  110  btnColor2->setColorDialogTitle( tr( 
"Select Ramp Color" ) );
 
  111  btnColor2->setContext( QStringLiteral( 
"symbology" ) );
 
  112  btnColor2->setShowNoColor( 
true );
 
  113  btnColor2->setNoColorString( tr( 
"Transparent" ) );
 
  114  updateColorButtons();
 
  119  cboType->blockSignals( 
true );
 
  120  cboType->addItem( tr( 
"Discrete" ) );
 
  121  cboType->addItem( tr( 
"Continuous" ) );
 
  123    cboType->setCurrentIndex( 0 );
 
  125    cboType->setCurrentIndex( 1 );
 
  126  cboType->blockSignals( 
false );
 
  128  if ( mRamp.
info().isEmpty() )
 
  129    btnInformation->setEnabled( 
false );
 
  131  mStopEditor->setGradientRamp( mRamp );
 
  138  mPlot->setFrameStyle( QFrame::NoFrame );
 
  139  QFrame *plotCanvasFrame = 
dynamic_cast<QFrame *
>( mPlot->canvas() );
 
  140  if ( plotCanvasFrame )
 
  141    plotCanvasFrame->setFrameStyle( QFrame::NoFrame );
 
  143  mPlot->setAxisScale( QwtPlot::yLeft, 0.0, 1.0 );
 
  144  mPlot->enableAxis( QwtPlot::yLeft, 
false );
 
  147  QwtPlotGrid *grid = 
new QwtPlotGrid();
 
  148  QwtScaleDiv gridDiv( 0.0, 1.0, QList<double>(), QList<double>(), QList<double>() << 0.2 << 0.4 << 0.6 << 0.8 );
 
  149  grid->setXDiv( gridDiv );
 
  150  grid->setYDiv( gridDiv );
 
  151  grid->setPen( QPen( QColor( 0, 0, 0, 50 ) ) );
 
  152  grid->attach( mPlot );
 
  154  mLightnessCurve = 
new QwtPlotCurve();
 
  155  mLightnessCurve->setTitle( tr( 
"Lightness" ) );
 
  156  mLightnessCurve->setPen( QPen( QColor( 70, 150, 255 ), 0.0 ) ),
 
  157                  mLightnessCurve->setRenderHint( QwtPlotItem::RenderAntialiased, 
true );
 
  158  mLightnessCurve->attach( mPlot );
 
  160  mHueCurve = 
new QwtPlotCurve();
 
  161  mHueCurve->setTitle( tr( 
"Hue" ) );
 
  162  mHueCurve->setPen( QPen( QColor( 255, 215, 70 ), 0.0 ) ),
 
  163            mHueCurve->setRenderHint( QwtPlotItem::RenderAntialiased, 
true );
 
  164  mHueCurve->attach( mPlot );
 
  166  mSaturationCurve = 
new QwtPlotCurve();
 
  167  mSaturationCurve->setTitle( tr( 
"Saturation" ) );
 
  168  mSaturationCurve->setPen( QPen( QColor( 255, 70, 150 ), 0.0 ) ),
 
  169                   mSaturationCurve->setRenderHint( QwtPlotItem::RenderAntialiased, 
true );
 
  170  mSaturationCurve->attach( mPlot );
 
  172  mAlphaCurve = 
new QwtPlotCurve();
 
  173  mAlphaCurve->setTitle( tr( 
"Opacity" ) );
 
  174  mAlphaCurve->setPen( QPen( QColor( 50, 50, 50 ), 0.0 ) ),
 
  175              mAlphaCurve->setRenderHint( QwtPlotItem::RenderAntialiased, 
true );
 
  176  mAlphaCurve->attach( mPlot );
 
  178  mPlotFilter = 
new QgsGradientPlotEventFilter( mPlot );
 
  179  connect( mPlotFilter, &QgsGradientPlotEventFilter::mousePress, 
this, &QgsGradientColorRampDialog::plotMousePress );
 
  180  connect( mPlotFilter, &QgsGradientPlotEventFilter::mouseRelease, 
this, &QgsGradientColorRampDialog::plotMouseRelease );
 
  181  connect( mPlotFilter, &QgsGradientPlotEventFilter::mouseMove, 
this, &QgsGradientColorRampDialog::plotMouseMove );
 
  184  mPlotHueCheckbox->setChecked( settings.
value( QStringLiteral( 
"GradientEditor/plotHue" ), 
false ).toBool() );
 
  185  mPlotLightnessCheckbox->setChecked( settings.
value( QStringLiteral( 
"GradientEditor/plotLightness" ), 
true ).toBool() );
 
  186  mPlotSaturationCheckbox->setChecked( settings.
value( QStringLiteral( 
"GradientEditor/plotSaturation" ), 
false ).toBool() );
 
  187  mPlotAlphaCheckbox->setChecked( settings.
value( QStringLiteral( 
"GradientEditor/plotAlpha" ), 
false ).toBool() );
 
  189  mHueCurve->setVisible( mPlotHueCheckbox->isChecked() );
 
  190  mLightnessCurve->setVisible( mPlotLightnessCheckbox->isChecked() );
 
  191  mSaturationCurve->setVisible( mPlotSaturationCheckbox->isChecked() );
 
  192  mAlphaCurve->setVisible( mPlotAlphaCheckbox->isChecked() );
 
  195  mStopEditor->selectStop( 0 );
 
  197  connect( mButtonBox, &QDialogButtonBox::helpRequested, 
this, &QgsGradientColorRampDialog::showHelp );
 
 
  203  settings.
setValue( QStringLiteral( 
"GradientEditor/plotHue" ), mPlotHueCheckbox->isChecked() );
 
  204  settings.
setValue( QStringLiteral( 
"GradientEditor/plotLightness" ), mPlotLightnessCheckbox->isChecked() );
 
  205  settings.
setValue( QStringLiteral( 
"GradientEditor/plotSaturation" ), mPlotSaturationCheckbox->isChecked() );
 
  206  settings.
setValue( QStringLiteral( 
"GradientEditor/plotAlpha" ), mPlotAlphaCheckbox->isChecked() );
 
 
  214  updateColorButtons();
 
 
  226void QgsGradientColorRampDialog::cboType_currentIndexChanged( 
int index )
 
  232  updateColorButtons();
 
  239void QgsGradientColorRampDialog::btnInformation_pressed()
 
  241  if ( mRamp.
info().isEmpty() )
 
  245  QLabel *label = 
nullptr;
 
  248  QTableWidget *tableInfo = 
new QTableWidget( dlg );
 
  249  tableInfo->verticalHeader()->hide();
 
  250  tableInfo->horizontalHeader()->hide();
 
  251  tableInfo->setRowCount( mRamp.
info().count() );
 
  252  tableInfo->setColumnCount( 2 );
 
  255  for ( QgsStringMap::const_iterator it = rampInfo.constBegin();
 
  256        it != rampInfo.constEnd(); ++it )
 
  258    if ( it.key().startsWith( QLatin1String( 
"cpt-city" ) ) )
 
  260    tableInfo->setItem( i, 0, 
new QTableWidgetItem( it.key() ) );
 
  261    tableInfo->setItem( i, 1, 
new QTableWidgetItem( it.value() ) );
 
  262    tableInfo->resizeRowToContents( i );
 
  265  tableInfo->resizeColumnToContents( 0 );
 
  266  tableInfo->horizontalHeader()->setStretchLastSection( 
true );
 
  267  tableInfo->setRowCount( i );
 
  268  tableInfo->setFixedHeight( tableInfo->rowHeight( 0 ) * i + 5 );
 
  269  dlg->
layout()->addWidget( tableInfo );
 
  270  dlg->resize( 600, 250 );
 
  272  dlg->
layout()->addSpacing( 5 );
 
  275  QString gradientFile = mRamp.
info().value( QStringLiteral( 
"cpt-city-gradient" ) );
 
  276  if ( ! gradientFile.isNull() )
 
  278    QString fileName = gradientFile;
 
  280    if ( ! QFile::exists( fileName ) )
 
  282      fileName = gradientFile;
 
  283      fileName.replace( QLatin1String( 
"<cpt-city>" ), QLatin1String( 
"http://soliton.vm.bytemark.co.uk/pub/cpt-city" ) );
 
  285    label = 
new QLabel( tr( 
"Gradient file : %1" ).arg( fileName ), dlg );
 
  286    label->setTextInteractionFlags( Qt::TextBrowserInteraction );
 
  287    dlg->
layout()->addSpacing( 5 );
 
  288    dlg->
layout()->addWidget( label );
 
  292  QString licenseFile = mRamp.
info().value( QStringLiteral( 
"cpt-city-license" ) );
 
  293  if ( !licenseFile.isNull() )
 
  295    QString fileName = licenseFile;
 
  297    if ( ! QFile::exists( fileName ) )
 
  299      fileName = licenseFile;
 
  300      fileName.replace( QLatin1String( 
"<cpt-city>" ), QLatin1String( 
"http://soliton.vm.bytemark.co.uk/pub/cpt-city" ) );
 
  302    label = 
new QLabel( tr( 
"License file : %1" ).arg( fileName ), dlg );
 
  303    label->setTextInteractionFlags( Qt::TextBrowserInteraction );
 
  304    dlg->
layout()->addSpacing( 5 );
 
  305    dlg->
layout()->addWidget( label );
 
  306    if ( QFile::exists( fileName ) )
 
  308      QTextEdit *textEdit = 
new QTextEdit( dlg );
 
  309      textEdit->setReadOnly( 
true );
 
  310      QFile file( fileName );
 
  311      if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
 
  313        textEdit->setText( file.readAll() );
 
  315        dlg->
layout()->addSpacing( 5 );
 
  316        dlg->
layout()->addWidget( textEdit );
 
  317        dlg->resize( 600, 500 );
 
  325void QgsGradientColorRampDialog::updateColorButtons()
 
  327  btnColor1->blockSignals( 
true );
 
  328  btnColor1->setColor( mRamp.
color1() );
 
  329  btnColor1->blockSignals( 
false );
 
  330  btnColor2->blockSignals( 
true );
 
  331  btnColor2->setColor( mRamp.
color2() );
 
  332  btnColor2->blockSignals( 
false );
 
  335void QgsGradientColorRampDialog::updateStopEditor()
 
  337  mStopEditor->blockSignals( 
true );
 
  338  mStopEditor->setGradientRamp( mRamp );
 
  339  mStopEditor->blockSignals( 
false );
 
  342void QgsGradientColorRampDialog::selectedStopChanged( 
const QgsGradientStop &stop )
 
  345  mColorWidget->blockSignals( 
true );
 
  346  mColorWidget->setColor( stop.
color );
 
  347  mColorWidget->blockSignals( 
false );
 
  348  mPositionSpinBox->blockSignals( 
true );
 
  349  mPositionSpinBox->setValue( stop.
offset * 100 );
 
  350  mPositionSpinBox->blockSignals( 
false );
 
  352  mStopColorSpec->setCurrentIndex( mStopColorSpec->findData( 
static_cast< int >( mStopEditor->selectedStop().colorSpec() ) ) );
 
  353  mStopDirection->setCurrentIndex( mStopDirection->findData( 
static_cast< int >( mStopEditor->selectedStop().direction() ) ) );
 
  359    mPositionSpinBox->setDisabled( 
true );
 
  360    mDeleteStopButton->setDisabled( 
true );
 
  364    mPositionSpinBox->setDisabled( 
false );
 
  365    mDeleteStopButton->setDisabled( 
false );
 
  369  mStopColorSpec->setEnabled( !( stop.
offset == 0 && stop.
color == mRamp.
color1() ) );
 
  370  mStopDirection->setEnabled( !( stop.
offset == 0 && stop.
color == mRamp.
color1() ) && hasDirection( mStopEditor->selectedStop().colorSpec() ) );
 
  375void QgsGradientColorRampDialog::colorWidgetChanged( 
const QColor &color )
 
  377  mStopEditor->setSelectedStopColor( color );
 
  380void QgsGradientColorRampDialog::mPositionSpinBox_valueChanged( 
double val )
 
  382  mStopEditor->setSelectedStopOffset( val / 100.0 );
 
  385void QgsGradientColorRampDialog::mPlotHueCheckbox_toggled( 
bool checked )
 
  387  mHueCurve->setVisible( checked );
 
  391void QgsGradientColorRampDialog::mPlotLightnessCheckbox_toggled( 
bool checked )
 
  393  mLightnessCurve->setVisible( checked );
 
  397void QgsGradientColorRampDialog::mPlotSaturationCheckbox_toggled( 
bool checked )
 
  399  mSaturationCurve->setVisible( checked );
 
  403void QgsGradientColorRampDialog::mPlotAlphaCheckbox_toggled( 
bool checked )
 
  405  mAlphaCurve->setVisible( checked );
 
  409void QgsGradientColorRampDialog::plotMousePress( QPointF point )
 
  414  mCurrentPlotColorComponent = -1;
 
  415  mCurrentPlotMarkerIndex = -1;
 
  418  for ( 
int i = 0; i < mRamp.
count(); ++i )
 
  421    double currentOff = 0.0;
 
  425      currentCol = mRamp.
color1();
 
  427    else if ( i == mRamp.
count() - 1 )
 
  430      currentCol = mRamp.
color2();
 
  434      currentOff = mRamp.
stops().at( i - 1 ).offset;
 
  435      currentCol = mRamp.
stops().at( i - 1 ).color;
 
  439    if ( mPlotHueCheckbox->isChecked() )
 
  441      currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.hslHueF(), 2.0 );
 
  442      if ( currentDist < minDist )
 
  444        minDist = currentDist;
 
  445        mCurrentPlotColorComponent = 0;
 
  446        mCurrentPlotMarkerIndex = i;
 
  449    if ( mPlotLightnessCheckbox->isChecked() )
 
  451      currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.lightnessF(), 2.0 );
 
  452      if ( currentDist < minDist )
 
  454        minDist = currentDist;
 
  455        mCurrentPlotColorComponent = 1;
 
  456        mCurrentPlotMarkerIndex = i;
 
  459    if ( mPlotSaturationCheckbox->isChecked() )
 
  461      currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.hslSaturationF(), 2.0 );
 
  462      if ( currentDist < minDist )
 
  464        minDist = currentDist;
 
  465        mCurrentPlotColorComponent = 2;
 
  466        mCurrentPlotMarkerIndex = i;
 
  469    if ( mPlotAlphaCheckbox->isChecked() )
 
  471      currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.alphaF(), 2.0 );
 
  472      if ( currentDist < minDist )
 
  474        minDist = currentDist;
 
  475        mCurrentPlotColorComponent = 3;
 
  476        mCurrentPlotMarkerIndex = i;
 
  482  if ( mCurrentPlotMarkerIndex >= 0 )
 
  483    mStopEditor->selectStop( mCurrentPlotMarkerIndex );
 
  486void QgsGradientColorRampDialog::plotMouseRelease( QPointF )
 
  488  mCurrentPlotColorComponent = -1;
 
  491void QgsGradientColorRampDialog::plotMouseMove( QPointF point )
 
  493  QColor newColor = mStopEditor->selectedStop().color;
 
  495  if ( mCurrentPlotColorComponent == 0 )
 
  496    newColor = QColor::fromHslF( std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ), newColor.hslSaturationF(), newColor.lightnessF(), newColor.alphaF() );
 
  497  else if ( mCurrentPlotColorComponent == 1 )
 
  498    newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ), newColor.alphaF() );
 
  499  else if ( mCurrentPlotColorComponent == 2 )
 
  500    newColor = QColor::fromHslF( newColor.hslHueF(), std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ), newColor.lightnessF(), newColor.alphaF() );
 
  501  else if ( mCurrentPlotColorComponent == 3 )
 
  502    newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), newColor.lightnessF(), std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ) );
 
  504  mStopEditor->setSelectedStopDetails( newColor, std::clamp( point.x(), qreal( 0.0 ), qreal( 1.0 ) ) );
 
  507bool byX( QPointF p1, QPointF p2 )
 
  509  return p1.x() < p2.x();
 
 
  512void QgsGradientColorRampDialog::addPlotMarker( 
double x, 
double y, 
const QColor &color, 
bool isSelected )
 
  514  QColor borderColor = color.darker( 200 );
 
  515  borderColor.setAlpha( 255 );
 
  517  QColor brushColor = color;
 
  518  brushColor.setAlpha( 255 );
 
  520  QwtPlotMarker *marker = 
new QwtPlotMarker();
 
  521  marker->setSymbol( 
new QwtSymbol( QwtSymbol::Ellipse,  QBrush( brushColor ), QPen( borderColor, isSelected ? 2 : 1 ), QSize( 8, 8 ) ) );
 
  522  marker->setValue( x, y );
 
  523  marker->attach( mPlot );
 
  524  marker->setRenderHint( QwtPlotItem::RenderAntialiased, 
true );
 
  528void QgsGradientColorRampDialog::addMarkersForColor( 
double x, 
const QColor &color, 
bool isSelected )
 
  530  if ( mPlotHueCheckbox->isChecked() )
 
  531    addPlotMarker( x, color.hslHueF(), color, isSelected && mCurrentPlotColorComponent == 0 );
 
  532  if ( mPlotLightnessCheckbox->isChecked() )
 
  533    addPlotMarker( x, color.lightnessF(), color, isSelected && mCurrentPlotColorComponent == 1 );
 
  534  if ( mPlotSaturationCheckbox->isChecked() )
 
  535    addPlotMarker( x, color.hslSaturationF(), color, isSelected && mCurrentPlotColorComponent == 2 );
 
  536  if ( mPlotAlphaCheckbox->isChecked() )
 
  537    addPlotMarker( x, color.alphaF(), color, isSelected && mCurrentPlotColorComponent == 3 );
 
  540bool QgsGradientColorRampDialog::hasDirection( QColor::Spec colorSpec )
 
  544    case QColor::Spec::Rgb:
 
  545    case QColor::Spec::ExtendedRgb:
 
  546    case QColor::Spec::Cmyk:
 
  547    case QColor::Spec::Invalid:
 
  550    case QColor::Spec::Hsv:
 
  551    case QColor::Spec::Hsl:
 
  558void QgsGradientColorRampDialog::updatePlot()
 
  561  const auto constMMarkers = mMarkers;
 
  562  for ( QwtPlotMarker *marker : constMMarkers )
 
  569  QPolygonF lightnessPoints;
 
  571  QPolygonF saturationPoints;
 
  572  QPolygonF alphaPoints;
 
  573  lightnessPoints << QPointF( 0.0, mRamp.
color1().lightnessF() );
 
  574  huePoints << QPointF( 0.0, mRamp.
color1().hslHueF() );
 
  575  saturationPoints << QPointF( 0.0, mRamp.
color1().hslSaturationF() );
 
  576  alphaPoints << QPointF( 0.0, mRamp.
color1().alphaF() );
 
  577  addMarkersForColor( 0, mRamp.
color1(), mCurrentPlotMarkerIndex == 0 );
 
  580  const auto constStops = mRamp.
stops();
 
  583    lightnessPoints << QPointF( stop.
offset, stop.
color.lightnessF() );
 
  584    huePoints << QPointF( stop.
offset, stop.
color.hslHueF() );
 
  585    saturationPoints << QPointF( stop.
offset, stop.
color.hslSaturationF() );
 
  586    alphaPoints << QPointF( stop.
offset, stop.
color.alphaF() );
 
  588    addMarkersForColor( stop.
offset, stop.
color, mCurrentPlotMarkerIndex == i );
 
  593  for ( 
double p = 0.001; p < 1.0; p += 0.001 )
 
  595    QColor 
c = mRamp.
color( p );
 
  596    lightnessPoints << QPointF( p, 
c.lightnessF() );
 
  597    huePoints << QPointF( p, 
c.hslHueF() );
 
  598    saturationPoints << QPointF( p, 
c.hslSaturationF() );
 
  599    alphaPoints << QPointF( p, 
c.alphaF() );
 
  602  lightnessPoints << QPointF( 1.0, mRamp.
color2().lightnessF() );
 
  603  huePoints << QPointF( 1.0, mRamp.
color2().hslHueF() );
 
  604  saturationPoints << QPointF( 1.0, mRamp.
color2().hslSaturationF() );
 
  605  alphaPoints << QPointF( 1.0, mRamp.
color2().alphaF() );
 
  606  addMarkersForColor( 1.0, mRamp.
color2(), mCurrentPlotMarkerIndex == i );
 
  608  std::sort( lightnessPoints.begin(), lightnessPoints.end(), 
byX );
 
  609  std::sort( huePoints.begin(), huePoints.end(), 
byX );
 
  610  std::sort( saturationPoints.begin(), saturationPoints.end(), 
byX );
 
  611  std::sort( alphaPoints.begin(), alphaPoints.end(), 
byX );
 
  613  mLightnessCurve->setSamples( lightnessPoints );
 
  614  mHueCurve->setSamples( huePoints );
 
  615  mSaturationCurve->setSamples( saturationPoints );
 
  616  mAlphaCurve->setSamples( alphaPoints );
 
  620void QgsGradientColorRampDialog::updateRampFromStopEditor()
 
  622  mRamp = mStopEditor->gradientRamp();
 
  625  mPositionSpinBox->blockSignals( 
true );
 
  626  mPositionSpinBox->setValue( mStopEditor->selectedStop().offset * 100 );
 
  627  mPositionSpinBox->blockSignals( 
false );
 
  628  mColorWidget->blockSignals( 
true );
 
  629  mColorWidget->setColor( mStopEditor->selectedStop().color );
 
  630  mColorWidget->blockSignals( 
false );
 
  632  mStopColorSpec->setCurrentIndex( mStopColorSpec->findData( 
static_cast< int >( mStopEditor->selectedStop().colorSpec() ) ) );
 
  633  mStopDirection->setCurrentIndex( mStopDirection->findData( 
static_cast< int >( mStopEditor->selectedStop().direction() ) ) );
 
  637  mStopColorSpec->setEnabled( !( mStopEditor->selectedStop().offset == 0 && mStopEditor->selectedStop().color == mRamp.
color1() ) );
 
  638  mStopDirection->setEnabled( !( mStopEditor->selectedStop().offset == 0 && mStopEditor->selectedStop().color == mRamp.
color1() ) && hasDirection( mStopEditor->selectedStop().colorSpec() ) );
 
  640  updateColorButtons();
 
  648  mStopEditor->setColor1( color );
 
  649  updateColorButtons();
 
 
  654  mStopEditor->setColor2( color );
 
  655  updateColorButtons();
 
 
  658void QgsGradientColorRampDialog::showHelp()
 
  660  QgsHelp::openHelp( QStringLiteral( 
"style_library/style_manager.html#setting-a-color-ramp" ) );
 
  666QgsGradientPlotEventFilter::QgsGradientPlotEventFilter( QwtPlot *plot )
 
  670  mPlot->canvas()->installEventFilter( 
this );
 
  673bool QgsGradientPlotEventFilter::eventFilter( QObject *
object, QEvent *event )
 
  675  if ( !mPlot->isEnabled() )
 
  676    return QObject::eventFilter( 
object, event );
 
  678  switch ( event->type() )
 
  680    case QEvent::MouseButtonPress:
 
  682      const QMouseEvent *mouseEvent = 
static_cast<QMouseEvent * 
>( event );
 
  683      if ( mouseEvent->button() == Qt::LeftButton )
 
  685        emit mousePress( mapPoint( mouseEvent->pos() ) );
 
  689    case QEvent::MouseMove:
 
  691      const QMouseEvent *mouseEvent = 
static_cast<QMouseEvent * 
>( event );
 
  692      if ( mouseEvent->buttons() & Qt::LeftButton )
 
  695        emit mouseMove( mapPoint( mouseEvent->pos() ) );
 
  699    case QEvent::MouseButtonRelease:
 
  701      const QMouseEvent *mouseEvent = 
static_cast<QMouseEvent * 
>( event );
 
  702      if ( mouseEvent->button() == Qt::LeftButton )
 
  704        emit mouseRelease( mapPoint( mouseEvent->pos() ) );
 
  712  return QObject::eventFilter( 
object, event );
 
  715QPointF QgsGradientPlotEventFilter::mapPoint( QPointF point )
 const 
  720  return QPointF( mPlot->canvasMap( QwtPlot::xBottom ).invTransform( point.x() ),
 
  721                  mPlot->canvasMap( QwtPlot::yLeft ).invTransform( point.y() ) );
 
AngularDirection
Angular directions.
 
@ CounterClockwise
Counter-clockwise direction.
 
@ Clockwise
Clockwise direction.
 
static QString defaultBaseDir()
 
A generic dialog with layout and button box.
 
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
 
~QgsGradientColorRampDialog() override
 
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
 
void setColor2(const QColor &color)
Sets the end color for the gradient ramp.
 
QgsGradientColorRamp ramp
 
void setRamp(const QgsGradientColorRamp &ramp)
Sets the color ramp to show in the dialog.
 
QgsGradientColorRampDialog(const QgsGradientColorRamp &ramp, QWidget *parent=nullptr)
Constructor for QgsGradientColorRampDialog.
 
void setColor1(const QColor &color)
Sets the start color for the gradient ramp.
 
void changed()
Emitted when the dialog settings change.
 
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
 
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
 
int count() const override
Returns number of defined colors, or -1 if undefined.
 
QgsStringMap info() const
Returns any additional info attached to the gradient ramp (e.g., authorship notes)
 
void convertToDiscrete(bool discrete)
Converts a gradient with existing color stops to or from discrete interpolation.
 
QColor::Spec colorSpec() const
Returns the color specification in which the color component interpolation will occur.
 
QColor color(double value) const override
Returns the color corresponding to a specified value.
 
QColor color1() const
Returns the gradient start color.
 
Qgis::AngularDirection direction() const
Returns the direction to traverse the color wheel using when interpolating hue-based color specificat...
 
QgsGradientStopsList stops() const
Returns the list of intermediate gradient stops for the ramp.
 
QColor color2() const
Returns the gradient end color.
 
void changed()
Emitted when the gradient ramp is changed by a user.
 
void deleteSelectedStop()
Deletes the current selected stop.
 
void selectedStopChanged(const QgsGradientStop &stop)
Emitted when the current selected stop changes.
 
Represents a color stop within a QgsGradientColorRamp color ramp.
 
double offset
Relative positional offset, between 0 and 1.
 
QColor color
Gradient color at stop.
 
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
 
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
 
This class is a composition of two QSettings instances:
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
#define BUILTIN_UNREACHABLE
 
QMap< QString, QString > QgsStringMap
 
bool byX(QPointF p1, QPointF p2)