qwt_panner.cpp
/******************************************************************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_panner.h"
#include "qwt_picker.h"
#include "qwt_painter.h"
#include <qpainter.h>
#include <qpixmap.h>
#include <qevent.h>
#include <qcursor.h>
#include <qbitmap.h>
static QVector< QwtPicker* > qwtActivePickers( QWidget* w )
{
QVector< QwtPicker* > pickers;
QObjectList children = w->children();
for ( int i = 0; i < children.size(); i++ )
{
QwtPicker* picker = qobject_cast< QwtPicker* >( children[i] );
if ( picker && picker->isEnabled() )
pickers += picker;
}
return pickers;
}
class QwtPanner::PrivateData
{
public:
PrivateData()
: button( Qt::LeftButton )
, buttonModifiers( Qt::NoModifier )
, abortKey( Qt::Key_Escape )
, abortKeyModifiers( Qt::NoModifier )
#ifndef QT_NO_CURSOR
, cursor( NULL )
, restoreCursor( NULL )
, hasCursor( false )
#endif
, isEnabled( false )
, orientations( Qt::Vertical | Qt::Horizontal )
{
}
~PrivateData()
{
#ifndef QT_NO_CURSOR
delete cursor;
delete restoreCursor;
#endif
}
Qt::MouseButton button;
Qt::KeyboardModifiers buttonModifiers;
int abortKey;
Qt::KeyboardModifiers abortKeyModifiers;
QPoint initialPos;
QPoint pos;
QPixmap pixmap;
QBitmap contentsMask;
#ifndef QT_NO_CURSOR
QCursor* cursor;
QCursor* restoreCursor;
bool hasCursor;
#endif
bool isEnabled;
Qt::Orientations orientations;
};
QwtPanner::QwtPanner( QWidget* parent )
: QWidget( parent )
{
m_data = new PrivateData();
setAttribute( Qt::WA_TransparentForMouseEvents );
setAttribute( Qt::WA_NoSystemBackground );
setFocusPolicy( Qt::NoFocus );
hide();
setEnabled( true );
}
QwtPanner::~QwtPanner()
{
delete m_data;
}
void QwtPanner::setMouseButton( Qt::MouseButton button,
Qt::KeyboardModifiers modifiers )
{
m_data->button = button;
m_data->buttonModifiers = modifiers;
}
void QwtPanner::getMouseButton( Qt::MouseButton& button,
Qt::KeyboardModifiers& modifiers ) const
{
button = m_data->button;
modifiers = m_data->buttonModifiers;
}
void QwtPanner::setAbortKey( int key,
Qt::KeyboardModifiers modifiers )
{
m_data->abortKey = key;
m_data->abortKeyModifiers = modifiers;
}
void QwtPanner::getAbortKey( int& key,
Qt::KeyboardModifiers& modifiers ) const
{
key = m_data->abortKey;
modifiers = m_data->abortKeyModifiers;
}
#ifndef QT_NO_CURSOR
void QwtPanner::setCursor( const QCursor& cursor )
{
m_data->cursor = new QCursor( cursor );
}
#endif
#ifndef QT_NO_CURSOR
const QCursor QwtPanner::cursor() const
{
if ( m_data->cursor )
return *m_data->cursor;
if ( parentWidget() )
return parentWidget()->cursor();
return QCursor();
}
#endif
void QwtPanner::setEnabled( bool on )
{
if ( m_data->isEnabled != on )
{
m_data->isEnabled = on;
QWidget* w = parentWidget();
if ( w )
{
if ( m_data->isEnabled )
{
w->installEventFilter( this );
}
else
{
w->removeEventFilter( this );
hide();
}
}
}
}
void QwtPanner::setOrientations( Qt::Orientations o )
{
m_data->orientations = o;
}
Qt::Orientations QwtPanner::orientations() const
{
return m_data->orientations;
}
bool QwtPanner::isOrientationEnabled( Qt::Orientation o ) const
{
return m_data->orientations & o;
}
bool QwtPanner::isEnabled() const
{
return m_data->isEnabled;
}
void QwtPanner::paintEvent( QPaintEvent* event )
{
int dx = m_data->pos.x() - m_data->initialPos.x();
int dy = m_data->pos.y() - m_data->initialPos.y();
QRectF r;
r.setSize( m_data->pixmap.size() / QwtPainter::devicePixelRatio( &m_data->pixmap ) );
r.moveCenter( QPointF( r.center().x() + dx, r.center().y() + dy ) );
QPixmap pm = QwtPainter::backingStore( this, size() );
QwtPainter::fillPixmap( parentWidget(), pm );
QPainter painter( &pm );
if ( !m_data->contentsMask.isNull() )
{
QPixmap masked = m_data->pixmap;
masked.setMask( m_data->contentsMask );
painter.drawPixmap( r.toRect(), masked );
}
else
{
painter.drawPixmap( r.toRect(), m_data->pixmap );
}
painter.end();
if ( !m_data->contentsMask.isNull() )
pm.setMask( m_data->contentsMask );
painter.begin( this );
painter.setClipRegion( event->region() );
painter.drawPixmap( 0, 0, pm );
}
QBitmap QwtPanner::contentsMask() const
{
return QBitmap();
}
QPixmap QwtPanner::grab() const
{
#if QT_VERSION >= 0x050000
return parentWidget()->grab( parentWidget()->rect() );
#else
return QPixmap::grabWidget( parentWidget() );
#endif
}
bool QwtPanner::eventFilter( QObject* object, QEvent* event )
{
if ( object == NULL || object != parentWidget() )
return false;
switch ( event->type() )
{
case QEvent::MouseButtonPress:
{
widgetMousePressEvent( static_cast< QMouseEvent* >( event ) );
break;
}
case QEvent::MouseMove:
{
widgetMouseMoveEvent( static_cast< QMouseEvent* >( event ) );
break;
}
case QEvent::MouseButtonRelease:
{
widgetMouseReleaseEvent( static_cast< QMouseEvent* >( event ) );
break;
}
case QEvent::KeyPress:
{
widgetKeyPressEvent( static_cast< QKeyEvent* >( event ) );
break;
}
case QEvent::KeyRelease:
{
widgetKeyReleaseEvent( static_cast< QKeyEvent* >( event ) );
break;
}
case QEvent::Paint:
{
if ( isVisible() )
return true;
break;
}
default:;
}
return false;
}
void QwtPanner::widgetMousePressEvent( QMouseEvent* mouseEvent )
{
if ( ( mouseEvent->button() != m_data->button )
|| ( mouseEvent->modifiers() != m_data->buttonModifiers ) )
{
return;
}
QWidget* w = parentWidget();
if ( w == NULL )
return;
#ifndef QT_NO_CURSOR
showCursor( true );
#endif
m_data->initialPos = m_data->pos = mouseEvent->pos();
setGeometry( parentWidget()->rect() );
// We don't want to grab the picker !
QVector< QwtPicker* > pickers = qwtActivePickers( parentWidget() );
for ( int i = 0; i < pickers.size(); i++ )
pickers[i]->setEnabled( false );
m_data->pixmap = grab();
m_data->contentsMask = contentsMask();
for ( int i = 0; i < pickers.size(); i++ )
pickers[i]->setEnabled( true );
show();
}
void QwtPanner::widgetMouseMoveEvent( QMouseEvent* mouseEvent )
{
if ( !isVisible() )
return;
QPoint pos = mouseEvent->pos();
if ( !isOrientationEnabled( Qt::Horizontal ) )
pos.setX( m_data->initialPos.x() );
if ( !isOrientationEnabled( Qt::Vertical ) )
pos.setY( m_data->initialPos.y() );
if ( pos != m_data->pos && rect().contains( pos ) )
{
m_data->pos = pos;
update();
Q_EMIT moved( m_data->pos.x() - m_data->initialPos.x(),
m_data->pos.y() - m_data->initialPos.y() );
}
}
void QwtPanner::widgetMouseReleaseEvent( QMouseEvent* mouseEvent )
{
if ( isVisible() )
{
hide();
#ifndef QT_NO_CURSOR
showCursor( false );
#endif
QPoint pos = mouseEvent->pos();
if ( !isOrientationEnabled( Qt::Horizontal ) )
pos.setX( m_data->initialPos.x() );
if ( !isOrientationEnabled( Qt::Vertical ) )
pos.setY( m_data->initialPos.y() );
m_data->pixmap = QPixmap();
m_data->contentsMask = QBitmap();
m_data->pos = pos;
if ( m_data->pos != m_data->initialPos )
{
Q_EMIT panned( m_data->pos.x() - m_data->initialPos.x(),
m_data->pos.y() - m_data->initialPos.y() );
}
}
}
void QwtPanner::widgetKeyPressEvent( QKeyEvent* keyEvent )
{
if ( ( keyEvent->key() == m_data->abortKey )
&& ( keyEvent->modifiers() == m_data->abortKeyModifiers ) )
{
hide();
#ifndef QT_NO_CURSOR
showCursor( false );
#endif
m_data->pixmap = QPixmap();
}
}
void QwtPanner::widgetKeyReleaseEvent( QKeyEvent* keyEvent )
{
Q_UNUSED( keyEvent );
}
#ifndef QT_NO_CURSOR
void QwtPanner::showCursor( bool on )
{
if ( on == m_data->hasCursor )
return;
QWidget* w = parentWidget();
if ( w == NULL || m_data->cursor == NULL )
return;
m_data->hasCursor = on;
if ( on )
{
if ( w->testAttribute( Qt::WA_SetCursor ) )
{
delete m_data->restoreCursor;
m_data->restoreCursor = new QCursor( w->cursor() );
}
w->setCursor( *m_data->cursor );
}
else
{
if ( m_data->restoreCursor )
{
w->setCursor( *m_data->restoreCursor );
delete m_data->restoreCursor;
m_data->restoreCursor = NULL;
}
else
w->unsetCursor();
}
}
#endif
#if QWT_MOC_INCLUDE
#include "moc_qwt_panner.cpp"
#endif
QVector
Definition: qwt_clipper.h:23
QwtPainter::fillPixmap
static void fillPixmap(const QWidget *, QPixmap &, const QPoint &offset=QPoint())
Definition: qwt_painter.cpp:1311
QwtPainter::devicePixelRatio
static qreal devicePixelRatio(const QPaintDevice *)
Definition: qwt_painter.cpp:1491
QwtPainter::backingStore
static QPixmap backingStore(QWidget *, const QSize &)
Definition: qwt_painter.cpp:1525
QwtPanner::orientations
Qt::Orientations orientations() const
Return the orientation, where panning is enabled.
Definition: qwt_panner.cpp:222
QwtPanner::isEnabled
bool isEnabled() const
Definition: qwt_panner.cpp:240
QwtPanner::~QwtPanner
virtual ~QwtPanner()
Destructor.
Definition: qwt_panner.cpp:101
QwtPanner::cursor
const QCursor cursor() const
Definition: qwt_panner.cpp:167
QwtPanner::eventFilter
virtual bool eventFilter(QObject *, QEvent *) override
Event filter.
Definition: qwt_panner.cpp:330
QwtPanner::setEnabled
void setEnabled(bool)
En/disable the panner.
Definition: qwt_panner.cpp:188
QwtPanner::widgetMouseMoveEvent
virtual void widgetMouseMoveEvent(QMouseEvent *)
Definition: qwt_panner.cpp:421
QwtPanner::setMouseButton
void setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
Definition: qwt_panner.cpp:110
QwtPanner::widgetKeyPressEvent
virtual void widgetKeyPressEvent(QKeyEvent *)
Definition: qwt_panner.cpp:482
QwtPanner::getMouseButton
void getMouseButton(Qt::MouseButton &button, Qt::KeyboardModifiers &) const
Get mouse button and modifiers used for panning.
Definition: qwt_panner.cpp:118
QwtPanner::widgetKeyReleaseEvent
virtual void widgetKeyReleaseEvent(QKeyEvent *)
Definition: qwt_panner.cpp:502
QwtPanner::moved
void moved(int dx, int dy)
QwtPanner::isOrientationEnabled
bool isOrientationEnabled(Qt::Orientation) const
Definition: qwt_panner.cpp:231
QwtPanner::paintEvent
virtual void paintEvent(QPaintEvent *) override
Paint event.
Definition: qwt_panner.cpp:253
QwtPanner::setOrientations
void setOrientations(Qt::Orientations)
Definition: qwt_panner.cpp:216
QwtPanner::contentsMask
virtual QBitmap contentsMask() const
Calculate a mask for the contents of the panned widget.
Definition: qwt_panner.cpp:297
QwtPanner::widgetMouseReleaseEvent
virtual void widgetMouseReleaseEvent(QMouseEvent *)
Definition: qwt_panner.cpp:449
QwtPanner::getAbortKey
void getAbortKey(int &key, Qt::KeyboardModifiers &) const
Get the abort key and modifiers.
Definition: qwt_panner.cpp:140
QwtPanner::grab
virtual QPixmap grab() const
Definition: qwt_panner.cpp:306
QwtPanner::setCursor
void setCursor(const QCursor &)
Definition: qwt_panner.cpp:156
QwtPanner::setAbortKey
void setAbortKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)
Definition: qwt_panner.cpp:132
QwtPanner::widgetMousePressEvent
virtual void widgetMousePressEvent(QMouseEvent *)
Definition: qwt_panner.cpp:381
QwtPanner::panned
void panned(int dx, int dy)
QwtPanner::QwtPanner
QwtPanner(QWidget *parent)
Definition: qwt_panner.cpp:87
QwtPicker
QwtPicker provides selections on a widget.
Definition: qwt_picker.h:104
QwtPicker::isEnabled
bool isEnabled() const
Definition: qwt_picker.cpp:399