310 lines
10 KiB
C++
Executable File
310 lines
10 KiB
C++
Executable File
|
|
/**
|
|
**
|
|
** @RDE_HEADER@
|
|
** Implementation 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
|
|
**
|
|
** -----------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "rubberband.h"
|
|
#include "rubberband_drawable.h"
|
|
#include "rubberband_handle.h"
|
|
#include "rubberband_handle_proxy.h"
|
|
#include "rubberband_point_handle.h"
|
|
#include "rubberband_internal.h"
|
|
#include "rubberband_base_internal.h"
|
|
|
|
#include "rubberband_factory.h"
|
|
|
|
#include <arcgis/MapGraphicsView.h>
|
|
|
|
// Qt
|
|
#include <QtCore/QMetaMethod>
|
|
#include <QtWidgets/QGraphicsPixmapItem>
|
|
|
|
|
|
namespace SituationMap { namespace RB
|
|
{
|
|
|
|
|
|
Rubberband::Rubberband( SituationMap::Map * map, QObject * parent, bool isActive )
|
|
: RubberbandBase(map,parent,isActive)
|
|
, _internal( new Rubberband::InternalData(map) )
|
|
, _state( RubberbandState::ConstructionState )
|
|
, _previewSidc()
|
|
, _previewCursorOffset(32,32)
|
|
, _previewSize(32)
|
|
{
|
|
_fillColor.setAlpha(100);
|
|
|
|
connect( &_previewSymbolResultWatcher
|
|
, &AdvancedSymbology::SymbolResultWatcher::resultReady
|
|
, this
|
|
, &Rubberband::onPreviewSymbolResultReady );
|
|
|
|
} /* Rubberband::Rubberband */
|
|
|
|
|
|
Rubberband::~Rubberband()
|
|
{
|
|
delete _internal;
|
|
_internal = nullptr;
|
|
} /* Rubberband::~Rubberband */
|
|
|
|
|
|
void Rubberband::connectPreviewPixmap( const QPixmap & symbolPixmap )
|
|
{
|
|
if (nullptr == _internal->_connectedPreviewPixmap)
|
|
{
|
|
_internal->_connectedPreviewPixmap = new QGraphicsPixmapItem( symbolPixmap );
|
|
_internal->_connectedPreviewPixmap -> setOffset(-qreal(symbolPixmap.width())/2,-qreal(symbolPixmap.height())/2);
|
|
|
|
_internal->_mapScene -> addItem( _internal->_connectedPreviewPixmap );
|
|
}
|
|
} /* RubberbandPointFeature::connectPreviewPixmap */
|
|
|
|
unsigned int Rubberband::coordinateCount() const { return static_cast<unsigned int>(_internal->_handleList.size()); }
|
|
|
|
|
|
void Rubberband::resetAction(AbstractEventDispatcher*, int, int)
|
|
{
|
|
disenableSelectedState();
|
|
disenableMultiSelectedState();
|
|
update();
|
|
} /* Rubberband::resetAction */
|
|
|
|
|
|
|
|
bool Rubberband::selectAction( AbstractEventDispatcher*, int x, int y )
|
|
{
|
|
if (rubberbandIsAlive())
|
|
{
|
|
QPointF scenePos = pixel2ScenePosition(x,y);
|
|
|
|
if (_baseInternal->buttonProxyActive(scenePos)) return false;
|
|
_baseInternal->_lastClickPosition = scenePos;
|
|
return true;
|
|
}
|
|
return false;
|
|
} /* Rubberband::selectAction */
|
|
|
|
|
|
bool Rubberband::multiSelectActionPress( AbstractEventDispatcher * causer, int x, int y )
|
|
{
|
|
if (rubberbandIsAlive())
|
|
{
|
|
if (isEnabledModificationState())
|
|
{
|
|
_baseInternal->_lastClickPosition = pixel2ScenePosition(x,y);
|
|
enableMultiSelectedState();
|
|
}
|
|
return selectAction( causer, x, y);
|
|
}
|
|
return false;
|
|
} /* RubberbandPointFeature::multiSelectActionPress */
|
|
|
|
|
|
bool Rubberband::multiSelectActionRelease( AbstractEventDispatcher * causer, int x, int y )
|
|
{
|
|
if (rubberbandIsAlive())
|
|
{
|
|
if (isEnabledModificationState())
|
|
{
|
|
updateButtonPosition();
|
|
activateButtons();
|
|
}
|
|
else return setCoordinateAction(causer,x,y);
|
|
}
|
|
return false;
|
|
} /* RubberbandPointFeature::multiSelectActionRelease */
|
|
|
|
|
|
void Rubberband::adjustConnectedPreviewPixmap( int x, int y )
|
|
{
|
|
if (_internal->_connectedPreviewPixmap)
|
|
{
|
|
_internal->_connectedPreviewPixmap -> setPos(pixel2ScenePosition( x+_previewCursorOffset.x(), y+_previewCursorOffset.y() ));
|
|
}
|
|
} /* Rubberband::adjustConnectedPreviewPixmap */
|
|
|
|
|
|
bool Rubberband::moveAction( AbstractEventDispatcher*, int x, int y )
|
|
{
|
|
adjustConnectedPreviewPixmap(x,y);
|
|
return rubberbandIsAlive();
|
|
|
|
} /* moveAction */
|
|
|
|
|
|
bool Rubberband::setCoordinateAction( AbstractEventDispatcher*, int x, int y )
|
|
{
|
|
if (rubberbandIsAlive())
|
|
{
|
|
QPointF scenePos = pixel2ScenePosition(x,y);
|
|
if (_baseInternal->buttonProxyActive(scenePos)) return false;
|
|
_internal->_lastClickPosition = scenePos;
|
|
return true;
|
|
}
|
|
return false;
|
|
} /* Rubberband::setCoordinateAction */
|
|
|
|
|
|
bool Rubberband::movePickedAction ( AbstractEventDispatcher*, int x, int y ) { adjustConnectedPreviewPixmap(x,y); return false; }
|
|
bool Rubberband::contextMenuAction ( AbstractEventDispatcher*, int x, int y ) { Q_UNUSED(x); Q_UNUSED(y); return rubberbandIsAlive(); }
|
|
bool Rubberband::completeStateAction ( AbstractEventDispatcher*, int x, int y ) { Q_UNUSED(x); Q_UNUSED(y); return rubberbandIsAlive(); }
|
|
bool Rubberband::deleteAction ( AbstractEventDispatcher*, int x, int y ) { Q_UNUSED(x); Q_UNUSED(y); return rubberbandIsAlive(); }
|
|
bool Rubberband::undoAction ( AbstractEventDispatcher*, int x, int y ) { Q_UNUSED(x); Q_UNUSED(y); return rubberbandIsAlive(); }
|
|
|
|
|
|
RubberbandHandle * Rubberband::pickHandle( int x, int y ) const
|
|
{
|
|
if (_internal->_mapView != nullptr)
|
|
{
|
|
QPointF scenePosition = pixel2ScenePosition(x,y);
|
|
for (auto handle : qAsConst(_internal->_handleList))
|
|
{
|
|
if (handle->isPositionInside(scenePosition))
|
|
return handle.get();
|
|
}
|
|
}
|
|
return nullptr;
|
|
} /* Rubberband::pickHandle */
|
|
|
|
|
|
void Rubberband::deSelectHandles()
|
|
{
|
|
for (auto handle : qAsConst(_internal->_handleList))
|
|
{
|
|
RubberbandHandle * handlePtr = handle.get();
|
|
if (handlePtr)
|
|
{
|
|
handlePtr->setSelection(false);
|
|
}
|
|
}
|
|
} /* Rubberband::deSelectHandles */
|
|
|
|
|
|
QRectF Rubberband::sceneBbox() const
|
|
{
|
|
DEBUG_LOG(_internal->_logger) << LOGFUNCTION;
|
|
|
|
QPointF topLeft( std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
|
|
QPointF bottomRight( std::numeric_limits<double>::min(), std::numeric_limits<double>::min() );
|
|
|
|
for (auto handle : qAsConst(_internal->_handleList))
|
|
{
|
|
RubberbandPointHandle * pointHandlePtr = dynamic_cast<RubberbandPointHandle*>(handle.get());
|
|
|
|
if (pointHandlePtr)
|
|
{
|
|
const QPointF & p = pointHandlePtr->getCoordinate()._sceneCoordinate;
|
|
if (topLeft.x() > p.x()) topLeft.setX(p.x());
|
|
if (topLeft.y() > p.y()) topLeft.setY(p.y());
|
|
if (bottomRight.x() < p.x()) bottomRight.setX(p.x());
|
|
if (bottomRight.y() < p.y()) bottomRight.setY(p.y());
|
|
}
|
|
}
|
|
|
|
return QRectF( topLeft, bottomRight );
|
|
|
|
} /* Rubberband::sceneBbox */
|
|
|
|
|
|
void Rubberband::update()
|
|
{
|
|
// Check Quartz
|
|
// if (isSignalConnected(QMetaMethod::fromSignal(&Rubberband::updatePreview)))
|
|
// {
|
|
// emit updatePreview( this );
|
|
// }
|
|
// if (_internal->_map->symbolDictionary().contains(_previewSidc))
|
|
// {
|
|
// const QImage& symbolImage = _internal->_map->symbolDictionary().symbolImageBySidc( _previewSidc, _previewSize );
|
|
// connectPreviewPixmap( QPixmap::fromImage(symbolImage) );
|
|
// }
|
|
|
|
if ((!_previewSidc.isEmpty()) && (nullptr == _internal->_connectedPreviewPixmap) && (!_previewSymbolResultWatcher.resultIsValid()))
|
|
{
|
|
_previewSymbolResultWatcher.setSymbolResult(_baseInternal->_map->symbolDictionary().findBaseSymbol(_previewSidc));
|
|
}
|
|
|
|
for (auto handle : qAsConst(_internal->_handleList))
|
|
{
|
|
handle -> setDrawColor(_handleDrawColor);
|
|
handle -> setFillColor(_handleFillColor);
|
|
handle -> setSelectionColor(_handleSelectionColor);
|
|
handle -> setPickingRatio( _pickingRatio );
|
|
}
|
|
|
|
updateButtonPosition();
|
|
|
|
if (_internal->_constructionObjectDraw != nullptr)
|
|
{
|
|
// _constructionObjectDraw -> setColors
|
|
}
|
|
|
|
externalUpdate();
|
|
|
|
} /* Rubberband::update */
|
|
|
|
|
|
void Rubberband::onPreviewSymbolResultReady()
|
|
{
|
|
QSharedPointer<AdvancedSymbology::SymbolResult> symResult = _previewSymbolResultWatcher.symbolResult();
|
|
|
|
if (!symResult) return; // should NEVER happen! (Which object should have triggered the signal???)
|
|
|
|
const QPixmap & symbolPixmap = QPixmap::fromImage(symResult->symbolImage().image()).scaled(_previewSize,_previewSize,Qt::KeepAspectRatio);
|
|
|
|
if (symbolPixmap.isNull())
|
|
{
|
|
DEBUG_LOG(_internal->_logger) << LOGFUNCTION << "Preview symbol image is empty.";
|
|
}
|
|
connectPreviewPixmap( symbolPixmap );
|
|
} /* Rubberband::onPreviewSymbolResultReady */
|
|
|
|
|
|
#include "./constrainsMarker.xpm"
|
|
|
|
void Rubberband::markFailedConstrains( const QPointF & scenePos, bool on )
|
|
{
|
|
if (on)
|
|
{
|
|
QPixmap markerPixmap(constrainsMarker_xpm);
|
|
|
|
if (nullptr == _internal->_constrainFailedMarker)
|
|
{
|
|
_internal->_constrainFailedMarker = new QGraphicsPixmapItem( markerPixmap );
|
|
_internal->_mapScene -> addItem( _internal->_constrainFailedMarker );
|
|
}
|
|
_internal->_constrainFailedMarker -> setOffset(-qreal(markerPixmap.width())/2,-qreal(markerPixmap.height())/2);
|
|
_internal->_constrainFailedMarker -> setPos(scenePos-QPointF(_previewCursorOffset));
|
|
_internal->_constrainFailedMarker->setVisible(true);
|
|
}
|
|
else if (_internal->_constrainFailedMarker) _internal->_constrainFailedMarker->setVisible(false);
|
|
} /* Rubberband::markFailedConstrains */
|
|
|
|
|
|
} } /* namespace SituationMap::RB */
|