mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-26 00:02:08 -05:00
Restore drawing of page grids
This commit is contained in:
parent
ec5698393b
commit
b42c055e97
@ -23,7 +23,9 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator
|
||||
enum ZValues
|
||||
{
|
||||
ZPage,
|
||||
ZGrid,
|
||||
ZMapTool,
|
||||
|
||||
};
|
||||
|
||||
QgsLayout( QgsProject *project );
|
||||
|
@ -30,6 +30,13 @@ class QgsLayoutContext
|
||||
typedef QFlags<QgsLayoutContext::Flag> Flags;
|
||||
|
||||
|
||||
enum GridStyle
|
||||
{
|
||||
GridLines,
|
||||
GridDots,
|
||||
GridCrosses
|
||||
};
|
||||
|
||||
QgsLayoutContext();
|
||||
|
||||
void setFlags( const QgsLayoutContext::Flags flags );
|
||||
@ -125,6 +132,72 @@ class QgsLayoutContext
|
||||
:rtype: QgsLayoutMeasurementConverter
|
||||
%End
|
||||
|
||||
bool gridVisible() const;
|
||||
%Docstring
|
||||
Returns true if the page grid should be drawn.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setGridResolution( const QgsLayoutMeasurement &resolution );
|
||||
%Docstring
|
||||
Sets the page/snap grid ``resolution``.
|
||||
.. seealso:: gridResolution()
|
||||
.. seealso:: setGridOffset()
|
||||
%End
|
||||
|
||||
QgsLayoutMeasurement gridResolution() const;
|
||||
%Docstring
|
||||
Returns the page/snap grid resolution.
|
||||
.. seealso:: setGridResolution()
|
||||
.. seealso:: gridOffset()
|
||||
:rtype: QgsLayoutMeasurement
|
||||
%End
|
||||
|
||||
void setGridOffset( const QgsLayoutPoint offset );
|
||||
%Docstring
|
||||
Sets the ``offset`` of the page/snap grid.
|
||||
.. seealso:: gridOffset()
|
||||
.. seealso:: setGridResolution()
|
||||
%End
|
||||
|
||||
QgsLayoutPoint gridOffset() const;
|
||||
%Docstring
|
||||
Returns the offset of the page/snap grid.
|
||||
.. seealso:: setGridOffset()
|
||||
.. seealso:: gridResolution()
|
||||
:rtype: QgsLayoutPoint
|
||||
%End
|
||||
|
||||
void setGridPen( const QPen &pen );
|
||||
%Docstring
|
||||
Sets the ``pen`` used for drawing page/snap grids.
|
||||
.. seealso:: gridPen()
|
||||
.. seealso:: setGridStyle()
|
||||
%End
|
||||
|
||||
QPen gridPen() const;
|
||||
%Docstring
|
||||
Returns the pen used for drawing page/snap grids.
|
||||
.. seealso:: setGridPen()
|
||||
.. seealso:: gridStyle()
|
||||
:rtype: QPen
|
||||
%End
|
||||
|
||||
void setGridStyle( const GridStyle style );
|
||||
%Docstring
|
||||
Sets the ``style`` used for drawing the page/snap grids.
|
||||
.. seealso:: gridStyle()
|
||||
.. seealso:: setGridPen()
|
||||
%End
|
||||
|
||||
GridStyle gridStyle() const;
|
||||
%Docstring
|
||||
Returns the style used for drawing the page/snap grids.
|
||||
.. seealso:: setGridStyle()
|
||||
.. seealso:: gridPen()
|
||||
:rtype: GridStyle
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsLayoutItemPage : QgsLayoutItem
|
||||
{
|
||||
%Docstring
|
||||
@ -75,6 +77,9 @@ class QgsLayoutItemPage : QgsLayoutItem
|
||||
:rtype: QgsLayoutItemPage.Orientation
|
||||
%End
|
||||
|
||||
virtual void attemptResize( const QgsLayoutSize &size );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = 0 );
|
||||
|
@ -40,7 +40,9 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
|
||||
enum ZValues
|
||||
{
|
||||
ZPage = 0, //!< Z-value for page (paper) items
|
||||
ZGrid = 9999, //!< Z-value for page grids
|
||||
ZMapTool = 10000, //!< Z-value for temporary map tool items
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,11 @@
|
||||
|
||||
QgsLayoutContext::QgsLayoutContext()
|
||||
: mFlags( FlagAntialiasing | FlagUseAdvancedEffects )
|
||||
{}
|
||||
, mGridResolution( QgsLayoutMeasurement( 10 ) )
|
||||
{
|
||||
mGridPen = QPen( QColor( 190, 190, 190, 100 ), 0 );
|
||||
mGridPen.setCosmetic( true );
|
||||
}
|
||||
|
||||
void QgsLayoutContext::setFlags( const QgsLayoutContext::Flags flags )
|
||||
{
|
||||
@ -77,3 +81,8 @@ double QgsLayoutContext::dpi() const
|
||||
{
|
||||
return mMeasurementConverter.dpi();
|
||||
}
|
||||
|
||||
bool QgsLayoutContext::gridVisible() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -46,6 +46,14 @@ class CORE_EXPORT QgsLayoutContext
|
||||
};
|
||||
Q_DECLARE_FLAGS( Flags, Flag )
|
||||
|
||||
//! Style for drawing the page/snapping grid
|
||||
enum GridStyle
|
||||
{
|
||||
GridLines, //! Solid lines
|
||||
GridDots, //! Dots
|
||||
GridCrosses //! Crosses
|
||||
};
|
||||
|
||||
QgsLayoutContext();
|
||||
|
||||
/**
|
||||
@ -139,6 +147,67 @@ class CORE_EXPORT QgsLayoutContext
|
||||
*/
|
||||
QgsLayoutMeasurementConverter &measurementConverter() { return mMeasurementConverter; }
|
||||
|
||||
/**
|
||||
* Returns true if the page grid should be drawn.
|
||||
*/
|
||||
bool gridVisible() const;
|
||||
|
||||
/**
|
||||
* Sets the page/snap grid \a resolution.
|
||||
* \see gridResolution()
|
||||
* \see setGridOffset()
|
||||
*/
|
||||
void setGridResolution( const QgsLayoutMeasurement &resolution ) { mGridResolution = resolution; }
|
||||
|
||||
/**
|
||||
* Returns the page/snap grid resolution.
|
||||
* \see setGridResolution()
|
||||
* \see gridOffset()
|
||||
*/
|
||||
QgsLayoutMeasurement gridResolution() const { return mGridResolution;}
|
||||
|
||||
/**
|
||||
* Sets the \a offset of the page/snap grid.
|
||||
* \see gridOffset()
|
||||
* \see setGridResolution()
|
||||
*/
|
||||
void setGridOffset( const QgsLayoutPoint offset ) { mGridOffset = offset; }
|
||||
|
||||
/**
|
||||
* Returns the offset of the page/snap grid.
|
||||
* \see setGridOffset()
|
||||
* \see gridResolution()
|
||||
*/
|
||||
QgsLayoutPoint gridOffset() const { return mGridOffset; }
|
||||
|
||||
/**
|
||||
* Sets the \a pen used for drawing page/snap grids.
|
||||
* \see gridPen()
|
||||
* \see setGridStyle()
|
||||
*/
|
||||
void setGridPen( const QPen &pen ) { mGridPen = pen; }
|
||||
|
||||
/**
|
||||
* Returns the pen used for drawing page/snap grids.
|
||||
* \see setGridPen()
|
||||
* \see gridStyle()
|
||||
*/
|
||||
QPen gridPen() const { return mGridPen; }
|
||||
|
||||
/**
|
||||
* Sets the \a style used for drawing the page/snap grids.
|
||||
* \see gridStyle()
|
||||
* \see setGridPen()
|
||||
*/
|
||||
void setGridStyle( const GridStyle style ) { mGridStyle = style; }
|
||||
|
||||
/**
|
||||
* Returns the style used for drawing the page/snap grids.
|
||||
* \see setGridStyle()
|
||||
* \see gridPen()
|
||||
*/
|
||||
GridStyle gridStyle() const { return mGridStyle; }
|
||||
|
||||
private:
|
||||
|
||||
Flags mFlags = 0;
|
||||
@ -148,6 +217,11 @@ class CORE_EXPORT QgsLayoutContext
|
||||
|
||||
QgsLayoutMeasurementConverter mMeasurementConverter;
|
||||
|
||||
QgsLayoutMeasurement mGridResolution;
|
||||
QgsLayoutPoint mGridOffset;
|
||||
QPen mGridPen;
|
||||
GridStyle mGridStyle = GridLines;
|
||||
|
||||
};
|
||||
|
||||
#endif //QGSLAYOUTCONTEXT_H
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "qgspagesizeregistry.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
QgsLayoutItemPage::QgsLayoutItemPage( QgsLayout *layout )
|
||||
: QgsLayoutItem( layout )
|
||||
@ -36,6 +37,9 @@ QgsLayoutItemPage::QgsLayoutItemPage( QgsLayout *layout )
|
||||
QFont font;
|
||||
QFontMetrics fm( font );
|
||||
mMaximumShadowWidth = fm.width( "X" );
|
||||
|
||||
mGrid.reset( new QgsLayoutItemPageGrid( pos().x(), pos().y(), rect().width(), rect().height(), mLayout ) );
|
||||
mGrid->setParentItem( this );
|
||||
}
|
||||
|
||||
void QgsLayoutItemPage::setPageSize( const QgsLayoutSize &size )
|
||||
@ -106,6 +110,13 @@ QgsLayoutItemPage::Orientation QgsLayoutItemPage::decodePageOrientation( const Q
|
||||
return Landscape;
|
||||
}
|
||||
|
||||
void QgsLayoutItemPage::attemptResize( const QgsLayoutSize &size )
|
||||
{
|
||||
QgsLayoutItem::attemptResize( size );
|
||||
//update size of attached grid to reflect new page size and position
|
||||
mGrid->setRect( 0, 0, rect().width(), rect().height() );
|
||||
}
|
||||
|
||||
void QgsLayoutItemPage::draw( QgsRenderContext &context, const QStyleOptionGraphicsItem * )
|
||||
{
|
||||
if ( !context.painter() || !mLayout /*|| !mLayout->pagesVisible() */ )
|
||||
@ -166,3 +177,103 @@ void QgsLayoutItemPage::draw( QgsRenderContext &context, const QStyleOptionGraph
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// QgsLayoutItemPageGrid
|
||||
//
|
||||
///@cond PRIVATE
|
||||
|
||||
QgsLayoutItemPageGrid::QgsLayoutItemPageGrid( double x, double y, double width, double height, QgsLayout *layout )
|
||||
: QGraphicsRectItem( 0, 0, width, height )
|
||||
, mLayout( layout )
|
||||
{
|
||||
// needed to access current view transform during paint operations
|
||||
setFlags( flags() | QGraphicsItem::ItemUsesExtendedStyleOption );
|
||||
setCacheMode( QGraphicsItem::DeviceCoordinateCache );
|
||||
setFlag( QGraphicsItem::ItemIsSelectable, false );
|
||||
setFlag( QGraphicsItem::ItemIsMovable, false );
|
||||
setZValue( QgsLayout::ZGrid );
|
||||
setPos( x, y );
|
||||
}
|
||||
|
||||
void QgsLayoutItemPageGrid::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
|
||||
{
|
||||
Q_UNUSED( pWidget );
|
||||
|
||||
//draw grid
|
||||
if ( !mLayout )
|
||||
return;
|
||||
|
||||
const QgsLayoutContext &context = mLayout->context();
|
||||
|
||||
if ( !context.gridVisible() || context.gridResolution().length() <= 0 )
|
||||
return;
|
||||
|
||||
QPointF gridOffset = mLayout->convertToLayoutUnits( context.gridOffset() );
|
||||
double gridResolution = mLayout->convertToLayoutUnits( context.gridResolution() );
|
||||
int gridMultiplyX = static_cast< int >( gridOffset.x() / gridResolution );
|
||||
int gridMultiplyY = static_cast< int >( gridOffset.y() / gridResolution );
|
||||
double currentXCoord = gridOffset.x() - gridMultiplyX * gridResolution;
|
||||
double currentYCoord;
|
||||
double minYCoord = gridOffset.y() - gridMultiplyY * gridResolution;
|
||||
|
||||
painter->save();
|
||||
//turn of antialiasing so grid is nice and sharp
|
||||
painter->setRenderHint( QPainter::Antialiasing, false );
|
||||
|
||||
switch ( context.gridStyle() )
|
||||
{
|
||||
case QgsLayoutContext::GridLines:
|
||||
{
|
||||
painter->setPen( context.gridPen() );
|
||||
|
||||
//draw vertical lines
|
||||
for ( ; currentXCoord <= rect().width(); currentXCoord += gridResolution )
|
||||
{
|
||||
painter->drawLine( QPointF( currentXCoord, 0 ), QPointF( currentXCoord, rect().height() ) );
|
||||
}
|
||||
|
||||
//draw horizontal lines
|
||||
currentYCoord = minYCoord;
|
||||
for ( ; currentYCoord <= rect().height(); currentYCoord += gridResolution )
|
||||
{
|
||||
painter->drawLine( QPointF( 0, currentYCoord ), QPointF( rect().width(), currentYCoord ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsLayoutContext::GridDots:
|
||||
case QgsLayoutContext::GridCrosses:
|
||||
{
|
||||
QPen gridPen = context.gridPen();
|
||||
painter->setPen( gridPen );
|
||||
painter->setBrush( QBrush( gridPen.color() ) );
|
||||
double halfCrossLength = 1;
|
||||
if ( context.gridStyle() == QgsLayoutContext::GridDots )
|
||||
{
|
||||
//dots are actually drawn as tiny crosses a few pixels across
|
||||
//set halfCrossLength to equivalent of 1 pixel
|
||||
halfCrossLength = 1 / itemStyle->matrix.m11();
|
||||
}
|
||||
else
|
||||
{
|
||||
halfCrossLength = gridResolution / 6;
|
||||
}
|
||||
|
||||
for ( ; currentXCoord <= rect().width(); currentXCoord += gridResolution )
|
||||
{
|
||||
currentYCoord = minYCoord;
|
||||
for ( ; currentYCoord <= rect().height(); currentYCoord += gridResolution )
|
||||
{
|
||||
painter->drawLine( QPointF( currentXCoord - halfCrossLength, currentYCoord ), QPointF( currentXCoord + halfCrossLength, currentYCoord ) );
|
||||
painter->drawLine( QPointF( currentXCoord, currentYCoord - halfCrossLength ), QPointF( currentXCoord, currentYCoord + halfCrossLength ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
///@endcond
|
||||
|
@ -22,6 +22,29 @@
|
||||
#include "qgslayoutitemregistry.h"
|
||||
#include "qgis_sip.h"
|
||||
|
||||
|
||||
///@cond PRIVATE
|
||||
#ifndef SIP_RUN
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* Item representing a grid. This is drawn separately to the underlying page item since the grid needs to be
|
||||
* drawn above all other layout items, while the paper item is drawn below all others.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsLayoutItemPageGrid: public QGraphicsRectItem
|
||||
{
|
||||
public:
|
||||
QgsLayoutItemPageGrid( double x, double y, double width, double height, QgsLayout *layout );
|
||||
|
||||
void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) override;
|
||||
|
||||
private:
|
||||
QgsLayout *mLayout = nullptr;
|
||||
};
|
||||
#endif
|
||||
///@endcond
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsLayoutItemPage
|
||||
@ -85,6 +108,8 @@ class CORE_EXPORT QgsLayoutItemPage : public QgsLayoutItem
|
||||
*/
|
||||
static QgsLayoutItemPage::Orientation decodePageOrientation( const QString &string, bool *ok SIP_OUT = nullptr );
|
||||
|
||||
void attemptResize( const QgsLayoutSize &size ) override;
|
||||
|
||||
protected:
|
||||
|
||||
void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr ) override;
|
||||
@ -93,6 +118,9 @@ class CORE_EXPORT QgsLayoutItemPage : public QgsLayoutItem
|
||||
|
||||
double mMaximumShadowWidth = -1;
|
||||
|
||||
std::unique_ptr< QgsLayoutItemPageGrid > mGrid;
|
||||
|
||||
friend class TestQgsLayoutPage;
|
||||
};
|
||||
|
||||
#endif //QGSLAYOUTITEMPAGE_H
|
||||
|
@ -35,6 +35,7 @@ class TestQgsLayoutPage : public QObject
|
||||
void itemType();
|
||||
void pageSize();
|
||||
void decodePageOrientation();
|
||||
void grid();
|
||||
|
||||
private:
|
||||
QString mReport;
|
||||
@ -125,5 +126,38 @@ void TestQgsLayoutPage::decodePageOrientation()
|
||||
QVERIFY( !ok );
|
||||
}
|
||||
|
||||
void TestQgsLayoutPage::grid()
|
||||
{
|
||||
// test that grid follows page around
|
||||
QgsProject p;
|
||||
QgsLayout l( &p );
|
||||
QgsLayoutItemPage *page = new QgsLayoutItemPage( &l );
|
||||
|
||||
// should have a grid
|
||||
QVERIFY( page->mGrid.get() );
|
||||
|
||||
// grid is parented to page, so while the grid should resize to match
|
||||
// page size, it should always report pos() of 0,0 (origin of page)
|
||||
page->attemptMove( QgsLayoutPoint( 5, 15 ) );
|
||||
page->attemptResize( QgsLayoutSize( 100, 200 ) );
|
||||
QCOMPARE( page->mGrid->rect().width(), 100.0 );
|
||||
QCOMPARE( page->mGrid->rect().height(), 200.0 );
|
||||
QCOMPARE( page->mGrid->pos().x(), 0.0 );
|
||||
QCOMPARE( page->mGrid->pos().y(), 0.0 );
|
||||
|
||||
page->attemptMove( QgsLayoutPoint( 25, 35 ) );
|
||||
QCOMPARE( page->mGrid->rect().width(), 100.0 );
|
||||
QCOMPARE( page->mGrid->rect().height(), 200.0 );
|
||||
QCOMPARE( page->mGrid->pos().x(), 0.0 );
|
||||
QCOMPARE( page->mGrid->pos().y(), 0.0 );
|
||||
|
||||
page->attemptResize( QgsLayoutSize( 150, 250 ) );
|
||||
QCOMPARE( page->mGrid->rect().width(), 150.0 );
|
||||
QCOMPARE( page->mGrid->rect().height(), 250.0 );
|
||||
QCOMPARE( page->mGrid->pos().x(), 0.0 );
|
||||
QCOMPARE( page->mGrid->pos().y(), 0.0 );
|
||||
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsLayoutPage )
|
||||
#include "testqgslayoutpage.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user