Source Code (Use browser search to find items of interest.)
Class Index
kmahjongg'Editor (./kdegames/kmahjongg/Editor.h:23)
class Editor: public QDialog
{
Q_OBJECT
public:
Editor
(
QWidget* parent = NULL,
const char* name = NULL
);
virtual ~Editor();
protected slots:
void topToolbarOption(int w);
void drawFrameMousePressEvent ( QMouseEvent* );
void drawFrameMouseMovedEvent ( QMouseEvent *);
protected:
enum {remove=98, insert=99, move=100};
void paintEvent( QPaintEvent* pa );
void setupToolbar();
void loadBoard(void);
bool saveBoard(void);
void newBoard(void);
void drawBackground(QPixmap *to);
void drawTiles(QPixmap *to);
bool testSave(void);
void transformPointToPosition(const QPoint &, POSITION &, bool align);
void drawCursor(POSITION &p, bool visible);
bool canInsert(POSITION &p);
void statusChanged(void);
const char *statusText(void);
private:
int mode;
int numTiles;
KToolBar *topToolbar;
KToolBar *sideToolbar;
FrameImage * drawFrame;
Tileset tiles;
BoardLayout theBoard;
bool clean;
POSITION currPos;
QLabel *theLabel;
private:
};
kmahjongg'Editor::Editor() (./kdegames/kmahjongg/Editor.cpp:48)
Editor::Editor
(
QWidget* parent,
const char* name
)
:
QDialog( parent, name, TRUE, 0 ), tiles(false)
{
int sWidth = (BoardLayout::width+2)*(tiles.qWidth());
int sHeight =( BoardLayout::height+2)*tiles.qHeight();
sWidth += 4*tiles.shadowSize();
drawFrame = new FrameImage( this, "drawFrame" );
drawFrame->setGeometry( 10, 40 ,sWidth ,sHeight);
drawFrame->setMinimumSize( 0, 0 );
drawFrame->setMaximumSize( 32767, 32767 );
drawFrame->setFocusPolicy( QWidget::NoFocus );
drawFrame->setBackgroundMode( QWidget::PaletteBackground );
drawFrame->setFontPropagation( QWidget::NoChildren );
drawFrame->setPalettePropagation( QWidget::NoChildren );
drawFrame->setFrameStyle( 49 );
drawFrame->setMouseTracking(true);
resize( sWidth+60, sHeight+60);
setMinimumSize( sWidth+60, sHeight+60);
setMaximumSize( sWidth+60, sHeight+60);
// setup the tool bar
setupToolbar();
// load in the tile set
tiles.loadTileset(preferences.tileset());
// tell the user what we do
setCaption(i18n("Edit board layout"));
connect( drawFrame, SIGNAL(mousePressed(QMouseEvent *) ),
SLOT(drawFrameMousePressEvent(QMouseEvent *)));
connect( drawFrame, SIGNAL(mouseMoved(QMouseEvent *) ),
SLOT(drawFrameMouseMovedEvent(QMouseEvent *)));
clean= true;
mode = insert;
numTiles=0;
statusChanged();
}
kmahjongg'Editor::~Editor() (./kdegames/kmahjongg/Editor.cpp:100)
Editor::~Editor()
{
}
// ---------------------------------------------------------
kmahjongg'Editor::setupToolbar() (./kdegames/kmahjongg/Editor.cpp:105)
void Editor::setupToolbar()
{
KIconLoader *loader = KGlobal::iconLoader();
topToolbar = new KToolBar( this, "editToolBar" );
KToolBarRadioGroup *radio = new KToolBarRadioGroup(topToolbar);
// new game
topToolbar->insertButton(loader->loadIcon("filenew", KIcon::Toolbar),
ID_TOOL_NEW, TRUE, i18n("New board."));
// open game
topToolbar->insertButton(loader->loadIcon("fileopen", KIcon::Toolbar),
ID_TOOL_LOAD, TRUE, i18n("Open board."));
// save game
topToolbar->insertButton(loader->loadIcon("filefloppy", KIcon::Toolbar),
ID_TOOL_SAVE, TRUE, i18n(" Save board."));
#ifdef FUTURE_OPTIONS
// Select
topToolbar->insertSeparator();
topToolbar->insertButton(loader->loadIcon("rectangle_select", KIcon::Toolbar),
ID_TOOL_SELECT, TRUE, i18n("Select."));
topToolbar->insertButton(loader->loadIcon("editcut", KIcon::Toolbar),
ID_TOOL_CUT, TRUE, i18n("Cut."));
topToolbar->insertButton(loader->loadIcon("editcopy", KIcon::Toolbar),
ID_TOOL_COPY, TRUE, i18n("Copy."));
topToolbar->insertButton(loader->loadIcon("editpaste", KIcon::Toolbar),
ID_TOOL_PASTE, TRUE, i18n("Paste."));
topToolbar->insertSeparator();
topToolbar->insertButton(loader->loadIcon("move", KIcon::Toolbar),
ID_TOOL_MOVE, TRUE, i18n("Move tiles."));
#endif
topToolbar->insertButton(loader->loadIcon("pencil", KIcon::Toolbar),
ID_TOOL_ADD, TRUE, i18n("Add tiles."));
topToolbar->insertButton(loader->loadIcon("delete", KIcon::Toolbar),
ID_TOOL_DEL, TRUE, i18n("Remove tiles."));
topToolbar->setToggle(ID_TOOL_ADD);
topToolbar->setToggle(ID_TOOL_MOVE);
topToolbar->setToggle(ID_TOOL_DEL);
topToolbar->toggleButton(ID_TOOL_ADD);
radio->addButton(ID_TOOL_ADD);
radio->addButton(ID_TOOL_MOVE);
radio->addButton(ID_TOOL_DEL);
// board shift
topToolbar->insertSeparator();
topToolbar->insertButton(loader->loadIcon("back", KIcon::Toolbar),
ID_TOOL_LEFT, TRUE, i18n("Shift left."));
topToolbar->insertButton(loader->loadIcon("up", KIcon::Toolbar),
ID_TOOL_UP, TRUE, i18n("Shift up."));
topToolbar->insertButton(loader->loadIcon("down", KIcon::Toolbar),
ID_TOOL_DOWN, TRUE, i18n("Shift down."));
topToolbar->insertButton(loader->loadIcon("forward", KIcon::Toolbar),
ID_TOOL_RIGHT, TRUE, i18n("Shift right."));
topToolbar->insertSeparator();
topToolbar->insertButton(loader->loadIcon("exit", KIcon::Toolbar),
ID_META_EXIT, TRUE, i18n("Exit."));
// status in the toolbar for now (ick)
theLabel = new QLabel(statusText(), topToolbar);
int lWidth = theLabel->sizeHint().width();
topToolbar->insertWidget(ID_TOOL_STATUS,lWidth, theLabel );
topToolbar->alignItemRight( ID_TOOL_STATUS, true );
//addToolBar(topToolbar);
connect( topToolbar, SIGNAL(clicked(int) ), SLOT( topToolbarOption(int) ) );
topToolbar->updateRects(0);
topToolbar->setFullWidth(true);
topToolbar->setBarPos(KToolBar::Top);
// topToolbar->enableMoving(false);
topToolbar->adjustSize();
setMinimumWidth(topToolbar->width());
}
kmahjongg'Editor::statusChanged() (./kdegames/kmahjongg/Editor.cpp:188)
void Editor::statusChanged(void) {
bool canSave = ((numTiles !=0) && ((numTiles & 1) == 0));
theLabel->setText(statusText());
topToolbar->setItemEnabled( ID_TOOL_SAVE, canSave);
}
kmahjongg'Editor::topToolbarOption() (./kdegames/kmahjongg/Editor.cpp:195)
void Editor::topToolbarOption(int option) {
switch(option) {
case ID_TOOL_NEW:
newBoard();
break;
case ID_TOOL_LOAD:
loadBoard();
break;
case ID_TOOL_SAVE:
saveBoard();
break;
case ID_TOOL_LEFT:
theBoard.shiftLeft();
repaint(false);
break;
case ID_TOOL_RIGHT:
theBoard.shiftRight();
repaint(false);
break;
case ID_TOOL_UP:
theBoard.shiftUp();
repaint(false);
break;
case ID_TOOL_DOWN:
theBoard.shiftDown();
repaint(false);
break;
case ID_TOOL_DEL:
mode=remove;
break;
case ID_TOOL_MOVE:
mode=move;
break;
case ID_TOOL_ADD:
mode = insert;
break;
case ID_META_EXIT:
close();
break;
default:
break;
}
}
kmahjongg'Editor::statusText() (./kdegames/kmahjongg/Editor.cpp:245)
const char *Editor::statusText(void) {
static char buff[256];
int x=currPos.x;
int y=currPos.y;
int z= currPos.e;
if (z == 100)
z = 0;
else
z=z+1;
if (x >=BoardLayout::width || x <0 || y >=BoardLayout::height || y <0)
x = y = z = 0;
sprintf(buff, i18n("Tiles: %3.3d Pos: %2.2d,%2.2d,%2.2d"), numTiles,
x,y,z);
return buff;
}
kmahjongg'Editor::loadBoard() (./kdegames/kmahjongg/Editor.cpp:266)
void Editor::loadBoard(void) {
if ( !testSave() )
return;
KURL url = KFileDialog::getOpenURL(
NULL,
"*.layout|Board layout (*.layout)\n"
"*.*|All files (*.*)",
this,
i18n("Open board layout." ));
if ( url.isEmpty() )
return;
theBoard.loadBoardLayout( url.path() );
repaint(false);
}
// Clear out the contents of the board. Repaint the screen
// set values to their defaults.
kmahjongg'Editor::newBoard() (./kdegames/kmahjongg/Editor.cpp:290)
void Editor::newBoard(void) {
if (!testSave())
return;
theBoard.clearBoardLayout();
clean=true;
numTiles=0;
statusChanged();
repaint(false);
}
kmahjongg'Editor::saveBoard() (./kdegames/kmahjongg/Editor.cpp:306)
bool Editor::saveBoard(void) {
// get a save file name
KURL url = KFileDialog::getSaveURL(
NULL,
"*.layout|Board layout (*.layout)\n"
"*.*|All files (*.*)",
this,
i18n("Save board layout." ));
if( !url.isLocalFile() )
{
KMessageBox::sorry( 0L, i18n( "Only saving to local files currently supported." ) );
return false;
}
if ( url.isEmpty() )
return false;
QFileInfo f( url.path() );
if ( f.exists() ) {
// if it already exists, querie the user for replacement
int res=KMessageBox::warningYesNo(this,
i18n("A file with that name "
"already exists, do you "
"wish to overwrite it?"),
i18n("Save board layout." ));
if (res != KMessageBox::Yes)
return false;
}
bool result = theBoard.saveBoardLayout( url.path() );
if (result==true){
clean = true;
return true;
} else {
return false;
}
}
// test if a save is required and return true if the app is to continue
// false if cancel is selected. (if ok then call out to save the board
kmahjongg'Editor::testSave() (./kdegames/kmahjongg/Editor.cpp:347)
bool Editor::testSave(void)
{
if (clean)
return(true);
int res;
res=KMessageBox::warningYesNoCancel(this,
i18n("The board has been modified, would you"
"like to save the changes?"));
if (res == KMessageBox::Yes) {
// yes to save
if (saveBoard()) {
return true;
} else {
KMessageBox::sorry(this, i18n("Save failed. Aborting operation."));
}
} else {
return (res != KMessageBox::Cancel);
}
return(true);
}
// The main paint event, draw in the grid and blit in
// the tiles as specified by the layout.
kmahjongg'Editor::paintEvent() (./kdegames/kmahjongg/Editor.cpp:375)
void Editor::paintEvent( QPaintEvent* ) {
// first we layer on a background grid
QPixmap buff;
QPixmap *dest=drawFrame->getPreviewPixmap();
buff.resize(dest->width(), dest->height());
drawBackground(&buff);
drawTiles(&buff);
bitBlt(dest, 0,0,&buff, 0,0,buff.width(), buff.height(), CopyROP);
drawFrame->repaint(false);
}
kmahjongg'Editor::drawBackground() (./kdegames/kmahjongg/Editor.cpp:387)
void Editor::drawBackground(QPixmap *pixmap) {
QPainter p(pixmap);
// blast in a white background
p.fillRect(0,0,pixmap->width(), pixmap->height(), QColor(white));
// now put in a grid of tile quater width squares
int sy = (tiles.height()/2)+tiles.shadowSize();
int sx = (tiles.width()/2);
for (int y=0; y<=BoardLayout::height; y++) {
int nextY=sy+(y*tiles.qHeight());
p.drawLine(sx, nextY,sx+(BoardLayout::width*tiles.qWidth()), nextY);
}
for (int x=0; x<=BoardLayout::width; x++) {
int nextX=sx+(x*tiles.qWidth());
p.drawLine(nextX, sy, nextX, sy+BoardLayout::height*tiles.qHeight());
}
}
kmahjongg'Editor::drawTiles() (./kdegames/kmahjongg/Editor.cpp:413)
void Editor::drawTiles(QPixmap *dest) {
QPainter p(dest);
// blast in a white background
tiles.loadTileset(preferences.tileset());
int xOffset = tiles.width()/2;
int yOffset = tiles.height()/2;
short tile = 0;
// we iterate over the depth stacking order. zach sucessive level is
// drawn one indent up and to the right. The indent is the width
// of the 3d relief on the tile left (tile shadow width)
for (int z=0; z<BoardLayout::depth; z++) {
// we draw down the board so the tile below over rights our border
for (int y = 0; y < BoardLayout::height; y++) {
// drawing right to left to prevent border overwrite
for (int x=BoardLayout::width-1; x>=0; x--) {
int sx = x*(tiles.qWidth() )+xOffset;
int sy = y*(tiles.qHeight() )+yOffset;
if (theBoard.getBoardData(z, y, x) != '1') {
continue;
}
QPixmap *t;
tile=(z*BoardLayout::depth)+
(y*BoardLayout::height)+
(x*BoardLayout::width);
// if (mode==remove && currPos.x==x && currPos.y==y && currPos.e==z) {
// t = tiles.selectedPixmaps(44));
// } else {
t = tiles.unselectedPixmaps(43);
// }
// Only one compilcation. Since we render top to bottom , left
// to right situations arise where...:
// there exists a tile one q height above and to the left
// in this situation we would draw our top left border over it
// we simply split the tile draw so the top half is drawn
// minus border
if ((x>1) && (y>0) && theBoard.getBoardData(z,y-1,x-2)=='1'){
bitBlt( dest,
sx+tiles.shadowSize(), sy,
t, tiles.shadowSize() ,0,
t->width()-tiles.shadowSize(),
t->height()/2, CopyROP );
bitBlt( dest, sx, sy+t->height()/2,
t, 0,t->height()/2,t->width(),t->height()/2,CopyROP);
} else {
bitBlt( dest, sx, sy,
t, 0,0, t->width(), t->height(), CopyROP );
}
tile++;
tile = tile % 143;
}
}
xOffset +=tiles.shadowSize();
yOffset -=tiles.shadowSize();
}
}
// convert mouse position on screen to a tile z y x coord
// different to the one in kmahjongg.cpp since if we hit ground
// we return a result too.
kmahjongg'Editor::transformPointToPosition() (./kdegames/kmahjongg/Editor.cpp:486)
void Editor::transformPointToPosition(
const QPoint& point,
POSITION& MouseClickPos,
bool align)
{
short z = 0; // shut the compiler up about maybe uninitialised errors
short y = 0;
short x = 0;
MouseClickPos.e = 100;
// iterate over z coordinate from top to bottom
for( z=BoardLayout::depth-1; z>=0; z-- )
{
// calculate mouse coordiantes --> position in game board
// the factor -theTiles.width()/2 must keep track with the
// offset for blitting in the print zvent (FIX ME)
x = ((point.x()-tiles.width()/2)-(z+1)*tiles.shadowSize())/ tiles.qWidth();
y = ((point.y()-tiles.height()/2)+ z*tiles.shadowSize()) / tiles.qHeight();
// skip when position is illegal
if (x<0 || x>=BoardLayout::width || y<0 || y>=BoardLayout::height)
continue;
//
switch( theBoard.getBoardData(z,y,x) )
{
case (UCHAR)'3': if (align)
x--;y--;
break;
case (UCHAR)'2': if (align)
x--;
break;
case (UCHAR)'4': if (align)
y--;
break;
case (UCHAR)'1': break;
default : continue;
}
// if gameboard is empty, skip
if ( ! theBoard.getBoardData(z,y,x) )
continue;
// here, position is legal
MouseClickPos.e = z;
MouseClickPos.y = y;
MouseClickPos.x = x;
MouseClickPos.f = theBoard.getBoardData(z,y,x);
break;
}
if (MouseClickPos.e == 100) {
MouseClickPos.x = x;
MouseClickPos.y = y;
MouseClickPos.f=0;
}
}
// we swallow the draw frames mouse clicks and process here
kmahjongg'Editor::drawFrameMousePressEvent() (./kdegames/kmahjongg/Editor.cpp:549)
void Editor::drawFrameMousePressEvent( QMouseEvent* e )
{
POSITION mPos;
transformPointToPosition(e->pos(), mPos, (mode == remove));
switch (mode) {
case remove:
if (!theBoard.tileAbove(mPos) && mPos.e < BoardLayout::depth && theBoard.isTileAt(mPos) ) {
theBoard.deleteTile(mPos);
numTiles--;
statusChanged();
drawFrameMouseMovedEvent(e);
repaint(false);
}
break;
case insert: {
POSITION n = mPos;
if (n.e == 100)
n.e = 0;
else
n.e += 1;
if (canInsert(n)) {
theBoard.insertTile(n);
numTiles++;
statusChanged();
repaint(false);
}
}
break;
default:
break;
}
}
kmahjongg'Editor::drawCursor() (./kdegames/kmahjongg/Editor.cpp:586)
void Editor::drawCursor(POSITION &p, bool visible)
{
int x = (tiles.width()/2)+(p.e*tiles.shadowSize())+(p.x * tiles.qWidth());
int y = (tiles.height()/2)-(p.e*tiles.shadowSize())+(p.y * tiles.qHeight());
int w = tiles.width();
int h = tiles.height();
if (p.e==100 || !visible)
x = -1;
drawFrame->setRect(x,y,w,h, tiles.shadowSize(), mode-remove);
drawFrame->repaint(false);
}
// we swallow the draw frames mouse moves and process here
kmahjongg'Editor::drawFrameMouseMovedEvent() (./kdegames/kmahjongg/Editor.cpp:605)
void Editor::drawFrameMouseMovedEvent( QMouseEvent* e ){
POSITION mPos;
transformPointToPosition(e->pos(), mPos, (mode == remove));
if ((mPos.x==currPos.x) && (mPos.y==currPos.y) && (mPos.e==currPos.e))
return;
currPos = mPos;
statusChanged();
switch(mode) {
case insert:
POSITION next;
next = currPos;
if (next.e == 100)
next.e = 0;
else
next.e += 1;
drawCursor(next, canInsert(next));
break;
case remove:
drawCursor(currPos, 1);
break;
case move:
break;
}
}
// can we inser a tile here. We can iff
// there are tiles in all positions below us (or we are a ground level)
// there are no tiles intersecting with us on this level
kmahjongg'Editor::canInsert() (./kdegames/kmahjongg/Editor.cpp:645)
bool Editor::canInsert(POSITION &p) {
if (p.e >= BoardLayout::depth)
return (false);
if (p.y >BoardLayout::height-2)
return false;
if (p.x >BoardLayout::width-2)
return false;
POSITION n = p;
if (p.e != 0) {
n.e -= 1;
if (!theBoard.allFilled(n))
return(false);
}
return(!theBoard.anyFilled(p));
}