Add files from zip
This commit is contained in:
377
examples/itemeditor/Editor.cpp
Normal file
377
examples/itemeditor/Editor.cpp
Normal file
@@ -0,0 +1,377 @@
|
||||
/*****************************************************************************
|
||||
* Qwt Examples - Copyright (C) 2002 Uwe Rathmann
|
||||
* This file may be used under the terms of the 3-clause BSD License
|
||||
*****************************************************************************/
|
||||
|
||||
#include "Editor.h"
|
||||
|
||||
#include <QwtPlot>
|
||||
#include <QwtPlotCanvas>
|
||||
#include <QwtScaleMap>
|
||||
#include <QwtPlotShapeItem>
|
||||
#include <QwtWidgetOverlay>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
namespace
|
||||
{
|
||||
class Overlay : public QwtWidgetOverlay
|
||||
{
|
||||
public:
|
||||
Overlay( QWidget* parent, Editor* editor )
|
||||
: QwtWidgetOverlay( parent )
|
||||
, m_editor( editor )
|
||||
{
|
||||
switch( editor->mode() )
|
||||
{
|
||||
case Editor::NoMask:
|
||||
{
|
||||
setMaskMode( QwtWidgetOverlay::NoMask );
|
||||
setRenderMode( QwtWidgetOverlay::AutoRenderMode );
|
||||
break;
|
||||
}
|
||||
case Editor::Mask:
|
||||
{
|
||||
setMaskMode( QwtWidgetOverlay::MaskHint );
|
||||
setRenderMode( QwtWidgetOverlay::AutoRenderMode );
|
||||
break;
|
||||
}
|
||||
case Editor::AlphaMask:
|
||||
{
|
||||
setMaskMode( QwtWidgetOverlay::AlphaMask );
|
||||
setRenderMode( QwtWidgetOverlay::AutoRenderMode );
|
||||
break;
|
||||
}
|
||||
case Editor::AlphaMaskRedraw:
|
||||
{
|
||||
setMaskMode( QwtWidgetOverlay::AlphaMask );
|
||||
setRenderMode( QwtWidgetOverlay::DrawOverlay );
|
||||
break;
|
||||
}
|
||||
case Editor::AlphaMaskCopyMask:
|
||||
{
|
||||
setMaskMode( QwtWidgetOverlay::AlphaMask );
|
||||
setRenderMode( QwtWidgetOverlay::CopyAlphaMask );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void drawOverlay( QPainter* painter ) const QWT_OVERRIDE
|
||||
{
|
||||
m_editor->drawOverlay( painter );
|
||||
}
|
||||
|
||||
virtual QRegion maskHint() const QWT_OVERRIDE
|
||||
{
|
||||
return m_editor->maskHint();
|
||||
}
|
||||
|
||||
private:
|
||||
Editor* m_editor;
|
||||
};
|
||||
}
|
||||
|
||||
Editor::Editor( QwtPlot* plot ):
|
||||
QObject( plot ),
|
||||
m_isEnabled( false ),
|
||||
m_overlay( NULL ),
|
||||
m_mode( Mask )
|
||||
{
|
||||
setEnabled( true );
|
||||
}
|
||||
|
||||
|
||||
Editor::~Editor()
|
||||
{
|
||||
delete m_overlay;
|
||||
}
|
||||
|
||||
QwtPlot* Editor::plot()
|
||||
{
|
||||
return qobject_cast< QwtPlot* >( parent() );
|
||||
}
|
||||
|
||||
const QwtPlot* Editor::plot() const
|
||||
{
|
||||
return qobject_cast< const QwtPlot* >( parent() );
|
||||
}
|
||||
|
||||
void Editor::setMode( Mode mode )
|
||||
{
|
||||
m_mode = mode;
|
||||
}
|
||||
|
||||
Editor::Mode Editor::mode() const
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
void Editor::setEnabled( bool on )
|
||||
{
|
||||
if ( on == m_isEnabled )
|
||||
return;
|
||||
|
||||
QwtPlot* plot = qobject_cast< QwtPlot* >( parent() );
|
||||
if ( plot )
|
||||
{
|
||||
m_isEnabled = on;
|
||||
|
||||
if ( on )
|
||||
{
|
||||
plot->canvas()->installEventFilter( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
plot->canvas()->removeEventFilter( this );
|
||||
|
||||
delete m_overlay;
|
||||
m_overlay = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Editor::isEnabled() const
|
||||
{
|
||||
return m_isEnabled;
|
||||
}
|
||||
|
||||
bool Editor::eventFilter( QObject* object, QEvent* event )
|
||||
{
|
||||
QwtPlot* plot = qobject_cast< QwtPlot* >( parent() );
|
||||
if ( plot && object == plot->canvas() )
|
||||
{
|
||||
switch( event->type() )
|
||||
{
|
||||
case QEvent::MouseButtonPress:
|
||||
{
|
||||
const QMouseEvent* mouseEvent =
|
||||
dynamic_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( m_overlay == NULL &&
|
||||
mouseEvent->button() == Qt::LeftButton )
|
||||
{
|
||||
const bool accepted = pressed( mouseEvent->pos() );
|
||||
if ( accepted )
|
||||
{
|
||||
m_overlay = new Overlay( plot->canvas(), this );
|
||||
|
||||
m_overlay->updateOverlay();
|
||||
m_overlay->show();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
if ( m_overlay )
|
||||
{
|
||||
const QMouseEvent* mouseEvent =
|
||||
dynamic_cast< QMouseEvent* >( event );
|
||||
|
||||
const bool accepted = moved( mouseEvent->pos() );
|
||||
if ( accepted )
|
||||
m_overlay->updateOverlay();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
const QMouseEvent* mouseEvent =
|
||||
static_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( m_overlay && mouseEvent->button() == Qt::LeftButton )
|
||||
{
|
||||
released( mouseEvent->pos() );
|
||||
|
||||
delete m_overlay;
|
||||
m_overlay = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return QObject::eventFilter( object, event );
|
||||
}
|
||||
|
||||
bool Editor::pressed( const QPoint& pos )
|
||||
{
|
||||
m_editedItem = itemAt( pos );
|
||||
if ( m_editedItem )
|
||||
{
|
||||
m_currentPos = pos;
|
||||
setItemVisible( m_editedItem, false );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // don't accept the position
|
||||
}
|
||||
|
||||
bool Editor::moved( const QPoint& pos )
|
||||
{
|
||||
if ( plot() == NULL )
|
||||
return false;
|
||||
|
||||
const QwtScaleMap xMap = plot()->canvasMap( m_editedItem->xAxis() );
|
||||
const QwtScaleMap yMap = plot()->canvasMap( m_editedItem->yAxis() );
|
||||
|
||||
const QPointF p1 = QwtScaleMap::invTransform( xMap, yMap, m_currentPos );
|
||||
const QPointF p2 = QwtScaleMap::invTransform( xMap, yMap, pos );
|
||||
|
||||
const QPainterPath shape = m_editedItem->shape().translated( p2 - p1 );
|
||||
|
||||
m_editedItem->setShape( shape );
|
||||
m_currentPos = pos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Editor::released( const QPoint& pos )
|
||||
{
|
||||
Q_UNUSED( pos );
|
||||
|
||||
if ( m_editedItem )
|
||||
{
|
||||
raiseItem( m_editedItem );
|
||||
setItemVisible( m_editedItem, true );
|
||||
}
|
||||
}
|
||||
|
||||
QwtPlotShapeItem* Editor::itemAt( const QPoint& pos ) const
|
||||
{
|
||||
const QwtPlot* plot = this->plot();
|
||||
if ( plot == NULL )
|
||||
return NULL;
|
||||
|
||||
// translate pos into the plot coordinates
|
||||
|
||||
using namespace QwtAxis;
|
||||
|
||||
double coords[ AxisPositions ];
|
||||
|
||||
coords[ XBottom ] = plot->canvasMap( XBottom ).invTransform( pos.x() );
|
||||
coords[ XTop ] = plot->canvasMap( XTop ).invTransform( pos.x() );
|
||||
coords[ YLeft ] = plot->canvasMap( YLeft ).invTransform( pos.y() );
|
||||
coords[ YRight ] = plot->canvasMap( YRight ).invTransform( pos.y() );
|
||||
|
||||
QwtPlotItemList items = plot->itemList();
|
||||
for ( int i = items.size() - 1; i >= 0; i-- )
|
||||
{
|
||||
QwtPlotItem* item = items[ i ];
|
||||
if ( item->isVisible() &&
|
||||
item->rtti() == QwtPlotItem::Rtti_PlotShape )
|
||||
{
|
||||
QwtPlotShapeItem* shapeItem = static_cast< QwtPlotShapeItem* >( item );
|
||||
const QPointF p( coords[ item->xAxis() ], coords[ item->yAxis() ] );
|
||||
|
||||
if ( shapeItem->boundingRect().contains( p )
|
||||
&& shapeItem->shape().contains( p ) )
|
||||
{
|
||||
return shapeItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QRegion Editor::maskHint() const
|
||||
{
|
||||
return maskHint( m_editedItem );
|
||||
}
|
||||
|
||||
QRegion Editor::maskHint( QwtPlotShapeItem* shapeItem ) const
|
||||
{
|
||||
const QwtPlot* plot = this->plot();
|
||||
if ( plot == NULL || shapeItem == NULL )
|
||||
return QRegion();
|
||||
|
||||
const QwtScaleMap xMap = plot->canvasMap( shapeItem->xAxis() );
|
||||
const QwtScaleMap yMap = plot->canvasMap( shapeItem->yAxis() );
|
||||
|
||||
QRect rect = QwtScaleMap::transform( xMap, yMap,
|
||||
shapeItem->shape().boundingRect() ).toRect();
|
||||
|
||||
const int m = 5; // some margin for the pen
|
||||
return rect.adjusted( -m, -m, m, m );
|
||||
}
|
||||
|
||||
void Editor::drawOverlay( QPainter* painter ) const
|
||||
{
|
||||
const QwtPlot* plot = this->plot();
|
||||
if ( plot == NULL || m_editedItem == NULL )
|
||||
return;
|
||||
|
||||
const QwtScaleMap xMap = plot->canvasMap( m_editedItem->xAxis() );
|
||||
const QwtScaleMap yMap = plot->canvasMap( m_editedItem->yAxis() );
|
||||
|
||||
painter->setRenderHint( QPainter::Antialiasing,
|
||||
m_editedItem->testRenderHint( QwtPlotItem::RenderAntialiased ) );
|
||||
|
||||
m_editedItem->draw( painter, xMap, yMap,
|
||||
plot->canvas()->contentsRect() );
|
||||
}
|
||||
|
||||
void Editor::raiseItem( QwtPlotShapeItem* shapeItem )
|
||||
{
|
||||
const QwtPlot* plot = this->plot();
|
||||
if ( plot == NULL || shapeItem == NULL )
|
||||
return;
|
||||
|
||||
const QwtPlotItemList items = plot->itemList();
|
||||
for ( int i = items.size() - 1; i >= 0; i-- )
|
||||
{
|
||||
QwtPlotItem* item = items[ i ];
|
||||
if ( shapeItem == item )
|
||||
return;
|
||||
|
||||
if ( item->isVisible() &&
|
||||
item->rtti() == QwtPlotItem::Rtti_PlotShape )
|
||||
{
|
||||
shapeItem->setZ( item->z() + 1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::setItemVisible( QwtPlotShapeItem* item, bool on )
|
||||
{
|
||||
if ( plot() == NULL || item == NULL || item->isVisible() == on )
|
||||
return;
|
||||
|
||||
const bool doAutoReplot = plot()->autoReplot();
|
||||
plot()->setAutoReplot( false );
|
||||
|
||||
item->setVisible( on );
|
||||
|
||||
plot()->setAutoReplot( doAutoReplot );
|
||||
|
||||
/*
|
||||
Avoid replot with a full repaint of the canvas.
|
||||
For special combinations - f.e. using the
|
||||
raster paint engine on a remote display -
|
||||
this makes a difference.
|
||||
*/
|
||||
|
||||
QwtPlotCanvas* canvas =
|
||||
qobject_cast< QwtPlotCanvas* >( plot()->canvas() );
|
||||
if ( canvas )
|
||||
canvas->invalidateBackingStore();
|
||||
|
||||
plot()->canvas()->update( maskHint( item ) );
|
||||
|
||||
}
|
||||
|
||||
#include "moc_Editor.cpp"
|
||||
Reference in New Issue
Block a user