Skip to content

Commit 76e2781

Browse files
committed
[FEATURE] Interactive color assistant for data defined colors
1 parent 077e880 commit 76e2781

7 files changed

+207
-2
lines changed

python/core/qgsproperty.sip

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class QgsPropertyDefinition
5858

5959
StandardPropertyTemplate standardTemplate() const;
6060

61+
bool supportsAssistant() const;
6162
};
6263

6364
class QgsProperty

src/core/qgsproperty.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ QgsPropertyDefinition::QgsPropertyDefinition( const QString& name, DataType data
177177
, mHelpText( helpText )
178178
{}
179179

180+
bool QgsPropertyDefinition::supportsAssistant() const
181+
{
182+
return mTypes == DataTypeNumeric || mStandardType == Size || mStandardType == StrokeWidth || mStandardType == ColorNoAlpha || mStandardType == ColorWithAlpha;
183+
}
184+
180185
QString QgsPropertyDefinition::trString()
181186
{
182187
// just something to reduce translation redundancy

src/core/qgsproperty.h

+6
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ class CORE_EXPORT QgsPropertyDefinition
150150
*/
151151
StandardPropertyTemplate standardTemplate() const { return mStandardType; }
152152

153+
/**
154+
* Returns true if the property is of a type which is compatible with property
155+
* override assistants.
156+
*/
157+
bool supportsAssistant() const;
158+
153159
private:
154160

155161
QString mName;

src/gui/qgspropertyassistantwidget.cpp

+69
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,16 @@ QgsPropertyAssistantWidget::QgsPropertyAssistantWidget( QWidget* parent ,
7171
case QgsPropertyDefinition::StrokeWidth:
7272
{
7373
mTransformerWidget = new QgsPropertySizeAssistantWidget( this, mDefinition, initialState );
74+
break;
75+
}
76+
77+
case QgsPropertyDefinition::ColorNoAlpha:
78+
case QgsPropertyDefinition::ColorWithAlpha:
79+
{
80+
mTransformerWidget = new QgsPropertyColorAssistantWidget( this, mDefinition, initialState );
81+
break;
7482
}
83+
7584
default:
7685
break;
7786
}
@@ -370,3 +379,63 @@ QList<QgsSymbolLegendNode*> QgsPropertyAbstractTransformerWidget::generatePrevie
370379
{
371380
return QList< QgsSymbolLegendNode* >();
372381
}
382+
383+
QgsPropertyColorAssistantWidget::QgsPropertyColorAssistantWidget( QWidget* parent, const QgsPropertyDefinition& definition, const QgsProperty& initialState )
384+
: QgsPropertyAbstractTransformerWidget( parent, definition )
385+
{
386+
setupUi( this );
387+
388+
layout()->setContentsMargins( 0, 0, 0, 0 );
389+
layout()->setMargin( 0 );
390+
391+
bool supportsAlpha = definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha;
392+
mNullColorButton->setAllowAlpha( supportsAlpha );
393+
394+
if ( const QgsColorRampTransformer* colorTransform = dynamic_cast< const QgsColorRampTransformer* >( initialState.transformer() ) )
395+
{
396+
mNullColorButton->setColor( colorTransform->nullColor() );
397+
mColorRampButton->setColorRamp( colorTransform->colorRamp() );
398+
}
399+
400+
connect( mNullColorButton, &QgsColorButton::colorChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
401+
connect( mColorRampButton, &QgsColorRampButton::colorRampChanged, this, &QgsPropertyColorAssistantWidget::widgetChanged );
402+
}
403+
404+
QgsColorRampTransformer* QgsPropertyColorAssistantWidget::createTransformer( double minValue, double maxValue ) const
405+
{
406+
QgsColorRampTransformer* transformer = new QgsColorRampTransformer(
407+
minValue,
408+
maxValue,
409+
mColorRampButton->colorRamp(),
410+
mNullColorButton->color() );
411+
return transformer;
412+
}
413+
414+
QList<QgsSymbolLegendNode*> QgsPropertyColorAssistantWidget::generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const
415+
{
416+
QList< QgsSymbolLegendNode* > nodes;
417+
418+
const QgsMarkerSymbol* legendSymbol = dynamic_cast<const QgsMarkerSymbol*>( symbol );
419+
std::unique_ptr< QgsMarkerSymbol > tempSymbol;
420+
421+
if ( !legendSymbol )
422+
{
423+
tempSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
424+
legendSymbol = tempSymbol.get();
425+
}
426+
if ( !legendSymbol )
427+
return nodes;
428+
429+
std::unique_ptr< QgsColorRampTransformer > t( createTransformer( minValue, maxValue ) );
430+
431+
for ( int i = 0; i < breaks.length(); i++ )
432+
{
433+
std::unique_ptr< QgsSymbolLegendNode > node;
434+
std::unique_ptr< QgsMarkerSymbol > symbolClone( static_cast<QgsMarkerSymbol*>( legendSymbol->clone() ) );
435+
symbolClone->setColor( t->color( breaks[i] ) );
436+
node.reset( new QgsSymbolLegendNode( parent, QgsLegendSymbolItem( symbolClone.get(), QString::number( i ), QString() ) ) );
437+
if ( node )
438+
nodes << node.release();
439+
}
440+
return nodes;
441+
}

src/gui/qgspropertyassistantwidget.h

+14
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "qgspanelwidget.h"
2222
#include "ui_qgspropertyassistantwidgetbase.h"
2323
#include "ui_qgspropertysizeassistantwidget.h"
24+
#include "ui_qgspropertycolorassistantwidget.h"
2425
#include "qgsproperty.h"
2526
#include "qgslayertreegroup.h"
2627
#include "qgssymbol.h"
@@ -71,6 +72,19 @@ class GUI_EXPORT QgsPropertySizeAssistantWidget : public QgsPropertyAbstractTran
7172
QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const override;
7273
};
7374

75+
class GUI_EXPORT QgsPropertyColorAssistantWidget : public QgsPropertyAbstractTransformerWidget, private Ui::PropertyColorAssistant
76+
{
77+
Q_OBJECT
78+
79+
public:
80+
81+
QgsPropertyColorAssistantWidget( QWidget* parent = nullptr, const QgsPropertyDefinition& definition = QgsPropertyDefinition(), const QgsProperty& initialState = QgsProperty() );
82+
83+
virtual QgsColorRampTransformer* createTransformer( double minValue, double maxValue ) const override;
84+
85+
QList< QgsSymbolLegendNode* > generatePreviews( const QList<double>& breaks, QgsLayerTreeLayer* parent, const QgsSymbol* symbol, double minValue, double maxValue ) const override;
86+
};
87+
7488
///@endcond PRIVATE
7589

7690
class GUI_EXPORT QgsPropertyAssistantWidget : public QgsPanelWidget, private Ui::PropertyAssistantBase

src/gui/qgspropertyoverridebutton.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ void QgsPropertyOverrideButton::aboutToShowMenu()
404404
mDefineMenu->addAction( mActionPasteExpr );
405405
}
406406

407-
if ( !mDefinition.name().isEmpty() )
407+
if ( !mDefinition.name().isEmpty() && mDefinition.supportsAssistant() )
408408
{
409409
mDefineMenu->addSeparator();
410410
mActionAssistant->setCheckable( mProperty.transformer() );
@@ -599,7 +599,7 @@ void QgsPropertyOverrideButton::updateGui()
599599
{
600600
icon = mProperty.isActive() ? QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineOn.svg" ) ) : QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefine.svg" ) );
601601

602-
if ( !mFieldNameList.contains( mFieldName ) )
602+
if ( !mFieldNameList.contains( mFieldName ) && !mProperty.transformer() )
603603
{
604604
icon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineError.svg" ) );
605605
deftip = tr( "'%1' field missing" ).arg( mFieldName );
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>PropertyColorAssistant</class>
4+
<widget class="QWidget" name="PropertyColorAssistant">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>267</width>
10+
<height>163</height>
11+
</rect>
12+
</property>
13+
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0">
14+
<item row="3" column="0">
15+
<widget class="QLabel" name="label_8">
16+
<property name="text">
17+
<string>Color when NULL</string>
18+
</property>
19+
</widget>
20+
</item>
21+
<item row="3" column="1">
22+
<widget class="QgsColorButton" name="mNullColorButton">
23+
<property name="sizePolicy">
24+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
25+
<horstretch>0</horstretch>
26+
<verstretch>0</verstretch>
27+
</sizepolicy>
28+
</property>
29+
<property name="minimumSize">
30+
<size>
31+
<width>120</width>
32+
<height>0</height>
33+
</size>
34+
</property>
35+
<property name="maximumSize">
36+
<size>
37+
<width>16777215</width>
38+
<height>16777215</height>
39+
</size>
40+
</property>
41+
<property name="text">
42+
<string/>
43+
</property>
44+
</widget>
45+
</item>
46+
<item row="4" column="0">
47+
<spacer name="verticalSpacer">
48+
<property name="orientation">
49+
<enum>Qt::Vertical</enum>
50+
</property>
51+
<property name="sizeHint" stdset="0">
52+
<size>
53+
<width>20</width>
54+
<height>40</height>
55+
</size>
56+
</property>
57+
</spacer>
58+
</item>
59+
<item row="2" column="0" colspan="2">
60+
<widget class="QgsColorRampButton" name="mColorRampButton">
61+
<property name="sizePolicy">
62+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
63+
<horstretch>0</horstretch>
64+
<verstretch>0</verstretch>
65+
</sizepolicy>
66+
</property>
67+
<property name="minimumSize">
68+
<size>
69+
<width>120</width>
70+
<height>0</height>
71+
</size>
72+
</property>
73+
<property name="maximumSize">
74+
<size>
75+
<width>16777215</width>
76+
<height>16777215</height>
77+
</size>
78+
</property>
79+
</widget>
80+
</item>
81+
<item row="1" column="0" colspan="2">
82+
<widget class="QLabel" name="label">
83+
<property name="text">
84+
<string>Color ramp</string>
85+
</property>
86+
</widget>
87+
</item>
88+
</layout>
89+
</widget>
90+
<customwidgets>
91+
<customwidget>
92+
<class>QgsColorRampButton</class>
93+
<extends>QToolButton</extends>
94+
<header>qgscolorrampbutton.h</header>
95+
<container>1</container>
96+
</customwidget>
97+
<customwidget>
98+
<class>QgsColorButton</class>
99+
<extends>QToolButton</extends>
100+
<header>qgscolorbutton.h</header>
101+
<container>1</container>
102+
</customwidget>
103+
</customwidgets>
104+
<tabstops>
105+
<tabstop>mColorRampButton</tabstop>
106+
<tabstop>mNullColorButton</tabstop>
107+
</tabstops>
108+
<resources/>
109+
<connections/>
110+
</ui>

0 commit comments

Comments
 (0)