QGIS API Documentation  3.13.0-Master (740be229cb)
qgsgradientcolorrampdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgradientcolorrampdialog.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgscolorramp.h"
19 #include "qgsdialog.h"
20 #include "qgscolordialog.h"
21 #include "qgscptcityarchive.h"
22 #include "qgssettings.h"
23 #include "qgsgui.h"
24 
25 #include <QColorDialog>
26 #include <QHeaderView>
27 #include <QInputDialog>
28 #include <QPainter>
29 #include <QTableWidget>
30 #include <QTextEdit>
31 
32 // QWT Charting widget
33 #include <qwt_global.h>
34 #include <qwt_plot_canvas.h>
35 #include <qwt_plot.h>
36 #include <qwt_plot_curve.h>
37 #include <qwt_plot_grid.h>
38 #include <qwt_plot_marker.h>
39 #include <qwt_plot_picker.h>
40 #include <qwt_picker_machine.h>
41 #include <qwt_plot_layout.h>
42 #include <qwt_symbol.h>
43 #include <qwt_legend.h>
44 
46  : QDialog( parent )
47  , mRamp( ramp )
48  , mCurrentPlotColorComponent( -1 )
49  , mCurrentPlotMarkerIndex( 0 )
50 {
51  setupUi( this );
53  connect( cboType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientColorRampDialog::cboType_currentIndexChanged );
54  connect( btnInformation, &QPushButton::pressed, this, &QgsGradientColorRampDialog::btnInformation_pressed );
55  connect( mPositionSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientColorRampDialog::mPositionSpinBox_valueChanged );
56  connect( mPlotHueCheckbox, &QCheckBox::toggled, this, &QgsGradientColorRampDialog::mPlotHueCheckbox_toggled );
57  connect( mPlotLightnessCheckbox, &QCheckBox::toggled, this, &QgsGradientColorRampDialog::mPlotLightnessCheckbox_toggled );
58  connect( mPlotSaturationCheckbox, &QCheckBox::toggled, this, &QgsGradientColorRampDialog::mPlotSaturationCheckbox_toggled );
59  connect( mPlotAlphaCheckbox, &QCheckBox::toggled, this, &QgsGradientColorRampDialog::mPlotAlphaCheckbox_toggled );
60 #ifdef Q_OS_MAC
61  setWindowModality( Qt::WindowModal );
62 #endif
63 
64  mPositionSpinBox->setShowClearButton( false );
65  btnColor1->setAllowOpacity( true );
66  btnColor1->setColorDialogTitle( tr( "Select Ramp Color" ) );
67  btnColor1->setContext( QStringLiteral( "symbology" ) );
68  btnColor1->setShowNoColor( true );
69  btnColor1->setNoColorString( tr( "Transparent" ) );
70  btnColor2->setAllowOpacity( true );
71  btnColor2->setColorDialogTitle( tr( "Select Ramp Color" ) );
72  btnColor2->setContext( QStringLiteral( "symbology" ) );
73  btnColor2->setShowNoColor( true );
74  btnColor2->setNoColorString( tr( "Transparent" ) );
75  updateColorButtons();
78 
79  // fill type combobox
80  cboType->blockSignals( true );
81  cboType->addItem( tr( "Discrete" ) );
82  cboType->addItem( tr( "Continuous" ) );
83  if ( mRamp.isDiscrete() )
84  cboType->setCurrentIndex( 0 );
85  else
86  cboType->setCurrentIndex( 1 );
87  cboType->blockSignals( false );
88 
89  if ( mRamp.info().isEmpty() )
90  btnInformation->setEnabled( false );
91 
92  mStopEditor->setGradientRamp( mRamp );
93  connect( mStopEditor, &QgsGradientStopEditor::changed, this, &QgsGradientColorRampDialog::updateRampFromStopEditor );
94 
95  connect( mColorWidget, &QgsCompoundColorWidget::currentColorChanged, this, &QgsGradientColorRampDialog::colorWidgetChanged );
96  connect( mDeleteStopButton, &QAbstractButton::clicked, mStopEditor, &QgsGradientStopEditor::deleteSelectedStop );
97 
98  // hide the ugly canvas frame
99  mPlot->setFrameStyle( QFrame::NoFrame );
100  QFrame *plotCanvasFrame = dynamic_cast<QFrame *>( mPlot->canvas() );
101  if ( plotCanvasFrame )
102  plotCanvasFrame->setFrameStyle( QFrame::NoFrame );
103 
104  mPlot->setAxisScale( QwtPlot::yLeft, 0.0, 1.0 );
105  mPlot->enableAxis( QwtPlot::yLeft, false );
106 
107  // add a grid
108  QwtPlotGrid *grid = new QwtPlotGrid();
109  QwtScaleDiv gridDiv( 0.0, 1.0, QList<double>(), QList<double>(), QList<double>() << 0.2 << 0.4 << 0.6 << 0.8 );
110  grid->setXDiv( gridDiv );
111  grid->setYDiv( gridDiv );
112  grid->setPen( QPen( QColor( 0, 0, 0, 50 ) ) );
113  grid->attach( mPlot );
114 
115  mLightnessCurve = new QwtPlotCurve();
116  mLightnessCurve->setTitle( tr( "Lightness" ) );
117  mLightnessCurve->setPen( QPen( QColor( 70, 150, 255 ), 0.0 ) ),
118  mLightnessCurve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
119  mLightnessCurve->attach( mPlot );
120 
121  mHueCurve = new QwtPlotCurve();
122  mHueCurve->setTitle( tr( "Hue" ) );
123  mHueCurve->setPen( QPen( QColor( 255, 215, 70 ), 0.0 ) ),
124  mHueCurve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
125  mHueCurve->attach( mPlot );
126 
127  mSaturationCurve = new QwtPlotCurve();
128  mSaturationCurve->setTitle( tr( "Saturation" ) );
129  mSaturationCurve->setPen( QPen( QColor( 255, 70, 150 ), 0.0 ) ),
130  mSaturationCurve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
131  mSaturationCurve->attach( mPlot );
132 
133  mAlphaCurve = new QwtPlotCurve();
134  mAlphaCurve->setTitle( tr( "Opacity" ) );
135  mAlphaCurve->setPen( QPen( QColor( 50, 50, 50 ), 0.0 ) ),
136  mAlphaCurve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
137  mAlphaCurve->attach( mPlot );
138 
139  mPlotFilter = new QgsGradientPlotEventFilter( mPlot );
140  connect( mPlotFilter, &QgsGradientPlotEventFilter::mousePress, this, &QgsGradientColorRampDialog::plotMousePress );
141  connect( mPlotFilter, &QgsGradientPlotEventFilter::mouseRelease, this, &QgsGradientColorRampDialog::plotMouseRelease );
142  connect( mPlotFilter, &QgsGradientPlotEventFilter::mouseMove, this, &QgsGradientColorRampDialog::plotMouseMove );
143 
144  QgsSettings settings;
145  mPlotHueCheckbox->setChecked( settings.value( QStringLiteral( "GradientEditor/plotHue" ), false ).toBool() );
146  mPlotLightnessCheckbox->setChecked( settings.value( QStringLiteral( "GradientEditor/plotLightness" ), true ).toBool() );
147  mPlotSaturationCheckbox->setChecked( settings.value( QStringLiteral( "GradientEditor/plotSaturation" ), false ).toBool() );
148  mPlotAlphaCheckbox->setChecked( settings.value( QStringLiteral( "GradientEditor/plotAlpha" ), false ).toBool() );
149 
150  mHueCurve->setVisible( mPlotHueCheckbox->isChecked() );
151  mLightnessCurve->setVisible( mPlotLightnessCheckbox->isChecked() );
152  mSaturationCurve->setVisible( mPlotSaturationCheckbox->isChecked() );
153  mAlphaCurve->setVisible( mPlotAlphaCheckbox->isChecked() );
154 
155  connect( mStopEditor, &QgsGradientStopEditor::selectedStopChanged, this, &QgsGradientColorRampDialog::selectedStopChanged );
156  mStopEditor->selectStop( 0 );
157 
158  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsGradientColorRampDialog::showHelp );
159 }
160 
162 {
163  QgsSettings settings;
164  settings.setValue( QStringLiteral( "GradientEditor/plotHue" ), mPlotHueCheckbox->isChecked() );
165  settings.setValue( QStringLiteral( "GradientEditor/plotLightness" ), mPlotLightnessCheckbox->isChecked() );
166  settings.setValue( QStringLiteral( "GradientEditor/plotSaturation" ), mPlotSaturationCheckbox->isChecked() );
167  settings.setValue( QStringLiteral( "GradientEditor/plotAlpha" ), mPlotAlphaCheckbox->isChecked() );
168 
169 }
170 
172 {
173  mRamp = ramp;
174 
175  updateColorButtons();
176  updateStopEditor();
177  updatePlot();
178 
179  emit changed();
180 }
181 
182 QDialogButtonBox *QgsGradientColorRampDialog::buttonBox() const
183 {
184  return mButtonBox;
185 }
186 
187 void QgsGradientColorRampDialog::cboType_currentIndexChanged( int index )
188 {
189  if ( ( index == 0 && mRamp.isDiscrete() ) ||
190  ( index == 1 && !mRamp.isDiscrete() ) )
191  return;
192  mRamp.convertToDiscrete( index == 0 );
193  updateColorButtons();
194  updateStopEditor();
195  updatePlot();
196 
197  emit changed();
198 }
199 
200 void QgsGradientColorRampDialog::btnInformation_pressed()
201 {
202  if ( mRamp.info().isEmpty() )
203  return;
204 
205  QgsDialog *dlg = new QgsDialog( this );
206  QLabel *label = nullptr;
207 
208  // information table
209  QTableWidget *tableInfo = new QTableWidget( dlg );
210  tableInfo->verticalHeader()->hide();
211  tableInfo->horizontalHeader()->hide();
212  tableInfo->setRowCount( mRamp.info().count() );
213  tableInfo->setColumnCount( 2 );
214  int i = 0;
215  QgsStringMap rampInfo = mRamp.info();
216  for ( QgsStringMap::const_iterator it = rampInfo.constBegin();
217  it != rampInfo.constEnd(); ++it )
218  {
219  if ( it.key().startsWith( QLatin1String( "cpt-city" ) ) )
220  continue;
221  tableInfo->setItem( i, 0, new QTableWidgetItem( it.key() ) );
222  tableInfo->setItem( i, 1, new QTableWidgetItem( it.value() ) );
223  tableInfo->resizeRowToContents( i );
224  i++;
225  }
226  tableInfo->resizeColumnToContents( 0 );
227  tableInfo->horizontalHeader()->setStretchLastSection( true );
228  tableInfo->setRowCount( i );
229  tableInfo->setFixedHeight( tableInfo->rowHeight( 0 ) * i + 5 );
230  dlg->layout()->addWidget( tableInfo );
231  dlg->resize( 600, 250 );
232 
233  dlg->layout()->addSpacing( 5 );
234 
235  // gradient file
236  QString gradientFile = mRamp.info().value( QStringLiteral( "cpt-city-gradient" ) );
237  if ( ! gradientFile.isNull() )
238  {
239  QString fileName = gradientFile;
240  fileName.replace( QLatin1String( "<cpt-city>" ), QgsCptCityArchive::defaultBaseDir() );
241  if ( ! QFile::exists( fileName ) )
242  {
243  fileName = gradientFile;
244  fileName.replace( QLatin1String( "<cpt-city>" ), QLatin1String( "http://soliton.vm.bytemark.co.uk/pub/cpt-city" ) );
245  }
246  label = new QLabel( tr( "Gradient file : %1" ).arg( fileName ), dlg );
247  label->setTextInteractionFlags( Qt::TextBrowserInteraction );
248  dlg->layout()->addSpacing( 5 );
249  dlg->layout()->addWidget( label );
250  }
251 
252  // license file
253  QString licenseFile = mRamp.info().value( QStringLiteral( "cpt-city-license" ) );
254  if ( !licenseFile.isNull() )
255  {
256  QString fileName = licenseFile;
257  fileName.replace( QLatin1String( "<cpt-city>" ), QgsCptCityArchive::defaultBaseDir() );
258  if ( ! QFile::exists( fileName ) )
259  {
260  fileName = licenseFile;
261  fileName.replace( QLatin1String( "<cpt-city>" ), QLatin1String( "http://soliton.vm.bytemark.co.uk/pub/cpt-city" ) );
262  }
263  label = new QLabel( tr( "License file : %1" ).arg( fileName ), dlg );
264  label->setTextInteractionFlags( Qt::TextBrowserInteraction );
265  dlg->layout()->addSpacing( 5 );
266  dlg->layout()->addWidget( label );
267  if ( QFile::exists( fileName ) )
268  {
269  QTextEdit *textEdit = new QTextEdit( dlg );
270  textEdit->setReadOnly( true );
271  QFile file( fileName );
272  if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
273  {
274  textEdit->setText( file.readAll() );
275  file.close();
276  dlg->layout()->addSpacing( 5 );
277  dlg->layout()->addWidget( textEdit );
278  dlg->resize( 600, 500 );
279  }
280  }
281  }
282 
283  dlg->show(); //non modal
284 }
285 
286 void QgsGradientColorRampDialog::updateColorButtons()
287 {
288  btnColor1->blockSignals( true );
289  btnColor1->setColor( mRamp.color1() );
290  btnColor1->blockSignals( false );
291  btnColor2->blockSignals( true );
292  btnColor2->setColor( mRamp.color2() );
293  btnColor2->blockSignals( false );
294 }
295 
296 void QgsGradientColorRampDialog::updateStopEditor()
297 {
298  mStopEditor->blockSignals( true );
299  mStopEditor->setGradientRamp( mRamp );
300  mStopEditor->blockSignals( false );
301 }
302 
303 void QgsGradientColorRampDialog::selectedStopChanged( const QgsGradientStop &stop )
304 {
305  mColorWidget->blockSignals( true );
306  mColorWidget->setColor( stop.color );
307  mColorWidget->blockSignals( false );
308  mPositionSpinBox->blockSignals( true );
309  mPositionSpinBox->setValue( stop.offset * 100 );
310  mPositionSpinBox->blockSignals( false );
311 
312  if ( ( stop.offset == 0 && stop.color == mRamp.color1() ) || ( stop.offset == 1.0 && stop.color == mRamp.color2() ) )
313  {
314  //first/last stop can't be repositioned
315  mPositionSpinBox->setDisabled( true );
316  mDeleteStopButton->setDisabled( true );
317  }
318  else
319  {
320  mPositionSpinBox->setDisabled( false );
321  mDeleteStopButton->setDisabled( false );
322  }
323 
324  updatePlot();
325 }
326 
327 void QgsGradientColorRampDialog::colorWidgetChanged( const QColor &color )
328 {
329  mStopEditor->setSelectedStopColor( color );
330 }
331 
332 void QgsGradientColorRampDialog::mPositionSpinBox_valueChanged( double val )
333 {
334  mStopEditor->setSelectedStopOffset( val / 100.0 );
335 }
336 
337 void QgsGradientColorRampDialog::mPlotHueCheckbox_toggled( bool checked )
338 {
339  mHueCurve->setVisible( checked );
340  updatePlot();
341 }
342 
343 void QgsGradientColorRampDialog::mPlotLightnessCheckbox_toggled( bool checked )
344 {
345  mLightnessCurve->setVisible( checked );
346  updatePlot();
347 }
348 
349 void QgsGradientColorRampDialog::mPlotSaturationCheckbox_toggled( bool checked )
350 {
351  mSaturationCurve->setVisible( checked );
352  updatePlot();
353 }
354 
355 void QgsGradientColorRampDialog::mPlotAlphaCheckbox_toggled( bool checked )
356 {
357  mAlphaCurve->setVisible( checked );
358  updatePlot();
359 }
360 
361 void QgsGradientColorRampDialog::plotMousePress( QPointF point )
362 {
363  //find closest part
364 
365  double minDist = 1;
366  mCurrentPlotColorComponent = -1;
367  mCurrentPlotMarkerIndex = -1;
368  // first color
369 
370  for ( int i = 0; i < mRamp.count(); ++i )
371  {
372  QColor currentCol;
373  double currentOff = 0.0;
374  if ( i == 0 )
375  {
376  currentOff = 0.0;
377  currentCol = mRamp.color1();
378  }
379  else if ( i == mRamp.count() - 1 )
380  {
381  currentOff = 1.0;
382  currentCol = mRamp.color2();
383  }
384  else
385  {
386  currentOff = mRamp.stops().at( i - 1 ).offset;
387  currentCol = mRamp.stops().at( i - 1 ).color;
388  }
389 
390  double currentDist;
391  if ( mPlotHueCheckbox->isChecked() )
392  {
393  currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.hslHueF(), 2.0 );
394  if ( currentDist < minDist )
395  {
396  minDist = currentDist;
397  mCurrentPlotColorComponent = 0;
398  mCurrentPlotMarkerIndex = i;
399  }
400  }
401  if ( mPlotLightnessCheckbox->isChecked() )
402  {
403  currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.lightnessF(), 2.0 );
404  if ( currentDist < minDist )
405  {
406  minDist = currentDist;
407  mCurrentPlotColorComponent = 1;
408  mCurrentPlotMarkerIndex = i;
409  }
410  }
411  if ( mPlotSaturationCheckbox->isChecked() )
412  {
413  currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.hslSaturationF(), 2.0 );
414  if ( currentDist < minDist )
415  {
416  minDist = currentDist;
417  mCurrentPlotColorComponent = 2;
418  mCurrentPlotMarkerIndex = i;
419  }
420  }
421  if ( mPlotAlphaCheckbox->isChecked() )
422  {
423  currentDist = std::pow( point.x() - currentOff, 2.0 ) + std::pow( point.y() - currentCol.alphaF(), 2.0 );
424  if ( currentDist < minDist )
425  {
426  minDist = currentDist;;
427  mCurrentPlotColorComponent = 3;
428  mCurrentPlotMarkerIndex = i;
429  }
430  }
431  }
432 
433  // watch out - selected stop index may differ if stops in editor are out of order!!!
434  if ( mCurrentPlotMarkerIndex >= 0 )
435  mStopEditor->selectStop( mCurrentPlotMarkerIndex );
436 }
437 
438 void QgsGradientColorRampDialog::plotMouseRelease( QPointF )
439 {
440  mCurrentPlotColorComponent = -1;
441 }
442 
443 void QgsGradientColorRampDialog::plotMouseMove( QPointF point )
444 {
445  QColor newColor = mStopEditor->selectedStop().color;
446 
447  if ( mCurrentPlotColorComponent == 0 )
448  newColor = QColor::fromHslF( qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ), newColor.hslSaturationF(), newColor.lightnessF(), newColor.alphaF() );
449  else if ( mCurrentPlotColorComponent == 1 )
450  newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ), newColor.alphaF() );
451  else if ( mCurrentPlotColorComponent == 2 )
452  newColor = QColor::fromHslF( newColor.hslHueF(), qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ), newColor.lightnessF(), newColor.alphaF() );
453  else if ( mCurrentPlotColorComponent == 3 )
454  newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), newColor.lightnessF(), qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ) );
455 
456  mStopEditor->setSelectedStopDetails( newColor, qBound( qreal( 0.0 ), point.x(), qreal( 1.0 ) ) );
457 }
458 
459 bool byX( QPointF p1, QPointF p2 )
460 {
461  return p1.x() < p2.x();
462 }
463 
464 void QgsGradientColorRampDialog::addPlotMarker( double x, double y, const QColor &color, bool isSelected )
465 {
466  QColor borderColor = color.darker( 200 );
467  borderColor.setAlpha( 255 );
468 
469  QColor brushColor = color;
470  brushColor.setAlpha( 255 );
471 
472  QwtPlotMarker *marker = new QwtPlotMarker();
473  marker->setSymbol( new QwtSymbol( QwtSymbol::Ellipse, QBrush( brushColor ), QPen( borderColor, isSelected ? 2 : 1 ), QSize( 8, 8 ) ) );
474  marker->setValue( x, y );
475  marker->attach( mPlot );
476  marker->setRenderHint( QwtPlotItem::RenderAntialiased, true );
477  mMarkers << marker;
478 }
479 
480 void QgsGradientColorRampDialog::addMarkersForColor( double x, const QColor &color, bool isSelected )
481 {
482  if ( mPlotHueCheckbox->isChecked() )
483  addPlotMarker( x, color.hslHueF(), color, isSelected && mCurrentPlotColorComponent == 0 );
484  if ( mPlotLightnessCheckbox->isChecked() )
485  addPlotMarker( x, color.lightnessF(), color, isSelected && mCurrentPlotColorComponent == 1 );
486  if ( mPlotSaturationCheckbox->isChecked() )
487  addPlotMarker( x, color.hslSaturationF(), color, isSelected && mCurrentPlotColorComponent == 2 );
488  if ( mPlotAlphaCheckbox->isChecked() )
489  addPlotMarker( x, color.alphaF(), color, isSelected && mCurrentPlotColorComponent == 3 );
490 }
491 
492 void QgsGradientColorRampDialog::updatePlot()
493 {
494  // remove existing markers
495  const auto constMMarkers = mMarkers;
496  for ( QwtPlotMarker *marker : constMMarkers )
497  {
498  marker->detach();
499  delete marker;
500  }
501  mMarkers.clear();
502 
503  QPolygonF lightnessPoints;
504  QPolygonF huePoints;
505  QPolygonF saturationPoints;
506  QPolygonF alphaPoints;
507  lightnessPoints << QPointF( 0.0, mRamp.color1().lightnessF() );
508  huePoints << QPointF( 0.0, mRamp.color1().hslHueF() );
509  saturationPoints << QPointF( 0.0, mRamp.color1().hslSaturationF() );
510  alphaPoints << QPointF( 0.0, mRamp.color1().alphaF() );
511  addMarkersForColor( 0, mRamp.color1(), mCurrentPlotMarkerIndex == 0 );
512 
513  int i = 1;
514  const auto constStops = mRamp.stops();
515  for ( const QgsGradientStop &stop : constStops )
516  {
517  lightnessPoints << QPointF( stop.offset, stop.color.lightnessF() );
518  huePoints << QPointF( stop.offset, stop.color.hslHueF() );
519  saturationPoints << QPointF( stop.offset, stop.color.hslSaturationF() );
520  alphaPoints << QPointF( stop.offset, stop.color.alphaF() );
521 
522  addMarkersForColor( stop.offset, stop.color, mCurrentPlotMarkerIndex == i );
523  i++;
524  }
525 
526  //add extra intermediate points
527  for ( double p = 0.001; p < 1.0; p += 0.001 )
528  {
529  QColor c = mRamp.color( p );
530  lightnessPoints << QPointF( p, c.lightnessF() );
531  huePoints << QPointF( p, c.hslHueF() );
532  saturationPoints << QPointF( p, c.hslSaturationF() );
533  alphaPoints << QPointF( p, c.alphaF() );
534  }
535 
536  lightnessPoints << QPointF( 1.0, mRamp.color2().lightnessF() );
537  huePoints << QPointF( 1.0, mRamp.color2().hslHueF() );
538  saturationPoints << QPointF( 1.0, mRamp.color2().hslSaturationF() );
539  alphaPoints << QPointF( 1.0, mRamp.color2().alphaF() );
540  addMarkersForColor( 1.0, mRamp.color2(), mCurrentPlotMarkerIndex == i );
541 
542  std::sort( lightnessPoints.begin(), lightnessPoints.end(), byX );
543  std::sort( huePoints.begin(), huePoints.end(), byX );
544  std::sort( saturationPoints.begin(), saturationPoints.end(), byX );
545  std::sort( alphaPoints.begin(), alphaPoints.end(), byX );
546 
547  mLightnessCurve->setSamples( lightnessPoints );
548  mHueCurve->setSamples( huePoints );
549  mSaturationCurve->setSamples( saturationPoints );
550  mAlphaCurve->setSamples( alphaPoints );
551  mPlot->replot();
552 }
553 
554 void QgsGradientColorRampDialog::updateRampFromStopEditor()
555 {
556  mRamp = mStopEditor->gradientRamp();
557  mPositionSpinBox->blockSignals( true );
558  mPositionSpinBox->setValue( mStopEditor->selectedStop().offset * 100 );
559  mPositionSpinBox->blockSignals( false );
560  mColorWidget->blockSignals( true );
561  mColorWidget->setColor( mStopEditor->selectedStop().color );
562  mColorWidget->blockSignals( false );
563 
564  updateColorButtons();
565  updatePlot();
566 
567  emit changed();
568 }
569 
570 void QgsGradientColorRampDialog::setColor1( const QColor &color )
571 {
572  mStopEditor->setColor1( color );
573  updateColorButtons();
574 }
575 
576 void QgsGradientColorRampDialog::setColor2( const QColor &color )
577 {
578  mStopEditor->setColor2( color );
579  updateColorButtons();
580 }
581 
582 void QgsGradientColorRampDialog::showHelp()
583 {
584  QgsHelp::openHelp( QStringLiteral( "style_library/style_manager.html#setting-a-color-ramp" ) );
585 }
586 
587 
589 
590 QgsGradientPlotEventFilter::QgsGradientPlotEventFilter( QwtPlot *plot )
591  : QObject( plot )
592  , mPlot( plot )
593 {
594  mPlot->canvas()->installEventFilter( this );
595 }
596 
597 bool QgsGradientPlotEventFilter::eventFilter( QObject *object, QEvent *event )
598 {
599  if ( !mPlot->isEnabled() )
600  return QObject::eventFilter( object, event );
601 
602  switch ( event->type() )
603  {
604  case QEvent::MouseButtonPress:
605  {
606  const QMouseEvent *mouseEvent = static_cast<QMouseEvent * >( event );
607  if ( mouseEvent->button() == Qt::LeftButton )
608  {
609  emit mousePress( mapPoint( mouseEvent->pos() ) );
610  }
611  break;
612  }
613  case QEvent::MouseMove:
614  {
615  const QMouseEvent *mouseEvent = static_cast<QMouseEvent * >( event );
616  if ( mouseEvent->buttons() & Qt::LeftButton )
617  {
618  // only emit when button pressed
619  emit mouseMove( mapPoint( mouseEvent->pos() ) );
620  }
621  break;
622  }
623  case QEvent::MouseButtonRelease:
624  {
625  const QMouseEvent *mouseEvent = static_cast<QMouseEvent * >( event );
626  if ( mouseEvent->button() == Qt::LeftButton )
627  {
628  emit mouseRelease( mapPoint( mouseEvent->pos() ) );
629  }
630  break;
631  }
632  default:
633  break;
634  }
635 
636  return QObject::eventFilter( object, event );
637 }
638 
639 QPointF QgsGradientPlotEventFilter::mapPoint( QPointF point ) const
640 {
641  if ( !mPlot )
642  return QPointF();
643 
644  return QPointF( mPlot->canvasMap( QwtPlot::xBottom ).invTransform( point.x() ),
645  mPlot->canvasMap( QwtPlot::yLeft ).invTransform( point.y() ) );
646 }
647 
void setColor2(const QColor &color)
Sets the end color for the gradient ramp.
Represents a color stop within a QgsGradientColorRamp color ramp.
Definition: qgscolorramp.h:101
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
void changed()
Emitted when the gradient ramp is changed by a user.
bool byX(QPointF p1, QPointF p2)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QColor color2() const
Returns the gradient end color.
Definition: qgscolorramp.h:179
static QString defaultBaseDir()
void setRamp(const QgsGradientColorRamp &ramp)
Sets the color ramp to show in the dialog.
A generic dialog with layout and button box.
Definition: qgsdialog.h:33
void convertToDiscrete(bool discrete)
Converts a gradient with existing color stops to or from discrete interpolation.
static QgsGui * instance()
Returns a pointer to the singleton instance.
Definition: qgsgui.cpp:62
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog&#39;s button box.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:694
QgsGradientColorRampDialog(const QgsGradientColorRamp &ramp, QWidget *parent=nullptr)
Constructor for QgsGradientColorRampDialog.
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
void deleteSelectedStop()
Deletes the current selected stop.
QgsStringMap info() const
Returns any additional info attached to the gradient ramp (e.g., authorship notes) ...
Definition: qgscolorramp.h:241
double offset
Relative positional offset, between 0 and 1.
Definition: qgscolorramp.h:116
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
Definition: qgscolorramp.h:202
QgsGradientStopsList stops() const
Returns the list of intermediate gradient stops for the ramp.
Definition: qgscolorramp.h:235
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
void selectedStopChanged(const QgsGradientStop &stop)
Emitted when the current selected stop changes.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
void currentColorChanged(const QColor &color)
Emitted when the dialog&#39;s color changes.
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
Definition: qgsdialog.h:46
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...
Definition: qgsgui.cpp:133
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QColor color(double value) const override
Returns the color corresponding to a specified value.
void changed()
Emitted when the dialog settings change.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Definition: qgscolorramp.h:139
QColor color1() const
Returns the gradient start color.
Definition: qgscolorramp.h:172
QgsGradientColorRamp ramp() const
Returns a color ramp representing the current settings from the dialog.
void setColor1(const QColor &color)
Sets the start color for the gradient ramp.
QColor color
Gradient color at stop.
Definition: qgscolorramp.h:118
int count() const override
Returns number of defined colors, or -1 if undefined.
Definition: qgscolorramp.h:159