mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Create rubber band classes for layout views
c++ QgsLayoutItem metadata classes can directly register a function which creates a QgsLayoutViewRubberBand for the item subclass. Python code cannot utilise this shortcut (due to inaccessibility of forward declared gui classes from core Python classes), so there's a separate gui registry utility class added for registering prototypes for rubber bands for already registered item types.
This commit is contained in:
parent
4ebea75e6a
commit
3843b5ef37
@ -61,6 +61,7 @@ class QgsLayoutItemAbstractMetadata
|
||||
:rtype: QWidget
|
||||
%End
|
||||
|
||||
|
||||
virtual void resolvePaths( QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving );
|
||||
%Docstring
|
||||
Resolve paths in the item's ``properties`` (if there are any paths).
|
||||
@ -78,6 +79,7 @@ class QgsLayoutItemAbstractMetadata
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsLayoutItemRegistry : QObject
|
||||
{
|
||||
%Docstring
|
||||
@ -141,6 +143,7 @@ class QgsLayoutItemRegistry : QObject
|
||||
:rtype: QWidget
|
||||
%End
|
||||
|
||||
|
||||
void resolvePaths( int type, QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) const;
|
||||
%Docstring
|
||||
Resolve paths in properties of a particular symbol layer.
|
||||
|
@ -42,7 +42,9 @@
|
||||
%Include editorwidgets/core/qgseditorwidgetautoconf.sip
|
||||
%Include layertree/qgslayertreeembeddedconfigwidget.sip
|
||||
%Include layertree/qgslayertreeembeddedwidgetregistry.sip
|
||||
%Include layout/qgslayoutitemregistryguiutils.sip
|
||||
%Include layout/qgslayoutviewmouseevent.sip
|
||||
%Include layout/qgslayoutviewrubberband.sip
|
||||
%Include locator/qgslocatorcontext.sip
|
||||
%Include raster/qgsrasterrendererwidget.sip
|
||||
%Include symbology-ng/qgssymbolwidgetcontext.sip
|
||||
|
46
python/gui/layout/qgslayoutitemregistryguiutils.sip
Normal file
46
python/gui/layout/qgslayoutitemregistryguiutils.sip
Normal file
@ -0,0 +1,46 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/layout/qgslayoutitemregistryguiutils.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsLayoutItemRegistryGuiUtils
|
||||
{
|
||||
%Docstring
|
||||
A group of static utilities for working with the gui based portions of
|
||||
QgsLayoutItemRegistry.
|
||||
|
||||
This class is designed to allow Python item subclasses to override the
|
||||
default GUI based QgsLayoutItemAbstractMetadata methods, which
|
||||
cannot be directly overridden from Python subclasses.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgslayoutitemregistryguiutils.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
static void setItemRubberBandPrototype( int type, QgsLayoutViewRubberBand *prototype /Transfer/ );
|
||||
%Docstring
|
||||
Sets a ``prototype`` for the rubber bands for the layout item with specified ``type``.
|
||||
Python subclasses of QgsLayoutItem must call this method to register their prototypes,
|
||||
as the usual c++ QgsLayoutItemAbstractMetadata are not accessible via the Python bindings.
|
||||
%End
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/layout/qgslayoutitemregistryguiutils.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
157
python/gui/layout/qgslayoutviewrubberband.sip
Normal file
157
python/gui/layout/qgslayoutviewrubberband.sip
Normal file
@ -0,0 +1,157 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/layout/qgslayoutviewrubberband.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsLayoutViewRubberBand
|
||||
{
|
||||
%Docstring
|
||||
QgsLayoutViewRubberBand is an abstract base class for temporary rubber band items
|
||||
in various shapes, for use within QgsLayoutView widgets.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
%End
|
||||
|
||||
%ConvertToSubClassCode
|
||||
if ( dynamic_cast<QgsLayoutViewMouseEvent *>( sipCpp ) )
|
||||
sipType = sipType_QgsLayoutViewMouseEvent;
|
||||
else
|
||||
sipType = 0;
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsLayoutViewRubberBand( QgsLayoutView *view );
|
||||
%Docstring
|
||||
Constructor for QgsLayoutViewRubberBand.
|
||||
%End
|
||||
|
||||
virtual ~QgsLayoutViewRubberBand();
|
||||
|
||||
virtual QgsLayoutViewRubberBand *create( QgsLayoutView *view ) const = 0 /Factory/;
|
||||
%Docstring
|
||||
Creates a new instance of the QgsLayoutViewRubberBand subclass.
|
||||
:rtype: QgsLayoutViewRubberBand
|
||||
%End
|
||||
|
||||
virtual void start( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
|
||||
%Docstring
|
||||
Called when a rubber band should be created at the specified
|
||||
starting ``position`` (in layout coordinate space).
|
||||
%End
|
||||
|
||||
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
|
||||
%Docstring
|
||||
Called when a rubber band should be updated to reflect a temporary
|
||||
ending ``position`` (in layout coordinate space).
|
||||
%End
|
||||
|
||||
virtual void finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
|
||||
%Docstring
|
||||
Called when a rubber band use has finished and the rubber
|
||||
band is no longer required.
|
||||
%End
|
||||
|
||||
QgsLayoutView *view() const;
|
||||
%Docstring
|
||||
Returns the view associated with the rubber band.
|
||||
.. seealso:: layout()
|
||||
:rtype: QgsLayoutView
|
||||
%End
|
||||
|
||||
QgsLayout *layout() const;
|
||||
%Docstring
|
||||
Returns the layout associated with the rubber band.
|
||||
.. seealso:: view()
|
||||
:rtype: QgsLayout
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
QRectF updateRect( QPointF start, QPointF position, bool constrainSquare, bool fromCenter );
|
||||
%Docstring
|
||||
Calculates an updated bounding box rectangle from a original ``start`` position
|
||||
and new ``position``. If ``constrainSquare`` is true then the bounding box will be
|
||||
forced to a square shape. If ``fromCenter`` is true then the original ``start``
|
||||
position will form the center point of the returned rectangle.
|
||||
:rtype: QRectF
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
class QgsLayoutViewRectangularRubberBand : QgsLayoutViewRubberBand
|
||||
{
|
||||
%Docstring
|
||||
QgsLayoutViewRectangularRubberBand is rectangular rubber band for use within QgsLayoutView widgets.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsLayoutViewRectangularRubberBand( QgsLayoutView *view );
|
||||
%Docstring
|
||||
Constructor for QgsLayoutViewRectangularRubberBand.
|
||||
%End
|
||||
virtual QgsLayoutViewRectangularRubberBand *create( QgsLayoutView *view ) const /Factory/;
|
||||
|
||||
|
||||
~QgsLayoutViewRectangularRubberBand();
|
||||
|
||||
virtual void start( QPointF position, Qt::KeyboardModifiers modifiers );
|
||||
|
||||
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );
|
||||
|
||||
virtual void finish( QPointF, Qt::KeyboardModifiers );
|
||||
|
||||
|
||||
};
|
||||
|
||||
class QgsLayoutViewEllipticalRubberBand : QgsLayoutViewRubberBand
|
||||
{
|
||||
%Docstring
|
||||
QgsLayoutViewEllipseRubberBand is elliptical rubber band for use within QgsLayoutView widgets.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsLayoutViewEllipticalRubberBand( QgsLayoutView *view );
|
||||
%Docstring
|
||||
Constructor for QgsLayoutViewEllipticalRubberBand.
|
||||
%End
|
||||
virtual QgsLayoutViewEllipticalRubberBand *create( QgsLayoutView *view ) const /Factory/;
|
||||
|
||||
|
||||
~QgsLayoutViewEllipticalRubberBand();
|
||||
|
||||
virtual void start( QPointF position, Qt::KeyboardModifiers modifiers );
|
||||
|
||||
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );
|
||||
|
||||
virtual void finish( QPointF, Qt::KeyboardModifiers );
|
||||
|
||||
|
||||
};
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/layout/qgslayoutviewrubberband.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -8,7 +8,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsLayoutViewToolAddItem : QgsLayoutViewTool
|
||||
{
|
||||
%Docstring
|
||||
|
@ -58,6 +58,17 @@ QWidget *QgsLayoutItemRegistry::createItemWidget( int type ) const
|
||||
return mMetadata[type]->createItemWidget();
|
||||
}
|
||||
|
||||
QgsLayoutViewRubberBand *QgsLayoutItemRegistry::createItemRubberBand( int type, QgsLayoutView *view ) const
|
||||
{
|
||||
if ( mRubberBandFunctions.contains( type ) )
|
||||
return mRubberBandFunctions.value( type )( view );
|
||||
|
||||
if ( !mMetadata.contains( type ) )
|
||||
return nullptr;
|
||||
|
||||
return mMetadata[type]->createRubberBand( view );
|
||||
}
|
||||
|
||||
void QgsLayoutItemRegistry::resolvePaths( int type, QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) const
|
||||
{
|
||||
if ( !mMetadata.contains( type ) )
|
||||
|
@ -25,7 +25,9 @@
|
||||
#include <functional>
|
||||
|
||||
class QgsLayout;
|
||||
class QgsLayoutView;
|
||||
class QgsLayoutItem;
|
||||
class QgsLayoutViewRubberBand;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
@ -73,6 +75,14 @@ class CORE_EXPORT QgsLayoutItemAbstractMetadata
|
||||
*/
|
||||
virtual QWidget *createItemWidget() SIP_FACTORY { return nullptr; }
|
||||
|
||||
/**
|
||||
* Creates a rubber band for use when creating layout items of this type. Can return nullptr if no rubber band
|
||||
* should be created.
|
||||
* \note not available in Python bindings. Python item subclasses must use QgsLayoutItemRegistryGuiUtils
|
||||
* to override the default rubber band creation function.
|
||||
*/
|
||||
virtual QgsLayoutViewRubberBand *createRubberBand( QgsLayoutView *view ) SIP_SKIP { Q_UNUSED( view ); return nullptr; }
|
||||
|
||||
/**
|
||||
* Resolve paths in the item's \a properties (if there are any paths).
|
||||
* When \a saving is true, paths are converted from absolute to relative,
|
||||
@ -99,6 +109,9 @@ typedef std::function<QgsLayoutItem *( QgsLayout *, const QVariantMap & )> QgsLa
|
||||
//! Layout item configuration widget creation function
|
||||
typedef std::function<QWidget *()> QgsLayoutItemWidgetFunc SIP_SKIP;
|
||||
|
||||
//! Layout rubber band creation function
|
||||
typedef std::function<QgsLayoutViewRubberBand *( QgsLayoutView * )> QgsLayoutItemRubberBandFunc SIP_SKIP;
|
||||
|
||||
//! Layout item path resolver function
|
||||
typedef std::function<void( QVariantMap &, const QgsPathResolver &, bool )> QgsLayoutItemPathResolverFunc SIP_SKIP;
|
||||
|
||||
@ -152,6 +165,18 @@ class CORE_EXPORT QgsLayoutItemMetadata : public QgsLayoutItemAbstractMetadata
|
||||
*/
|
||||
void setWidgetFunction( QgsLayoutItemWidgetFunc function ) { mWidgetFunc = function; }
|
||||
|
||||
/**
|
||||
* Returns the classes' rubber band creation function.
|
||||
* \see setRubberBandCreationFunction()
|
||||
*/
|
||||
QgsLayoutItemRubberBandFunc rubberBandCreationFunction() const { return mRubberBandFunc; }
|
||||
|
||||
/**
|
||||
* Sets the classes' rubber band creation \a function.
|
||||
* \see rubberBandCreationFunction()
|
||||
*/
|
||||
void setRubberBandCreationFunction( QgsLayoutItemRubberBandFunc function ) { mRubberBandFunc = function; }
|
||||
|
||||
QIcon icon() const override { return mIcon.isNull() ? QgsLayoutItemAbstractMetadata::icon() : mIcon; }
|
||||
QgsLayoutItem *createItem( QgsLayout *layout, const QVariantMap &properties ) override { return mCreateFunc ? mCreateFunc( layout, properties ) : nullptr; }
|
||||
QWidget *createItemWidget() override { return mWidgetFunc ? mWidgetFunc() : nullptr; }
|
||||
@ -165,6 +190,7 @@ class CORE_EXPORT QgsLayoutItemMetadata : public QgsLayoutItemAbstractMetadata
|
||||
QIcon mIcon;
|
||||
QgsLayoutItemCreateFunc mCreateFunc = nullptr;
|
||||
QgsLayoutItemWidgetFunc mWidgetFunc = nullptr;
|
||||
QgsLayoutItemRubberBandFunc mRubberBandFunc = nullptr;
|
||||
QgsLayoutItemPathResolverFunc mPathResolverFunc = nullptr;
|
||||
|
||||
};
|
||||
@ -237,6 +263,12 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject
|
||||
*/
|
||||
QWidget *createItemWidget( int type ) const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates a new rubber band item for the specified item \a type and destination \a view.
|
||||
* \note not available from Python bindings
|
||||
*/
|
||||
QgsLayoutViewRubberBand *createItemRubberBand( int type, QgsLayoutView *view ) const SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Resolve paths in properties of a particular symbol layer.
|
||||
* This normally means converting relative paths to absolute paths when loading
|
||||
@ -264,6 +296,10 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject
|
||||
|
||||
QMap<int, QgsLayoutItemAbstractMetadata *> mMetadata;
|
||||
|
||||
QMap<int, QgsLayoutItemRubberBandFunc > mRubberBandFunctions;
|
||||
|
||||
friend class QgsLayoutItemRegistryGuiUtils;
|
||||
|
||||
};
|
||||
|
||||
#endif //QGSLAYOUTITEMREGISTRY_H
|
||||
|
@ -158,8 +158,10 @@ SET(QGIS_GUI_SRCS
|
||||
layertree/qgslayertreeview.cpp
|
||||
layertree/qgslayertreeviewdefaultactions.cpp
|
||||
|
||||
layout/qgslayoutitemregistryguiutils.cpp
|
||||
layout/qgslayoutview.cpp
|
||||
layout/qgslayoutviewmouseevent.cpp
|
||||
layout/qgslayoutviewrubberband.cpp
|
||||
layout/qgslayoutviewtool.cpp
|
||||
layout/qgslayoutviewtooladditem.cpp
|
||||
|
||||
@ -721,7 +723,9 @@ SET(QGIS_GUI_HDRS
|
||||
layertree/qgslayertreeembeddedconfigwidget.h
|
||||
layertree/qgslayertreeembeddedwidgetregistry.h
|
||||
|
||||
layout/qgslayoutitemregistryguiutils.h
|
||||
layout/qgslayoutviewmouseevent.h
|
||||
layout/qgslayoutviewrubberband.h
|
||||
|
||||
locator/qgslocatorcontext.h
|
||||
|
||||
|
27
src/gui/layout/qgslayoutitemregistryguiutils.cpp
Normal file
27
src/gui/layout/qgslayoutitemregistryguiutils.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
/***************************************************************************
|
||||
qgslayoutitemregistryguiutils.h
|
||||
-------------------------------
|
||||
Date : July 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "qgslayoutitemregistryguiutils.h"
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
|
||||
void QgsLayoutItemRegistryGuiUtils::setItemRubberBandPrototype( int type, QgsLayoutViewRubberBand *prototype )
|
||||
{
|
||||
auto create = [prototype]( QgsLayoutView * view )->QgsLayoutViewRubberBand *
|
||||
{
|
||||
return prototype->create( view );
|
||||
};
|
||||
QgsApplication::layoutItemRegistry()->mRubberBandFunctions.insert( type, create );
|
||||
}
|
50
src/gui/layout/qgslayoutitemregistryguiutils.h
Normal file
50
src/gui/layout/qgslayoutitemregistryguiutils.h
Normal file
@ -0,0 +1,50 @@
|
||||
/***************************************************************************
|
||||
qgslayoutitemregistryguiutils.h
|
||||
-------------------------------
|
||||
Date : July 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSLAYOUTITEMREGISTRYGUIUTILS_H
|
||||
#define QGSLAYOUTITEMREGISTRYGUIUTILS_H
|
||||
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgslayoutitemregistry.h"
|
||||
|
||||
class QgsLayoutViewRubberBand;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* A group of static utilities for working with the gui based portions of
|
||||
* QgsLayoutItemRegistry.
|
||||
*
|
||||
* This class is designed to allow Python item subclasses to override the
|
||||
* default GUI based QgsLayoutItemAbstractMetadata methods, which
|
||||
* cannot be directly overridden from Python subclasses.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsLayoutItemRegistryGuiUtils
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Sets a \a prototype for the rubber bands for the layout item with specified \a type.
|
||||
* Python subclasses of QgsLayoutItem must call this method to register their prototypes,
|
||||
* as the usual c++ QgsLayoutItemAbstractMetadata are not accessible via the Python bindings.
|
||||
*/
|
||||
static void setItemRubberBandPrototype( int type, QgsLayoutViewRubberBand *prototype SIP_TRANSFER );
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSLAYOUTITEMREGISTRYGUIUTILS_H
|
222
src/gui/layout/qgslayoutviewrubberband.cpp
Normal file
222
src/gui/layout/qgslayoutviewrubberband.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
/***************************************************************************
|
||||
qgslayoutviewrubberband.cpp
|
||||
---------------------------
|
||||
Date : July 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
#include "qgslayout.h"
|
||||
#include "qgslayoutview.h"
|
||||
#include <QGraphicsRectItem>
|
||||
#include <QGraphicsEllipseItem>
|
||||
|
||||
QgsLayoutViewRubberBand::QgsLayoutViewRubberBand( QgsLayoutView *view )
|
||||
: mView( view )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsLayoutView *QgsLayoutViewRubberBand::view() const
|
||||
{
|
||||
return mView;
|
||||
}
|
||||
|
||||
QgsLayout *QgsLayoutViewRubberBand::layout() const
|
||||
{
|
||||
return mView->currentLayout();
|
||||
}
|
||||
|
||||
QRectF QgsLayoutViewRubberBand::updateRect( QPointF start, QPointF position, bool constrainSquare, bool fromCenter )
|
||||
{
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
|
||||
double dx = position.x() - start.x();
|
||||
double dy = position.y() - start.y();
|
||||
|
||||
if ( constrainSquare )
|
||||
{
|
||||
if ( fabs( dx ) > fabs( dy ) )
|
||||
{
|
||||
width = fabs( dx );
|
||||
height = width;
|
||||
}
|
||||
else
|
||||
{
|
||||
height = fabs( dy );
|
||||
width = height;
|
||||
}
|
||||
|
||||
x = start.x() - ( ( dx < 0 ) ? width : 0 );
|
||||
y = start.y() - ( ( dy < 0 ) ? height : 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
//not constraining
|
||||
if ( dx < 0 )
|
||||
{
|
||||
x = position.x();
|
||||
width = -dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = start.x();
|
||||
width = dx;
|
||||
}
|
||||
|
||||
if ( dy < 0 )
|
||||
{
|
||||
y = position.y();
|
||||
height = -dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = start.y();
|
||||
height = dy;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fromCenter )
|
||||
{
|
||||
x = start.x() - width;
|
||||
y = start.y() - height;
|
||||
width *= 2.0;
|
||||
height *= 2.0;
|
||||
}
|
||||
|
||||
return QRectF( x, y, width, height );
|
||||
}
|
||||
|
||||
|
||||
QgsLayoutViewRectangularRubberBand::QgsLayoutViewRectangularRubberBand( QgsLayoutView *view )
|
||||
: QgsLayoutViewRubberBand( view )
|
||||
{
|
||||
}
|
||||
|
||||
QgsLayoutViewRectangularRubberBand *QgsLayoutViewRectangularRubberBand::create( QgsLayoutView *view ) const
|
||||
{
|
||||
return new QgsLayoutViewRectangularRubberBand( view );
|
||||
}
|
||||
|
||||
QgsLayoutViewRectangularRubberBand::~QgsLayoutViewRectangularRubberBand()
|
||||
{
|
||||
if ( mRubberBandItem )
|
||||
{
|
||||
layout()->removeItem( mRubberBandItem );
|
||||
delete mRubberBandItem;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutViewRectangularRubberBand::start( QPointF position, Qt::KeyboardModifiers )
|
||||
{
|
||||
QTransform t;
|
||||
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
|
||||
mRubberBandItem->setBrush( Qt::NoBrush );
|
||||
mRubberBandItem->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
|
||||
mRubberBandStartPos = position;
|
||||
t.translate( position.x(), position.y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZMapTool );
|
||||
layout()->addItem( mRubberBandItem );
|
||||
layout()->update();
|
||||
}
|
||||
|
||||
void QgsLayoutViewRectangularRubberBand::update( QPointF position, Qt::KeyboardModifiers modifiers )
|
||||
{
|
||||
if ( !mRubberBandItem )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool constrainSquare = modifiers & Qt::ShiftModifier;
|
||||
bool fromCenter = modifiers & Qt::AltModifier;
|
||||
|
||||
QRectF newRect = updateRect( mRubberBandStartPos, position, constrainSquare, fromCenter );
|
||||
mRubberBandItem->setRect( 0, 0, newRect.width(), newRect.height() );
|
||||
QTransform t;
|
||||
t.translate( newRect.x(), newRect.y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
}
|
||||
|
||||
void QgsLayoutViewRectangularRubberBand::finish( QPointF, Qt::KeyboardModifiers )
|
||||
{
|
||||
if ( mRubberBandItem )
|
||||
{
|
||||
layout()->removeItem( mRubberBandItem );
|
||||
delete mRubberBandItem;
|
||||
mRubberBandItem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QgsLayoutViewEllipticalRubberBand::QgsLayoutViewEllipticalRubberBand( QgsLayoutView *view )
|
||||
: QgsLayoutViewRubberBand( view )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsLayoutViewEllipticalRubberBand *QgsLayoutViewEllipticalRubberBand::create( QgsLayoutView *view ) const
|
||||
{
|
||||
return new QgsLayoutViewEllipticalRubberBand( view );
|
||||
}
|
||||
|
||||
QgsLayoutViewEllipticalRubberBand::~QgsLayoutViewEllipticalRubberBand()
|
||||
{
|
||||
if ( mRubberBandItem )
|
||||
{
|
||||
layout()->removeItem( mRubberBandItem );
|
||||
delete mRubberBandItem;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutViewEllipticalRubberBand::start( QPointF position, Qt::KeyboardModifiers )
|
||||
{
|
||||
QTransform t;
|
||||
mRubberBandItem = new QGraphicsEllipseItem( 0, 0, 0, 0 );
|
||||
mRubberBandItem->setBrush( Qt::NoBrush );
|
||||
mRubberBandItem->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
|
||||
mRubberBandStartPos = position;
|
||||
t.translate( position.x(), position.y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZMapTool );
|
||||
layout()->addItem( mRubberBandItem );
|
||||
layout()->update();
|
||||
}
|
||||
|
||||
void QgsLayoutViewEllipticalRubberBand::update( QPointF position, Qt::KeyboardModifiers modifiers )
|
||||
{
|
||||
if ( !mRubberBandItem )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool constrainSquare = modifiers & Qt::ShiftModifier;
|
||||
bool fromCenter = modifiers & Qt::AltModifier;
|
||||
|
||||
QRectF newRect = updateRect( mRubberBandStartPos, position, constrainSquare, fromCenter );
|
||||
mRubberBandItem->setRect( 0, 0, newRect.width(), newRect.height() );
|
||||
QTransform t;
|
||||
t.translate( newRect.x(), newRect.y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
}
|
||||
|
||||
void QgsLayoutViewEllipticalRubberBand::finish( QPointF, Qt::KeyboardModifiers )
|
||||
{
|
||||
if ( mRubberBandItem )
|
||||
{
|
||||
layout()->removeItem( mRubberBandItem );
|
||||
delete mRubberBandItem;
|
||||
mRubberBandItem = nullptr;
|
||||
}
|
||||
}
|
169
src/gui/layout/qgslayoutviewrubberband.h
Normal file
169
src/gui/layout/qgslayoutviewrubberband.h
Normal file
@ -0,0 +1,169 @@
|
||||
/***************************************************************************
|
||||
qgslayoutviewrubberband.h
|
||||
-------------------------
|
||||
Date : July 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSLAYOUTVIEWRUBBERBAND_H
|
||||
#define QGSLAYOUTVIEWRUBBERBAND_H
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis_sip.h"
|
||||
|
||||
class QgsLayoutView;
|
||||
class QGraphicsRectItem;
|
||||
class QGraphicsEllipseItem;
|
||||
class QgsLayout;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* QgsLayoutViewRubberBand is an abstract base class for temporary rubber band items
|
||||
* in various shapes, for use within QgsLayoutView widgets.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsLayoutViewRubberBand
|
||||
{
|
||||
|
||||
#ifdef SIP_RUN
|
||||
SIP_CONVERT_TO_SUBCLASS_CODE
|
||||
if ( dynamic_cast<QgsLayoutViewMouseEvent *>( sipCpp ) )
|
||||
sipType = sipType_QgsLayoutViewMouseEvent;
|
||||
else
|
||||
sipType = 0;
|
||||
SIP_END
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsLayoutViewRubberBand.
|
||||
*/
|
||||
QgsLayoutViewRubberBand( QgsLayoutView *view );
|
||||
|
||||
virtual ~QgsLayoutViewRubberBand() = default;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the QgsLayoutViewRubberBand subclass.
|
||||
*/
|
||||
virtual QgsLayoutViewRubberBand *create( QgsLayoutView *view ) const = 0 SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Called when a rubber band should be created at the specified
|
||||
* starting \a position (in layout coordinate space).
|
||||
*/
|
||||
virtual void start( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
|
||||
|
||||
/**
|
||||
* Called when a rubber band should be updated to reflect a temporary
|
||||
* ending \a position (in layout coordinate space).
|
||||
*/
|
||||
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
|
||||
|
||||
/**
|
||||
* Called when a rubber band use has finished and the rubber
|
||||
* band is no longer required.
|
||||
*/
|
||||
virtual void finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
|
||||
|
||||
/**
|
||||
* Returns the view associated with the rubber band.
|
||||
* \see layout()
|
||||
*/
|
||||
QgsLayoutView *view() const;
|
||||
|
||||
/**
|
||||
* Returns the layout associated with the rubber band.
|
||||
* \see view()
|
||||
*/
|
||||
QgsLayout *layout() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Calculates an updated bounding box rectangle from a original \a start position
|
||||
* and new \a position. If \a constrainSquare is true then the bounding box will be
|
||||
* forced to a square shape. If \a fromCenter is true then the original \a start
|
||||
* position will form the center point of the returned rectangle.
|
||||
*/
|
||||
QRectF updateRect( QPointF start, QPointF position, bool constrainSquare, bool fromCenter );
|
||||
|
||||
private:
|
||||
|
||||
QgsLayoutView *mView = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* QgsLayoutViewRectangularRubberBand is rectangular rubber band for use within QgsLayoutView widgets.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsLayoutViewRectangularRubberBand : public QgsLayoutViewRubberBand
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsLayoutViewRectangularRubberBand.
|
||||
*/
|
||||
QgsLayoutViewRectangularRubberBand( QgsLayoutView *view );
|
||||
QgsLayoutViewRectangularRubberBand *create( QgsLayoutView *view ) const override SIP_FACTORY;
|
||||
|
||||
~QgsLayoutViewRectangularRubberBand();
|
||||
|
||||
void start( QPointF position, Qt::KeyboardModifiers modifiers ) override;
|
||||
void update( QPointF position, Qt::KeyboardModifiers modifiers ) override;
|
||||
void finish( QPointF, Qt::KeyboardModifiers ) override;
|
||||
|
||||
private:
|
||||
|
||||
//! Rubber band item
|
||||
QGraphicsRectItem *mRubberBandItem = nullptr;
|
||||
|
||||
//! Start of rubber band creation
|
||||
QPointF mRubberBandStartPos;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* QgsLayoutViewEllipseRubberBand is elliptical rubber band for use within QgsLayoutView widgets.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsLayoutViewEllipticalRubberBand : public QgsLayoutViewRubberBand
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsLayoutViewEllipticalRubberBand.
|
||||
*/
|
||||
QgsLayoutViewEllipticalRubberBand( QgsLayoutView *view );
|
||||
QgsLayoutViewEllipticalRubberBand *create( QgsLayoutView *view ) const override SIP_FACTORY;
|
||||
|
||||
~QgsLayoutViewEllipticalRubberBand();
|
||||
|
||||
void start( QPointF position, Qt::KeyboardModifiers modifiers ) override;
|
||||
void update( QPointF position, Qt::KeyboardModifiers modifiers ) override;
|
||||
void finish( QPointF, Qt::KeyboardModifiers ) override;
|
||||
|
||||
private:
|
||||
|
||||
//! Rubber band item
|
||||
QGraphicsEllipseItem *mRubberBandItem = nullptr;
|
||||
|
||||
//! Start of rubber band creation
|
||||
QPointF mRubberBandStartPos;
|
||||
|
||||
};
|
||||
#endif // QGSLAYOUTVIEWRUBBERBAND_H
|
@ -21,6 +21,7 @@
|
||||
#include "qgslayoutitemregistry.h"
|
||||
#include "qgslayoutviewmouseevent.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
#include <QGraphicsRectItem>
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
@ -40,22 +41,24 @@ void QgsLayoutViewToolAddItem::setItemType( int itemType )
|
||||
|
||||
void QgsLayoutViewToolAddItem::layoutPressEvent( QgsLayoutViewMouseEvent *event )
|
||||
{
|
||||
QTransform t;
|
||||
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
|
||||
mRubberBandItem->setBrush( Qt::NoBrush );
|
||||
mRubberBandItem->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
|
||||
mMousePressStartPos = event->pos();
|
||||
mRubberBandStartPos = QPointF( event->layoutPoint().x(), event->layoutPoint().y() );
|
||||
t.translate( event->x(), event->y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZMapTool );
|
||||
layout()->addItem( mRubberBandItem );
|
||||
layout()->update();
|
||||
if ( event->button() != Qt::LeftButton )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mRubberBand.reset( QgsApplication::layoutItemRegistry()->createItemRubberBand( mItemType, view() ) );
|
||||
if ( mRubberBand )
|
||||
{
|
||||
mRubberBand->start( event->layoutPoint(), event->modifiers() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddItem::layoutMoveEvent( QgsLayoutViewMouseEvent *event )
|
||||
{
|
||||
updateRubberBandRect( event->layoutPoint(), event->modifiers() & Qt::ShiftModifier, event->modifiers() & Qt::AltModifier );
|
||||
if ( mRubberBand )
|
||||
{
|
||||
mRubberBand->update( event->layoutPoint(), event->modifiers() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *event )
|
||||
@ -65,6 +68,11 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mRubberBand )
|
||||
{
|
||||
mRubberBand->finish( event->layoutPoint(), event->modifiers() );
|
||||
}
|
||||
|
||||
// click? or click-and-drag?
|
||||
QPoint mousePressStopPoint = event->pos();
|
||||
int diffX = mousePressStopPoint.x() - mMousePressStartPos.x();
|
||||
@ -74,88 +82,12 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even
|
||||
{
|
||||
clickOnly = true;
|
||||
}
|
||||
Q_UNUSED( clickOnly );
|
||||
|
||||
if ( mRubberBandItem )
|
||||
{
|
||||
layout()->removeItem( mRubberBandItem );
|
||||
delete mRubberBandItem;
|
||||
mRubberBandItem = nullptr;
|
||||
}
|
||||
|
||||
QgsLogger::debug( QStringLiteral( "creating new %1 item " ).arg( QgsApplication::layoutItemRegistry()->itemMetadata( mItemType )->visibleName() ) );
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddItem::updateRubberBandRect( QPointF pos, const bool constrainSquare, const bool fromCenter )
|
||||
{
|
||||
if ( !mRubberBandItem )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
|
||||
double dx = pos.x() - mRubberBandStartPos.x();
|
||||
double dy = pos.y() - mRubberBandStartPos.y();
|
||||
|
||||
if ( constrainSquare )
|
||||
{
|
||||
if ( fabs( dx ) > fabs( dy ) )
|
||||
{
|
||||
width = fabs( dx );
|
||||
height = width;
|
||||
}
|
||||
else
|
||||
{
|
||||
height = fabs( dy );
|
||||
width = height;
|
||||
}
|
||||
|
||||
x = mRubberBandStartPos.x() - ( ( dx < 0 ) ? width : 0 );
|
||||
y = mRubberBandStartPos.y() - ( ( dy < 0 ) ? height : 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
//not constraining
|
||||
if ( dx < 0 )
|
||||
{
|
||||
x = pos.x();
|
||||
width = -dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = mRubberBandStartPos.x();
|
||||
width = dx;
|
||||
}
|
||||
|
||||
if ( dy < 0 )
|
||||
{
|
||||
y = pos.y();
|
||||
height = -dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = mRubberBandStartPos.y();
|
||||
height = dy;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fromCenter )
|
||||
{
|
||||
x = mRubberBandStartPos.x() - width;
|
||||
y = mRubberBandStartPos.y() - height;
|
||||
width *= 2.0;
|
||||
height *= 2.0;
|
||||
}
|
||||
|
||||
mRubberBandItem->setRect( 0, 0, width, height );
|
||||
QTransform t;
|
||||
t.translate( x, y );
|
||||
mRubberBandItem->setTransform( t );
|
||||
}
|
||||
|
||||
int QgsLayoutViewToolAddItem::itemType() const
|
||||
{
|
||||
return mItemType;
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "qgis.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgslayoutviewtool.h"
|
||||
|
||||
class QGraphicsRectItem;
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
@ -57,7 +57,7 @@ class GUI_EXPORT QgsLayoutViewToolAddItem : public QgsLayoutViewTool
|
||||
int mItemType = 0;
|
||||
|
||||
//! Rubber band item
|
||||
QGraphicsRectItem *mRubberBandItem = nullptr;
|
||||
std::unique_ptr< QgsLayoutViewRubberBand > mRubberBand;
|
||||
|
||||
//! Start position for mouse press
|
||||
QPoint mMousePressStartPos;
|
||||
@ -65,9 +65,6 @@ class GUI_EXPORT QgsLayoutViewToolAddItem : public QgsLayoutViewTool
|
||||
//! Start of rubber band creation
|
||||
QPointF mRubberBandStartPos;
|
||||
|
||||
//! Redraws the rectangular rubber band
|
||||
void updateRubberBandRect( QPointF pos, const bool constrainSquare = false, const bool fromCenter = false );
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSLAYOUTVIEWTOOLADDITEM_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user