Move more functionality to c++ base class

This commit is contained in:
Nyall Dawson 2020-03-02 12:35:29 +10:00
parent 0dbb082dfd
commit 2f8dbacc87
4 changed files with 87 additions and 27 deletions

View File

@ -47,6 +47,20 @@ Returns the model component associated with this item.
QgsProcessingModelAlgorithm *model();
%Docstring
Returns the model associated with this item.
%End
QFont font() const;
%Docstring
Returns the font used to render text in the item.
.. seealso:: :py:func:`setFont`
%End
void setFont( const QFont &font );
%Docstring
Sets the ``font`` used to render text in the item.
.. seealso:: :py:func:`font`
%End
signals:
@ -78,6 +92,14 @@ The default implementation does nothing.
Called when the component should be deleted.
The default implementation does nothing.
%End
protected:
QString truncatedTextForItem( const QString &text ) const;
%Docstring
Truncates a ``text`` string so that it fits nicely within the item's width,
accounting for margins and interactive buttons.
%End
};

View File

@ -48,21 +48,17 @@ pluginPath = os.path.split(os.path.dirname(__file__))[0]
class ModelerGraphicItem(QgsModelComponentGraphicItem):
BUTTON_WIDTH = 16
repaintArrows = pyqtSignal()
updateArrowPaths = pyqtSignal()
def __init__(self, element, model):
super().__init__(element, model, None)
self.item_font = QFont()
self.item_font.setPixelSize(12)
self.pixmap = None
self.picture = None
self.hover_over_item = False
def boundingRect(self):
fm = QFontMetricsF(self.item_font)
fm = QFontMetricsF(self.font())
unfolded = isinstance(self.component(),
QgsProcessingModelChildAlgorithm) and not self.component().parametersCollapsed()
numParams = len([a for a in self.component().algorithm().parameterDefinitions() if
@ -107,19 +103,6 @@ class ModelerGraphicItem(QgsModelComponentGraphicItem):
self.update()
self.repaintArrows.emit()
def getAdjustedText(self, text):
fm = QFontMetricsF(self.item_font)
w = fm.width(text)
if w < self.component().size().width() - 25 - ModelerGraphicItem.BUTTON_WIDTH:
return text
text = text[0:-3] + ''
w = fm.width(text)
while w > self.component().size().width() - 25 - ModelerGraphicItem.BUTTON_WIDTH:
text = text[0:-4] + ''
w = fm.width(text)
return text
def itemRect(self):
return QRectF(-(self.component().size().width() + 2) / 2.0,
-(self.component().size().height() + 2) / 2.0,
@ -149,14 +132,14 @@ class ModelerGraphicItem(QgsModelComponentGraphicItem):
painter.setPen(QPen(stroke, 0)) # 0 width "cosmetic" pen
painter.setBrush(QBrush(color, Qt.SolidPattern))
painter.drawRect(rect)
painter.setFont(self.item_font)
painter.setFont(self.font())
painter.setPen(QPen(Qt.black))
text = self.getAdjustedText(self.text)
text = self.truncatedTextForItem(self.text)
if isinstance(self.component(), QgsProcessingModelChildAlgorithm) and not self.component().isActive():
painter.setPen(QPen(Qt.gray))
text = text + "\n(deactivated)"
fm = QFontMetricsF(self.item_font)
text = self.getAdjustedText(self.text)
fm = QFontMetricsF(self.font())
text = self.truncatedTextForItem(self.text)
h = fm.ascent()
pt = QPointF(-self.component().size().width() / 2 + 25, self.component().size().height() / 2.0 - h + 1)
painter.drawText(pt, text)
@ -170,7 +153,7 @@ class ModelerGraphicItem(QgsModelComponentGraphicItem):
if not self.component().parametersCollapsed():
for param in [p for p in self.component().algorithm().parameterDefinitions() if not p.isDestination()]:
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
text = self.getAdjustedText(param.description())
text = self.truncatedTextForItem(param.description())
h = -(fm.height() * 1.2) * (i + 1)
h = h - self.component().size().height() / 2.0 + 5
pt = QPointF(-self.component().size().width() / 2 + 33, h)
@ -182,7 +165,7 @@ class ModelerGraphicItem(QgsModelComponentGraphicItem):
painter.drawText(pt, 'Out')
if not self.component().outputsCollapsed():
for i, out in enumerate(self.component().algorithm().outputDefinitions()):
text = self.getAdjustedText(out.description())
text = self.truncatedTextForItem(out.description())
h = fm.height() * 1.2 * (i + 2)
h = h + self.component().size().height() / 2.0
pt = QPointF(-self.component().size().width() / 2 + 33, h)
@ -202,7 +185,7 @@ class ModelerGraphicItem(QgsModelComponentGraphicItem):
if isinstance(self.component(), QgsProcessingModelParameter):
paramIndex = -1
offsetX = 0
fm = QFontMetricsF(self.item_font)
fm = QFontMetricsF(self.font())
if isinstance(self.component(), QgsProcessingModelChildAlgorithm):
h = -(fm.height() * 1.2) * (paramIndex + 2) - fm.height() / 2.0 + 8
h = h - self.component().size().height() / 2.0
@ -214,8 +197,8 @@ class ModelerGraphicItem(QgsModelComponentGraphicItem):
if isinstance(self.component(),
QgsProcessingModelChildAlgorithm) and self.component().algorithm().outputDefinitions():
outputIndex = (outputIndex if not self.component().outputsCollapsed() else -1)
text = self.getAdjustedText(self.component().algorithm().outputDefinitions()[outputIndex].description())
fm = QFontMetricsF(self.item_font)
text = self.truncatedTextForItem(self.component().algorithm().outputDefinitions()[outputIndex].description())
fm = QFontMetricsF(self.font())
w = fm.width(text)
h = fm.height() * 1.2 * (outputIndex + 1) + fm.height() / 2.0
y = h + self.component().size().height() / 2.0 + 5

View File

@ -38,6 +38,8 @@ QgsModelComponentGraphicItem::QgsModelComponentGraphicItem( QgsProcessingModelCo
setFlag( QGraphicsItem::ItemSendsGeometryChanges, true );
setZValue( QgsModelGraphicsScene::ZValues::ModelComponent );
mFont.setPixelSize( 12 );
QSvgRenderer svg( QgsApplication::iconPath( QStringLiteral( "mActionEditModelComponent.svg" ) ) );
QPicture editPicture;
QPainter painter( &editPicture );
@ -69,6 +71,36 @@ QgsProcessingModelAlgorithm *QgsModelComponentGraphicItem::model()
return mModel;
}
QFont QgsModelComponentGraphicItem::font() const
{
return mFont;
}
void QgsModelComponentGraphicItem::setFont( const QFont &font )
{
mFont = font;
update();
}
QString QgsModelComponentGraphicItem::truncatedTextForItem( const QString &text ) const
{
QFontMetricsF fm( mFont );
double width = fm.boundingRect( text ).width();
if ( width < mComponent->size().width() - 25 - mButtonSize.width() )
return text;
QString t = text;
t = t.left( t.length() - 3 ) + QChar( 0x2026 );
width = fm.boundingRect( t ).width();
while ( width > mComponent->size().width() - 25 - mButtonSize.width() )
{
t = t.left( t.length() - 4 ) + QChar( 0x2026 );
width = fm.boundingRect( t ).width();
}
return t;
}
QgsModelParameterGraphicItem::QgsModelParameterGraphicItem( QgsProcessingModelParameter *parameter, QgsProcessingModelAlgorithm *model, QGraphicsItem *parent )
: QgsModelComponentGraphicItem( parameter, model, parent )
{

View File

@ -19,6 +19,7 @@
#include "qgis.h"
#include "qgis_gui.h"
#include <QGraphicsObject>
#include <QFont>
class QgsProcessingModelComponent;
class QgsProcessingModelParameter;
@ -63,6 +64,18 @@ class GUI_EXPORT QgsModelComponentGraphicItem : public QGraphicsObject
*/
QgsProcessingModelAlgorithm *model();
/**
* Returns the font used to render text in the item.
* \see setFont()
*/
QFont font() const;
/**
* Sets the \a font used to render text in the item.
* \see font()
*/
void setFont( const QFont &font );
signals:
// TEMPORARY ONLY during refactoring
@ -96,6 +109,14 @@ class GUI_EXPORT QgsModelComponentGraphicItem : public QGraphicsObject
*/
virtual void deleteComponent() {}
protected:
/**
* Truncates a \a text string so that it fits nicely within the item's width,
* accounting for margins and interactive buttons.
*/
QString truncatedTextForItem( const QString &text ) const;
private:
std::unique_ptr< QgsProcessingModelComponent > mComponent;
@ -108,6 +129,8 @@ class GUI_EXPORT QgsModelComponentGraphicItem : public QGraphicsObject
static constexpr double DEFAULT_BUTTON_HEIGHT = 16;
QSizeF mButtonSize { DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT };
QFont mFont;
};
/**