Skip to content

Commit

Permalink
Port frame and background handling to layout items
Browse files Browse the repository at this point in the history
And add support for frame widths with units
  • Loading branch information
nyalldawson committed Oct 6, 2017
1 parent 2d484db commit 4e61ea8
Show file tree
Hide file tree
Showing 11 changed files with 557 additions and 22 deletions.
138 changes: 138 additions & 0 deletions python/core/layout/qgslayoutitem.sip
Expand Up @@ -222,6 +222,113 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
virtual QgsAbstractLayoutUndoCommand *createCommand( const QString &text, int id, QUndoCommand *parent = 0 ) /Factory/;


bool hasFrame() const;
%Docstring
Returns true if the item includes a frame.
.. seealso:: setFrameEnabled()
.. seealso:: frameStrokeWidth()
.. seealso:: frameJoinStyle()
.. seealso:: frameStrokeColor()
:rtype: bool
%End

virtual void setFrameEnabled( bool drawFrame );
%Docstring
Sets whether this item has a frame drawn around it or not.
.. seealso:: hasFrame()
.. seealso:: setFrameStrokeWidth()
.. seealso:: setFrameJoinStyle()
.. seealso:: setFrameStrokeColor()
%End

void setFrameStrokeColor( const QColor &color );
%Docstring
Sets the frame stroke ``color``.
.. seealso:: frameStrokeColor()
.. seealso:: setFrameEnabled()
.. seealso:: setFrameJoinStyle()
.. seealso:: setFrameStrokeWidth()
%End

QColor frameStrokeColor() const;
%Docstring
Returns the frame's stroke color. This is only used if hasFrame() returns true.
.. seealso:: hasFrame()
.. seealso:: setFrameStrokeColor()
.. seealso:: frameJoinStyle()
.. seealso:: setFrameStrokeColor()
:rtype: QColor
%End

virtual void setFrameStrokeWidth( const QgsLayoutMeasurement &width );
%Docstring
Sets the frame stroke ``width``.
.. seealso:: frameStrokeWidth()
.. seealso:: setFrameEnabled()
.. seealso:: setFrameJoinStyle()
.. seealso:: setFrameStrokeColor()
%End

QgsLayoutMeasurement frameStrokeWidth() const;
%Docstring
Returns the frame's stroke width. This is only used if hasFrame() returns true.
.. seealso:: hasFrame()
.. seealso:: setFrameStrokeWidth()
.. seealso:: frameJoinStyle()
.. seealso:: frameStrokeColor()
:rtype: QgsLayoutMeasurement
%End

Qt::PenJoinStyle frameJoinStyle() const;
%Docstring
Returns the join style used for drawing the item's frame.
.. seealso:: hasFrame()
.. seealso:: setFrameJoinStyle()
.. seealso:: frameStrokeWidth()
.. seealso:: frameStrokeColor()
:rtype: Qt.PenJoinStyle
%End

void setFrameJoinStyle( const Qt::PenJoinStyle style );
%Docstring
Sets the join ``style`` used when drawing the item's frame.
.. seealso:: setFrameEnabled()
.. seealso:: frameJoinStyle()
.. seealso:: setFrameStrokeWidth()
.. seealso:: setFrameStrokeColor()
%End

bool hasBackground() const;
%Docstring
Returns true if the item has a background.
.. seealso:: setBackgroundEnabled()
.. seealso:: backgroundColor()
:rtype: bool
%End

void setBackgroundEnabled( bool drawBackground );
%Docstring
Sets whether this item has a background drawn under it or not.
.. seealso:: hasBackground()
.. seealso:: setBackgroundColor()
%End

QColor backgroundColor() const;
%Docstring
Returns the background color for this item. This is only used if hasBackground()
returns true.
.. seealso:: setBackgroundColor()
.. seealso:: hasBackground()
:rtype: QColor
%End

void setBackgroundColor( const QColor &color );
%Docstring
Sets the background ``color`` for this item.
.. seealso:: backgroundColor()
.. seealso:: setBackgroundEnabled()
%End

public slots:

virtual void refresh();
Expand Down Expand Up @@ -258,6 +365,13 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
.. seealso:: itemRotation()
%End

signals:

void frameChanged();
%Docstring
Emitted if the item's frame style changes.
%End

protected:

virtual void drawDebugRect( QPainter *painter );
Expand All @@ -274,6 +388,16 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
Use the QgsRenderContext methods to convert from millimeters or other units to the painter's units.
%End

virtual void drawFrame( QgsRenderContext &context );
%Docstring
Draws the frame around the item.
%End

virtual void drawBackground( QgsRenderContext &context );
%Docstring
Draws the background for the item.
%End

virtual void setFixedSize( const QgsLayoutSize &size );
%Docstring
Sets a fixed ``size`` for the layout item, which prevents it from being freely
Expand Down Expand Up @@ -314,6 +438,20 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
.. seealso:: refreshItemPosition()
%End

void refreshFrame( bool updateItem = true );
%Docstring
Refresh item's frame, considering data defined colors and frame size.
If ``updateItem`` is set to false, the item will not be automatically updated
after the frame is set and a later call to update() must be made.
%End

void refreshBackgroundColor( bool updateItem = true );
%Docstring
Refresh item's background color, considering data defined colors.
If ``updateItem`` is set to false, the item will not be automatically updated
after the frame color is set and a later call to update() must be made.
%End

QPointF adjustPointForReferencePosition( const QPointF &point, const QSizeF &size, const ReferencePoint &reference ) const;
%Docstring
Adjusts the specified ``point`` at which a ``reference`` position of the item
Expand Down
4 changes: 4 additions & 0 deletions python/core/layout/qgslayoutitempage.sip
Expand Up @@ -102,6 +102,10 @@ class QgsLayoutItemPage : QgsLayoutItem

virtual void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = 0 );

virtual void drawFrame( QgsRenderContext &context );

virtual void drawBackground( QgsRenderContext &context );


};

Expand Down
159 changes: 159 additions & 0 deletions src/core/layout/qgslayoutitem.cpp
Expand Up @@ -41,6 +41,10 @@ QgsLayoutItem::QgsLayoutItem( QgsLayout *layout )
mItemPosition = QgsLayoutPoint( scenePos().x(), scenePos().y(), initialUnits );
mItemSize = QgsLayoutSize( rect().width(), rect().height(), initialUnits );

// required to initially setup background/frame style
refreshBackgroundColor( false );
refreshFrame( false );

initConnectionsToLayout();
}

Expand Down Expand Up @@ -136,7 +140,9 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
// painter is already scaled to dots
// need to translate so that item origin is at 0,0 in painter coordinates (not bounding rect origin)
p.translate( -boundingRect().x() * context.scaleFactor(), -boundingRect().y() * context.scaleFactor() );
drawBackground( context );
draw( context, itemStyle );
drawFrame( context );
p.end();

painter->save();
Expand All @@ -153,9 +159,15 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
painter->save();
preparePainter( painter );
QgsRenderContext context = QgsLayoutUtils::createRenderContextForLayout( mLayout, painter, destinationDpi );
drawBackground( context );

// scale painter from mm to dots
painter->scale( 1.0 / context.scaleFactor(), 1.0 / context.scaleFactor() );
draw( context, itemStyle );

painter->scale( context.scaleFactor(), context.scaleFactor() );
drawFrame( context );

painter->restore();
}
}
Expand Down Expand Up @@ -266,6 +278,66 @@ QgsAbstractLayoutUndoCommand *QgsLayoutItem::createCommand( const QString &text,
return new QgsLayoutItemUndoCommand( this, text, id, parent );
}

void QgsLayoutItem::setFrameEnabled( bool drawFrame )
{
if ( drawFrame == mFrame )
{
//no change
return;
}

mFrame = drawFrame;
refreshFrame( true );
emit frameChanged();
}

void QgsLayoutItem::setFrameStrokeColor( const QColor &color )
{
if ( mFrameColor == color )
{
//no change
return;
}
mFrameColor = color;
// apply any datadefined overrides
refreshFrame( true );
emit frameChanged();
}

void QgsLayoutItem::setFrameStrokeWidth( const QgsLayoutMeasurement &width )
{
if ( mFrameWidth == width )
{
//no change
return;
}
mFrameWidth = width;
refreshFrame();
emit frameChanged();
}

void QgsLayoutItem::setFrameJoinStyle( const Qt::PenJoinStyle style )
{
if ( mFrameJoinStyle == style )
{
//no change
return;
}
mFrameJoinStyle = style;

QPen itemPen = pen();
itemPen.setJoinStyle( mFrameJoinStyle );
setPen( itemPen );
emit frameChanged();
}

void QgsLayoutItem::setBackgroundColor( const QColor &color )
{
mBackgroundColor = color;
// apply any datadefined overrides
refreshBackgroundColor( true );
}

QgsLayoutPoint QgsLayoutItem::applyDataDefinedPosition( const QgsLayoutPoint &position )
{
if ( !mLayout )
Expand Down Expand Up @@ -337,6 +409,14 @@ void QgsLayoutItem::refreshDataDefinedProperty( const QgsLayoutObject::DataDefin
{
refreshItemRotation();
}
if ( property == QgsLayoutObject::FrameColor || property == QgsLayoutObject::AllProperties )
{
refreshFrame( false );
}
if ( property == QgsLayoutObject::BackgroundColor || property == QgsLayoutObject::AllProperties )
{
refreshBackgroundColor( false );
}
}

void QgsLayoutItem::setItemRotation( const double angle )
Expand Down Expand Up @@ -402,6 +482,32 @@ void QgsLayoutItem::drawDebugRect( QPainter *painter )
painter->restore();
}

void QgsLayoutItem::drawFrame( QgsRenderContext &context )
{
if ( !mFrame || !context.painter() )
return;

QPainter *p = context.painter();
p->save();
p->setPen( pen() );
p->setBrush( Qt::NoBrush );
p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
p->restore();
}

void QgsLayoutItem::drawBackground( QgsRenderContext &context )
{
if ( !mBackground || !context.painter() )
return;

QPainter *p = context.painter();
p->save();
p->setBrush( brush() );
p->setPen( Qt::NoPen );
p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
p->restore();
}

void QgsLayoutItem::setFixedSize( const QgsLayoutSize &size )
{
mFixedSize = size;
Expand Down Expand Up @@ -593,3 +699,56 @@ void QgsLayoutItem::refreshItemRotation()
{
setItemRotation( itemRotation() );
}

void QgsLayoutItem::refreshFrame( bool updateItem )
{
if ( !mFrame )
{
setPen( Qt::NoPen );
return;
}

//data defined stroke color set?
bool ok = false;
QColor frameColor = mDataDefinedProperties.valueAsColor( QgsLayoutObject::FrameColor, createExpressionContext(), mFrameColor, &ok );
QPen itemPen = pen();
if ( ok )
{
itemPen.setColor( frameColor );
}
else
{
itemPen.setColor( mFrameColor );
}

if ( mLayout )
itemPen.setWidthF( mLayout->convertToLayoutUnits( mFrameWidth ) );
else
itemPen.setWidthF( mFrameWidth.length() );

setPen( itemPen );

if ( updateItem )
{
update();
}
}

void QgsLayoutItem::refreshBackgroundColor( bool updateItem )
{
//data defined fill color set?
bool ok = false;
QColor backgroundColor = mDataDefinedProperties.valueAsColor( QgsLayoutObject::BackgroundColor, createExpressionContext(), mBackgroundColor, &ok );
if ( ok )
{
setBrush( QBrush( backgroundColor, Qt::SolidPattern ) );
}
else
{
setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
}
if ( updateItem )
{
update();
}
}

0 comments on commit 4e61ea8

Please sign in to comment.