Skip to content
Permalink
Browse files

Move item state handling to c++

  • Loading branch information
nyalldawson committed Mar 2, 2020
1 parent 2f8dbac commit 1bf51a4fbbd19c10c9be60915bed5cd1694065bf
@@ -27,6 +27,13 @@ Base class for graphic items representing model components in the model designer
%End
public:

enum State
{
Normal,
Selected,
Hover,
};

QgsModelComponentGraphicItem( QgsProcessingModelComponent *component /Transfer/,
QgsProcessingModelAlgorithm *model,
QGraphicsItem *parent /TransferThis/ );
@@ -61,6 +68,39 @@ Returns the font used to render text in the item.
Sets the ``font`` used to render text in the item.

.. seealso:: :py:func:`font`
%End

virtual void mouseDoubleClickEvent( QGraphicsSceneMouseEvent *event );

virtual void hoverEnterEvent( QGraphicsSceneHoverEvent *event );

virtual void hoverMoveEvent( QGraphicsSceneHoverEvent *event );

virtual void hoverLeaveEvent( QGraphicsSceneHoverEvent *event );


QRectF itemRect() const;
%Docstring
Returns the rectangle representing the body of the item.
%End

QString label() const;
%Docstring
Returns the item's label text.

.. seealso:: :py:func:`setLabel`
%End

void setLabel( const QString &label );
%Docstring
Returns the item's ``label`` text.

.. seealso:: :py:func:`label`
%End

State state() const;
%Docstring
Returns the item's current state.
%End

signals:
@@ -71,11 +111,20 @@ Sets the ``font`` used to render text in the item.
Emitted by the item to request a repaint of the parent model scene.
%End


void changed();
%Docstring
Emitted when the definition of the associated component is changed
by the item.
%End

void repaintArrows();
%Docstring
Emitted when item requests that all connected arrows are repainted.
%End

void updateArrowPaths();
%Docstring
Emitted when item requires that all connected arrow paths are recalculated.
%End

protected slots:
@@ -48,17 +48,19 @@

from qgis.core import (QgsProcessingModelChildAlgorithm,
QgsProcessingModelParameter)
from qgis.gui import QgsModelGraphicsScene
from qgis.gui import (
QgsModelGraphicsScene,
QgsModelComponentGraphicItem
)
from qgis.PyQt.QtCore import Qt, QPointF
from qgis.PyQt.QtWidgets import QApplication, QGraphicsPathItem, QGraphicsItem
from qgis.PyQt.QtGui import QPen, QPainterPath, QPolygonF, QPainter, QPalette
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem


class ModelerArrowItem(QGraphicsPathItem):

def __init__(self, startItem, startIndex, endItem, endIndex,
parent=None, scene=None):
parent=None):
super(ModelerArrowItem, self).__init__(parent)
self.arrowHead = QPolygonF()
self.endIndex = endIndex
@@ -128,9 +130,9 @@ def updatePath(self):
def paint(self, painter, option, widget=None):
color = self.myColor

if self.startItem.isSelected() or self.endItem.isSelected():
if self.startItem.state() == QgsModelComponentGraphicItem.Selected or self.endItem.state() == QgsModelComponentGraphicItem.Selected:
color.setAlpha(220)
elif self.startItem.hover_over_item or self.endItem.hover_over_item:
elif self.startItem.state() == QgsModelComponentGraphicItem.Hover or self.endItem.state() == QgsModelComponentGraphicItem.Hover:
color.setAlpha(150)
else:
color.setAlpha(80)
@@ -48,14 +48,10 @@

class ModelerGraphicItem(QgsModelComponentGraphicItem):

repaintArrows = pyqtSignal()
updateArrowPaths = pyqtSignal()

def __init__(self, element, model):
super().__init__(element, model, None)
self.pixmap = None
self.picture = None
self.hover_over_item = False

def boundingRect(self):
fm = QFontMetricsF(self.font())
@@ -75,40 +71,6 @@ def boundingRect(self):
self.component().size().height() + hDown + hUp)
return rect

def mouseDoubleClickEvent(self, event):
self.editComponent()

def hoverEnterEvent(self, event):
self.updateToolTip(event)

def hoverMoveEvent(self, event):
self.updateToolTip(event)

def hoverLeaveEvent(self, event):
self.setToolTip('')
if self.hover_over_item:
self.hover_over_item = False
self.update()
self.repaintArrows.emit()

def updateToolTip(self, event):
prev_status = self.hover_over_item
if self.itemRect().contains(event.pos()):
self.setToolTip(self.text)
self.hover_over_item = True
else:
self.setToolTip('')
self.hover_over_item = False
if self.hover_over_item != prev_status:
self.update()
self.repaintArrows.emit()

def itemRect(self):
return QRectF(-(self.component().size().width() + 2) / 2.0,
-(self.component().size().height() + 2) / 2.0,
self.component().size().width() + 2,
self.component().size().height() + 2)

def paint(self, painter, option, widget=None):
rect = self.itemRect()

@@ -124,22 +86,22 @@ def paint(self, painter, option, widget=None):
color = QColor(172, 196, 114)
stroke = QColor(90, 140, 90)
selected = QColor(42, 65, 42)
if self.isSelected():
if self.state() == QgsModelComponentGraphicItem.Selected:
stroke = selected
color = color.darker(110)
if self.hover_over_item:
if self.state() == QgsModelComponentGraphicItem.Hover:
color = color.darker(105)
painter.setPen(QPen(stroke, 0)) # 0 width "cosmetic" pen
painter.setBrush(QBrush(color, Qt.SolidPattern))
painter.drawRect(rect)
painter.setFont(self.font())
painter.setPen(QPen(Qt.black))
text = self.truncatedTextForItem(self.text)
text = self.truncatedTextForItem(self.label())
if isinstance(self.component(), QgsProcessingModelChildAlgorithm) and not self.component().isActive():
painter.setPen(QPen(Qt.gray))
text = text + "\n(deactivated)"
fm = QFontMetricsF(self.font())
text = self.truncatedTextForItem(self.text)
text = self.truncatedTextForItem(self.label())
h = fm.ascent()
pt = QPointF(-self.component().size().width() / 2 + 25, self.component().size().height() / 2.0 - h + 1)
painter.drawText(pt, text)
@@ -240,9 +202,9 @@ def __init__(self, element, model):
painter.end()
paramDef = self.model().parameterDefinition(element.parameterName())
if paramDef:
self.text = paramDef.description()
self.setLabel(paramDef.description())
else:
self.text = 'Error ({})'.format(element.parameterName())
self.setLabel('Error ({})'.format(element.parameterName()))

def create_widget_context(self):
"""
@@ -281,7 +243,7 @@ def editComponent(self):
self.component().setParameterName(new_param.name())
self.component().setDescription(new_param.name())
self.model().addModelParameter(new_param, self.component())
self.text = new_param.description()
self.setLabel(new_param.description())
self.requestModelRepaint.emit()

def deleteComponent(self):
@@ -323,7 +285,7 @@ def __init__(self, element, model):
self.pixmap = None
else:
self.pixmap = element.algorithm().icon().pixmap(15, 15)
self.text = element.description()
self.setLabel(element.description())

alg = element.algorithm()
if [a for a in alg.parameterDefinitions() if not a.isDestination()]:
@@ -429,7 +391,7 @@ def __init__(self, element, model):
painter = QPainter(self.picture)
svg.render(painter)
painter.end()
self.text = element.name()
self.setLabel(element.name())

def editComponent(self):
child_alg = self.model().childAlgorithm(self.component().childId())
@@ -24,6 +24,7 @@
#include <QSvgRenderer>
#include <QPicture>
#include <QPainter>
#include <QGraphicsSceneHoverEvent>

///@cond NOT_STABLE

@@ -82,6 +83,40 @@ void QgsModelComponentGraphicItem::setFont( const QFont &font )
update();
}

void QgsModelComponentGraphicItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * )
{
editComponent();
}

void QgsModelComponentGraphicItem::hoverEnterEvent( QGraphicsSceneHoverEvent *event )
{
updateToolTip( event->pos() );
}

void QgsModelComponentGraphicItem::hoverMoveEvent( QGraphicsSceneHoverEvent *event )
{
updateToolTip( event->pos() );
}

void QgsModelComponentGraphicItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * )
{
setToolTip( QString() );
if ( mIsHovering )
{
mIsHovering = false;
update();
emit repaintArrows();
}
}

QRectF QgsModelComponentGraphicItem::itemRect() const
{
return QRectF( -( mComponent->size().width() + 2 ) / 2.0,
-( mComponent->size().height() + 2 ) / 2.0,
mComponent->size().width() + 2,
mComponent->size().height() + 2 );
}

QString QgsModelComponentGraphicItem::truncatedTextForItem( const QString &text ) const
{
QFontMetricsF fm( mFont );
@@ -100,6 +135,47 @@ QString QgsModelComponentGraphicItem::truncatedTextForItem( const QString &text
return t;
}

void QgsModelComponentGraphicItem::updateToolTip( const QPointF &pos )
{
const bool prevHoverStatus = mIsHovering;
if ( itemRect().contains( pos ) )
{
setToolTip( mLabel );
mIsHovering = true;
}
else
{
setToolTip( QString() );
mIsHovering = false;
}
if ( mIsHovering != prevHoverStatus )
{
update();
emit repaintArrows();
}
}

QString QgsModelComponentGraphicItem::label() const
{
return mLabel;
}

void QgsModelComponentGraphicItem::setLabel( const QString &label )
{
mLabel = label;
update();
}

QgsModelComponentGraphicItem::State QgsModelComponentGraphicItem::state() const
{
if ( isSelected() )
return Selected;
else if ( mIsHovering )
return Hover;
else
return Normal;
}


QgsModelParameterGraphicItem::QgsModelParameterGraphicItem( QgsProcessingModelParameter *parameter, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
: QgsModelComponentGraphicItem( parameter, model, parent )

0 comments on commit 1bf51a4

Please sign in to comment.
You can’t perform that action at this time.