summaryrefslogtreecommitdiffstats
path: root/examples/tetrix/tqdragapp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/tetrix/tqdragapp.cpp')
-rw-r--r--examples/tetrix/tqdragapp.cpp502
1 files changed, 502 insertions, 0 deletions
diff --git a/examples/tetrix/tqdragapp.cpp b/examples/tetrix/tqdragapp.cpp
new file mode 100644
index 000000000..014583a29
--- /dev/null
+++ b/examples/tetrix/tqdragapp.cpp
@@ -0,0 +1,502 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for TQt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "tqdragapp.h"
+#include "tqptrlist.h"
+#include "ntqintdict.h"
+#include "tqpopupmenu.h"
+#include "ntqguardedptr.h"
+#include "ntqcolor.h"
+#include "tqwidget.h"
+#include "ntqfontmetrics.h"
+#include "ntqcursor.h"
+#include "tqobjectlist.h"
+
+TQWidget *cursorWidget( TQPoint * = 0 );
+
+class TQDragger;
+
+
+class DropWindow : public TQWidget
+{
+ TQ_OBJECT
+public:
+ void paintEvent( TQPaintEvent * );
+ void closeEvent( TQCloseEvent * );
+
+ TQDragger *master;
+};
+
+
+struct DropInfo {
+ DropInfo() { w=0; }
+ ~DropInfo() { delete w; }
+ DropWindow *w;
+ bool userOpened;
+};
+
+struct DraggedInfo {
+ TQWidget *w;
+ TQWidget *mother;
+ TQPoint pos;
+};
+
+
+class TQDragger : public TQObject
+{
+ TQ_OBJECT
+public:
+ TQDragger();
+ ~TQDragger();
+
+ bool notify( TQObject *, TQEvent * ); // event filter
+ void closeDropWindow( DropWindow * );
+public slots:
+ void openDropWindow();
+ void killDropWindow();
+ void killAllDropWindows();
+ void sendChildHome();
+ void sendAllChildrenHome();
+private:
+ bool isParentToDragged( TQWidget * );
+ bool noWidgets( TQWidget * );
+ void killDropWindow( DropInfo * );
+ void killAllDropWindows( bool );
+ void sendChildHome( DraggedInfo * );
+ void sendAllChildrenHome( TQWidget * );
+ TQWidget *openDropWindow( const TQRect&, bool );
+
+ bool startGrab();
+ void grabFinished();
+ bool dragEvent( TQWidget *, TQMouseEvent * );
+ bool killDropEvent( TQMouseEvent * );
+ bool sendChildEvent( TQMouseEvent * );
+
+ bool killingDrop;
+ bool sendingChild;
+ TQWidget *clickedWidget;
+ TQGuardedPtr<TQWidget> hostWidget;
+ TQCursor cursor;
+
+ TQPopupMenu* menu;
+ TQPoint clickOffset;
+ TQColor dragBackground;
+ TQColor dragForeground;
+ DraggedInfo dragInfo;
+ TQIntDict<DraggedInfo> draggedDict;
+ TQIntDict<DropInfo> dropDict;
+};
+
+
+TQDragApplication::TQDragApplication( int &argc, char **argv )
+ : TQApplication( argc, argv ), dragger( 0 )
+{
+ dragger = new TQDragger;
+}
+
+TQDragApplication::~TQDragApplication()
+{
+ delete dragger;
+}
+
+bool TQDragApplication::notify( TQObject *o, TQEvent *e )
+{
+ if ( dragger && !dragger->notify( o, e ) )
+ return TQApplication::notify( o, e );
+ else
+ return FALSE;
+}
+
+void DropWindow::paintEvent( TQPaintEvent * )
+{
+ 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( TQCloseEvent *e )
+{
+ master->closeDropWindow( this );
+ e->ignore();
+}
+
+TQDragger::TQDragger()
+{
+ dragInfo.w = 0;
+ killingDrop = FALSE;
+ sendingChild = FALSE;
+ draggedDict.setAutoDelete( TRUE );
+ dropDict .setAutoDelete( TRUE );
+
+ menu = new TQPopupMenu;
+ 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, TQ_SLOT(openDropWindow()) );
+ menu->connectItem( 2, this, TQ_SLOT(killDropWindow()) );
+ menu->connectItem( 3, this, TQ_SLOT(killAllDropWindows()) );
+// menu->connectItem( 4, this, TQ_SLOT(sendChildHome()) );
+ menu->connectItem( 5, this, TQ_SLOT(sendAllChildrenHome()) );
+}
+
+TQDragger::~TQDragger()
+{
+ delete menu;
+}
+
+
+bool TQDragger::notify( TQObject *o, TQEvent *e )
+{
+ if ( !o->isWidgetType() || o == menu )
+ return FALSE;
+ switch( e->type() ) {
+ case TQEvent::MouseMove:
+ {
+ TQMouseEvent *tmp = (TQMouseEvent*) e;
+ if ( killingDrop )
+ return killDropEvent( tmp );
+ if ( sendingChild )
+ return sendChildEvent( tmp );
+ if ( tmp->state() & TQMouseEvent::RightButton )
+ return dragEvent( (TQWidget*) o, tmp );
+ break;
+ }
+ case TQEvent::MouseButtonPress:
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseButtonDblClick:
+ {
+ TQMouseEvent *tmp = (TQMouseEvent*) e;
+ if ( killingDrop )
+ return killDropEvent( tmp );
+ if ( sendingChild )
+ return sendChildEvent( tmp );
+ if ( tmp->button() == TQMouseEvent::RightButton )
+ return dragEvent( (TQWidget*) o, tmp );
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+bool TQDragger::isParentToDragged( TQWidget *w )
+{
+ TQIntDictIterator<DraggedInfo> iter( draggedDict );
+
+ DraggedInfo *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if ( tmp->mother == w )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool TQDragger::noWidgets( TQWidget *w )
+{
+ const TQObjectList *l = w->children();
+ if ( !l )
+ return TRUE;
+ TQObjectListIt iter( *l );
+ TQObject *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if ( tmp->isWidgetType() )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void TQDragger::sendAllChildrenHome( TQWidget *w )
+{
+ const TQObjectList *l = w->children();
+ if ( !l )
+ return;
+ TQObjectListIt iter( *l );
+ TQObject *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if ( tmp->isWidgetType() ) {
+ sendAllChildrenHome( (TQWidget*) tmp );
+ DraggedInfo *di = draggedDict.find( (long) tmp );
+ if ( di )
+ sendChildHome( di );
+ }
+ }
+}
+
+bool TQDragger::dragEvent( TQWidget *w, TQMouseEvent *e )
+{
+ switch( e->type() ) {
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::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;
+ TQPoint p = w->mapToGlobal(TQPoint(0,0));
+ w->reparent( 0, WType_Popup, p, TRUE );
+
+ return TRUE;
+ }
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseMove: {
+ if ( dragInfo.w != 0 ) {
+ TQPoint p = TQCursor::pos() - clickOffset;
+ dragInfo.w->move( p );
+ if ( e->type() == TQEvent::MouseMove )
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ if ( !dragInfo.w )
+ return FALSE;
+ if ( w != dragInfo.w )
+ w = dragInfo.w;
+ dragInfo.w = 0;
+ w->hide();
+ TQPoint pos;
+ TQWidget *target = cursorWidget( &pos );
+ pos = pos - clickOffset;
+ TQPoint p;
+ if ( !target ) {
+ target = openDropWindow( TQRect( pos, w->size() ),
+ FALSE);
+ p = TQPoint( 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 TQDragger::killDropEvent( TQMouseEvent *e )
+{
+ switch( e->type() ) {
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseButtonPress:
+ clickedWidget = cursorWidget();
+ return TRUE;
+ case TQEvent::MouseButtonRelease:
+ hostWidget->releaseMouse();
+ if ( clickedWidget ) {
+ DropInfo *tmp = dropDict.find( (long) clickedWidget );
+ if( tmp ) {
+ killDropWindow( tmp );
+ dropDict.remove( (long) tmp->w );
+ }
+ }
+ grabFinished();
+ return TRUE;
+ case TQEvent::MouseMove:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+bool TQDragger::sendChildEvent( TQMouseEvent *e )
+{
+ switch( e->type() ) {
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseButtonPress:
+ clickedWidget = cursorWidget();
+ return TRUE;
+ case TQEvent::MouseButtonRelease:
+ hostWidget->releaseMouse();
+ if ( clickedWidget ) {
+ DraggedInfo *tmp = draggedDict.find((long) clickedWidget);
+ if( tmp ) {
+ TQWidget *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 TQEvent::MouseMove:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+bool TQDragger::startGrab()
+{
+ if ( !hostWidget )
+ return FALSE;
+ clickedWidget = 0;
+ cursor = hostWidget->cursor();
+ hostWidget->grabMouse();
+ hostWidget->setCursor( TQCursor( CrossCursor ) );
+ return TRUE;
+}
+
+void TQDragger::grabFinished()
+{
+ killingDrop = FALSE;
+ sendingChild = FALSE;
+ if(hostWidget)
+ hostWidget->setCursor( cursor );
+}
+
+void TQDragger::closeDropWindow( DropWindow *w )
+{
+ DropInfo *tmp = dropDict.find( (long) w);
+ if( tmp )
+ killDropWindow( tmp );
+}
+
+void TQDragger::openDropWindow()
+{
+ TQWidget *tmp = openDropWindow( TQRect(100, 100, 300, 200), TRUE );
+ tmp->show();
+}
+
+TQWidget *TQDragger::openDropWindow( const TQRect &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 TQDragger::killDropWindow()
+{
+ if ( startGrab() )
+ killingDrop = TRUE;
+}
+
+void TQDragger::killDropWindow( DropInfo *di )
+{
+ const TQObjectList *l = di->w->children();
+ if ( !l )
+ return;
+ TQObjectListIt iter( *l );
+ TQObject *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 TQDragger::killAllDropWindows()
+{
+ killAllDropWindows( FALSE );
+}
+
+void TQDragger::killAllDropWindows( bool autoOnly )
+{
+ TQIntDictIterator<DropInfo> iter( dropDict );
+
+ DropInfo *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ if( !autoOnly || !tmp->userOpened ) {
+ killDropWindow( tmp );
+ dropDict.remove( (long) tmp->w );
+ }
+ }
+}
+
+void TQDragger::sendChildHome( DraggedInfo *i )
+{
+ i->w->reparent( i->mother, 0, i->pos, TRUE );
+}
+
+void TQDragger::sendChildHome()
+{
+ if ( startGrab() )
+ sendingChild = TRUE;
+}
+
+void TQDragger::sendAllChildrenHome()
+{
+ TQIntDictIterator<DraggedInfo> iter( draggedDict );
+
+ DraggedInfo *tmp;
+ while( (tmp = iter.current()) ) {
+ ++iter;
+ sendChildHome( tmp );
+ draggedDict.remove( (long) tmp->w );
+ }
+ killAllDropWindows( TRUE );
+ draggedDict.clear();
+}
+
+
+TQWidget *cursorWidget( TQPoint *p )
+{
+ TQPoint curpos = TQCursor::pos();
+ if ( p )
+ *p = curpos;
+ return TQApplication::widgetAt( curpos );
+}
+
+
+#include "tqdragapp.moc"