地面站终端 App
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

547 lines
12 KiB

15 years ago
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* 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
*****************************************************************************/
// vim: expandtab
#include <qpainter.h>
#include <qpixmap.h>
#include <qevent.h>
#include <qframe.h>
#include <qcursor.h>
#if QT_VERSION < 0x040000
#include <qobjectlist.h>
#endif
#include "qwt_picker.h"
#include "qwt_array.h"
#include "qwt_panner.h"
static QwtArray<QwtPicker *> activePickers(QWidget *w)
{
QwtArray<QwtPicker *> pickers;
#if QT_VERSION >= 0x040000
QObjectList children = w->children();
for ( int i = 0; i < children.size(); i++ ) {
15 years ago
QObject *obj = children[i];
if ( obj->inherits("QwtPicker") ) {
15 years ago
QwtPicker *picker = (QwtPicker *)obj;
if ( picker->isEnabled() )
pickers += picker;
}
}
#else
QObjectList *children = (QObjectList *)w->children();
if ( children ) {
for ( QObjectListIterator it(*children); it.current(); ++it ) {
15 years ago
QObject *obj = (QObject *)it.current();
if ( obj->inherits("QwtPicker") ) {
15 years ago
QwtPicker *picker = (QwtPicker *)obj;
if ( picker->isEnabled() ) {
15 years ago
pickers.resize(pickers.size() + 1);
pickers[int(pickers.size()) - 1] = picker;
}
}
}
}
#endif
return pickers;
}
class QwtPanner::PrivateData
{
public:
PrivateData():
button(Qt::LeftButton),
buttonState(Qt::NoButton),
abortKey(Qt::Key_Escape),
abortKeyState(Qt::NoButton),
#ifndef QT_NO_CURSOR
cursor(NULL),
restoreCursor(NULL),
hasCursor(false),
#endif
isEnabled(false) {
15 years ago
#if QT_VERSION >= 0x040000
orientations = Qt::Vertical | Qt::Horizontal;
#else
orientations[Qt::Vertical] = true;
orientations[Qt::Horizontal] = true;
#endif
}
~PrivateData() {
15 years ago
#ifndef QT_NO_CURSOR
delete cursor;
delete restoreCursor;
#endif
}
15 years ago
int button;
int buttonState;
int abortKey;
int abortKeyState;
QPoint initialPos;
QPoint pos;
QPixmap pixmap;
#ifndef QT_NO_CURSOR
QCursor *cursor;
QCursor *restoreCursor;
bool hasCursor;
#endif
bool isEnabled;
#if QT_VERSION >= 0x040000
Qt::Orientations orientations;
#else
bool orientations[2];
#endif
};
/*!
Creates an panner that is enabled for the left mouse button.
\param parent Parent widget to be panned
*/
QwtPanner::QwtPanner(QWidget *parent):
QWidget(parent)
{
d_data = new PrivateData();
#if QT_VERSION >= 0x040000
setAttribute(Qt::WA_TransparentForMouseEvents);
setAttribute(Qt::WA_NoSystemBackground);
setFocusPolicy(Qt::NoFocus);
#else
setBackgroundMode(Qt::NoBackground);
setFocusPolicy(QWidget::NoFocus);
#endif
hide();
setEnabled(true);
}
//! Destructor
QwtPanner::~QwtPanner()
{
delete d_data;
}
/*!
Change the mouse button
The defaults are Qt::LeftButton and Qt::NoButton
*/
void QwtPanner::setMouseButton(int button, int buttonState)
{
d_data->button = button;
d_data->buttonState = buttonState;
}
//! Get the mouse button
void QwtPanner::getMouseButton(int &button, int &buttonState) const
{
button = d_data->button;
buttonState = d_data->buttonState;
}
/*!
Change the abort key
The defaults are Qt::Key_Escape and Qt::NoButton
*/
void QwtPanner::setAbortKey(int key, int state)
{
d_data->abortKey = key;
d_data->abortKeyState = state;
}
//! Get the abort key
void QwtPanner::getAbortKey(int &key, int &state) const
{
key = d_data->abortKey;
state = d_data->abortKeyState;
}
/*!
Change the cursor, that is active while panning
The default is the cursor of the parent widget.
\param cursor New cursor
\sa setCursor()
*/
#ifndef QT_NO_CURSOR
void QwtPanner::setCursor(const QCursor &cursor)
{
d_data->cursor = new QCursor(cursor);
}
#endif
/*!
\return Cursor that is active while panning
\sa setCursor()
*/
#ifndef QT_NO_CURSOR
const QCursor QwtPanner::cursor() const
{
if ( d_data->cursor )
return *d_data->cursor;
if ( parentWidget() )
return parentWidget()->cursor();
return QCursor();
}
#endif
/*!
15 years ago
\brief En/disable the panner
15 years ago
When enabled is true an event filter is installed for
the observed widget, otherwise the event filter is removed.
\param on true or false
\sa isEnabled(), eventFilter()
*/
void QwtPanner::setEnabled(bool on)
{
if ( d_data->isEnabled != on ) {
15 years ago
d_data->isEnabled = on;
QWidget *w = parentWidget();
if ( w ) {
if ( d_data->isEnabled ) {
15 years ago
w->installEventFilter(this);
} else {
15 years ago
w->removeEventFilter(this);
hide();
}
}
}
}
#if QT_VERSION >= 0x040000
/*!
Set the orientations, where panning is enabled
The default value is in both directions: Qt::Horizontal | Qt::Vertical
/param o Orientation
*/
void QwtPanner::setOrientations(Qt::Orientations o)
{
d_data->orientations = o;
}
//! Return the orientation, where paning is enabled
Qt::Orientations QwtPanner::orientations() const
{
return d_data->orientations;
}
#else
void QwtPanner::enableOrientation(Qt::Orientation o, bool enable)
{
if ( o == Qt::Vertical || o == Qt::Horizontal )
d_data->orientations[o] = enable;
}
#endif
/*!
15 years ago
Return true if a orientatio is enabled
\sa orientations(), setOrientations()
*/
bool QwtPanner::isOrientationEnabled(Qt::Orientation o) const
{
#if QT_VERSION >= 0x040000
return d_data->orientations & o;
#else
if ( o == Qt::Vertical || o == Qt::Horizontal )
return d_data->orientations[o];
return false;
#endif
}
/*!
\return true when enabled, false otherwise
\sa setEnabled, eventFilter()
*/
bool QwtPanner::isEnabled() const
{
return d_data->isEnabled;
}
/*!
\brief Paint event
Repaint the grabbed pixmap on its current position and
fill the empty spaces by the background of the parent widget.
\param pe Paint event
*/
void QwtPanner::paintEvent(QPaintEvent *pe)
{
QPixmap pm(size());
QPainter painter(&pm);
const QColor bg =
#if QT_VERSION < 0x040000
parentWidget()->palette().color(
QPalette::Normal, QColorGroup::Background);
#else
parentWidget()->palette().color(
QPalette::Normal, QPalette::Background);
#endif
painter.setPen(Qt::NoPen);
painter.setBrush(QBrush(bg));
painter.drawRect(0, 0, pm.width(), pm.height());
int dx = d_data->pos.x() - d_data->initialPos.x();
int dy = d_data->pos.y() - d_data->initialPos.y();
QRect r(0, 0, d_data->pixmap.width(), d_data->pixmap.height());
r.moveCenter(QPoint(r.center().x() + dx, r.center().y() + dy));
painter.drawPixmap(r, d_data->pixmap);
painter.end();
painter.begin(this);
painter.setClipRegion(pe->region());
painter.drawPixmap(0, 0, pm);
}
/*!
15 years ago
\brief Event filter
When isEnabled() the mouse events of the observed widget are filtered.
\sa widgetMousePressEvent(), widgetMouseReleaseEvent(),
widgetMouseMoveEvent()
*/
bool QwtPanner::eventFilter(QObject *o, QEvent *e)
{
if ( o == NULL || o != parentWidget() )
return false;
switch(e->type()) {
case QEvent::MouseButtonPress: {
widgetMousePressEvent((QMouseEvent *)e);
break;
}
case QEvent::MouseMove: {
widgetMouseMoveEvent((QMouseEvent *)e);
break;
}
case QEvent::MouseButtonRelease: {
widgetMouseReleaseEvent((QMouseEvent *)e);
break;
}
case QEvent::KeyPress: {
widgetKeyPressEvent((QKeyEvent *)e);
break;
}
case QEvent::KeyRelease: {
widgetKeyReleaseEvent((QKeyEvent *)e);
break;
}
case QEvent::Paint: {
if ( isVisible() )
return true;
break;
}
default:
;
15 years ago
}
return false;
}
/*!
Handle a mouse press event for the observed widget.
\param me Mouse event
\sa eventFilter(), widgetMouseReleaseEvent(),
widgetMouseMoveEvent(),
*/
void QwtPanner::widgetMousePressEvent(QMouseEvent *me)
{
if ( me->button() != d_data->button )
return;
QWidget *w = parentWidget();
if ( w == NULL )
return;
#if QT_VERSION < 0x040000
if ( (me->state() & Qt::KeyButtonMask) !=
(d_data->buttonState & Qt::KeyButtonMask) )
15 years ago
#else
if ( (me->modifiers() & Qt::KeyboardModifierMask) !=
(int)(d_data->buttonState & Qt::KeyboardModifierMask) )
15 years ago
#endif
{
return;
}
#ifndef QT_NO_CURSOR
showCursor(true);
#endif
d_data->initialPos = d_data->pos = me->pos();
QRect cr = parentWidget()->rect();
if ( parentWidget()->inherits("QFrame") ) {
15 years ago
const QFrame* frame = (QFrame*)parentWidget();
cr = frame->contentsRect();
}
setGeometry(cr);
// We don't want to grab the picker !
QwtArray<QwtPicker *> pickers = activePickers(parentWidget());
for ( int i = 0; i < (int)pickers.size(); i++ )
pickers[i]->setEnabled(false);
d_data->pixmap = QPixmap::grabWidget(parentWidget(),
cr.x(), cr.y(), cr.width(), cr.height());
15 years ago
for ( int i = 0; i < (int)pickers.size(); i++ )
pickers[i]->setEnabled(true);
show();
}
/*!
Handle a mouse move event for the observed widget.
\param me Mouse event
\sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent()
*/
void QwtPanner::widgetMouseMoveEvent(QMouseEvent *me)
{
if ( !isVisible() )
return;
QPoint pos = me->pos();
if ( !isOrientationEnabled(Qt::Horizontal) )
pos.setX(d_data->initialPos.x());
if ( !isOrientationEnabled(Qt::Vertical) )
pos.setY(d_data->initialPos.y());
if ( pos != d_data->pos && rect().contains(pos) ) {
15 years ago
d_data->pos = pos;
update();
emit moved(d_data->pos.x() - d_data->initialPos.x(),
d_data->pos.y() - d_data->initialPos.y());
15 years ago
}
}
/*!
Handle a mouse release event for the observed widget.
\param me Mouse event
\sa eventFilter(), widgetMousePressEvent(),
widgetMouseMoveEvent(),
*/
void QwtPanner::widgetMouseReleaseEvent(QMouseEvent *me)
{
if ( isVisible() ) {
15 years ago
hide();
#ifndef QT_NO_CURSOR
showCursor(false);
#endif
QPoint pos = me->pos();
if ( !isOrientationEnabled(Qt::Horizontal) )
pos.setX(d_data->initialPos.x());
if ( !isOrientationEnabled(Qt::Vertical) )
pos.setY(d_data->initialPos.y());
d_data->pixmap = QPixmap();
d_data->pos = pos;
if ( d_data->pos != d_data->initialPos ) {
emit panned(d_data->pos.x() - d_data->initialPos.x(),
d_data->pos.y() - d_data->initialPos.y());
15 years ago
}
}
}
/*!
Handle a key press event for the observed widget.
\param ke Key event
\sa eventFilter(), widgetKeyReleaseEvent()
*/
void QwtPanner::widgetKeyPressEvent(QKeyEvent *ke)
{
if ( ke->key() == d_data->abortKey ) {
15 years ago
const bool matched =
#if QT_VERSION < 0x040000
(ke->state() & Qt::KeyButtonMask) ==
(d_data->abortKeyState & Qt::KeyButtonMask);
15 years ago
#else
(ke->modifiers() & Qt::KeyboardModifierMask) ==
(int)(d_data->abortKeyState & Qt::KeyboardModifierMask);
15 years ago
#endif
if ( matched ) {
15 years ago
hide();
#ifndef QT_NO_CURSOR
showCursor(false);
#endif
d_data->pixmap = QPixmap();
}
}
}
/*!
Handle a key release event for the observed widget.
\param ke Key event
\sa eventFilter(), widgetKeyReleaseEvent()
*/
void QwtPanner::widgetKeyReleaseEvent(QKeyEvent *)
{
}
#ifndef QT_NO_CURSOR
void QwtPanner::showCursor(bool on)
{
if ( on == d_data->hasCursor )
return;
QWidget *w = parentWidget();
if ( w == NULL || d_data->cursor == NULL )
return;
d_data->hasCursor = on;
if ( on ) {
15 years ago
#if QT_VERSION < 0x040000
if ( w->testWState(WState_OwnCursor) )
#else
if ( w->testAttribute(Qt::WA_SetCursor) )
#endif
{
delete d_data->restoreCursor;
d_data->restoreCursor = new QCursor(w->cursor());
}
w->setCursor(*d_data->cursor);
} else {
if ( d_data->restoreCursor ) {
15 years ago
w->setCursor(*d_data->restoreCursor);
delete d_data->restoreCursor;
d_data->restoreCursor = NULL;
} else
15 years ago
w->unsetCursor();
}
}
#endif