QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
qgsmodelgraphicitem.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmodelgraphicitem.cpp
3 ----------------------------------
4 Date : February 2020
5 Copyright : (C) 2020 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsmodelgraphicitem.h"
17
18#include "qgsapplication.h"
23#include "qgsmodelviewtool.h"
29
30#include <QGraphicsSceneMouseEvent>
31#include <QPainter>
32#include <QSvgRenderer>
33
34#include "moc_qgsmodelgraphicitem.cpp"
35
37
38QgsModelDesignerFlatButtonGraphicItem::QgsModelDesignerFlatButtonGraphicItem( QGraphicsItem *parent, const QPicture &picture, const QPointF &position, const QSizeF &size )
39 : QGraphicsObject( parent )
40 , mPicture( picture )
41 , mPosition( position )
42 , mSize( size )
43{
44 setAcceptHoverEvents( true );
45 setFlag( QGraphicsItem::ItemIsMovable, false );
46 setCacheMode( QGraphicsItem::DeviceCoordinateCache );
47}
48
49void QgsModelDesignerFlatButtonGraphicItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * )
50{
51 if ( QgsModelGraphicsScene *modelScene = qobject_cast<QgsModelGraphicsScene *>( scene() ) )
52 {
53 if ( modelScene->flags() & QgsModelGraphicsScene::FlagHideControls )
54 return;
55 }
56
57 if ( mHoverState )
58 {
59 painter->setPen( QPen( Qt::transparent, 1.0 ) );
60 painter->setBrush( QBrush( QColor( 55, 55, 55, 33 ), Qt::SolidPattern ) );
61 }
62 else
63 {
64 painter->setPen( QPen( Qt::transparent, 1.0 ) );
65 painter->setBrush( QBrush( Qt::transparent, Qt::SolidPattern ) );
66 }
67 const QPointF topLeft = mPosition - QPointF( std::floor( mSize.width() / 2 ), std::floor( mSize.height() / 2 ) );
68 const QRectF rect = QRectF( topLeft.x(), topLeft.y(), mSize.width(), mSize.height() );
69 painter->drawRect( rect );
70 painter->drawPicture( topLeft.x(), topLeft.y(), mPicture );
71}
72
73QRectF QgsModelDesignerFlatButtonGraphicItem::boundingRect() const
74{
75 return QRectF( mPosition.x() - std::floor( mSize.width() / 2 ), mPosition.y() - std::floor( mSize.height() / 2 ), mSize.width(), mSize.height() );
76}
77
78void QgsModelDesignerFlatButtonGraphicItem::hoverEnterEvent( QGraphicsSceneHoverEvent * )
79{
80 if ( view()->tool() && !view()->tool()->allowItemInteraction() )
81 mHoverState = false;
82 else
83 mHoverState = true;
84 update();
85}
86
87void QgsModelDesignerFlatButtonGraphicItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * )
88{
89 mHoverState = false;
90 update();
91}
92
93void QgsModelDesignerFlatButtonGraphicItem::mousePressEvent( QGraphicsSceneMouseEvent * )
94{
95 if ( view()->tool() && view()->tool()->allowItemInteraction() )
96 emit clicked();
97}
98
99void QgsModelDesignerFlatButtonGraphicItem::modelHoverEnterEvent( QgsModelViewMouseEvent * )
100{
101 if ( view()->tool() && !view()->tool()->allowItemInteraction() )
102 mHoverState = false;
103 else
104 mHoverState = true;
105 update();
106}
107
108void QgsModelDesignerFlatButtonGraphicItem::modelHoverLeaveEvent( QgsModelViewMouseEvent * )
109{
110 mHoverState = false;
111 update();
112}
113
114void QgsModelDesignerFlatButtonGraphicItem::modelPressEvent( QgsModelViewMouseEvent *event )
115{
116 if ( view()->tool() && view()->tool()->allowItemInteraction() && event->button() == Qt::LeftButton )
117 {
118 QMetaObject::invokeMethod( this, "clicked", Qt::QueuedConnection );
119 mHoverState = false;
120 update();
121 }
122}
123
124void QgsModelDesignerFlatButtonGraphicItem::setPosition( const QPointF &position )
125{
126 mPosition = position;
127 prepareGeometryChange();
128 update();
129}
130
131QgsModelGraphicsView *QgsModelDesignerFlatButtonGraphicItem::view()
132{
133 return qobject_cast<QgsModelGraphicsView *>( scene()->views().first() );
134}
135
136void QgsModelDesignerFlatButtonGraphicItem::setPicture( const QPicture &picture )
137{
138 mPicture = picture;
139 update();
140}
141
142//
143// QgsModelDesignerFoldButtonGraphicItem
144//
145
146QgsModelDesignerFoldButtonGraphicItem::QgsModelDesignerFoldButtonGraphicItem( QGraphicsItem *parent, bool folded, const QPointF &position, const QSizeF &size )
147 : QgsModelDesignerFlatButtonGraphicItem( parent, QPicture(), position, size )
148 , mFolded( folded )
149{
150 QSvgRenderer svg( QgsApplication::iconPath( QStringLiteral( "mIconModelerExpand.svg" ) ) );
151 QPainter painter( &mPlusPicture );
152 svg.render( &painter );
153 painter.end();
154
155 QSvgRenderer svg2( QgsApplication::iconPath( QStringLiteral( "mIconModelerCollapse.svg" ) ) );
156 painter.begin( &mMinusPicture );
157 svg2.render( &painter );
158 painter.end();
159
160 setPicture( mFolded ? mPlusPicture : mMinusPicture );
161}
162
163void QgsModelDesignerFoldButtonGraphicItem::mousePressEvent( QGraphicsSceneMouseEvent *event )
164{
165 mFolded = !mFolded;
166 setPicture( mFolded ? mPlusPicture : mMinusPicture );
167 emit folded( mFolded );
168 QgsModelDesignerFlatButtonGraphicItem::mousePressEvent( event );
169}
170
171void QgsModelDesignerFoldButtonGraphicItem::modelPressEvent( QgsModelViewMouseEvent *event )
172{
173 mFolded = !mFolded;
174 setPicture( mFolded ? mPlusPicture : mMinusPicture );
175 emit folded( mFolded );
176 QgsModelDesignerFlatButtonGraphicItem::modelPressEvent( event );
177}
178
179
180QgsModelDesignerSocketGraphicItem::QgsModelDesignerSocketGraphicItem( QgsModelComponentGraphicItem *parent, QgsProcessingModelComponent *component, int index, const QPointF &position, Qt::Edge edge, const QSizeF &size )
181 : QgsModelDesignerFlatButtonGraphicItem( parent, QPicture(), position, size )
182 , mComponentItem( parent )
183 , mComponent( component )
184 , mIndex( index )
185 , mEdge( edge )
186{
187}
188
189void QgsModelDesignerSocketGraphicItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * )
190{
191 QColor outlineColor = socketColor();
192 QColor fillColor = QColor( outlineColor );
193
194 if ( isInput() )
195 {
196 fillColor.setAlpha( isDefaultParameterValue() ? 30 : 255 );
197 }
198 else
199 {
200 // outputs are always filled sockets
201 fillColor.setAlpha( 255 );
202 }
203
204 // Outline style
205 painter->setPen( QPen( outlineColor, mHoverState ? mSocketOutlineWidth * 2 : mSocketOutlineWidth ) );
206
207 // Fill style
208 painter->setBrush( QBrush( fillColor, Qt::SolidPattern ) );
209
210 painter->setRenderHint( QPainter::Antialiasing );
211
212 // Radius of the socket circle
213 constexpr float DISPLAY_SIZE = 4;
214
215 // Offset of the socket to separate from the label
216 constexpr float ELLIPSE_OFFSET = 0.4;
217 QPointF ellipsePosition = QPointF( position().x() + ELLIPSE_OFFSET, position().y() + ELLIPSE_OFFSET );
218 painter->drawEllipse( ellipsePosition, DISPLAY_SIZE, DISPLAY_SIZE );
219
220 /* Uncomment to display bounding box */
221#if 0
222 painter->save();
223 painter->setPen( QPen() );
224 painter->setBrush( QBrush() );
225 painter->drawRect( boundingRect() );
226 painter->restore();
227#endif
228}
229
230
231QColor QgsModelDesignerSocketGraphicItem::socketColor() const
232{
233 return mComponentItem->linkColor( mEdge, mIndex );
234}
235
236
237bool QgsModelDesignerSocketGraphicItem::isDefaultParameterValue() const
238{
239 if ( !mComponent )
240 {
241 return false;
242 }
243
244 const QgsProcessingModelChildAlgorithm *child = dynamic_cast<const QgsProcessingModelChildAlgorithm *>( mComponent );
245
246 if ( !child )
247 {
248 return false;
249 }
250
251 bool isDefaultValue = true;
252
253 // We can only know if the socket should be filled if the algorithm is non null
254 if ( child->algorithm() )
255 {
256 switch ( mEdge )
257 {
258 // Input params
259 case Qt::TopEdge:
260 {
261 const QgsProcessingParameterDefinitions params = child->algorithm()->parameterDefinitions();
262 const QgsProcessingParameterDefinition *param = params.value( mIndex );
263 if ( !param )
264 break;
265
266 const QString name = param->name();
267
268 QgsProcessingModelChildParameterSources paramSources = child->parameterSources().value( name );
269 if ( paramSources.empty() )
270 {
271 break;
272 }
273
274 // The default value can only happen in the case of the parameter uses a static value
275 if ( paramSources[0].source() != Qgis::ProcessingModelChildParameterSource::StaticValue )
276 {
277 isDefaultValue = false;
278 break;
279 }
280
281 isDefaultValue = paramSources[0].staticValue() == param->defaultValue();
282 break;
283 }
284
285 // Outputs
286 case Qt::BottomEdge:
287 case Qt::LeftEdge:
288 case Qt::RightEdge:
289 break;
290 }
291 }
292
293 return isDefaultValue;
294}
295
@ StaticValue
Parameter value is a static value.
Definition qgis.h:3850
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
A mouse event which is the result of a user interaction with a QgsModelGraphicsView.
Base class for the definition of processing parameters.
QVariant defaultValue() const
Returns the default value for the parameter.
QString name() const
Returns the name of the parameter.
QList< const QgsProcessingParameterDefinition * > QgsProcessingParameterDefinitions
List of processing parameters.