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.
tdegames/kblackbox/kbbgfx.cpp

474 lines
10 KiB

//
//
// KBlackBox
//
// A simple game inspired by an emacs module
//
// File: kbbgfx.cpp
//
// The implementation of the KBBGraphic widget
//
#include <tqpainter.h>
#include <tqpixmap.h>
#include <tqcolor.h>
#include <tqkeycode.h>
#include <tqwmatrix.h>
#include "kbbgfx.h"
#include "util.h"
/*
Constructs a KBBGraphic widget.
*/
KBBGraphic::KBBGraphic( TQPixmap **p, TQWidget* parent, const char* name )
: TQWidget( parent, name )
{
int i;
curRow = curCol = 0;
setFocusPolicy( TQ_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 TQPixmap * [NROFTYPES];
for (i = 0; i < NROFTYPES; i++) {
pixScaled[i] = new TQPixmap;
}
}
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;
TQWMatrix 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; }
TQSize KBBGraphic::sizeHint() const { return TQSize(wHint(), hHint()); }
/*
Returns a pointer to graphicBoard
*/
RectOnArray *KBBGraphic::getGraphicBoard() { return graphicBoard; }
/*
Handles cell painting for the KBBGraphic widget.
*/
void KBBGraphic::paintCell( TQPainter* p, int row, int col )
{
if (pix == NULL) paintCellDefault( p, row, col );
else paintCellPixmap( p, row, col );
}
void KBBGraphic::paintCellPixmap( TQPainter* p, int row, int col )
{
int w = cellW;
int h = cellH;
int x2 = w - 1;
int y2 = h - 1;
int type;
TQPixmap 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.
*/
TQString 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( TQPainter* p, int row, int col )
{
int w = cellW;
int h = cellH;
int x2 = w - 1;
int y2 = h - 1;
int type;
TQColor 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.
*/
TQString 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( TQPaintEvent* )
{
int i, j;
TQPainter 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( TQResizeEvent* )
{
int w = TQWidget::width();
int h = TQWidget::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 TQPixmap( cellW * numRows, cellH * numCols );
}
/*
Handles mouse press events for the KBBGraphic widget.
*/
void KBBGraphic::mousePressEvent( TQMouseEvent* e )
{
if (inputAccepted) {
/*
* Middle click finishes the game.
*/
if (e->button() == Qt::MidButton) {
emit endMouseClicked();
return;
}
int oldRow = curRow;
int oldCol = curCol;
TQPoint 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( TQMouseEvent* e ) {
if (inputAccepted) {
int oldRow = curRow;
int oldCol = curCol;
TQPoint 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, Qt::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( TQFocusEvent* )
{
repaint( FALSE );
}
/*
Handles focus loss events for the KBBGraphic widget.
*/
void KBBGraphic::focusOutEvent( TQFocusEvent* )
{
repaint( FALSE );
}
/*
Sets whether user input is processed or not.
*/
void KBBGraphic::setInputAccepted( bool b )
{
inputAccepted = b;
if (b) setFocusPolicy( TQ_StrongFocus );
else setFocusPolicy( TQ_NoFocus );
}
/*
Updates the cell at (col,row).
*/
void KBBGraphic::updateElement( int col, int row )
{
TQPainter paint( this );
paint.setViewport( col * cellW, row * cellH, width(), height() );
paintCell( &paint, row, col );
}
#include "kbbgfx.moc"