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