mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[FEATURE] Interactive curve editing for property overrides
This adds a new interactive "curve" to the assistant widgets. It allows you to fine tune exactly how input values get mapped to output sizes/colors/etc. Think GIMP or Photoshop curves, but for your data...
This commit is contained in:
parent
45861d39f8
commit
cc9b5a47b7
@ -51,6 +51,7 @@
|
||||
%Include qgsconfigureshortcutsdialog.sip
|
||||
%Include qgscredentialdialog.sip
|
||||
%Include qgscustomdrophandler.sip
|
||||
%Include qgscurveeditorwidget.sip
|
||||
%Include qgsdetaileditemdata.sip
|
||||
%Include qgsdetaileditemdelegate.sip
|
||||
%Include qgsdetaileditemwidget.sip
|
||||
|
23
python/gui/qgscurveeditorwidget.sip
Normal file
23
python/gui/qgscurveeditorwidget.sip
Normal file
@ -0,0 +1,23 @@
|
||||
class QgsCurveEditorWidget : QWidget
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgscurveeditorwidget.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
|
||||
QgsCurveEditorWidget( QWidget* parent /TransferThis/ = 0, const QgsCurveTransform& curve = QgsCurveTransform() );
|
||||
|
||||
QgsCurveTransform curve() const;
|
||||
|
||||
void setCurve( const QgsCurveTransform& curve );
|
||||
|
||||
signals:
|
||||
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void keyPressEvent( QKeyEvent *event );
|
||||
|
||||
};
|
@ -193,6 +193,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgscredentialdialog.cpp
|
||||
qgscursors.cpp
|
||||
qgscustomdrophandler.cpp
|
||||
qgscurveeditorwidget.cpp
|
||||
qgsdatumtransformdialog.cpp
|
||||
qgsdetaileditemdata.cpp
|
||||
qgsdetaileditemdelegate.cpp
|
||||
@ -345,6 +346,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgscompoundcolorwidget.h
|
||||
qgsconfigureshortcutsdialog.h
|
||||
qgscredentialdialog.h
|
||||
qgscurveeditorwidget.h
|
||||
qgsdatumtransformdialog.h
|
||||
qgsdetaileditemdelegate.h
|
||||
qgsdetaileditemwidget.h
|
||||
|
312
src/gui/qgscurveeditorwidget.cpp
Normal file
312
src/gui/qgscurveeditorwidget.cpp
Normal file
@ -0,0 +1,312 @@
|
||||
/***************************************************************************
|
||||
qgscurveeditorwidget.cpp
|
||||
------------------------
|
||||
begin : February 2017
|
||||
copyright : (C) 2017 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "qgscurveeditorwidget.h"
|
||||
|
||||
#include <qmath.h>
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
|
||||
// QWT Charting widget
|
||||
#include <qwt_global.h>
|
||||
#include <qwt_plot_canvas.h>
|
||||
#include <qwt_plot.h>
|
||||
#include <qwt_plot_curve.h>
|
||||
#include <qwt_plot_grid.h>
|
||||
#include <qwt_plot_marker.h>
|
||||
#include <qwt_plot_picker.h>
|
||||
#include <qwt_picker_machine.h>
|
||||
#include <qwt_plot_layout.h>
|
||||
#include <qwt_symbol.h>
|
||||
#include <qwt_legend.h>
|
||||
|
||||
QgsCurveEditorWidget::QgsCurveEditorWidget( QWidget* parent, const QgsCurveTransform& transform )
|
||||
: QWidget( parent )
|
||||
, mCurve( transform )
|
||||
, mCurrentPlotMarkerIndex( -1 )
|
||||
{
|
||||
mPlot = new QwtPlot();
|
||||
mPlot->setMinimumSize( QSize( 0, 100 ) );
|
||||
mPlot->setAxisScale( QwtPlot::yLeft, 0, 1 );
|
||||
mPlot->setAxisScale( QwtPlot::yRight, 0, 1 );
|
||||
mPlot->setAxisScale( QwtPlot::xBottom, 0, 1 );
|
||||
mPlot->setAxisScale( QwtPlot::xTop, 0, 1 );
|
||||
|
||||
QVBoxLayout* vlayout = new QVBoxLayout();
|
||||
vlayout->addWidget( mPlot );
|
||||
setLayout( vlayout );
|
||||
|
||||
// hide the ugly canvas frame
|
||||
mPlot->setFrameStyle( QFrame::NoFrame );
|
||||
#if defined(QWT_VERSION) && QWT_VERSION>=0x060000
|
||||
QFrame* plotCanvasFrame = dynamic_cast<QFrame*>( mPlot->canvas() );
|
||||
if ( plotCanvasFrame )
|
||||
plotCanvasFrame->setFrameStyle( QFrame::NoFrame );
|
||||
#else
|
||||
mPlot->canvas()->setFrameStyle( QFrame::NoFrame );
|
||||
#endif
|
||||
|
||||
mPlot->enableAxis( QwtPlot::yLeft, false );
|
||||
mPlot->enableAxis( QwtPlot::xBottom, false );
|
||||
|
||||
// add a grid
|
||||
QwtPlotGrid * grid = new QwtPlotGrid();
|
||||
QwtScaleDiv gridDiv( 0.0, 1.0, QList<double>(), QList<double>(), QList<double>() << 0.2 << 0.4 << 0.6 << 0.8 );
|
||||
grid->setXDiv( gridDiv );
|
||||
grid->setYDiv( gridDiv );
|
||||
grid->setPen( QPen( QColor( 0, 0, 0, 50 ) ) );
|
||||
grid->attach( mPlot );
|
||||
|
||||
mPlotCurve = new QwtPlotCurve();
|
||||
mPlotCurve->setTitle( QStringLiteral( "Curve" ) );
|
||||
mPlotCurve->setPen( QPen( QColor( 30, 30, 30 ), 0.0 ) ),
|
||||
mPlotCurve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
|
||||
mPlotCurve->attach( mPlot );
|
||||
|
||||
mPlotFilter = new QgsCurveEditorPlotEventFilter( mPlot );
|
||||
connect( mPlotFilter, &QgsCurveEditorPlotEventFilter::mousePress, this, &QgsCurveEditorWidget::plotMousePress );
|
||||
connect( mPlotFilter, &QgsCurveEditorPlotEventFilter::mouseRelease, this, &QgsCurveEditorWidget::plotMouseRelease );
|
||||
connect( mPlotFilter, &QgsCurveEditorPlotEventFilter::mouseMove, this, &QgsCurveEditorWidget::plotMouseMove );
|
||||
|
||||
mPlotCurve->setVisible( true );
|
||||
updatePlot();
|
||||
}
|
||||
|
||||
void QgsCurveEditorWidget::setCurve( const QgsCurveTransform& curve )
|
||||
{
|
||||
mCurve = curve;
|
||||
updatePlot();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsCurveEditorWidget::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
if ( event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace )
|
||||
{
|
||||
QList< QgsPoint > cp = mCurve.controlPoints();
|
||||
if ( mCurrentPlotMarkerIndex > 0 && mCurrentPlotMarkerIndex < cp.count() - 1 )
|
||||
{
|
||||
cp.removeAt( mCurrentPlotMarkerIndex );
|
||||
mCurve.setControlPoints( cp );
|
||||
updatePlot();
|
||||
emit changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsCurveEditorWidget::plotMousePress( QPointF point )
|
||||
{
|
||||
mCurrentPlotMarkerIndex = findNearestControlPoint( point );
|
||||
if ( mCurrentPlotMarkerIndex < 0 )
|
||||
{
|
||||
// add a new point
|
||||
mCurve.addControlPoint( point.x(), point.y() );
|
||||
mCurrentPlotMarkerIndex = findNearestControlPoint( point );
|
||||
emit changed();
|
||||
}
|
||||
updatePlot();
|
||||
}
|
||||
|
||||
|
||||
int QgsCurveEditorWidget::findNearestControlPoint( QPointF point ) const
|
||||
{
|
||||
double minDist = 3.0 / mPlot->width();
|
||||
int currentPlotMarkerIndex = -1;
|
||||
|
||||
QList< QgsPoint > controlPoints = mCurve.controlPoints();
|
||||
|
||||
for ( int i = 0; i < controlPoints.count(); ++i )
|
||||
{
|
||||
QgsPoint currentPoint = controlPoints.at( i );
|
||||
double currentDist;
|
||||
currentDist = qPow( point.x() - currentPoint.x(), 2.0 ) + qPow( point.y() - currentPoint.y(), 2.0 );
|
||||
if ( currentDist < minDist )
|
||||
{
|
||||
minDist = currentDist;
|
||||
currentPlotMarkerIndex = i;
|
||||
}
|
||||
}
|
||||
return currentPlotMarkerIndex;
|
||||
}
|
||||
|
||||
|
||||
void QgsCurveEditorWidget::plotMouseRelease( QPointF )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsCurveEditorWidget::plotMouseMove( QPointF point )
|
||||
{
|
||||
if ( mCurrentPlotMarkerIndex < 0 )
|
||||
return;
|
||||
|
||||
QList< QgsPoint > cp = mCurve.controlPoints();
|
||||
bool removePoint = false;
|
||||
if ( mCurrentPlotMarkerIndex == 0 )
|
||||
{
|
||||
point.setX( qMin( point.x(), cp.at( 1 ).x() - 0.01 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
removePoint = point.x() <= cp.at( mCurrentPlotMarkerIndex - 1 ).x();
|
||||
}
|
||||
if ( mCurrentPlotMarkerIndex == cp.count() - 1 )
|
||||
{
|
||||
point.setX( qMax( point.x(), cp.at( mCurrentPlotMarkerIndex - 1 ).x() + 0.01 ) );
|
||||
removePoint = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
removePoint = removePoint || point.x() >= cp.at( mCurrentPlotMarkerIndex + 1 ).x();
|
||||
}
|
||||
|
||||
if ( removePoint )
|
||||
{
|
||||
cp.removeAt( mCurrentPlotMarkerIndex );
|
||||
mCurrentPlotMarkerIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp[ mCurrentPlotMarkerIndex ] = QgsPoint( point.x(), point.y() );
|
||||
}
|
||||
mCurve.setControlPoints( cp );
|
||||
updatePlot();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsCurveEditorWidget::addPlotMarker( double x, double y, bool isSelected )
|
||||
{
|
||||
QColor borderColor( 0, 0, 0 );
|
||||
|
||||
QColor brushColor = isSelected ? borderColor : QColor( 255, 255, 255, 0 );
|
||||
|
||||
QwtPlotMarker *marker = new QwtPlotMarker();
|
||||
#if defined(QWT_VERSION) && QWT_VERSION>=0x060000
|
||||
marker->setSymbol( new QwtSymbol( QwtSymbol::Ellipse, QBrush( brushColor ), QPen( borderColor, isSelected ? 2 : 1 ), QSize( 6, 6 ) ) );
|
||||
#else
|
||||
marker->setSymbol( QwtSymbol( QwtSymbol::Ellipse, QBrush( brushColor ), QPen( borderColor, isSelected ? 2 : 1 ), QSize( 6, 6 ) ) );
|
||||
#endif
|
||||
marker->setValue( x, y );
|
||||
marker->attach( mPlot );
|
||||
marker->setRenderHint( QwtPlotItem::RenderAntialiased, true );
|
||||
mMarkers << marker;
|
||||
}
|
||||
|
||||
void QgsCurveEditorWidget::updatePlot()
|
||||
{
|
||||
// remove existing markers
|
||||
Q_FOREACH ( QwtPlotMarker* marker, mMarkers )
|
||||
{
|
||||
marker->detach();
|
||||
delete marker;
|
||||
}
|
||||
mMarkers.clear();
|
||||
|
||||
QPolygonF curvePoints;
|
||||
QVector< double > x;
|
||||
|
||||
int i = 0;
|
||||
Q_FOREACH ( const QgsPoint& point, mCurve.controlPoints() )
|
||||
{
|
||||
x << point.x();
|
||||
addPlotMarker( point.x(), point.y(), mCurrentPlotMarkerIndex == i );
|
||||
i++;
|
||||
}
|
||||
|
||||
//add extra intermediate points
|
||||
|
||||
for ( double p = 0; p <= 1.0; p += 0.01 )
|
||||
{
|
||||
x << p;
|
||||
}
|
||||
std::sort( x.begin(), x.end() );
|
||||
QVector< double > y = mCurve.y( x );
|
||||
|
||||
for ( int j = 0; j < x.count(); ++j )
|
||||
{
|
||||
curvePoints << QPointF( x.at( j ), y.at( j ) );
|
||||
}
|
||||
|
||||
#if defined(QWT_VERSION) && QWT_VERSION>=0x060000
|
||||
mPlotCurve->setSamples( curvePoints );
|
||||
#else
|
||||
mPlotCurve->setData( curvePoints );
|
||||
#endif
|
||||
mPlot->replot();
|
||||
}
|
||||
|
||||
|
||||
/// @cond PRIVATE
|
||||
|
||||
QgsCurveEditorPlotEventFilter::QgsCurveEditorPlotEventFilter( QwtPlot *plot )
|
||||
: QObject( plot )
|
||||
, mPlot( plot )
|
||||
{
|
||||
mPlot->canvas()->installEventFilter( this );
|
||||
}
|
||||
|
||||
bool QgsCurveEditorPlotEventFilter::eventFilter( QObject *object, QEvent *event )
|
||||
{
|
||||
if ( !mPlot->isEnabled() )
|
||||
return QObject::eventFilter( object, event );
|
||||
|
||||
switch ( event->type() )
|
||||
{
|
||||
case QEvent::MouseButtonPress:
|
||||
{
|
||||
const QMouseEvent* mouseEvent = static_cast<QMouseEvent* >( event );
|
||||
if ( mouseEvent->button() == Qt::LeftButton )
|
||||
{
|
||||
emit mousePress( mapPoint( mouseEvent->pos() ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
const QMouseEvent* mouseEvent = static_cast<QMouseEvent* >( event );
|
||||
if ( mouseEvent->buttons() & Qt::LeftButton )
|
||||
{
|
||||
// only emit when button pressed
|
||||
emit mouseMove( mapPoint( mouseEvent->pos() ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
const QMouseEvent* mouseEvent = static_cast<QMouseEvent* >( event );
|
||||
if ( mouseEvent->button() == Qt::LeftButton )
|
||||
{
|
||||
emit mouseRelease( mapPoint( mouseEvent->pos() ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QObject::eventFilter( object, event );
|
||||
}
|
||||
|
||||
QPointF QgsCurveEditorPlotEventFilter::mapPoint( QPointF point ) const
|
||||
{
|
||||
if ( !mPlot )
|
||||
return QPointF();
|
||||
|
||||
return QPointF( mPlot->canvasMap( QwtPlot::xBottom ).invTransform( point.x() ),
|
||||
mPlot->canvasMap( QwtPlot::yLeft ).invTransform( point.y() ) );
|
||||
}
|
||||
|
||||
///@endcond
|
118
src/gui/qgscurveeditorwidget.h
Normal file
118
src/gui/qgscurveeditorwidget.h
Normal file
@ -0,0 +1,118 @@
|
||||
/***************************************************************************
|
||||
qgscurveeditorwidget.h
|
||||
----------------------
|
||||
begin : February 2017
|
||||
copyright : (C) 2017 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCURVEEDITORWIDGET_H
|
||||
#define QGSCURVEEDITORWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "qgis_gui.h"
|
||||
#include "qgspropertytransformer.h"
|
||||
|
||||
class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
class QwtPlotMarker;
|
||||
class QgsCurveEditorPlotEventFilter;
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsCurveEditorWidget
|
||||
* A widget for manipulating QgsCurveTransform curves.
|
||||
* \note added in QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsCurveEditorWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsCurveEditorWidget.
|
||||
*/
|
||||
QgsCurveEditorWidget( QWidget* parent = nullptr, const QgsCurveTransform& curve = QgsCurveTransform() );
|
||||
|
||||
/**
|
||||
* Returns a curve representing the current curve from the widget.
|
||||
* @see setCurve()
|
||||
*/
|
||||
QgsCurveTransform curve() const { return mCurve; }
|
||||
|
||||
/**
|
||||
* Sets the \a curve to show in the widget.
|
||||
* @see curve()
|
||||
*/
|
||||
void setCurve( const QgsCurveTransform& curve );
|
||||
|
||||
signals:
|
||||
|
||||
//! Emitted when the widget curve changes
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void keyPressEvent( QKeyEvent *event ) override ;
|
||||
|
||||
private slots:
|
||||
|
||||
void plotMousePress( QPointF point );
|
||||
void plotMouseRelease( QPointF point );
|
||||
void plotMouseMove( QPointF point );
|
||||
|
||||
private:
|
||||
|
||||
QgsCurveTransform mCurve;
|
||||
|
||||
QwtPlot* mPlot = nullptr;
|
||||
|
||||
QwtPlotCurve* mPlotCurve = nullptr;
|
||||
|
||||
QList< QwtPlotMarker* > mMarkers;
|
||||
QgsCurveEditorPlotEventFilter* mPlotFilter = nullptr;
|
||||
int mCurrentPlotMarkerIndex;
|
||||
|
||||
void updatePlot();
|
||||
void addPlotMarker( double x, double y, bool isSelected = false );
|
||||
|
||||
int findNearestControlPoint( QPointF point ) const;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// NOTE:
|
||||
// For private only, not part of stable api or exposed to Python bindings
|
||||
//
|
||||
/// @cond PRIVATE
|
||||
class GUI_EXPORT QgsCurveEditorPlotEventFilter: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
QgsCurveEditorPlotEventFilter( QwtPlot *plot );
|
||||
|
||||
virtual bool eventFilter( QObject* object, QEvent* event ) override;
|
||||
|
||||
signals:
|
||||
|
||||
void mousePress( QPointF );
|
||||
void mouseRelease( QPointF );
|
||||
void mouseMove( QPointF );
|
||||
|
||||
private:
|
||||
|
||||
QwtPlot* mPlot;
|
||||
QPointF mapPoint( QPointF point ) const;
|
||||
};
|
||||
///@endcond
|
||||
|
||||
#endif // QGSCURVEEDITORWIDGET_H
|
@ -51,6 +51,12 @@ QgsPropertyAssistantWidget::QgsPropertyAssistantWidget( QWidget* parent ,
|
||||
{
|
||||
minValueSpinBox->setValue( initialState.transformer()->minValue() );
|
||||
maxValueSpinBox->setValue( initialState.transformer()->maxValue() );
|
||||
|
||||
if ( initialState.transformer()->curveTransform() )
|
||||
{
|
||||
mTransformCurveCheckBox->setChecked( true );
|
||||
mCurveEditor->setCurve( *initialState.transformer()->curveTransform() );
|
||||
}
|
||||
}
|
||||
|
||||
connect( computeValuesButton, &QPushButton::clicked, this, &QgsPropertyAssistantWidget::computeValuesFromLayer );
|
||||
@ -108,10 +114,12 @@ QgsPropertyAssistantWidget::QgsPropertyAssistantWidget( QWidget* parent ,
|
||||
mOutputWidget->layout()->addWidget( mTransformerWidget );
|
||||
connect( mTransformerWidget, &QgsPropertyAbstractTransformerWidget::widgetChanged, this, &QgsPropertyAssistantWidget::widgetChanged );
|
||||
}
|
||||
mTransformCurveCheckBox->setVisible( mTransformerWidget );
|
||||
|
||||
connect( minValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
|
||||
connect( maxValueSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
|
||||
connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString& ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsPropertyAssistantWidget::widgetChanged );
|
||||
connect( mCurveEditor, &QgsCurveEditorWidget::changed, this, &QgsPropertyAssistantWidget::widgetChanged );
|
||||
connect( this, &QgsPropertyAssistantWidget::widgetChanged, this, &QgsPropertyAssistantWidget::updatePreview );
|
||||
updatePreview();
|
||||
}
|
||||
@ -131,7 +139,18 @@ void QgsPropertyAssistantWidget::updateProperty( QgsProperty& property )
|
||||
property.setField( mExpressionWidget->currentField() );
|
||||
|
||||
if ( mTransformerWidget )
|
||||
property.setTransformer( mTransformerWidget->createTransformer( minValueSpinBox->value(), maxValueSpinBox->value() ) );
|
||||
{
|
||||
std::unique_ptr< QgsPropertyTransformer> t( mTransformerWidget->createTransformer( minValueSpinBox->value(), maxValueSpinBox->value() ) );
|
||||
if ( mTransformCurveCheckBox->isChecked() )
|
||||
{
|
||||
t->setCurveTransform( new QgsCurveTransform( mCurveEditor->curve() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
t->setCurveTransform( nullptr );
|
||||
}
|
||||
property.setTransformer( t.release() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsPropertyAssistantWidget::setDockMode( bool dockMode )
|
||||
@ -180,8 +199,9 @@ void QgsPropertyAssistantWidget::updatePreview()
|
||||
QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( minValueSpinBox->value(),
|
||||
maxValueSpinBox->value(), 8 );
|
||||
|
||||
QgsCurveTransform curve = mCurveEditor->curve();
|
||||
QList< QgsSymbolLegendNode* > nodes = mTransformerWidget->generatePreviews( breaks, mLayerTreeLayer, mSymbol.get(), minValueSpinBox->value(),
|
||||
maxValueSpinBox->value() );
|
||||
maxValueSpinBox->value(), mTransformCurveCheckBox->isChecked() ? &curve : nullptr );
|
||||
|
||||
int widthMax = 0;
|
||||
int i = 0;
|
||||
@ -353,7 +373,7 @@ QgsSizeScaleTransformer* QgsPropertySizeAssistantWidget::createTransformer( doub
|
||||
return transformer;
|
||||
}
|
||||
|
||||
QList< QgsSymbolLegendNode* > QgsPropertySizeAssistantWidget::generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const
|
||||
QList< QgsSymbolLegendNode* > QgsPropertySizeAssistantWidget::generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue, QgsCurveTransform* curve ) const
|
||||
{
|
||||
QList< QgsSymbolLegendNode* > nodes;
|
||||
|
||||
@ -376,6 +396,8 @@ QList< QgsSymbolLegendNode* > QgsPropertySizeAssistantWidget::generatePreviews(
|
||||
return nodes;
|
||||
|
||||
std::unique_ptr< QgsSizeScaleTransformer > t( createTransformer( minValue, maxValue ) );
|
||||
if ( curve )
|
||||
t->setCurveTransform( new QgsCurveTransform( *curve ) );
|
||||
|
||||
for ( int i = 0; i < breaks.length(); i++ )
|
||||
{
|
||||
@ -401,7 +423,7 @@ QList< QgsSymbolLegendNode* > QgsPropertySizeAssistantWidget::generatePreviews(
|
||||
return nodes;
|
||||
}
|
||||
|
||||
QList<QgsSymbolLegendNode*> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double>& , QgsLayerTreeLayer* , const QgsSymbol*, double, double ) const
|
||||
QList<QgsSymbolLegendNode*> QgsPropertyAbstractTransformerWidget::generatePreviews( const QList<double>& , QgsLayerTreeLayer* , const QgsSymbol*, double, double, QgsCurveTransform* ) const
|
||||
{
|
||||
return QList< QgsSymbolLegendNode* >();
|
||||
}
|
||||
@ -451,7 +473,7 @@ QgsColorRampTransformer* QgsPropertyColorAssistantWidget::createTransformer( dou
|
||||
return transformer;
|
||||
}
|
||||
|
||||
QList<QgsSymbolLegendNode*> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const
|
||||
QList<QgsSymbolLegendNode*> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue , QgsCurveTransform* curve ) const
|
||||
{
|
||||
QList< QgsSymbolLegendNode* > nodes;
|
||||
|
||||
@ -467,6 +489,8 @@ QList<QgsSymbolLegendNode*> QgsPropertyColorAssistantWidget::generatePreviews( c
|
||||
return nodes;
|
||||
|
||||
std::unique_ptr< QgsColorRampTransformer > t( createTransformer( minValue, maxValue ) );
|
||||
if ( curve )
|
||||
t->setCurveTransform( new QgsCurveTransform( *curve ) );
|
||||
|
||||
for ( int i = 0; i < breaks.length(); i++ )
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ class GUI_EXPORT QgsPropertyAbstractTransformerWidget : public QWidget
|
||||
|
||||
virtual QgsPropertyTransformer* createTransformer( double minValue, double maxValue ) const = 0;
|
||||
|
||||
virtual QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const;
|
||||
virtual QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue, QgsCurveTransform* curve ) const;
|
||||
|
||||
signals:
|
||||
|
||||
@ -82,7 +82,7 @@ class GUI_EXPORT QgsPropertySizeAssistantWidget : public QgsPropertyAbstractTran
|
||||
|
||||
virtual QgsSizeScaleTransformer* createTransformer( double minValue, double maxValue ) const override;
|
||||
|
||||
QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const override;
|
||||
QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue, QgsCurveTransform* curve ) const override;
|
||||
};
|
||||
|
||||
class GUI_EXPORT QgsPropertyColorAssistantWidget : public QgsPropertyAbstractTransformerWidget, private Ui::PropertyColorAssistant
|
||||
@ -95,7 +95,7 @@ class GUI_EXPORT QgsPropertyColorAssistantWidget : public QgsPropertyAbstractTra
|
||||
|
||||
virtual QgsColorRampTransformer* createTransformer( double minValue, double maxValue ) const override;
|
||||
|
||||
QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const override;
|
||||
QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue, QgsCurveTransform* curve ) const override;
|
||||
};
|
||||
|
||||
///@endcond PRIVATE
|
||||
|
@ -6,22 +6,12 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>522</width>
|
||||
<height>332</height>
|
||||
<width>525</width>
|
||||
<height>426</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,0">
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="QTreeView" name="mLegendPreview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,0,0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Output</string>
|
||||
@ -60,6 +50,16 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QFrame" name="mLegendVerticalFrame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
@ -153,14 +153,60 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QFrame" name="mLegendVerticalFrame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
<item row="0" column="1" rowspan="3">
|
||||
<widget class="QTreeView" name="mLegendPreview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="mTransformCurveCheckBox">
|
||||
<property name="title">
|
||||
<string>Apply transform curve</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">composeritem</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QgsCurveEditorWidget" name="mCurveEditor" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -183,6 +229,18 @@
|
||||
<header>qgspanelwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBoxBasic</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header location="global">qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsCurveEditorWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">qgscurveeditorwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mExpressionWidget</tabstop>
|
||||
|
Loading…
x
Reference in New Issue
Block a user