summaryrefslogtreecommitdiffstats
path: root/examples/tetrix/qdragapp.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /examples/tetrix/qdragapp.cpp
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'examples/tetrix/qdragapp.cpp')
-rw-r--r--examples/tetrix/qdragapp.cpp502
1 files changed, 502 insertions, 0 deletions
diff --git a/examples/tetrix/qdragapp.cpp b/examples/tetrix/qdragapp.cpp
new file mode 100644
index 0000000..b6fafdc
--- /dev/null
+++ b/examples/tetrix/qdragapp.cpp
@@ -0,0 +1,502 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "qdragapp.h"
+#include "qptrlist.h"
+#include "qintdict.h"
+#include "qpopupmenu.h"
+#include "qguardedptr.h"
+#include "qcolor.h"
+#include "qwidget.h"
+#include "qfontmetrics.h"
+#include "qcursor.h"
+#include "qobjectlist.h"
+
+QWidget *cursorWidget( QPoint * = 0 );
+
+class QDragger;
+
+
+class DropWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ void paintEvent( QPaintEvent * );
+ void closeEvent( QCloseEvent * );
+
+ QDragger *master;
+};
+
+
+struct DropInfo {
+ DropInfo() { w=0; }
+ ~DropInfo() { delete w; }
+ DropWindow *w;
+ bool userOpened;
+};
+
+struct DraggedInfo {
+ QWidget *w;
+ QWidget *mother;
+ QPoint pos;
+};
+
+
+class QDragger : public QObject
+{
+ Q_OBJECT
+public:
+ QDragger();
+ ~QDragger();
+
+ bool notify( QObject *, QEvent * ); // event filter
+ void closeDropWindow( DropWindow * );
+public slots:
+ void openDropWindow();
+ void killDropWindow();
+ void killAllDropWindows();
+ void sendChildHome();
+ void sendAllChildrenHome();
+private:
+ bool isParentToDragged( QWidget * );
+ bool noWidgets( QWidget * );
+ void killDropWindow( DropInfo * );
+ void killAllDropWindows( bool );
+ void sendChildHome( DraggedInfo * );
+ void sendAllChildrenHome( QWidget * );
+ QWidget *openDropWindow( const QRect&, bool );
+
+ bool startGrab();
+ void grabFinished();
+ bool dragEvent( QWidget *, QMouseEvent * );
+ bool killDropEvent( QMouseEvent * );
+ bool sendChildEvent( QMouseEvent * );
+
+ bool killingDrop;
+ bool sendingChild;
+ QWidget *clickedWidget;
+ QGuardedPtr<QWidget> hostWidget;
+ QCursor cursor;
+
+ QPopupMenu* menu;
+ QPoint clickOffset;
+ QColor dragBackground;
+ QColor dragForeground;
+ DraggedInfo dragInfo;
+ QIntDict<DraggedInfo> draggedDict;
+ QIntDict<DropInfo> dropDict;
+};
+
+
+QDragApplication::QDragApplication( int &argc, char **argv )
+ : QApplication( argc, argv ), dragger( 0 )
+{
+ dragger = new QDragger;
+}
+
+QDragApplication::~QDragApplication()
+{
+ delete dragger;
+}
+
+bool QDragApplication::notify( QObject *o, QEvent *e )
+{
+ if ( dragger && !dragger->notify( o, e ) )
+ return QApplication::notify( o, e );
+ else
+ return FALSE;
+}
+
+void DropWindow::paintEvent( QPaintEvent * )
+{
+ const char *msg = "Drag widgets and drop them here or anywhere!";
+ int startX = ( width() - fontMetrics().width( msg ) )/2;
+ startX = startX < 0 ? 0 : startX;
+
+ drawText( startX, height()/2, msg );
+}
+
+void DropWindow::closeEvent( QCloseEvent *e )
+{
+ master->closeDropWindow( this );
+ e->ignore();
+}
+
+QDragger::QDragger()
+{
+ dragInfo.w = 0;
+ killingDrop = FALSE;
+ sendingChild = FALSE;
+ draggedDict.setAutoDelete( TRUE );
+ dropDict .setAutoDelete( TRUE );
+
+ menu = new QPopupMenu;
+ menu->insertItem( "Open drop window", 1 );
+ menu->insertItem( "Kill drop window", 2 );
+ menu->insertItem( "Kill all drop windows", 3 );
+ menu->insertSeparator();
+// menu->insertItem( "Send child home", 4 );
+ menu->insertItem( "Send all children home", 5 );
+
+ menu->connectItem( 1, this, SLOT(openDropWindow()) );
+ menu->connectItem( 2, this, SLOT(killDropWindow()) );
+ menu->connectItem( 3, this, SLOT(killAllDropWindows()) );
+// menu->connectItem( 4, this, SLOT(sendChildHome()) );
+ menu->connectItem( 5, this, SLOT(sendAllChildrenHome()) );
+}
+
+QDragger::~QDragger()
+{
+ delete menu;
+}
+
+
+bool QDragger::notify( QObject *o, QEvent *e )
+{
+ if ( !o->isWidgetType() || o == menu )
+ return FALSE;
+ switch( e->type() ) {
+ case QEvent::MouseMove:
+ {
+ QMouseEvent *tmp = (QMouseEvent*) e;
+ if ( killingDrop )
+ return killDropEvent( tmp );
+ if ( sendingChild )
+ return sendChildEvent( tmp );
+ if ( tmp->state() & QMouseEvent::RightButton )
+ return dragEvent( (QWidget*) o, tmp );
+ break;
+ }
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ {
+ QMouseEvent *tmp = (QMouseEvent*) e;
+ if ( killingDrop )
+ return killDropEvent( tmp );
+ if ( sendingChild )
+ return sendChildEvent( tmp );
+ if ( tmp->button() == QMouseEvent::RightButton )
+ return dragEvent( (QWidget*) o, tmp );
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+bool QDragger::isParentToDragged( QWidget *w )
+{
+ QIntDictIterator<DraggedInfo> iter( draggedDict );
+
+ DraggedInfo *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if ( tmp->mother == w )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool QDragger::noWidgets( QWidget *w )
+{
+ const QObjectList *l = w->children();
+ if ( !l )
+ return TRUE;
+ QObjectListIt iter( *l );
+ QObject *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if ( tmp->isWidgetType() )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void QDragger::sendAllChildrenHome( QWidget *w )
+{
+ const QObjectList *l = w->children();
+ if ( !l )
+ return;
+ QObjectListIt iter( *l );
+ QObject *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if ( tmp->isWidgetType() ) {
+ sendAllChildrenHome( (QWidget*) tmp );
+ DraggedInfo *di = draggedDict.find( (long) tmp );
+ if ( di )
+ sendChildHome( di );
+ }
+ }
+}
+
+bool QDragger::dragEvent( QWidget *w, QMouseEvent *e )
+{
+ switch( e->type() ) {
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress: {
+ if ( !noWidgets( w ) || // has widget children
+ isParentToDragged( w ) || // has had widget children
+ w->parentWidget() == 0 ) { // is top level window
+ hostWidget = w;
+ menu->popup( w->mapToGlobal( e->pos() ) );
+ return TRUE;
+ }
+ if ( !draggedDict.find( (long) w ) ) {
+ DraggedInfo *tmp = new DraggedInfo;
+ tmp->w = w;
+ tmp->mother = w->parentWidget();
+ tmp->pos = w->frameGeometry().topLeft();
+ draggedDict.insert( (long) w, tmp );
+ }
+ dragBackground = w->backgroundColor();
+ dragForeground = w->foregroundColor();
+ dragInfo.w = w;
+ dragInfo.mother = w->parentWidget();
+ dragInfo.pos = w->frameGeometry().topLeft();
+ clickOffset = e->pos();
+ dragInfo.w = w;
+ QPoint p = w->mapToGlobal(QPoint(0,0));
+ w->reparent( 0, WType_Popup, p, TRUE );
+
+ return TRUE;
+ }
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove: {
+ if ( dragInfo.w != 0 ) {
+ QPoint p = QCursor::pos() - clickOffset;
+ dragInfo.w->move( p );
+ if ( e->type() == QEvent::MouseMove )
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ if ( !dragInfo.w )
+ return FALSE;
+ if ( w != dragInfo.w )
+ w = dragInfo.w;
+ dragInfo.w = 0;
+ w->hide();
+ QPoint pos;
+ QWidget *target = cursorWidget( &pos );
+ pos = pos - clickOffset;
+ QPoint p;
+ if ( !target ) {
+ target = openDropWindow( QRect( pos, w->size() ),
+ FALSE);
+ p = QPoint( 0, 0 );
+ }
+ else
+ p = target->mapFromGlobal( pos );
+ w->reparent( target, 0, p, TRUE );
+ DropInfo *tmp = dropDict.find( (long) dragInfo.mother );
+ if ( tmp ) {
+ if ( !tmp->userOpened && noWidgets( tmp->w ) )
+ dropDict.remove( (long) tmp->w );
+ }
+ if ( !target->isVisible() )
+ target->show();
+ }
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+bool QDragger::killDropEvent( QMouseEvent *e )
+{
+ switch( e->type() ) {
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ clickedWidget = cursorWidget();
+ return TRUE;
+ case QEvent::MouseButtonRelease:
+ hostWidget->releaseMouse();
+ if ( clickedWidget ) {
+ DropInfo *tmp = dropDict.find( (long) clickedWidget );
+ if( tmp ) {
+ killDropWindow( tmp );
+ dropDict.remove( (long) tmp->w );
+ }
+ }
+ grabFinished();
+ return TRUE;
+ case QEvent::MouseMove:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+bool QDragger::sendChildEvent( QMouseEvent *e )
+{
+ switch( e->type() ) {
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ clickedWidget = cursorWidget();
+ return TRUE;
+ case QEvent::MouseButtonRelease:
+ hostWidget->releaseMouse();
+ if ( clickedWidget ) {
+ DraggedInfo *tmp = draggedDict.find((long) clickedWidget);
+ if( tmp ) {
+ QWidget *parent = tmp->w->parentWidget();
+ sendChildHome( tmp );
+ DropInfo *dri = dropDict.find( (long) parent );
+ if ( dri && noWidgets(dri->w) && !dri->userOpened ) {
+ killDropWindow( dri );
+ dropDict.remove( (long) dri );
+ }
+ }
+ grabFinished();
+ }
+ return TRUE;
+ case QEvent::MouseMove:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+bool QDragger::startGrab()
+{
+ if ( !hostWidget )
+ return FALSE;
+ clickedWidget = 0;
+ cursor = hostWidget->cursor();
+ hostWidget->grabMouse();
+ hostWidget->setCursor( QCursor( CrossCursor ) );
+ return TRUE;
+}
+
+void QDragger::grabFinished()
+{
+ killingDrop = FALSE;
+ sendingChild = FALSE;
+ if(hostWidget)
+ hostWidget->setCursor( cursor );
+}
+
+void QDragger::closeDropWindow( DropWindow *w )
+{
+ DropInfo *tmp = dropDict.find( (long) w);
+ if( tmp )
+ killDropWindow( tmp );
+}
+
+void QDragger::openDropWindow()
+{
+ QWidget *tmp = openDropWindow( QRect(100, 100, 300, 200), TRUE );
+ tmp->show();
+}
+
+QWidget *QDragger::openDropWindow( const QRect &r, bool user )
+{
+ DropInfo *tmp = new DropInfo;
+ DropWindow *w = new DropWindow;
+ if ( user ) {
+ tmp->userOpened = TRUE;
+ w->setCaption( "Drop window" );
+ } else {
+ tmp->userOpened = FALSE;
+ w->setCaption( "Auto drop window" );
+ }
+ tmp->w = w;
+ w->master = this;
+ w->setGeometry( r );
+ dropDict.insert( (long) w, tmp );
+ w->show();
+ return w;
+}
+
+void QDragger::killDropWindow()
+{
+ if ( startGrab() )
+ killingDrop = TRUE;
+}
+
+void QDragger::killDropWindow( DropInfo *di )
+{
+ const QObjectList *l = di->w->children();
+ if ( !l )
+ return;
+ QObjectListIt iter( *l );
+ QObject *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if ( tmp->isWidgetType() ) {
+ DraggedInfo *dri = draggedDict.find( (long) tmp );
+ if ( dri ) {
+ sendChildHome( dri );
+ draggedDict.remove( (long) tmp );
+ }
+ }
+ }
+ di->w->hide();
+}
+
+void QDragger::killAllDropWindows()
+{
+ killAllDropWindows( FALSE );
+}
+
+void QDragger::killAllDropWindows( bool autoOnly )
+{
+ QIntDictIterator<DropInfo> iter( dropDict );
+
+ DropInfo *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if( !autoOnly || !tmp->userOpened ) {
+ killDropWindow( tmp );
+ dropDict.remove( (long) tmp->w );
+ }
+ }
+}
+
+void QDragger::sendChildHome( DraggedInfo *i )
+{
+ i->w->reparent( i->mother, 0, i->pos, TRUE );
+}
+
+void QDragger::sendChildHome()
+{
+ if ( startGrab() )
+ sendingChild = TRUE;
+}
+
+void QDragger::sendAllChildrenHome()
+{
+ QIntDictIterator<DraggedInfo> iter( draggedDict );
+
+ DraggedInfo *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ sendChildHome( tmp );
+ draggedDict.remove( (long) tmp->w );
+ }
+ killAllDropWindows( TRUE );
+ draggedDict.clear();
+}
+
+
+QWidget *cursorWidget( QPoint *p )
+{
+ QPoint curpos = QCursor::pos();
+ if ( p )
+ *p = curpos;
+ return QApplication::widgetAt( curpos );
+}
+
+
+#include "qdragapp.moc"