diff --git a/python/gui/gui.sip b/python/gui/gui.sip index 225ef6a593c..98cb3be40e3 100644 --- a/python/gui/gui.sip +++ b/python/gui/gui.sip @@ -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 diff --git a/python/gui/qgscurveeditorwidget.sip b/python/gui/qgscurveeditorwidget.sip new file mode 100644 index 00000000000..799aa05acdd --- /dev/null +++ b/python/gui/qgscurveeditorwidget.sip @@ -0,0 +1,23 @@ +class QgsCurveEditorWidget : QWidget +{ +%TypeHeaderCode +#include +%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 ); + +}; diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f829bed14a6..b1c93d4529f 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -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 diff --git a/src/gui/qgscurveeditorwidget.cpp b/src/gui/qgscurveeditorwidget.cpp new file mode 100644 index 00000000000..d3ae90e2865 --- /dev/null +++ b/src/gui/qgscurveeditorwidget.cpp @@ -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 +#include +#include +#include + +// QWT Charting widget +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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( 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(), QList(), QList() << 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( event ); + if ( mouseEvent->button() == Qt::LeftButton ) + { + emit mousePress( mapPoint( mouseEvent->pos() ) ); + } + break; + } + case QEvent::MouseMove: + { + const QMouseEvent* mouseEvent = static_cast( 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( 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 diff --git a/src/gui/qgscurveeditorwidget.h b/src/gui/qgscurveeditorwidget.h new file mode 100644 index 00000000000..c87be3294f3 --- /dev/null +++ b/src/gui/qgscurveeditorwidget.h @@ -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 +#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 diff --git a/src/gui/qgspropertyassistantwidget.cpp b/src/gui/qgspropertyassistantwidget.cpp index 165c1677add..59cfea5a12b 100644 --- a/src/gui/qgspropertyassistantwidget.cpp +++ b/src/gui/qgspropertyassistantwidget.cpp @@ -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 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& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const +QList< QgsSymbolLegendNode* > QgsPropertySizeAssistantWidget::generatePreviews( const QList& 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 QgsPropertyAbstractTransformerWidget::generatePreviews( const QList& , QgsLayerTreeLayer* , const QgsSymbol*, double, double ) const +QList QgsPropertyAbstractTransformerWidget::generatePreviews( const QList& , QgsLayerTreeLayer* , const QgsSymbol*, double, double, QgsCurveTransform* ) const { return QList< QgsSymbolLegendNode* >(); } @@ -451,7 +473,7 @@ QgsColorRampTransformer* QgsPropertyColorAssistantWidget::createTransformer( dou return transformer; } -QList QgsPropertyColorAssistantWidget::generatePreviews( const QList& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const +QList QgsPropertyColorAssistantWidget::generatePreviews( const QList& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue , QgsCurveTransform* curve ) const { QList< QgsSymbolLegendNode* > nodes; @@ -467,6 +489,8 @@ QList 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++ ) { diff --git a/src/gui/qgspropertyassistantwidget.h b/src/gui/qgspropertyassistantwidget.h index abc8f819c73..ab89f467337 100644 --- a/src/gui/qgspropertyassistantwidget.h +++ b/src/gui/qgspropertyassistantwidget.h @@ -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& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const; + virtual QList< QgsSymbolLegendNode* > generatePreviews( const QList& 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& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const override; + QList< QgsSymbolLegendNode* > generatePreviews( const QList& 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& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const override; + QList< QgsSymbolLegendNode* > generatePreviews( const QList& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue, QgsCurveTransform* curve ) const override; }; ///@endcond PRIVATE diff --git a/src/ui/qgspropertyassistantwidgetbase.ui b/src/ui/qgspropertyassistantwidgetbase.ui index 026f0bb17e4..22fc30bc7d9 100644 --- a/src/ui/qgspropertyassistantwidgetbase.ui +++ b/src/ui/qgspropertyassistantwidgetbase.ui @@ -6,22 +6,12 @@ 0 0 - 522 - 332 + 525 + 426 - - - - - - 200 - 0 - - - - - + + Output @@ -60,6 +50,16 @@ + + + + QFrame::NoFrame + + + QFrame::Plain + + + @@ -153,14 +153,60 @@ - - - - QFrame::NoFrame + + + + + 200 + 0 + - - QFrame::Plain + + + + + + Apply transform curve + + true + + + false + + + true + + + composeritem + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 100 + + + + Qt::StrongFocus + + + + @@ -183,6 +229,18 @@
qgspanelwidget.h
1 + + QgsCollapsibleGroupBoxBasic + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
+ + QgsCurveEditorWidget + QWidget +
qgscurveeditorwidget.h
+ 1 +
mExpressionWidget