Skip to content

Commit 51efa19

Browse files
committed
Port item frame related code from composer
1 parent 0b18829 commit 51efa19

File tree

4 files changed

+99
-1
lines changed

4 files changed

+99
-1
lines changed

python/core/layout/qgslayoutitem.sip

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,31 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
344344
.. seealso:: setBackgroundEnabled()
345345
%End
346346

347+
virtual double estimatedFrameBleed() const;
348+
%Docstring
349+
Returns the estimated amount the item's frame bleeds outside the item's
350+
actual rectangle. For instance, if the item has a 2mm frame stroke, then
351+
1mm of this frame is drawn outside the item's rect. In this case the
352+
return value will be 1.0.
353+
354+
Returned values are in layout units.
355+
356+
.. seealso:: rectWithFrame()
357+
:rtype: float
358+
%End
359+
360+
virtual QRectF rectWithFrame() const;
361+
%Docstring
362+
Returns the item's rectangular bounds, including any bleed caused by the item's frame.
363+
The bounds are returned in the item's coordinate system (see Qt's QGraphicsItem docs for
364+
more details about QGraphicsItem coordinate systems). The results differ from Qt's rect()
365+
function, as rect() makes no allowances for the portion of outlines which are drawn
366+
outside of the item.
367+
368+
.. seealso:: estimatedFrameBleed()
369+
:rtype: QRectF
370+
%End
371+
347372
public slots:
348373

349374
virtual void refresh();

src/core/layout/qgslayoutitem.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,22 @@ void QgsLayoutItem::setBackgroundColor( const QColor &color )
359359
refreshBackgroundColor( true );
360360
}
361361

362+
double QgsLayoutItem::estimatedFrameBleed() const
363+
{
364+
if ( !hasFrame() )
365+
{
366+
return 0;
367+
}
368+
369+
return pen().widthF() / 2.0;
370+
}
371+
372+
QRectF QgsLayoutItem::rectWithFrame() const
373+
{
374+
double frameBleed = estimatedFrameBleed();
375+
return rect().adjusted( -frameBleed, -frameBleed, frameBleed, frameBleed );
376+
}
377+
362378
QgsLayoutPoint QgsLayoutItem::applyDataDefinedPosition( const QgsLayoutPoint &position )
363379
{
364380
if ( !mLayout )

src/core/layout/qgslayoutitem.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,29 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
347347
*/
348348
void setBackgroundColor( const QColor &color );
349349

350+
/**
351+
* Returns the estimated amount the item's frame bleeds outside the item's
352+
* actual rectangle. For instance, if the item has a 2mm frame stroke, then
353+
* 1mm of this frame is drawn outside the item's rect. In this case the
354+
* return value will be 1.0.
355+
*
356+
* Returned values are in layout units.
357+
358+
* \see rectWithFrame()
359+
*/
360+
virtual double estimatedFrameBleed() const;
361+
362+
/**
363+
* Returns the item's rectangular bounds, including any bleed caused by the item's frame.
364+
* The bounds are returned in the item's coordinate system (see Qt's QGraphicsItem docs for
365+
* more details about QGraphicsItem coordinate systems). The results differ from Qt's rect()
366+
* function, as rect() makes no allowances for the portion of outlines which are drawn
367+
* outside of the item.
368+
*
369+
* \see estimatedFrameBleed()
370+
*/
371+
virtual QRectF rectWithFrame() const;
372+
350373
public slots:
351374

352375
/**

tests/src/python/test_qgslayoutitem.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
QgsLayoutObject,
2121
QgsProperty,
2222
QgsLayoutMeasurement,
23-
QgsUnitTypes)
23+
QgsUnitTypes,
24+
QgsLayoutPoint,
25+
QgsLayoutSize)
26+
from qgis.PyQt.QtCore import QRectF
2427
from qgis.PyQt.QtGui import QColor
2528
from qgis.PyQt.QtTest import QSignalSpy
2629

@@ -101,6 +104,37 @@ def testLocked(self):
101104
item.setLocked(False)
102105
self.assertEqual(len(lock_changed_spy), 2)
103106

107+
def testFrameBleed(self):
108+
layout = QgsLayout(QgsProject.instance())
109+
item = QgsLayoutItemMap(layout)
110+
item.setFrameEnabled(False)
111+
self.assertEqual(item.estimatedFrameBleed(), 0)
112+
113+
item.setFrameStrokeWidth(QgsLayoutMeasurement(10, QgsUnitTypes.LayoutMillimeters))
114+
item.setFrameEnabled(False)
115+
self.assertEqual(item.estimatedFrameBleed(), 0)
116+
item.setFrameEnabled(True)
117+
self.assertEqual(item.estimatedFrameBleed(), 5) # only half bleeds out!
118+
119+
item.setFrameStrokeWidth(QgsLayoutMeasurement(10, QgsUnitTypes.LayoutCentimeters))
120+
self.assertEqual(item.estimatedFrameBleed(), 50) # only half bleeds out!
121+
122+
def testRectWithFrame(self):
123+
layout = QgsLayout(QgsProject.instance())
124+
item = QgsLayoutItemMap(layout)
125+
item.attemptMove(QgsLayoutPoint(6, 10, QgsUnitTypes.LayoutMillimeters))
126+
item.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
127+
128+
item.setFrameEnabled(False)
129+
self.assertEqual(item.rectWithFrame(), QRectF(0, 0, 18, 12))
130+
item.setFrameStrokeWidth(QgsLayoutMeasurement(10, QgsUnitTypes.LayoutMillimeters))
131+
item.setFrameEnabled(False)
132+
self.assertEqual(item.rectWithFrame(), QRectF(0, 0, 18, 12))
133+
item.setFrameEnabled(True)
134+
self.assertEqual(item.rectWithFrame(), QRectF(-5.0, -5.0, 28.0, 22.0))
135+
item.setFrameStrokeWidth(QgsLayoutMeasurement(10, QgsUnitTypes.LayoutCentimeters))
136+
self.assertEqual(item.rectWithFrame(), QRectF(-50.0, -50.0, 118.0, 112.0))
137+
104138

105139
if __name__ == '__main__':
106140
unittest.main()

0 commit comments

Comments
 (0)