summaryrefslogtreecommitdiffstats
path: root/kblackbox/kbbgfx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kblackbox/kbbgfx.cpp')
-rw-r--r--kblackbox/kbbgfx.cpp473
1 files changed, 473 insertions, 0 deletions
diff --git a/kblackbox/kbbgfx.cpp b/kblackbox/kbbgfx.cpp
new file mode 100644
index 00000000..d37edc1e
--- /dev/null
+++ b/kblackbox/kbbgfx.cpp
@@ -0,0 +1,473 @@
+//
+//
+// KBlackBox
+//
+// A simple game inspired by an emacs module
+//
+// File: kbbgfx.cpp
+//
+// The implementation of the KBBGraphic widget
+//
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qcolor.h>
+#include <qkeycode.h>
+#include <qwmatrix.h>
+
+#include "kbbgfx.h"
+#include "util.h"
+
+/*
+ Constructs a KBBGraphic widget.
+*/
+
+KBBGraphic::KBBGraphic( QPixmap **p, QWidget* parent, const char* name )
+ : QWidget( parent, name )
+{
+ int i;
+
+ curRow = curCol = 0;
+ setFocusPolicy( NoFocus );
+ setBackgroundColor( gray );
+ setCellWidth( CELLW ); // set width of cell in pixels
+ setCellHeight( CELLH ); // set height of cell in pixels
+ setMouseTracking( FALSE );
+
+ pix = p;
+ if (pix == NULL) pixScaled = NULL;
+ else {
+ pixScaled = new QPixmap * [NROFTYPES];
+ for (i = 0; i < NROFTYPES; i++) {
+ pixScaled[i] = new QPixmap;
+ }
+ }
+ graphicBoard = NULL;
+ drawBuffer = NULL;
+}
+
+/*
+ Destructor: deallocates memory for contents
+*/
+
+KBBGraphic::~KBBGraphic()
+{
+ int i;
+
+ if (pix != NULL) {
+ for (i = 0; i < NROFTYPES; i++) {
+ delete pix[i];
+ }
+ delete pix;
+ }
+ if (pixScaled != NULL) {
+ for (i = 0; i < NROFTYPES; i++) {
+ delete pixScaled[i];
+ }
+ delete pixScaled;
+ }
+ delete graphicBoard;
+ delete drawBuffer;
+}
+
+/*
+ Sets the size of the table
+*/
+
+void KBBGraphic::setSize( int w, int h )
+{
+ if ((w != numCols) || (h != numRows)) {
+ delete graphicBoard;
+ graphicBoard = new RectOnArray( w, h );
+ graphicBoard->fill( OUTERBBG );
+ setNumCols( w );
+ setNumRows( h );
+ setCellWidth( CELLW );
+ setCellHeight( CELLH );
+ minW = cellW * numRows;
+ minH = cellH * numCols;
+ emit(sizeChanged());
+ }
+}
+
+void KBBGraphic::setCellWidth( int w )
+{
+ cellW = w;
+}
+
+void KBBGraphic::setCellHeight( int h )
+{
+ cellH = h;
+}
+
+void KBBGraphic::setNumRows( int rows )
+{
+ numRows = rows;
+}
+
+void KBBGraphic::setNumCols( int cols )
+{
+ numCols = cols;
+}
+
+/*
+ Scales all pixmaps to desired size.
+*/
+
+void KBBGraphic::scalePixmaps( int w, int h )
+{
+ int i, w0, h0;
+ QWMatrix wm;
+
+ w0 = pix[0]->width();
+ h0 = pix[0]->height();
+ wm.scale( (float) w / (float) w0, (float) h / (float) h0 );
+ for (i = 0; i < NROFTYPES; i++) {
+ *pixScaled[i] = pix[i]->xForm( wm );
+ }
+}
+
+/*
+ Returns the sizes of the table
+*/
+
+int KBBGraphic::numC() { return numCols; }
+int KBBGraphic::numR() { return numRows; }
+int KBBGraphic::width() { return cellW * numRows; }
+int KBBGraphic::height() { return cellH * numCols; }
+int KBBGraphic::wHint() const { return minW; }
+int KBBGraphic::hHint() const { return minH; }
+QSize KBBGraphic::sizeHint() const { return QSize(wHint(), hHint()); }
+
+/*
+ Returns a pointer to graphicBoard
+*/
+
+RectOnArray *KBBGraphic::getGraphicBoard() { return graphicBoard; }
+
+/*
+ Handles cell painting for the KBBGraphic widget.
+*/
+
+void KBBGraphic::paintCell( QPainter* p, int row, int col )
+{
+ if (pix == NULL) paintCellDefault( p, row, col );
+ else paintCellPixmap( p, row, col );
+}
+
+void KBBGraphic::paintCellPixmap( QPainter* p, int row, int col )
+{
+ int w = cellW;
+ int h = cellH;
+ int x2 = w - 1;
+ int y2 = h - 1;
+ int type;
+ QPixmap pm;
+
+ // kdDebug(12009) << p->viewport().width() << endl;
+
+ switch (type = graphicBoard->get( col, row )) {
+ case MARK1BBG: pm = *pixScaled[MARK1BBG]; break;
+ case OUTERBBG: pm = *pixScaled[OUTERBBG]; break;
+ case INNERBBG: pm = *pixScaled[INNERBBG]; break;
+ case LASERBBG: pm = *pixScaled[LASERBBG]; break;
+ case LFIREBBG: pm = *pixScaled[LFIREBBG]; break;
+ case FBALLBBG: pm = *pixScaled[FBALLBBG]; break;
+ case TBALLBBG: pm = *pixScaled[TBALLBBG]; break;
+ case WBALLBBG: pm = *pixScaled[WBALLBBG]; break;
+ default: pm = *pixScaled[OUTERBBG];
+ }
+ // kdDebug(12009) << pm.width() << " " << w << endl;
+ p->drawPixmap( 0, 0, pm );
+ // bitBlt( this, col * w, row * h, &pm );
+
+ p->setPen( black );
+
+ if (type == INNERBBG) {
+ p->drawLine( x2, 0, x2, y2 ); // draw vertical line on right
+ p->drawLine( 0, y2, x2, y2 ); // draw horiz. line at bottom
+ p->drawLine( 0, 0, x2, 0 );
+ p->drawLine( 0, 0, 0, y2 );
+ }
+
+ /*
+ Extra drawings for boxes aroud lasers.
+ */
+ QString s;
+ switch (type) {
+ case RLASERBBG:
+ s.sprintf( "%c", 'R' );
+ p->drawText( 1, 1, x2-1, y2-1, AlignCenter, s );
+ break;
+ case HLASERBBG:
+ s.sprintf( "%c", 'H' );
+ p->drawText( 1, 1, x2-1, y2-1, AlignCenter, s );
+ break;
+ }
+ if (type < 0) {
+ s.sprintf( "%d", -type );
+ p->drawText( 1, 1, x2-1, y2-1, AlignCenter, s );
+ }
+
+ /*
+ Draw extra frame inside if this is the current cell.
+ */
+ p->setPen( yellow );
+ if ( (row == curRow) && (col == curCol) ) { // if we are on current cell,
+ if ( hasFocus() ) {
+ p->drawRect( 0, 0, x2, y2 );
+ }
+ else { // we don't have focus, so
+ p->setPen( DotLine ); // use dashed line to
+ p->drawRect( 0, 0, x2, y2 );
+ p->setPen( SolidLine ); // restore to normal
+ }
+ }
+}
+
+void KBBGraphic::paintCellDefault( QPainter* p, int row, int col )
+{
+ int w = cellW;
+ int h = cellH;
+ int x2 = w - 1;
+ int y2 = h - 1;
+ int type;
+ QColor color;
+
+ switch (type = graphicBoard->get( col, row )) {
+ case MARK1BBG: color = darkRed; break;
+ case OUTERBBG: color = white; break;
+ case INNERBBG: color = gray; break;
+ case LASERBBG: color = darkGreen; break;
+ case LFIREBBG: color = green; break;
+ case FBALLBBG: color = red; break;
+ case TBALLBBG: color = blue; break;
+ case WBALLBBG: color = cyan; break;
+ default: color = white;
+ }
+ p->fillRect( 0, 0, x2, y2, color );
+
+ p->setPen( black );
+ p->drawLine( x2, 0, x2, y2 ); // draw vertical line on right
+ p->drawLine( 0, y2, x2, y2 ); // draw horiz. line at bottom
+
+ /*
+ Extra drawings for boxes aroud lasers.
+ */
+ QString s;
+ switch (type) {
+ case RLASERBBG:
+ s.sprintf( "%c", 'R' );
+ p->drawText( 1, 1, x2-1, y2-1, AlignCenter, s );
+ break;
+ case HLASERBBG:
+ s.sprintf( "%c", 'H' );
+ p->drawText( 1, 1, x2-1, y2-1, AlignCenter, s );
+ break;
+ }
+ if (type < 0) {
+ s.sprintf( "%d", -type );
+ p->drawText( 1, 1, x2-1, y2-1, AlignCenter, s );
+ }
+
+ /*
+ Draw extra frame inside if this is the current cell.
+ */
+ if ( (row == curRow) && (col == curCol) ) { // if we are on current cell,
+ if ( hasFocus() ) {
+ p->drawEllipse( 1, 1, x2-2, y2-2 ); // draw ellipse
+ }
+ else { // we don't have focus, so
+ p->setPen( DotLine ); // use dashed line to
+ p->drawEllipse( 1, 1, x2-2, y2-2 ); // draw ellipse
+ p->setPen( SolidLine ); // restore to normal
+ }
+ }
+}
+
+/*
+ Xperimantal...
+*/
+
+void KBBGraphic::paintEvent( QPaintEvent* )
+{
+ int i, j;
+ QPainter paint( drawBuffer );
+
+ // kdDebug(12009) << drawBuffer->width() << endl;
+ for (i = 0; i < numRows; i++) {
+ for (j = 0; j < numCols; j++) {
+ paint.setViewport( j * cellW, i * cellH, width(), height() );
+ paintCell( &paint, i, j );
+ }
+ }
+ bitBlt( this, 0, 0, drawBuffer );
+}
+
+/*
+ Resize event of the KBBGraphic widget.
+*/
+
+void KBBGraphic::resizeEvent( QResizeEvent* )
+{
+ int w = QWidget::width();
+ int h = QWidget::height();
+ int wNew, hNew;
+
+ // kbDebug() << w << " " << h << " " << minW << " " << minH << endl;
+ if (w > minW) {
+ wNew = w / numC();
+ } else {
+ wNew = CELLW;
+ }
+ if (h > minH) {
+ hNew = h / numR();
+ } else {
+ hNew = CELLH;
+ }
+ if (pix != NULL) scalePixmaps( wNew, hNew );
+ setCellWidth( wNew );
+ setCellHeight( hNew );
+
+ delete drawBuffer;
+ drawBuffer = new QPixmap( cellW * numRows, cellH * numCols );
+}
+
+/*
+ Handles mouse press events for the KBBGraphic widget.
+*/
+void KBBGraphic::mousePressEvent( QMouseEvent* e )
+{
+ if (inputAccepted) {
+ /*
+ * Middle click finishes the game.
+ */
+ if (e->button() == MidButton) {
+ emit endMouseClicked();
+ return;
+ }
+ int oldRow = curRow;
+ int oldCol = curCol;
+ QPoint pos = e->pos(); // extract pointer position
+ curRow = pos.y() / cellH;
+ curCol = pos.x() / cellW;
+ //kdDebug(12009) << e->state() << " " << LeftButton << " " << e->state()&LeftButton << endl;
+ updateElement( oldCol, oldRow );
+ emit inputAt( curCol, curRow, e->button() );
+ }
+}
+
+
+/*
+ Handles mouse move events for the KBBGraphic widget.
+*/
+
+void KBBGraphic::mouseMoveEvent( QMouseEvent* e ) {
+ if (inputAccepted) {
+ int oldRow = curRow;
+ int oldCol = curCol;
+ QPoint pos = e->pos(); // extract pointer position
+ int movRow = pos.y() / cellH;
+ int movCol = pos.x() / cellW;
+ // kdDebug(12009) << movRow << " " << curRow << endl;
+ if ( (curRow != movRow) // if current cell has moved,
+ || (curCol != movCol) ) {
+ curRow = movRow;
+ curCol = movCol;
+ updateElement( oldCol, oldRow );
+ emit inputAt( curCol, curRow, e->state() );
+ }
+ }
+}
+
+void KBBGraphic::slotUp()
+{
+ if( curRow > 0 ) {
+ moveSelection( -1, 0 );
+ }
+}
+
+void KBBGraphic::slotDown()
+{
+ if( curRow < numRows-1 ) {
+ moveSelection( 1, 0 );
+ }
+}
+
+void KBBGraphic::slotLeft()
+{
+ if( curCol > 0 ) {
+ moveSelection( 0, -1 );
+ }
+}
+
+void KBBGraphic::slotRight()
+{
+ if( curCol < numCols-1 ) {
+ moveSelection( 0, 1 );
+ }
+}
+
+void KBBGraphic::slotInput()
+{
+ if ( !inputAccepted ) {
+ return;
+ }
+ emit inputAt( curCol, curRow, LeftButton );
+// updateElement( curCol, curRow );
+}
+
+void KBBGraphic::moveSelection(int drow, int dcol)
+{
+ if ( !dcol && !drow || !inputAccepted ) {
+ return;
+ }
+ curCol += dcol;
+ curRow += drow;
+ updateElement( curCol - dcol, curRow - drow );
+ updateElement( curCol, curRow );
+}
+
+/*
+ Handles focus reception events for the KBBGraphic widget.
+*/
+
+void KBBGraphic::focusInEvent( QFocusEvent* )
+{
+ repaint( FALSE );
+}
+
+
+/*
+ Handles focus loss events for the KBBGraphic widget.
+*/
+
+void KBBGraphic::focusOutEvent( QFocusEvent* )
+{
+ repaint( FALSE );
+}
+
+/*
+ Sets whether user input is processed or not.
+*/
+
+void KBBGraphic::setInputAccepted( bool b )
+{
+ inputAccepted = b;
+ if (b) setFocusPolicy( StrongFocus );
+ else setFocusPolicy( NoFocus );
+}
+
+/*
+ Updates the cell at (col,row).
+*/
+
+void KBBGraphic::updateElement( int col, int row )
+{
+ QPainter paint( this );
+
+ paint.setViewport( col * cellW, row * cellH, width(), height() );
+ paintCell( &paint, row, col );
+}
+
+#include "kbbgfx.moc"