[FEATURE] Interactive color assistant for data defined colors

This commit is contained in:
Nyall Dawson 2017-02-13 13:15:43 +10:00
parent 077e880444
commit 76e27818a5
7 changed files with 207 additions and 2 deletions

View File

@ -58,6 +58,7 @@ class QgsPropertyDefinition
StandardPropertyTemplate standardTemplate() const;
bool supportsAssistant() const;
};
class QgsProperty

View File

@ -177,6 +177,11 @@ QgsPropertyDefinition::QgsPropertyDefinition( const QString& name, DataType data
, mHelpText( helpText )
{}
bool QgsPropertyDefinition::supportsAssistant() const
{
return mTypes == DataTypeNumeric || mStandardType == Size || mStandardType == StrokeWidth || mStandardType == ColorNoAlpha || mStandardType == ColorWithAlpha;
}
QString QgsPropertyDefinition::trString()
{
// just something to reduce translation redundancy

View File

@ -150,6 +150,12 @@ class CORE_EXPORT QgsPropertyDefinition
*/
StandardPropertyTemplate standardTemplate() const { return mStandardType; }
/**
* Returns true if the property is of a type which is compatible with property
* override assistants.
*/
bool supportsAssistant() const;
private:
QString mName;

View File

@ -71,7 +71,16 @@ QgsPropertyAssistantWidget::QgsPropertyAssistantWidget( QWidget* parent ,
case QgsPropertyDefinition::StrokeWidth:
{
mTransformerWidget = new QgsPropertySizeAssistantWidget( this, mDefinition, initialState );
break;
}
case QgsPropertyDefinition::ColorNoAlpha:
case QgsPropertyDefinition::ColorWithAlpha:
{
mTransformerWidget = new QgsPropertyColorAssistantWidget( this, mDefinition, initialState );
break;
}
default:
break;
}
@ -370,3 +379,63 @@ QList<QgsSymbolLegendNode*> QgsPropertyAbstractTransformerWidget::generatePrevie
{
return QList< QgsSymbolLegendNode* >();
}
QgsPropertyColorAssistantWidget::QgsPropertyColorAssistantWidget( QWidget* parent, const QgsPropertyDefinition& definition, const QgsProperty& initialState )
: QgsPropertyAbstractTransformerWidget( parent, definition )
{
setupUi( this );
layout()->setContentsMargins( 0, 0, 0, 0 );
layout()->setMargin( 0 );
bool supportsAlpha = definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha;
mNullColorButton->setAllowAlpha( supportsAlpha );
if ( const QgsColorRampTransformer* colorTransform = dynamic_cast< const QgsColorRampTransformer* >( initialState.transformer() ) )
{
mNullColorButton->setColor( colorTransform->nullColor() );
mColorRampButton->setColorRamp( colorTransform->colorRamp() );
}
connect( mNullColorButton, &QgsColorButton::colorChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
connect( mColorRampButton, &QgsColorRampButton::colorRampChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
}
QgsColorRampTransformer* QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
{
QgsColorRampTransformer* transformer = new QgsColorRampTransformer(
minValue,
maxValue,
mColorRampButton->colorRamp(),
mNullColorButton->color() );
return transformer;
}
QList<QgsSymbolLegendNode*> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const
{
QList< QgsSymbolLegendNode* > nodes;
const QgsMarkerSymbol* legendSymbol = dynamic_cast<const QgsMarkerSymbol*>( symbol );
std::unique_ptr< QgsMarkerSymbol > tempSymbol;
if ( !legendSymbol )
{
tempSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
legendSymbol = tempSymbol.get();
}
if ( !legendSymbol )
return nodes;
std::unique_ptr< QgsColorRampTransformer > t( createTransformer( minValue, maxValue ) );
for ( int i = 0; i < breaks.length(); i++ )
{
std::unique_ptr< QgsSymbolLegendNode > node;
std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol*>( legendSymbol->clone() ) );
symbolClone->setColor( t->color( breaks[i] ) );
node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
if ( node )
nodes << node.release();
}
return nodes;
}

View File

@ -21,6 +21,7 @@
#include "qgspanelwidget.h"
#include "ui_qgspropertyassistantwidgetbase.h"
#include "ui_qgspropertysizeassistantwidget.h"
#include "ui_qgspropertycolorassistantwidget.h"
#include "qgsproperty.h"
#include "qgslayertreegroup.h"
#include "qgssymbol.h"
@ -71,6 +72,19 @@ class GUI_EXPORT QgsPropertySizeAssistantWidget : public QgsPropertyAbstractTran
QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const override;
};
class GUI_EXPORT QgsPropertyColorAssistantWidget : public QgsPropertyAbstractTransformerWidget, private Ui::PropertyColorAssistant
{
Q_OBJECT
public:
QgsPropertyColorAssistantWidget( QWidget* parent = nullptr, const QgsPropertyDefinition& definition = QgsPropertyDefinition(), const QgsProperty& initialState = QgsProperty() );
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;
};
///@endcond PRIVATE
class GUI_EXPORT QgsPropertyAssistantWidget : public QgsPanelWidget, private Ui::PropertyAssistantBase

View File

@ -404,7 +404,7 @@ void QgsPropertyOverrideButton::aboutToShowMenu()
mDefineMenu->addAction( mActionPasteExpr );
}
if ( !mDefinition.name().isEmpty() )
if ( !mDefinition.name().isEmpty() && mDefinition.supportsAssistant() )
{
mDefineMenu->addSeparator();
mActionAssistant->setCheckable( mProperty.transformer() );
@ -599,7 +599,7 @@ void QgsPropertyOverrideButton::updateGui()
{
icon = mProperty.isActive() ? QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineOn.svg" ) ) : QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefine.svg" ) );
if ( !mFieldNameList.contains( mFieldName ) )
if ( !mFieldNameList.contains( mFieldName ) && !mProperty.transformer() )
{
icon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineError.svg" ) );
deftip = tr( "'%1' field missing" ).arg( mFieldName );

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PropertyColorAssistant</class>
<widget class="QWidget" name="PropertyColorAssistant">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>267</width>
<height>163</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0">
<item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Color when NULL</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QgsColorButton" name="mNullColorButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="2">
<widget class="QgsColorRampButton" name="mColorRampButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Color ramp</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsColorRampButton</class>
<extends>QToolButton</extends>
<header>qgscolorrampbutton.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorButton</class>
<extends>QToolButton</extends>
<header>qgscolorbutton.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mColorRampButton</tabstop>
<tabstop>mNullColorButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>