summaryrefslogtreecommitdiffstats
path: root/examples/tetrix
diff options
context:
space:
mode:
Diffstat (limited to 'examples/tetrix')
-rw-r--r--examples/tetrix/README28
-rw-r--r--examples/tetrix/gtetrix.cpp502
-rw-r--r--examples/tetrix/gtetrix.h92
-rw-r--r--examples/tetrix/qdragapp.cpp502
-rw-r--r--examples/tetrix/qdragapp.h31
-rw-r--r--examples/tetrix/qtetrix.cpp176
-rw-r--r--examples/tetrix/qtetrix.h74
-rw-r--r--examples/tetrix/qtetrixb.cpp241
-rw-r--r--examples/tetrix/qtetrixb.h69
-rw-r--r--examples/tetrix/tetrix.cpp24
-rw-r--r--examples/tetrix/tetrix.doc15
-rw-r--r--examples/tetrix/tetrix.pro19
-rw-r--r--examples/tetrix/tpiece.cpp180
-rw-r--r--examples/tetrix/tpiece.h50
14 files changed, 2003 insertions, 0 deletions
diff --git a/examples/tetrix/README b/examples/tetrix/README
new file mode 100644
index 000000000..869c2dbfb
--- /dev/null
+++ b/examples/tetrix/README
@@ -0,0 +1,28 @@
+ Oslo, May 14 1995
+
+This code was written to test the very first Qt skeleton. It was in
+fact the first Qt application and was written at a time when Qt only
+had pushbutton widgets and the drawing engine was limited to drawing
+text in a single font and drawing lines (no kidding, those were the
+only two drawing operations). In fact the tetrix project doubled the
+number of widgets in Qt by introducing the QLCDNumber widget. The whole
+application was written in 5 evenings and 1 weekend and is not very
+well documented. The tetrix engine is implemented in the GenericTetrix
+class and was first made on my good old 10 MHZ AT where I made a DOS
+text-mode Tetrix (using about 50 lines) to test it out, it was later
+moved to a SUN Sparc 10, where it met Qt. GenericTetrix is totally
+independent of Qt, feel free to use it in any way you like. (see the
+file gtetrix.h for a brief description of how to use it)
+
+Enjoy!
+
+ Eirik Eng
+ -----
+
+P.S. Tetrix has later been updated to show new versions of Qt.
+
+P.P.S The tetrix program uses a special application object called
+ QDragApplication. Try to guess what it does.
+ Hint: Try pressing the right mouse button somewhere in the
+ tetrix window and start dragging....
+
diff --git a/examples/tetrix/gtetrix.cpp b/examples/tetrix/gtetrix.cpp
new file mode 100644
index 000000000..92b946b44
--- /dev/null
+++ b/examples/tetrix/gtetrix.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 "gtetrix.h"
+
+#include <string.h>
+
+GenericTetrix::GenericTetrix(int boardWidth,int boardHeight)
+{
+ int i,j;
+
+ width = boardWidth;
+ height = boardHeight;
+ boardPtr = new int[height*width]; // Note the order, this makes it easier
+ // to remove full lines.
+ for(i = 0 ; i < height ; i++)
+ for(j = 0 ; j < width ; j++)
+ board(j,i) = 0;
+ currentLine = -1; // -1 if no falling piece.
+ currentPos = 0;
+ showNext = 0; // FALSE
+ nLinesRemoved = 0;
+ nPiecesDropped = 0;
+ score = 0;
+ level = 1;
+ gameID = 0;
+ nClearLines = height;
+}
+
+GenericTetrix::~GenericTetrix()
+{
+ delete[] boardPtr;
+}
+
+
+void GenericTetrix::clearBoard(int fillRandomLines)
+{
+ int i,j;
+
+ if (fillRandomLines >= height)
+ fillRandomLines = height - 1;
+
+ erasePiece();
+ for(i = height - nClearLines - 1 ; i >= fillRandomLines ; i--)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0) {
+ draw(j,i,0);
+ board(j,i) = 0;
+ }
+ if (fillRandomLines != 0)
+ for (i = 0 ; i < fillRandomLines ; i++) {
+ fillRandom(i);
+ }
+ nClearLines = height - fillRandomLines;
+}
+
+void GenericTetrix::showBoard()
+{
+ int i,j;
+
+ showPiece();
+ for(i = height - nClearLines - 1 ; i >= 0 ; i--)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0)
+ draw(j,i,board(j,i));
+}
+
+void GenericTetrix::hideBoard()
+{
+ int i,j;
+
+ erasePiece();
+ for(i = height - nClearLines - 1 ; i >= 0 ; i--)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0)
+ draw(j,i,0);
+}
+
+void GenericTetrix::startGame(int gameType,int fillRandomLines)
+{
+ gameID = gameType;
+ clearBoard(fillRandomLines);
+ nLinesRemoved = 0;
+ updateRemoved(nLinesRemoved);
+ nClearLines = height;
+ nPiecesDropped = 0;
+ score = 0;
+ updateScore(score);
+ level = 1;
+ updateLevel(level);
+ newPiece();
+}
+
+void GenericTetrix::revealNextPiece(int revealIt)
+{
+ if (showNext == revealIt)
+ return;
+ showNext = revealIt;
+ if (!showNext)
+ eraseNextPiece();
+ else
+ showNextPiece();
+}
+
+void GenericTetrix::updateBoard(int x1,int y1,int x2, int y2,
+ int dontUpdateBlanks)
+{
+ int i,j;
+ int tmp;
+
+ if (x1 > x2) {
+ tmp = x2;
+ x2 = x1;
+ x1 = tmp;
+ }
+ if (y1 > y2) {
+ tmp = y2;
+ y2 = y1;
+ y1 = tmp;
+ }
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 >= width)
+ x2 = width - 1;
+ if (y1 < 0)
+ y1 = 0;
+ if (y2 >= height)
+ y2 = height - 1;
+ for(i = y1 ; i <= y2 ; i++)
+ for(j = x1 ; j <= x2 ; j++)
+ if (!dontUpdateBlanks || board(j,height - i - 1) != 0)
+ draw(j,height - i - 1,board(j,height - i - 1));
+ showPiece(); // Remember to update piece correctly!!!!
+}
+
+
+void GenericTetrix::fillRandom(int line)
+{
+ int i,j;
+ int holes;
+
+ for(i = 0 ; i < width ; i++)
+ board(i,line) = TetrixPiece::randomValue(7);
+ holes = 0;
+ for(i = 0 ; i < width ; i++)
+ if (board(i,line) == 0) // Count holes in the line.
+ holes++;
+ if (holes == 0) // Full line, make a random hole:
+ board(TetrixPiece::randomValue(width),line) = 0;
+ if (holes == width) // Empty line, make a random square:
+ board(TetrixPiece::randomValue(width),line) =
+ TetrixPiece::randomValue(6) + 1;
+ for(j = 0 ; j < width ; j++)
+ draw(j,i,board(j,i));
+}
+
+void GenericTetrix::moveLeft(int steps)
+{
+ while(steps) {
+ if (!canMoveTo(currentPos - 1,currentLine))
+ return;
+ moveTo(currentPos - 1,currentLine);
+ steps--;
+ }
+}
+
+void GenericTetrix::moveRight(int steps)
+{
+ while(steps) {
+ if (!canMoveTo(currentPos + 1,currentLine))
+ return;
+ moveTo(currentPos + 1,currentLine);
+ steps--;
+ }
+}
+
+void GenericTetrix::rotateLeft()
+{
+ TetrixPiece tmp(currentPiece);
+
+ tmp.rotateLeft();
+ if (!canPosition(tmp))
+ return;
+ position(tmp);
+ currentPiece = tmp;
+}
+
+void GenericTetrix::rotateRight()
+{
+ TetrixPiece tmp(currentPiece);
+
+ tmp.rotateRight();
+ if (!canPosition(tmp))
+ return;
+ position(tmp);
+ currentPiece = tmp;
+}
+
+void GenericTetrix::dropDown()
+{
+ if (currentLine == -1)
+ return;
+
+ int dropHeight = 0;
+ int newLine = currentLine;
+ while(newLine) {
+ if (!canMoveTo(currentPos,newLine - 1))
+ break;
+ newLine--;
+ dropHeight++;
+ }
+ if (dropHeight != 0)
+ moveTo(currentPos,newLine);
+ internalPieceDropped(dropHeight);
+}
+
+void GenericTetrix::oneLineDown()
+{
+ if (currentLine == -1)
+ return;
+ if (canMoveTo(currentPos,currentLine - 1)) {
+ moveTo(currentPos,currentLine - 1);
+ } else {
+ internalPieceDropped(0);
+ }
+}
+
+void GenericTetrix::newPiece()
+{
+ currentPiece = nextPiece;
+ if (showNext)
+ eraseNextPiece();
+ nextPiece.setRandomType();
+ if (showNext)
+ showNextPiece();
+ currentLine = height - 1 + currentPiece.getMinY();
+ currentPos = width/2 + 1;
+ if (!canMoveTo(currentPos,currentLine)) {
+ currentLine = -1;
+ gameOver();
+ } else {
+ showPiece();
+ }
+}
+
+void GenericTetrix::removePiece()
+{
+ erasePiece();
+ currentLine = -1;
+}
+
+void GenericTetrix::drawNextSquare(int,int,int)
+{
+
+}
+
+void GenericTetrix::pieceDropped(int)
+{
+ newPiece();
+}
+
+void GenericTetrix::updateRemoved(int)
+{
+}
+
+void GenericTetrix::updateScore(int)
+{
+}
+
+void GenericTetrix::updateLevel(int)
+{
+}
+
+void GenericTetrix::removeFullLines()
+{
+ int i,j,k;
+ int nFullLines;
+
+ for(i = 0 ; i < height - nClearLines ; i++) {
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) == 0)
+ break;
+ if (j == width) {
+ nFullLines = 1;
+ for(k = i + 1 ; k < height - nClearLines ; k++) {
+ for(j = 0 ; j < width ; j++)
+ if (board(j,k) == 0)
+ break;
+ if (j == width) {
+ nFullLines++;
+ } else {
+ for(j = 0 ; j < width ; j++) {
+ if (board(j,k - nFullLines) != board(j,k)) {
+ board(j,k - nFullLines) = board(j,k);
+ draw( j,k - nFullLines,
+ board(j,k - nFullLines));
+ }
+ }
+ }
+ }
+ nClearLines = nClearLines + nFullLines;
+ nLinesRemoved = nLinesRemoved + nFullLines;
+ updateRemoved(nLinesRemoved);
+ score = score + 10*nFullLines; // updateScore must be
+ // called by caller!
+ for (i = height - nClearLines ;
+ i < height - nClearLines + nFullLines ;
+ i++)
+ for(j = 0 ; j < width ; j++)
+ if (board(j,i) != 0) {
+ draw(j,i,0);
+ board(j,i) = 0;
+ }
+ }
+ }
+}
+
+void GenericTetrix::showPiece()
+{
+ int x,y;
+
+ if (currentLine == -1)
+ return;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ draw(currentPos + x,currentLine - y,currentPiece.getType());
+ }
+}
+
+void GenericTetrix::erasePiece()
+{
+ int x,y;
+
+ if (currentLine == -1)
+ return;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ draw(currentPos + x,currentLine - y,0);
+ }
+}
+
+void GenericTetrix::internalPieceDropped(int dropHeight)
+{
+ gluePiece();
+ nPiecesDropped++;
+ if (nPiecesDropped % 25 == 0) {
+ level++;
+ updateLevel(level);
+ }
+ score = score + 7 + dropHeight;
+ removeFullLines();
+ updateScore(score);
+ pieceDropped(dropHeight);
+}
+
+void GenericTetrix::gluePiece()
+{
+ int x,y;
+ int min;
+
+ if (currentLine == -1)
+ return;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ board(currentPos + x,currentLine - y) = currentPiece.getType();
+ }
+ min = currentPiece.getMinY();
+ if (currentLine - min >= height - nClearLines)
+ nClearLines = height - currentLine + min - 1;
+}
+
+void GenericTetrix::showNextPiece(int erase)
+{
+ int x,y;
+ int minX = nextPiece.getMinX();
+ int minY = nextPiece.getMinY();
+ int maxX = nextPiece.getMaxX();
+ int maxY = nextPiece.getMaxY();
+
+ int xOffset = (3 - (maxX - minX))/2;
+ int yOffset = (3 - (maxY - minY))/2;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ nextPiece.getCoord(i,x,y);
+ if (erase)
+ drawNextSquare(x + xOffset - minX,
+ y + yOffset - minY,0);
+ else
+ drawNextSquare(x + xOffset - minX,
+ y + yOffset - minY,nextPiece.getType());
+ }
+}
+
+int GenericTetrix::canPosition(TetrixPiece &piece)
+{
+ if (currentLine == -1)
+ return 0;
+
+ int x,y;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ piece.getCoord(i,x,y);
+ x = currentPos + x;
+ y = currentLine - y; // Board and pieces have inverted y-coord. systems.
+ if (x < 0 || x >= width || y < 0 || y >= height)
+ return 0; // Outside board, cannot put piece here.
+ if (board(x,y) != 0)
+ return 0; // Over a non-zero square, cannot put piece here.
+ }
+ return 1; // Inside board and no non-zero squares underneath.
+
+}
+
+int GenericTetrix::canMoveTo(int xPosition,int line)
+{
+ if (currentLine == -1)
+ return 0;
+
+ int x,y;
+
+ for(int i = 0 ; i < 4 ; i++) {
+ currentPiece.getCoord(i,x,y);
+ x = xPosition + x;
+ y = line - y; // Board and pieces have inverted y-coord. systems.
+ if (x < 0 || x >= width || y < 0 || y >= height)
+ return 0; // Outside board, cannot put piece here.
+ if (board(x,y) != 0)
+ return 0; // Over a non-zero square, cannot put piece here.
+ }
+ return 1; // Inside board and no non-zero squares underneath.
+}
+
+void GenericTetrix::moveTo(int xPosition,int line)
+{
+ if (currentLine == -1)
+ return;
+ optimizedMove(xPosition,line,currentPiece);
+ currentPos = xPosition;
+ currentLine = line;
+}
+
+void GenericTetrix::position(TetrixPiece &piece)
+{
+ if (currentLine == -1)
+ return;
+
+ optimizedMove(currentPos,currentLine,piece);
+}
+
+void GenericTetrix::optimizedMove(int newPos, int newLine,
+ TetrixPiece &newPiece)
+{
+ int updates [8][3];
+ int nUpdates;
+ int value;
+ int x,y;
+ int i,j;
+
+ for(i = 0 ; i < 4 ; i++) { // Put the erasing coords into updates
+ currentPiece.getCoord(i,x,y);
+ updates[i][0] = currentPos + x;
+ updates[i][1] = currentLine - y;
+ updates[i][2] = 0;
+ }
+ nUpdates = 4;
+ for(i = 0 ; i < 4 ; i++) { // Any drawing coord same as an erasing one?
+ newPiece.getCoord(i,x,y);
+ x = newPos + x;
+ y = newLine - y;
+ for (j = 0 ; j < 4 ; j++)
+ if (updates[j][0] == x && updates[j][1] == y) { // Same coord,
+ // don't have to erase
+ if (currentPiece.getType() == newPiece.getType())
+ updates[j][2] = -1; // Correct on screen, no update!
+ else
+ updates[j][2] = newPiece.getType();
+ break;
+ }
+ if (j == 4) { // This coord does not overlap an erasing one
+ updates[nUpdates][0] = x;
+ updates[nUpdates][1] = y;
+ updates[nUpdates][2] = newPiece.getType();
+ nUpdates++;
+ }
+ }
+ for (i = 0 ; i < nUpdates ; i++) { // Do the updating
+ x = updates[i][0];
+ y = updates[i][1];
+ value = updates[i][2];
+ if (value != -1) // Only update if new value != current
+ draw(x,y,value);
+ }
+}
diff --git a/examples/tetrix/gtetrix.h b/examples/tetrix/gtetrix.h
new file mode 100644
index 000000000..170def596
--- /dev/null
+++ b/examples/tetrix/gtetrix.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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.
+**
+*****************************************************************************/
+
+#ifndef GTETRIX_H
+#define GTETRIX_H
+
+#include "tpiece.h"
+
+
+class GenericTetrix
+{
+public:
+ GenericTetrix(int boardWidth = 10,int boardHeight = 22);
+ virtual ~GenericTetrix();
+
+ void clearBoard(int fillRandomLines = 0);
+ void revealNextPiece(int revealIt);
+ void updateBoard(int x1,int y1,int x2,int y2,int dontUpdateBlanks = 0);
+ void updateNext(){if (showNext) showNextPiece();}
+ void hideBoard();
+ void showBoard();
+ void fillRandom(int line);
+
+ void moveLeft(int steps = 1);
+ void moveRight(int steps = 1);
+ void rotateLeft();
+ void rotateRight();
+ void dropDown();
+ void oneLineDown();
+ void newPiece();
+ void removePiece();
+
+ int noOfClearLines() {return nClearLines;}
+ int getLinesRemoved() {return nLinesRemoved;}
+ int getPiecesDropped() {return nPiecesDropped;}
+ int getScore() {return score;}
+ int getLevel() {return level;}
+ int boardHeight() {return height;}
+ int boardWidth() {return width;}
+
+ virtual void drawSquare(int x,int y,int value) = 0;
+ virtual void gameOver() = 0;
+
+ virtual void startGame(int gameType = 0,int fillRandomLines = 0);
+ virtual void drawNextSquare(int x,int y,int value);
+ virtual void pieceDropped(int dropHeight);
+ virtual void updateRemoved(int noOfLines);
+ virtual void updateScore(int newScore);
+ virtual void updateLevel(int newLevel);
+
+private:
+ void draw(int x, int y, int value){drawSquare(x,height - y,value);}
+ void removeFullLines();
+ void removeLine(int line);
+ void showPiece();
+ void erasePiece();
+ void internalPieceDropped(int dropHeight);
+ void gluePiece();
+ void showNextPiece(int erase = 0);
+ void eraseNextPiece(){showNextPiece(1);};
+ int canPosition(TetrixPiece &piece); // Returns a boolean value.
+ int canMoveTo(int xPosition, int line); // Returns a boolean value.
+ void moveTo(int xPosition,int line);
+ void position(TetrixPiece &piece);
+ void optimizedMove(int newPos, int newLine,TetrixPiece &newPiece);
+
+ int &board(int x,int y){return boardPtr[width*y + x];}
+
+ TetrixPiece currentPiece;
+ TetrixPiece nextPiece;
+ int currentLine;
+ int currentPos;
+ int showNext; // Boolean variable.
+ int nLinesRemoved;
+ int nPiecesDropped;
+ int score;
+ int level;
+ int gameID;
+ int nClearLines;
+ int width;
+ int height;
+ int *boardPtr;
+};
+
+
+#endif
diff --git a/examples/tetrix/qdragapp.cpp b/examples/tetrix/qdragapp.cpp
new file mode 100644
index 000000000..409d418b3
--- /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 TQt. 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"
+
+TQWidget *cursorWidget( TQPoint * = 0 );
+
+class TQDragger;
+
+
+class DropWindow : public TQWidget
+{
+ Q_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
+{
+ Q_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, 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()) );
+}
+
+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 "qdragapp.moc"
diff --git a/examples/tetrix/qdragapp.h b/examples/tetrix/qdragapp.h
new file mode 100644
index 000000000..f0334b829
--- /dev/null
+++ b/examples/tetrix/qdragapp.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** 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.
+**
+*****************************************************************************/
+
+#ifndef TQDRAGAPP_H
+#define TQDRAGAPP_H
+
+#include "qapplication.h"
+
+class TQDragger;
+
+class TQDragApplication : public TQApplication
+{
+ Q_OBJECT
+public:
+ TQDragApplication( int &argc, char **argv );
+ virtual ~TQDragApplication();
+
+ virtual bool notify( TQObject *, TQEvent * ); // event filter
+
+private:
+ TQDragger *dragger;
+};
+
+
+#endif // TQDRAGAPP_H
diff --git a/examples/tetrix/qtetrix.cpp b/examples/tetrix/qtetrix.cpp
new file mode 100644
index 000000000..68b49c254
--- /dev/null
+++ b/examples/tetrix/qtetrix.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** 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 "qtetrix.h"
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qdatetime.h>
+
+
+void drawTetrixButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColor *color, TQWidget *widg)
+{
+ if ( color ) {
+ TQPointArray a;
+ a.setPoints( 3, x,y+h-1, x,y, x+w-1,y );
+ p->setPen( color->light() );
+ p->drawPolyline( a );
+ a.setPoints( 3, x+1,y+h-1, x+w-1,y+h-1, x+w-1,y+1 );
+ p->setPen( color->dark() );
+ p->drawPolyline( a );
+ x++;
+ y++;
+ w -= 2;
+ h -= 2;
+ p->fillRect( x, y, w, h, *color );
+ }
+ else if(widg) {
+ widg->erase(x, y, w, h);
+ } else {
+ p->fillRect(x, y, w, h, p->backgroundColor());
+ }
+}
+
+
+ShowNextPiece::ShowNextPiece( TQWidget *parent, const char *name )
+ : TQFrame( parent, name )
+{
+ setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
+ xOffset = -1; // -1 until first resizeEvent.
+}
+
+void ShowNextPiece::resizeEvent( TQResizeEvent *e )
+{
+ TQSize sz = e->size();
+ blockWidth = (sz.width() - 3)/5;
+ blockHeight = (sz.height() - 3)/6;
+ xOffset = (sz.width() - 3)/5;
+ yOffset = (sz.height() - 3)/6;
+}
+
+
+void ShowNextPiece::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+ drawFrame( &p );
+ p.end(); // explicit end() so any slots can paint too
+ emit update();
+}
+
+
+void ShowNextPiece::drawNextSquare(int x, int y,TQColor *color)
+{
+ if (xOffset == -1) // Before first resizeEvent?
+ return;
+
+ TQPainter paint;
+ paint.begin(this);
+ drawTetrixButton( &paint, xOffset+x*blockWidth, yOffset+y*blockHeight,
+ blockWidth, blockHeight, color, this );
+ paint.end();
+}
+
+
+TQTetrix::TQTetrix( TQWidget *parent, const char *name )
+ : TQWidget( parent, name )
+{
+ TQTime t = TQTime::currentTime();
+ TetrixPiece::setRandomSeed( (((double)t.hour())+t.minute()+t.second())/
+ (24+60+60) );
+
+#define ADD_LABEL( str, x, y, w, h ) \
+ { TQLabel *label = new TQLabel(str,this); \
+ label->setGeometry(x,y,w,h); \
+ label->setAlignment(AlignCenter|AlignVCenter); }
+
+ ADD_LABEL( "NEXT", 50, 10, 78, 30 );
+ ADD_LABEL( "SCORE", 330, 10, 178, 30 );
+ ADD_LABEL( "LEVEL", 50, 130, 78, 30 );
+ ADD_LABEL( "LINES REMOVED", 330, 130, 178, 30 );
+
+ board = new TQTetrixBoard(this);
+ showNext = new ShowNextPiece(this);
+#ifndef QT_NO_LCDNUMBER
+ showScore = new TQLCDNumber(5,this);
+ showLevel = new TQLCDNumber(2,this);
+ showLines = new TQLCDNumber(5,this);
+#else
+ showScore = new TQLabel("0",this);
+ showLevel = new TQLabel("0",this);
+ showLines = new TQLabel("0",this);
+ showScore->setAlignment(AlignCenter);
+ showLines->setAlignment(AlignCenter);
+ showLevel->setAlignment(AlignCenter);
+ showScore->setFrameStyle(TQFrame::Sunken|TQFrame::Box);
+ showLines->setFrameStyle(TQFrame::Sunken|TQFrame::Box);
+ showLevel->setFrameStyle(TQFrame::Sunken|TQFrame::Box);
+#endif
+ tquitButton = new TQPushButton("&Quit",this);
+ startButton = new TQPushButton("&New Game",this);
+ pauseButton = new TQPushButton("&Pause",this);
+
+ // Don't let the buttons get keyboard focus
+ tquitButton->setFocusPolicy( TQWidget::NoFocus );
+ startButton->setFocusPolicy( TQWidget::NoFocus );
+ pauseButton->setFocusPolicy( TQWidget::NoFocus );
+
+ connect( board, SIGNAL(gameOverSignal()), SLOT(gameOver()) );
+ connect( board, SIGNAL(drawNextSquareSignal(int,int,TQColor*)), showNext,
+ SLOT(drawNextSquare(int,int,TQColor*)) );
+ connect( showNext, SIGNAL(update()), board, SLOT(updateNext()) );
+#ifndef QT_NO_LCDNUMBER
+ connect( board, SIGNAL(updateScoreSignal(int)), showScore,
+ SLOT(display(int)) );
+ connect( board, SIGNAL(updateLevelSignal(int)), showLevel,
+ SLOT(display(int)));
+ connect( board, SIGNAL(updateRemovedSignal(int)), showLines,
+ SLOT(display(int)));
+#else
+ connect( board, SIGNAL(updateScoreSignal(int)), showScore,
+ SLOT(setNum(int)) );
+ connect( board, SIGNAL(updateLevelSignal(int)), showLevel,
+ SLOT(setNum(int)));
+ connect( board, SIGNAL(updateRemovedSignal(int)), showLines,
+ SLOT(setNum(int)));
+#endif
+ connect( startButton, SIGNAL(clicked()), board, SLOT(start()) );
+ connect( tquitButton , SIGNAL(clicked()), SLOT(tquit()));
+ connect( pauseButton, SIGNAL(clicked()), board, SLOT(pause()) );
+
+ board->setGeometry( 150, 20, 153, 333 );
+ showNext->setGeometry( 50, 40, 78, 94 );
+ showScore->setGeometry( 330, 40, 178, 93 );
+ showLevel->setGeometry( 50, 160, 78, 93 );
+ showLines->setGeometry( 330, 160, 178, 93 );
+#ifndef QT_NO_LCDNUMBER
+ showScore->display( 0 );
+ showLevel->display( 0 );
+ showLines->display( 0 );
+#else
+ showScore->setNum( 0 );
+ showLevel->setNum( 0 );
+ showLines->setNum( 0 );
+#endif
+ startButton->setGeometry( 46, 288, 90, 30 );
+ tquitButton->setGeometry( 370, 265, 90, 30 );
+ pauseButton->setGeometry( 370, 310, 90, 30 );
+ board->revealNextPiece(TRUE);
+
+ resize( 550, 370 );
+}
+
+void TQTetrix::gameOver()
+{
+}
+
+
+void TQTetrix::tquit()
+{
+ qApp->tquit();
+}
diff --git a/examples/tetrix/qtetrix.h b/examples/tetrix/qtetrix.h
new file mode 100644
index 000000000..36d8bd041
--- /dev/null
+++ b/examples/tetrix/qtetrix.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** 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.
+**
+*****************************************************************************/
+
+#ifndef TQTETRIX_H
+#define TQTETRIX_H
+
+#include "qtetrixb.h"
+#include <qframe.h>
+#include <qlcdnumber.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qpainter.h>
+
+
+class ShowNextPiece : public TQFrame
+{
+ Q_OBJECT
+ friend class TQTetrix;
+public:
+ ShowNextPiece( TQWidget *parent=0, const char *name=0 );
+public slots:
+ void drawNextSquare( int x, int y,TQColor *color );
+signals:
+ void update();
+private:
+ void paintEvent( TQPaintEvent * );
+ void resizeEvent( TQResizeEvent * );
+
+ int blockWidth,blockHeight;
+ int xOffset,yOffset;
+};
+
+
+class TQTetrix : public TQWidget
+{
+ Q_OBJECT
+public:
+ TQTetrix( TQWidget *parent=0, const char *name=0 );
+ void startGame() { board->startGame(); }
+
+public slots:
+ void gameOver();
+ void tquit();
+private:
+ void keyPressEvent( TQKeyEvent *e ) { board->keyPressEvent(e); }
+
+ TQTetrixBoard *board;
+ ShowNextPiece *showNext;
+#ifndef QT_NO_LCDNUMBER
+ TQLCDNumber *showScore;
+ TQLCDNumber *showLevel;
+ TQLCDNumber *showLines;
+#else
+ TQLabel *showScore;
+ TQLabel *showLevel;
+ TQLabel *showLines;
+#endif
+ TQPushButton *tquitButton;
+ TQPushButton *startButton;
+ TQPushButton *pauseButton;
+};
+
+
+void drawTetrixButton( TQPainter *, int x, int y, int w, int h,
+ const TQColor *color, TQWidget *widg);
+
+
+#endif
diff --git a/examples/tetrix/qtetrixb.cpp b/examples/tetrix/qtetrixb.cpp
new file mode 100644
index 000000000..26fd2c2d0
--- /dev/null
+++ b/examples/tetrix/qtetrixb.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** 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 "qtetrixb.h"
+#include "qtetrix.h"
+#include <qtimer.h>
+#include <qpainter.h>
+
+const int waitAfterLineTime = 500;
+
+TQTetrixBoard::TQTetrixBoard( TQWidget *p, const char *name )
+ : TQFrame( p, name )
+{
+ setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
+ paint = 0;
+ paint_widget = 0;
+ timer = new TQTimer(this);
+ connect( timer, SIGNAL(timeout()), SLOT(timeout()) );
+
+ colors[0].setRgb(200,100,100);
+ colors[1].setRgb(100,200,100);
+ colors[2].setRgb(100,100,200);
+ colors[3].setRgb(200,200,100);
+ colors[4].setRgb(200,100,200);
+ colors[5].setRgb(100,200,200);
+ colors[6].setRgb(218,170, 0);
+
+ xOffset = -1; // -1 until a resizeEvent is received.
+ blockWidth = 20;
+ yOffset = 30;
+ blockHeight = 20;
+ noGame = TRUE;
+ isPaused = FALSE;
+ waitingAfterLine = FALSE;
+ updateTimeoutTime(); // Sets timeoutTime
+}
+
+void TQTetrixBoard::startGame(int gameType,int fillRandomLines)
+{
+ if ( isPaused )
+ return; // ignore if game is paused
+ noGame = FALSE;
+ GenericTetrix::startGame( gameType, fillRandomLines );
+ // Note that the timer is started by updateLevel!
+}
+
+
+void TQTetrixBoard::pause()
+{
+ if ( noGame ) // game not active
+ return;
+ isPaused = !isPaused;
+ if ( isPaused ) {
+ timer->stop();
+ hideBoard();
+ }
+ else
+ timer->start(timeoutTime);
+ update();
+}
+
+
+void TQTetrixBoard::drawSquare(int x,int y,int value)
+{
+ if (xOffset == -1) // Before first resizeEvent?
+ return;
+
+ const int X = xOffset + x*blockWidth;
+ const int Y = yOffset + (y - 1)*blockHeight;
+
+ bool localPainter = paint == 0;
+ TQPainter *p;
+ TQWidget *w;
+ if ( localPainter ) {
+ p = new TQPainter( this );
+ w = this;
+ } else {
+ p = paint;
+ w = paint_widget;
+ }
+ drawTetrixButton( p, X, Y, blockWidth, blockHeight,
+ value == 0 ? 0 : &colors[value-1], w);
+ /*
+ if ( value != 0 ) {
+ TQColor tc, bc;
+ tc = colors[value-1].light();
+ bc = colors[value-1].dark();
+ p->drawShadePanel( X, Y, blockWidth, blockHeight,
+ tc, bc, 1, colors[value-1], TRUE );
+ }
+ else
+ p->fillRect( X, Y, blockWidth, blockHeight, backgroundColor() );
+ */
+ if ( localPainter )
+ delete p;
+}
+
+void TQTetrixBoard::drawNextSquare( int x, int y, int value )
+{
+ if ( value == 0 )
+ emit drawNextSquareSignal (x, y, 0 );
+ else
+ emit drawNextSquareSignal( x, y, &colors[value-1] );
+}
+
+void TQTetrixBoard::updateRemoved( int noOfLines )
+{
+ if ( noOfLines > 0 ) {
+ timer->stop();
+ timer->start( waitAfterLineTime );
+ waitingAfterLine = TRUE;
+ }
+ emit updateRemovedSignal( noOfLines );
+}
+
+void TQTetrixBoard::updateScore( int newScore )
+{
+ emit updateScoreSignal( newScore );
+}
+
+void TQTetrixBoard::updateLevel( int newLevel )
+{
+ timer->stop();
+ updateTimeoutTime();
+ timer->start( timeoutTime );
+ emit updateLevelSignal( newLevel );
+}
+
+void TQTetrixBoard::pieceDropped(int)
+{
+ if ( waitingAfterLine ) // give player a break if a line has been removed
+ return;
+ newPiece();
+}
+
+void TQTetrixBoard::gameOver()
+{
+ timer->stop();
+ noGame = TRUE;
+ emit gameOverSignal();
+}
+
+void TQTetrixBoard::timeout()
+{
+ if ( waitingAfterLine ) {
+ timer->stop();
+ waitingAfterLine = FALSE;
+ newPiece();
+ timer->start( timeoutTime );
+ } else {
+ oneLineDown();
+ }
+}
+
+void TQTetrixBoard::drawContents( TQPainter *p )
+{
+ const char *text = "Press \"Pause\"";
+ TQRect r = contentsRect();
+ paint = p; // set widget painter
+ if ( isPaused ) {
+ p->drawText( r, AlignCenter | AlignVCenter, text );
+ return;
+ }
+ int x1,y1,x2,y2;
+ x1 = (r.left() - xOffset) / blockWidth;
+ if (x1 < 0)
+ x1 = 0;
+ if (x1 >= boardWidth())
+ x1 = boardWidth() - 1;
+
+ x2 = (r.right() - xOffset) / blockWidth;
+ if (x2 < 0)
+ x2 = 0;
+ if (x2 >= boardWidth())
+ x2 = boardWidth() - 1;
+
+ y1 = (r.top() - yOffset) / blockHeight;
+ if (y1 < 0)
+ y1 = 0;
+ if (y1 >= boardHeight())
+ y1 = boardHeight() - 1;
+
+ y2 = (r.bottom() - yOffset) / blockHeight;
+ if (y2 < 0)
+ y2 = 0;
+ if (y2 >= boardHeight())
+ y2 = boardHeight() - 1;
+
+ updateBoard( x1, y1, x2, y2, TRUE );
+ paint = 0; // reset widget painter
+ return;
+}
+
+void TQTetrixBoard::resizeEvent(TQResizeEvent *e)
+{
+ TQSize sz = e->size();
+ blockWidth = (sz.width() - 3)/10;
+ blockHeight = (sz.height() - 3)/22;
+ xOffset = 1;
+ yOffset = 1;
+}
+
+void TQTetrixBoard::keyPressEvent( TQKeyEvent *e )
+{
+ if ( noGame || isPaused || waitingAfterLine )
+ return;
+ switch( e->key() ) {
+ case Key_Left :
+ moveLeft();
+ break;
+ case Key_Right :
+ moveRight();
+ break;
+ case Key_Down :
+ rotateRight();
+ break;
+ case Key_Up :
+ rotateLeft();
+ break;
+ case Key_Space :
+ dropDown();
+ break;
+ case Key_D :
+ oneLineDown();
+ break;
+ default:
+ return;
+ }
+ e->accept();
+}
+
+void TQTetrixBoard::updateTimeoutTime()
+{
+ timeoutTime = 1000/(1 + getLevel());
+}
diff --git a/examples/tetrix/qtetrixb.h b/examples/tetrix/qtetrixb.h
new file mode 100644
index 000000000..236f02e18
--- /dev/null
+++ b/examples/tetrix/qtetrixb.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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.
+**
+*****************************************************************************/
+
+#ifndef TQTETRIXB_H
+#define TQTETRIXB_H
+
+#include "gtetrix.h"
+#include <qframe.h>
+
+class TQTimer;
+
+class TQTetrixBoard : public TQFrame, public GenericTetrix
+{
+ Q_OBJECT
+public:
+ TQTetrixBoard( TQWidget *parent=0, const char *name=0 );
+
+ void gameOver();
+ void startGame(int gameType = 0,int fillRandomLines = 0);
+
+public slots:
+ void timeout();
+ void updateNext() { GenericTetrix::updateNext(); }
+ void key(TQKeyEvent *e) { keyPressEvent(e); }
+ void start() { startGame(); }
+ void pause();
+
+signals:
+ void gameOverSignal();
+ void drawNextSquareSignal(int x,int y,TQColor *color1);
+ void updateRemovedSignal(int noOfLines);
+ void updateScoreSignal(int score);
+ void updateLevelSignal(int level);
+
+public: // until we have keyboard focus, should be protected
+ void keyPressEvent( TQKeyEvent * );
+
+private:
+ void drawContents( TQPainter * );
+ void resizeEvent( TQResizeEvent * );
+ void drawSquare(int x,int y,int value);
+ void drawNextSquare(int x,int y,int value);
+ void updateRemoved(int noOfLines);
+ void updateScore(int newScore);
+ void updateLevel(int newLlevel);
+ void pieceDropped(int dropHeight);
+ void updateTimeoutTime();
+
+ TQTimer *timer;
+
+ int xOffset,yOffset;
+ int blockWidth,blockHeight;
+ int timeoutTime;
+ bool noGame;
+ bool isPaused;
+ bool waitingAfterLine;
+
+ TQColor colors[7];
+ TQPainter *paint;
+ TQWidget *paint_widget;
+};
+
+#endif
diff --git a/examples/tetrix/tetrix.cpp b/examples/tetrix/tetrix.cpp
new file mode 100644
index 000000000..e3cf9c29f
--- /dev/null
+++ b/examples/tetrix/tetrix.cpp
@@ -0,0 +1,24 @@
+/****************************************************************************
+**
+** 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 "qtetrix.h"
+#include "qdragapp.h"
+#include "qfont.h"
+
+int main( int argc, char **argv )
+{
+ TQApplication::setColorSpec( TQApplication::CustomColor );
+ TQDragApplication a(argc,argv);
+ TQTetrix *tetrix = new TQTetrix;
+ tetrix->setCaption("Tetrix");
+ a.setMainWidget(tetrix);
+ tetrix->setCaption("TQt Example - Tetrix");
+ tetrix->show();
+ return a.exec();
+}
diff --git a/examples/tetrix/tetrix.doc b/examples/tetrix/tetrix.doc
new file mode 100644
index 000000000..93afca4eb
--- /dev/null
+++ b/examples/tetrix/tetrix.doc
@@ -0,0 +1,15 @@
+/*
+*/
+/*! \page tetrix-example.html
+
+ \ingroup examples
+ \title Tetrix
+
+ This is the Qt implementation of the well known game Tetris.
+
+ <hr>
+
+ Main:
+
+ \include tetrix/tetrix.cpp
+*/
diff --git a/examples/tetrix/tetrix.pro b/examples/tetrix/tetrix.pro
new file mode 100644
index 000000000..ad8ad831a
--- /dev/null
+++ b/examples/tetrix/tetrix.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+TARGET = tetrix
+
+CONFIG += qt warn_on release
+DEPENDPATH = ../../include
+
+REQUIRES = small-config
+
+HEADERS = gtetrix.h \
+ qdragapp.h \
+ qtetrix.h \
+ qtetrixb.h \
+ tpiece.h
+SOURCES = gtetrix.cpp \
+ qdragapp.cpp \
+ qtetrix.cpp \
+ qtetrixb.cpp \
+ tetrix.cpp \
+ tpiece.cpp
diff --git a/examples/tetrix/tpiece.cpp b/examples/tetrix/tpiece.cpp
new file mode 100644
index 000000000..71e47e9b3
--- /dev/null
+++ b/examples/tetrix/tpiece.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** 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 "tpiece.h"
+#include "qstring.h"
+#include <stdlib.h>
+
+void TetrixPiece::rotateLeft()
+{
+ if ( pieceType == 5 ) // don't rotate square piece type
+ return;
+ int tmp;
+ for (int i = 0 ; i < 4 ; i++) {
+ tmp = getXCoord(i);
+ setXCoord(i,getYCoord(i));
+ setYCoord(i,-tmp);
+ }
+}
+
+void TetrixPiece::rotateRight()
+{
+ if ( pieceType == 5 ) // don't rotate square piece type
+ return;
+ int tmp;
+ for (int i = 0 ; i < 4 ; i++) {
+ tmp = getXCoord(i);
+ setXCoord(i,-getYCoord(i));
+ setYCoord(i,tmp);
+ }
+}
+
+int TetrixPiece::getMinX()
+{
+ int tmp = coordinates[0][0];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp > coordinates[i][0])
+ tmp = coordinates[i][0];
+ return tmp;
+}
+
+int TetrixPiece::getMaxX()
+{
+ int tmp = coordinates[0][0];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp < coordinates[i][0])
+ tmp = coordinates[i][0];
+ return tmp;
+
+}
+
+int TetrixPiece::getMinY()
+{
+ int tmp = coordinates[0][1];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp > coordinates[i][1])
+ tmp = coordinates[i][1];
+ return tmp;
+}
+
+int TetrixPiece::getMaxY()
+{
+ int tmp = coordinates[0][1];
+ for(int i = 1 ; i < 4 ; i++)
+ if (tmp < coordinates[i][1])
+ tmp = coordinates[i][1];
+ return tmp;
+}
+
+void TetrixPiece::initialize(int type)
+{
+ static int pieceTypes[7][4][2] = {{{ 0,-1},
+ { 0, 0},
+ {-1, 0},
+ {-1, 1}},
+
+ {{ 0,-1},
+ { 0, 0},
+ { 1, 0},
+ { 1, 1}},
+
+ {{ 0,-1},
+ { 0, 0},
+ { 0, 1},
+ { 0, 2}},
+
+ {{-1, 0},
+ { 0, 0},
+ { 1, 0},
+ { 0, 1}},
+
+ {{ 0, 0},
+ { 1, 0},
+ { 0, 1},
+ { 1, 1}},
+
+ {{-1,-1},
+ { 0,-1},
+ { 0, 0},
+ { 0, 1}},
+
+ {{ 1,-1},
+ { 0,-1},
+ { 0, 0},
+ { 0, 1}}};
+ if (type < 1 || type > 7)
+ type = 1;
+ pieceType = type;
+ for(int i = 0 ; i < 4 ; i++) {
+ coordinates[i][0] = pieceTypes[type - 1][i][0];
+ coordinates[i][1] = pieceTypes[type - 1][i][1];
+ }
+}
+
+
+/*
+ * Sigh, oh beautiful nostalgia! This random algorithm has
+ * been taken from the book "Adventures with your pocket calculator"
+ * and I used it in my first implemented and machine-
+ * run program of any size to speak of. Imagine how hungry I
+ * was after having programmed BASIC on paper for
+ * half a year?!!?!?!?!?!? The first program I typed in was a
+ * slot machine game and was made in BASIC on a SHARP
+ * PC-1211 with 1,47 KB RAM (one point four seven kilobytes) and
+ * a one-line LCD-display (I think it had 32 characters) in the
+ * year of our lord 1981. The man I had bought the machine from worked
+ * as a COBOL programmer and was amazed and impressed
+ * when I demonstrated the program 2 days after I had
+ * bought the machine, quote: "Gees, I have been looking so long
+ * for a "random" command in that BASIC, what is it called?"
+ * Oh, how I still get a thrill out of the thought of the
+ * explanation I then gave him...
+ */
+
+/*
+ * Sukk, aa vakre nostalgi! Denne random algoritmen er
+ * tatt fra boka "Adventures with your pocket calculator"
+ * og den brukte jeg i mitt foerste implementerte og maskin-
+ * kjoerte program av nevneverdig stoerrelse. Tror du jeg var
+ * noe sulten etter aa ha programmert BASIC paa papir i et
+ * halvt aar?!!?!?!?!?!? Programmet jeg tasta inn foerst var et
+ * "enarmet banditt" spill og ble laget i BASIC paa en SHARP
+ * PC-1211 med 1,47 KB RAM (en komma foertisju kilobyte) og
+ * et en-linjers LCD-display (tror det hadde 32 karakterer) i det
+ * herrens aar 1981. Mannen jeg kjoepte maskinen av jobbet til
+ * daglig med COBOL programmering og var forbloeffet og imponert
+ * da jeg demonstrerte programmet 2 dager etter at jeg hadde
+ * kjoept maskinen, sitat: "Joess, jeg som har leita saa lenge
+ * etter en random kommando i den BASICen, hva var det den
+ * het?" Aa, jeg frydes ennaa ved tanken paa forklaringen jeg
+ * deretter ga ham...
+ */
+
+double TetrixPiece::randomSeed = 0.33333;
+
+void TetrixPiece::setRandomSeed(double seed)
+{
+ TQCString buffer;
+ if (seed < 0)
+ seed = - seed;
+ if (seed >= 1)
+ seed = seed - (double) ((int) seed);
+ buffer.sprintf("%1.5f",(float) seed);
+ for (int i = 0 ; i < 5 ; i++)
+ if ((buffer[i + 2] - '0') % 2 == 0)
+ buffer[i + 2]++;
+ randomSeed = atof(buffer);
+}
+
+int TetrixPiece::randomValue(int maxPlusOne)
+{
+ randomSeed = randomSeed*147;
+ randomSeed = randomSeed - (double) ((int) randomSeed);
+ return (int) (randomSeed*maxPlusOne);
+}
diff --git a/examples/tetrix/tpiece.h b/examples/tetrix/tpiece.h
new file mode 100644
index 000000000..11a0ffb49
--- /dev/null
+++ b/examples/tetrix/tpiece.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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.
+**
+*****************************************************************************/
+
+#ifndef TPIECE_H
+#define TPIECE_H
+
+class TetrixPiece
+{
+public:
+ TetrixPiece() {setRandomType();}
+ TetrixPiece(int type) {initialize(type % 7 + 1);}
+
+ void setRandomType() {initialize(randomValue(7) + 1);}
+
+ void rotateLeft();
+ void rotateRight();
+
+ int getType() {return pieceType;}
+ int getXCoord(int index) {return coordinates[index][0];}
+ int getYCoord(int index) {return coordinates[index][1];}
+ void getCoord(int index,int &x,int&y){x = coordinates[index][0];
+ y = coordinates[index][1];}
+ int getMinX();
+ int getMaxX();
+ int getMinY();
+ int getMaxY();
+
+ static void setRandomSeed(double seed);
+ static int randomValue(int maxPlusOne);
+
+private:
+ void setXCoord(int index,int value) {coordinates[index][0] = value;}
+ void setYCoord(int index,int value) {coordinates[index][1] = value;}
+ void setCoords(int index,int x,int y){coordinates[index][0] = x;
+ coordinates[index][1] = y;}
+ void initialize(int type);
+
+ int pieceType;
+ int coordinates[4][2];
+
+ static double randomSeed;
+};
+
+#endif