Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+500
@@ -0,0 +1,500 @@
|
||||
/**
|
||||
**
|
||||
** @RDE_HEADER@
|
||||
** Definition of base class for rubberbands
|
||||
** $Id$
|
||||
** $HeadURL$
|
||||
** $Author$
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
**
|
||||
** Hardware-Environment: Intel-PC
|
||||
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
|
||||
**
|
||||
** Language ........: C++ 11
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
**
|
||||
** Author ...........: Jörg Turla, SPD G, Tel. 3132
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
**
|
||||
** Notes .........:
|
||||
**
|
||||
** 27.03.2015, JT : First edition for use with Qt5
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "event_dispatcher.h"
|
||||
#include "event_delegater.h"
|
||||
|
||||
#include <Map/map.h>
|
||||
#include <Common/ref_pointer.h>
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include <QtGui/QColor>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace Esri {
|
||||
namespace ArcGISRuntime {
|
||||
class MapGraphicsView;
|
||||
class Point;
|
||||
} }
|
||||
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
/**
|
||||
Namespace for all rubberband stuff (is part of namespace SituationMap)
|
||||
*/
|
||||
namespace RB
|
||||
{
|
||||
/**
|
||||
*/
|
||||
enum class CoordinateSystem
|
||||
{
|
||||
Map,
|
||||
Geo
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@class RubberbandBase rubberband_base.h
|
||||
@brief Base class of all Rubberbands
|
||||
|
||||
Rubberbands are used to create or modifiy geometries like lines, circles, polygons etc. by processing
|
||||
Qt input events like keyboard and mouse events. To create a rubberband the RubberbandFactory has to be used.
|
||||
At end of rubberband processing the signal \c abort or\c apply are emitted. To delete the rubberband the
|
||||
function deleteMySelf must be called. To use the delete operator is dangerous because at end of signal
|
||||
processing some program code may be performed.
|
||||
|
||||
Example to how to use rubberband:
|
||||
|
||||
@code
|
||||
|
||||
SituationMap::Map & map = ...
|
||||
|
||||
const RubberbandFactory & rubberbandFactory = map.rubberbandFactory();
|
||||
|
||||
RubberbandPointFeature * rubberband = rubberbandFactory.create<RubberbandPointFeature>();
|
||||
if (rubberband != nullptr)
|
||||
{
|
||||
QObject::connect( rubberband, &SiMapRubBnd::Rubberband::apply, [=](SiMapRubBnd::Rubberband * rubberband )
|
||||
{
|
||||
// rubberband has finished input
|
||||
if (rubberband)
|
||||
{
|
||||
const QVector<QPointF> & vertexList = rubberband->coordinateVector();
|
||||
|
||||
// do something with vertexList
|
||||
|
||||
rubberband->deleteMySelf(); // notice don't call here delete rubberband directly !!!
|
||||
}
|
||||
} );
|
||||
|
||||
QObject::connect( rubberband, &SiMapRubBnd::Rubberband::abort, this, [=](SiMapRubBnd::Rubberband * rubberband )
|
||||
{
|
||||
// Rubberband has been aborted by user
|
||||
if (rubberband)
|
||||
{
|
||||
rubberband->deleteMySelf(); // notice don't call here delete rubberband directly !!!
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@endcode
|
||||
|
||||
Following keyboard commands are available in active rubberbands:
|
||||
|
||||
| Key | Modifier | Funktion |
|
||||
| :----: |:-------: | :--------------------------------------------------------------------------- |
|
||||
| Esc | | Rubberband abbrechen |
|
||||
| Return | | Rubberband abschließen und Eingabe übernehmen wenn möglich, sonst Abbruch |
|
||||
| Left | | Selektierten Handle (Punkt,Frame) um 1 Pixel nach links schieben |
|
||||
| Right | | Selektierten Handle (Punkt,Frame) um 1 Pixel nach rechts schieben |
|
||||
| Up | | Selektierten Handle (Punkt,Frame) um 1 Pixel nach oben schieben |
|
||||
| Down | | Selektierten Handle (Punkt,Frame) um 1 Pixel nach unten schieben |
|
||||
| Left | Shift | Selektierten Handle (Punkt,Frame) um 10 Pixel nach links schieben |
|
||||
| Right | Shift | Selektierten Handle (Punkt,Frame) um 10 Pixel nach rechts schieben |
|
||||
| Up | Shift | Selektierten Handle (Punkt,Frame) um 10 Pixel nach oben schieben |
|
||||
| Down | Shift | Selektierten Handle (Punkt,Frame) um 10 Pixel nach unten schieben |
|
||||
|
||||
@see EventDispatcher
|
||||
@see Rubberband, RubberbandPointFeature, RubberbandPointCluster, RubberbandMultiPointFeature, RubberbandRectangle, RubberbandEllipse, RubberbandCorridor, RubberbandArrow
|
||||
Rubberband3D, RubberbandPointFeature3D, RubberbandMultiPointFeature3D
|
||||
|
||||
*/
|
||||
|
||||
class SITUATIONMAP_EXPORT RubberbandBase : public QObject, public EventDispatcher::EventActionInterface
|
||||
{
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Because class EventDispatcher::EventActionInterface is a pure virtual interface function the classic way of declaration would be
|
||||
*
|
||||
* SITUATIONMAP_EXPORT Rubberband : public QObject, public virtual EventDispatcher::EventActionInterface
|
||||
*
|
||||
* But with Visual Studio 2013 virtual inheritance combined with constructor delegation doesn't work and may crash the program. In
|
||||
* this case the virtual inheritance of EventActionInterface isn't need because in the derived classes multiple inheritance will
|
||||
* not be used.
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@name Construction & Destruction
|
||||
@{
|
||||
*/
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
Constructs a Rubberband for a situation map. Use \c RubberbandFactor to create a rubberband.
|
||||
In case of the user actions the autoDelete mechanism can be used to delete the rubberband. Sometimes
|
||||
the application wants to finish a running rubberband. This can be done by calling \c deleteMySelf. The
|
||||
rubberband will be destroyed also automatically if the parent QObject or the map (see
|
||||
SituationMap::Map::beginDestroy signal) will be destroyed.
|
||||
|
||||
@param map Pointer to SituationMap::Map
|
||||
@param parent Pointer to QObject to use as parent.
|
||||
@isActive If set to false the Rubberband is not active and have to be actived to start the input.
|
||||
@see RubberbandFactory
|
||||
*/
|
||||
RubberbandBase( SituationMap::Map * map, QObject * parent, bool isActive = true );
|
||||
|
||||
~RubberbandBase();
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
Activate rubberband if it has been created with \c isActive = false.
|
||||
*/
|
||||
void activate();
|
||||
|
||||
/**
|
||||
Provides a list of active rubberbands for a situation map.
|
||||
*/
|
||||
static QList<RubberbandBase*> activeRubberbands( SituationMap::Map * map );
|
||||
|
||||
/**
|
||||
Delete active rubberbands for a situation map.
|
||||
*/
|
||||
static void deleteAllActiveRubberbands( SituationMap::Map * map );
|
||||
|
||||
/**
|
||||
Use deleteMySelft instead of delete operator to avoid dangling this pointerin Qt signal processing. It calls delete this; later on.
|
||||
*/
|
||||
void deleteMySelf();
|
||||
|
||||
/**
|
||||
If setting auto delete flag to true the delete will be done automatically after sending signal abort or apply.
|
||||
The default value of auto delete flag is false.
|
||||
@{
|
||||
*/
|
||||
inline void setAutoDelete(bool on) { _autoDelete = on; }
|
||||
|
||||
|
||||
inline bool autoDelete() const { return _autoDelete; }
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
Returns true if the rubberband is already alive. Should be tested after creation of a rubberband because it is
|
||||
possibled to create not living rubberbands, e.g. a rubberband was create twice and the first one has not finished
|
||||
*/
|
||||
inline bool rubberbandIsAlive() const { return !_viewPortEventDispatcher.isNull(); }
|
||||
|
||||
/** A single user action step has finished. Interim results can be used to show a preview now.
|
||||
*/
|
||||
void userActionFinished() override { emit interimResultsChanged(this); }
|
||||
|
||||
/**
|
||||
@name ColorSettings Methodes to define visual behaviour of rubberband
|
||||
@{
|
||||
*/
|
||||
inline void setDrawColor (const QColor & col ) { _drawColor = col; update(); } ///< set color for general drawing
|
||||
inline void setFillColor (const QColor & col ) { _fillColor = col; update(); } ///< set color for general filling
|
||||
inline void setHandleDrawColor (const QColor & col ) { _handleDrawColor = col; update(); } ///< set color for drawing handles
|
||||
inline void setHandleFillColor (const QColor & col ) { _handleFillColor = col; update(); } ///< set color for filling handles
|
||||
inline void setHandleSelectionColor(const QColor & col ) { _handleSelectionColor = col; update(); } ///< set handle selection color
|
||||
inline void setFrameColor (const QColor & col ) { _frameColor = col; update(); } ///< set frame handle outline color
|
||||
inline void setFrameFillColor (const QColor & col ) { _frameFillColor = col; update(); } ///< set frame handle fill color
|
||||
inline void setFrameHandleMargin (int margin ) { _frameHandleMargin = margin; update(); } ///< set margin of frame in pixel
|
||||
|
||||
inline void setPickingRatio (unsigned int size ) { _pickingRatio = size; update(); } ///< set size of point handles
|
||||
inline void setLineHandleWidth (unsigned int width ) { _lineHandleWidth = width; update(); } ///< set width of line handles
|
||||
|
||||
inline const QColor getDrawColor () const { return _drawColor; } ///< get color for general drawing
|
||||
inline const QColor getFillColor () const { return _fillColor; } ///< get color for general filling
|
||||
inline const QColor getHandleDrawColor() const { return _handleDrawColor; } ///< get color for drawing handles
|
||||
inline const QColor getHandleFillColor() const { return _handleFillColor; } ///< get color for filling handles
|
||||
inline const QColor getHandleSelectionColor() const { return _handleSelectionColor; } ///< get handle selection color
|
||||
inline const QColor getFrameColor() const { return _frameColor; } ///< get frame handle outline color
|
||||
inline const QColor getFrameFillColor() const { return _frameFillColor; } ///< get frame handle fill color
|
||||
inline int getFrameHandleMargin() const { return _frameHandleMargin; } ///< get margin of frame in pixel
|
||||
|
||||
inline unsigned int getPickingRatio() const { return _pickingRatio; } ///< get size of point handles
|
||||
/** @} */
|
||||
|
||||
bool applyAndEndAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
||||
bool abortAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
||||
|
||||
/**
|
||||
@name Set icons for rubberband buttons
|
||||
|
||||
In case of the application doesn't use the default rubberband icons other icons can be set with the setIcon functions. This redefine
|
||||
of the button icons have to be done before creating a rubberband.
|
||||
@{
|
||||
*/
|
||||
static void setIconApply( const QPixmap & );
|
||||
static void setIconAbort( const QPixmap & );
|
||||
static void setIconUndo ( const QPixmap & );
|
||||
|
||||
static void resetIconsToDefault();
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
Start Rubberband mouse input automatically by program
|
||||
*/
|
||||
bool autoSelectAction( int x, int y );
|
||||
|
||||
/**
|
||||
If set to true the rubberband will send apply signal after leaving construction state and ends
|
||||
otherwise it continues in modification state. Default value is true.
|
||||
*/
|
||||
inline void enableFinishAfterConstruction(bool flag) { _finishAfterConstruction = flag; }
|
||||
|
||||
|
||||
/**
|
||||
Defines fixed widget position of rubberband button box
|
||||
*/
|
||||
void setFixedButtonBoxPosition( QPoint widgetPos );
|
||||
|
||||
|
||||
/**
|
||||
Undefines fixed widget position. The rubberband button box will be placed at the bottom right coner of
|
||||
the rubberbands bounding box.
|
||||
*/
|
||||
void unsetFixedButtonBoxPosition();
|
||||
|
||||
/**
|
||||
Returns true if a fixed widget position of rubberband button box is used.
|
||||
*/
|
||||
bool isButtonBoxPositionFixed();
|
||||
|
||||
/**
|
||||
@name EventHandlerInterface Methodes of AbstractEventDispatcher::EventActionInterface
|
||||
The interface between EventDispatcher and Rubberband are defined in class AbstractEventDispatcher.
|
||||
To Implement the interface these methodes have to be override again in the derived classes of the Rubberband class. */
|
||||
/**
|
||||
@{
|
||||
*/
|
||||
|
||||
bool buttonPositionAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
||||
|
||||
void unlinkEventDispatcher ( AbstractEventDispatcher * causer ) override;
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
Returns true if the coordinates are valid elsewise false
|
||||
*/
|
||||
virtual bool coordinatesAreValid() const { return true; }
|
||||
|
||||
|
||||
/**
|
||||
Returns count of coordinates
|
||||
*/
|
||||
virtual unsigned int coordinateCount() const = 0;
|
||||
|
||||
/**
|
||||
Returns constructed or modified coordinates
|
||||
@param cs Defines the coordinate system of returned coordinates.
|
||||
*/
|
||||
virtual QVector<QPointF> coordinateVector( CoordinateSystem cs = CoordinateSystem::Geo ) const = 0;
|
||||
|
||||
/**
|
||||
Returns a single coordinate from rubberbands coordinate list
|
||||
@param idx index of coordinate
|
||||
@param cs Defines the coordinate system of returned coordinate.
|
||||
*/
|
||||
virtual QPointF singleCoordinate( unsigned int idx = 0, CoordinateSystem cs = CoordinateSystem::Geo ) const = 0;
|
||||
|
||||
/**
|
||||
Sets coordinates to modify to internal coordinate list
|
||||
|
||||
@param pntList List of coordinates to modify
|
||||
@param cs Defines the coordinate system of input coordinates.
|
||||
*/
|
||||
virtual void setCoordinateVector( const QVector<QPointF> & pntList, CoordinateSystem cs = CoordinateSystem::Geo ) = 0;
|
||||
|
||||
/**
|
||||
Set user defined informations to this rubberband
|
||||
*/
|
||||
inline void setUserData(void * p)
|
||||
{
|
||||
_userData = p;
|
||||
}
|
||||
|
||||
/**
|
||||
returns the user defined informations, which are set with methode userData(void*)
|
||||
*/
|
||||
inline void * userData() { return _userData; }
|
||||
|
||||
|
||||
/**
|
||||
Draw rubberband manually by calling the update function. In general it is not neccessary to call draw function.
|
||||
But in some cases, for example the color setting functions, the graphic view update will not be done automatically.
|
||||
Here calling draw forces an update of graphic view.
|
||||
*/
|
||||
inline void draw() { update(); }
|
||||
|
||||
|
||||
/**
|
||||
Sets call back function to realize an external update. The updateFunctor should return false to abort update process. In other case it have to return true.
|
||||
*/
|
||||
void installExternalUpdate(const std::function<bool(RubberbandBase*)> & updateFunctor);
|
||||
|
||||
|
||||
/**
|
||||
Returns true if there is a active rubberband on map.
|
||||
@param map Pointer to map
|
||||
*/
|
||||
static bool isRubberbandActive( SituationMap::Map * map );
|
||||
|
||||
/**
|
||||
Abort all active rubberbands on map.
|
||||
@param map Pointer to map
|
||||
*/
|
||||
static void abortActiveRubberbands( SituationMap::Map * map );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
Q_REQUIRED_RESULT QPointF projectCoordinateToMap( CoordinateSystem cs, const QPointF &loc ) const;
|
||||
Q_REQUIRED_RESULT QPointF projectCoordinateFromMap( CoordinateSystem cs, const QPointF & loc ) const;
|
||||
Q_REQUIRED_RESULT QPointF projectCoordinateFromMap( CoordinateSystem cs, const Esri::ArcGISRuntime::Point & loc ) const;
|
||||
|
||||
inline void doAutoDelete() { if (_autoDelete) deleteMySelf(); }
|
||||
|
||||
void updateButtonPosition();
|
||||
|
||||
QPointF pixel2ScenePosition( int x, int y ) const;
|
||||
|
||||
virtual void update() = 0;
|
||||
|
||||
void externalUpdate();
|
||||
|
||||
/*
|
||||
Forward declaration of internal container class for member variables. The derived classes of Rubberband
|
||||
often have also a declaration of InternalData for there own internal members.
|
||||
*/
|
||||
class BaseInternalData;
|
||||
|
||||
BaseInternalData *_baseInternal;
|
||||
|
||||
QColor _drawColor;
|
||||
QColor _fillColor;
|
||||
QColor _handleDrawColor;
|
||||
QColor _handleFillColor;
|
||||
QColor _handleSelectionColor;
|
||||
QColor _frameColor;
|
||||
QColor _frameFillColor;
|
||||
QColor _frameSelectionColor;
|
||||
int _frameHandleMargin;
|
||||
|
||||
unsigned int _lineHandleWidth;
|
||||
|
||||
unsigned int _pickingRatio;
|
||||
|
||||
bool _finishAfterConstruction;
|
||||
bool _autoDelete;
|
||||
|
||||
QPointer<EventDispatcher> _viewPortEventDispatcher;
|
||||
QPointer<EventDelegater> _windowEventDispatcher;
|
||||
|
||||
virtual QRectF sceneBbox() const = 0;
|
||||
|
||||
virtual void activateButtons();
|
||||
virtual void deactivateButtons();
|
||||
virtual void adjustButtons();
|
||||
virtual void applyButtonClicked();
|
||||
virtual void cancelButtonClicked();
|
||||
virtual void undoButtonClicked();
|
||||
|
||||
protected slots:
|
||||
|
||||
void onDo_applyButtonClicked() { applyButtonClicked(); }
|
||||
void onDo_cancelButtonClicked() { cancelButtonClicked(); }
|
||||
void onDo_undoButtonClicked() { undoButtonClicked(); }
|
||||
|
||||
void onDo_updateButtonFixCoordinates();
|
||||
|
||||
private:
|
||||
|
||||
void * _userData;
|
||||
|
||||
friend class RubberbandFactory;
|
||||
|
||||
static void * operator new(size_t);
|
||||
|
||||
/**
|
||||
The function \c allowMultipleRubberbands set a flag to allow new to create more than one rubberband
|
||||
per situation map for the next new operator call. The function is used in class RubberbandFactory. The
|
||||
value will be resetted to \c false at end of new operator.
|
||||
*/
|
||||
static void allowMultipleRubberbands( bool ok );
|
||||
|
||||
/**
|
||||
The function \c currentFactoryMap defines the calling situation map for the next new operator call. The
|
||||
function is used in class RubberbandFactory.The value will be resetted to \c nullptr at end of new operator.
|
||||
*/
|
||||
static void currentFactoryMap( SituationMap::Map * map );
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
The abort signal will be emitted, when the abortAction has been called by one of the attached event handlers.
|
||||
Before emtting the signal the event handler are closed and deleted. To avoid memory leaks the application has to
|
||||
ensure that the delete function is called for this rubberband. See also example code at beginning.
|
||||
|
||||
@param rbnd pointer to this Rubberband
|
||||
*/
|
||||
void abort( RubberbandBase * rbnd );
|
||||
|
||||
/**
|
||||
The apply signal will be emitted, when the applyAndEndAction has been called by one of the attached event handler. The connected slot can now
|
||||
read the geometry information. Before emtting the signal the event handler are closed and deleted.To avoid memory leaks the application has to
|
||||
ensure that the delete function is called for this rubberband. See also example code at beginning.
|
||||
|
||||
@param rbnd pointer to this Rubberband.
|
||||
*/
|
||||
void apply( RubberbandBase * rbnd );
|
||||
|
||||
/**
|
||||
The finished signal will be emitted, when the rubberband is going to terminate and all user actions are done.
|
||||
|
||||
@param rbnd pointer to this Rubberband.
|
||||
*/
|
||||
void finished( RubberbandBase * rbnd );
|
||||
|
||||
/**
|
||||
The coordinatesChanged signal will be emitted , when the user has changed, removed or added coordinates. Can be used to implement
|
||||
a preview of interim results.
|
||||
*/
|
||||
void interimResultsChanged( RubberbandBase * rbnd );
|
||||
|
||||
}; /* Rubberband */
|
||||
|
||||
} } /* namespace SituationMap::RB */
|
||||
Reference in new issue
Block a user