Skip to content

Commit

Permalink
[FEATURE] Interactive color assistant for data defined colors
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Feb 14, 2017
1 parent 077e880 commit 76e2781
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 2 deletions.
1 change: 1 addition & 0 deletions python/core/qgsproperty.sip
Expand Up @@ -58,6 +58,7 @@ class QgsPropertyDefinition

StandardPropertyTemplate standardTemplate() const;

bool supportsAssistant() const;
};

class QgsProperty
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsproperty.cpp
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions src/core/qgsproperty.h
Expand Up @@ -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;
Expand Down
69 changes: 69 additions & 0 deletions src/gui/qgspropertyassistantwidget.cpp
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
14 changes: 14 additions & 0 deletions src/gui/qgspropertyassistantwidget.h
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgspropertyoverridebutton.cpp
Expand Up @@ -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() );
Expand Down Expand Up @@ -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 );
Expand Down
110 changes: 110 additions & 0 deletions src/ui/qgspropertycolorassistantwidget.ui
@@ -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>

0 comments on commit 76e2781

Please sign in to comment.