320 lines
14 KiB
Objective-C
Executable File
320 lines
14 KiB
Objective-C
Executable File
/**
|
|
**
|
|
** @RDE_HEADER@
|
|
** Definition of base class for 2D 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 "rubberband_base.h"
|
|
|
|
#include <Map/map.h>
|
|
#include <Common/ref_pointer.h>
|
|
|
|
#include <QtCore/QFlags>
|
|
#include <QtCore/QPointer>
|
|
|
|
#include <memory>
|
|
|
|
|
|
namespace Esri {
|
|
namespace ArcGISRuntime {
|
|
class MapGraphicsView;
|
|
class Point;
|
|
} }
|
|
|
|
|
|
|
|
namespace SituationMap
|
|
{
|
|
|
|
/**
|
|
Namespace for all rubberband stuff (is part of namespace SituationMap)
|
|
*/
|
|
namespace RB
|
|
{
|
|
class RubberbandDrawable;
|
|
class RubberbandHandle;
|
|
|
|
/**
|
|
@class Rubberband rubberband.h
|
|
@brief Base class of all 2D rubberbands
|
|
|
|
Rubberbands are used to create or modifiy 2D 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 RubberbandBase, Rubberband, RubberbandPointFeature, RubberbandPointCluster, RubberbandMultiPointFeature, RubberbandRectangle, RubberbandEllipse, RubberbandCorridor, RubberbandArrow
|
|
*/
|
|
|
|
class SITUATIONMAP_EXPORT Rubberband : public RubberbandBase
|
|
{
|
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
* 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:
|
|
|
|
/**
|
|
@defgroup States Internal state of the rubberband
|
|
@{
|
|
*/
|
|
|
|
enum RubberbandState : unsigned int
|
|
{
|
|
ConstructionState = 1 << 0, ///< Construction state is active when a geomtrie is been build new
|
|
ModificationState = 1 << 1, ///< Modification state is active when a existing geometrie is been modified
|
|
SelectedState = 1 << 2, ///< Selection state is active, one ore more handles are selected
|
|
MultiSelectedState = 1 << 3, ///< multiple handles can be selected
|
|
ConstructionWidthState = 1 << 4 ///< Initial define of a width e.b. for corridors
|
|
}; /* RubberbandSate */
|
|
|
|
Q_DECLARE_FLAGS(RubberbandStates,RubberbandState)
|
|
|
|
/** @} */
|
|
|
|
/**
|
|
@name Construction & Destruction
|
|
@{
|
|
*/
|
|
|
|
private:
|
|
|
|
friend class RubberbandFreeHand;
|
|
friend class RubberbandPointFeature;
|
|
friend class RubberbandMultiPointFeature;
|
|
friend class RubberbandMultiEllipseFeature;
|
|
friend class RubberbandRectangle;
|
|
friend class RubberbandStateSelect;
|
|
friend class RubberbandTransformMove;
|
|
friend class RubberbandTransformRotate;
|
|
friend class RubberbandTransformScale;
|
|
|
|
/**
|
|
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
|
|
*/
|
|
explicit Rubberband( SituationMap::Map * map, QObject * parent, bool isActive = true );
|
|
|
|
public:
|
|
Q_DISABLE_COPY(Rubberband)
|
|
|
|
virtual ~Rubberband();
|
|
|
|
/** @} */
|
|
|
|
/**
|
|
@addtogroup States Methodes to query and modify rubberband states
|
|
@{
|
|
*/
|
|
inline bool isEnabledConstructionState() const { return _state.testFlag(RubberbandState::ConstructionState); }
|
|
inline bool isEnabledModificationState() const { return _state.testFlag(RubberbandState::ModificationState); }
|
|
inline bool isEnabledSelectedState() const { return _state.testFlag(RubberbandState::SelectedState); }
|
|
inline bool isEnabledMultiSelectedState() const { return _state.testFlag(RubberbandState::MultiSelectedState); }
|
|
|
|
inline void enableConstructionState() { disenableModificationState(); }
|
|
inline void enableModificationState() { disenableConstructionState(); }
|
|
inline void enableSelectedState() { _state |= RubberbandState::SelectedState; }
|
|
inline void enableMultiSelectedState() { _state |= RubberbandState::MultiSelectedState; }
|
|
|
|
inline void disenableConstructionState() { _state &= ~QFlags<RubberbandState>(RubberbandState::ConstructionState); _state |= RubberbandState::ModificationState; }
|
|
inline void disenableModificationState() { _state &= ~QFlags<RubberbandState>(RubberbandState::ModificationState); _state |= RubberbandState::ConstructionState; }
|
|
inline void disenableSelectedState() { _state &= ~QFlags<RubberbandState>(RubberbandState::SelectedState); }
|
|
inline void disenableMultiSelectedState() { _state &= ~QFlags<RubberbandState>(RubberbandState::MultiSelectedState); }
|
|
//@}
|
|
|
|
/**
|
|
@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 selectAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool multiSelectActionPress ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool multiSelectActionRelease( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool setCoordinateAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool moveAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool movePickedAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
void resetAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool contextMenuAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool completeStateAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool deleteAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
bool undoAction ( AbstractEventDispatcher * causer, int x, int y ) override;
|
|
|
|
|
|
/** @} */
|
|
|
|
/**
|
|
@name Preview Setting Methodes to define visual behaviour of rubberband preview
|
|
@{
|
|
*/
|
|
inline void setPreviewSidc (const QString & sidc ) { _previewSidc = sidc; update(); } ///< Defines tactical symbol for preview
|
|
inline void setPreviewOffset (const QPoint & off ) { _previewCursorOffset = off; update(); } ///< set offset to cursor position for preview pixmap
|
|
inline void setPreviewSize (unsigned int size ) { _previewSize = size; update(); } ///< set size of preview pixmap
|
|
|
|
inline QString getPreviewSidc() const { return _previewSidc; } ///< get code of tactical preview symbol
|
|
inline const QPoint getPreviewOffset() const { return _previewCursorOffset; } ///< get offset to cursor position for preview pixmap
|
|
inline unsigned int getPreviewSize() const { return _previewSize; } ///< get size of preview pixmap
|
|
/** @} */
|
|
|
|
|
|
/**
|
|
Returns Sidc code of preview symbol (if defined)
|
|
*/
|
|
inline QString previewSidc() const { return _previewSidc; }
|
|
|
|
/**
|
|
Sets a QPixmap to use for drawing symbol preview image
|
|
@param symbolImage a nice QPixmap
|
|
*/
|
|
void connectPreviewPixmap( const QPixmap & symbolPixmap );
|
|
|
|
/**
|
|
Returns count of coordinates
|
|
*/
|
|
virtual unsigned int coordinateCount() const override;
|
|
|
|
protected:
|
|
|
|
void deSelectHandles();
|
|
|
|
|
|
void update() override;
|
|
|
|
/**
|
|
Returns the rubberband handle at screen position (x,y) or nullptr if there isn't any handle at this
|
|
position.
|
|
*/
|
|
RubberbandHandle * pickHandle( int x, int y ) const;
|
|
|
|
/**
|
|
Moves preview image to QGraphicView position (x,y) in window coordinates.
|
|
*/
|
|
void adjustConnectedPreviewPixmap( int x, int y );
|
|
|
|
|
|
/**
|
|
Shows a icon near the cursor to mark failing constrains.
|
|
*/
|
|
void markFailedConstrains( const QPointF & scenePos, bool on );
|
|
|
|
/*
|
|
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.
|
|
*/
|
|
struct InternalData;
|
|
|
|
InternalData * _internal;
|
|
|
|
RubberbandStates _state;
|
|
|
|
QString _previewSidc;
|
|
QPoint _previewCursorOffset;
|
|
unsigned int _previewSize;
|
|
|
|
AdvancedSymbology::SymbolResultWatcher _previewSymbolResultWatcher;
|
|
|
|
QRectF sceneBbox() const override;
|
|
|
|
protected slots:
|
|
|
|
void onPreviewSymbolResultReady();
|
|
|
|
}; /* Rubberband */
|
|
|
|
} } /* namespace SituationMap::RB */
|