/*************************************************************************** Description : KPuzzle - A KDE Jigsaw Puzzle Game Version : 0.2 Copyright : (C) 2000-2001 by Michael Wand EMail : mwand@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "main.h" #include "picview.h" #include "kpuzzlegame.h" #include "kpuzzleview.h" #include #include #include #include #include #include /* Constructor. Parent is the KPuzzleView object. */ CPicview::CPicview(QWidget* parent) : QWidget(parent) { _pixmap = NULL; setMouseTracking(false); setBackgroundMode(NoBackground); _vRectTopLeft = QPoint(0,0); setCursor(KCursor::crossCursor()); } /* Destructor */ CPicview::~CPicview() { if (_pixmap) delete _pixmap; } /* Paint this widget. */ void CPicview::paintEvent(QPaintEvent* e) { if (_pixmap == NULL) return; bitBlt(this,0,0,_pixmap,0,0,_pixmap->width(),_pixmap->height()); QPainter pt(this); QPen pen(QColor(255,255,255),2,DashLine); pt.setPen(pen); pt.drawRect(vRect()); } /* Mouse event. */ void CPicview::mouseMoveEvent(QMouseEvent* e) { QPoint pos = DPtoLP(e->pos()); QRect udRect(pos,_vRectSize); udRect = udRect.unite(vRect()); _vRectTopLeft = pos; emit sigChangeViewPos(translate2GamePixmap(_vRectTopLeft)); update(udRect); } /* Mouse event. */ void CPicview::mousePressEvent(QMouseEvent* e) { QPoint pos = DPtoLP(e->pos()); QRect udRect(pos,_vRectSize); udRect = udRect.unite(vRect()); _vRectTopLeft = pos; emit sigChangeViewPos(translate2GamePixmap(_vRectTopLeft)); update(udRect); } /* Mouse event. */ void CPicview::mouseReleaseEvent(QMouseEvent* e) { } /* Coordinate transformation */ QPoint CPicview::DPtoLP(QPoint p) { /* Mouse click is always the middle of a rectangle */ p.setX(p.x() - _vRectSize.width() / 2); if (p.x() < 0) p.setX(0); if (realPixmapSize().width() - p.x() < _vRectSize.width()) p.setX(realPixmapSize().width() - _vRectSize.width()); p.setY(p.y() - _vRectSize.height() / 2); if (p.y() < 0) p.setY(0); if (realPixmapSize().height() - p.y() < _vRectSize.height()) p.setY(realPixmapSize().height() - _vRectSize.height()); return p; } /* Update the pixmap this widget is showing. */ void CPicview::updatePixmap(QPixmap* p,QRect udRect) { ASSERT(PICVIEW_WIDTH == this->width()); ASSERT(PICVIEW_HEIGHT == this->height()); if (p) { QWMatrix sc; if ((float) p->height() / p->width() > 0.75) sc.scale(PICVIEW_HEIGHT / p->height(), PICVIEW_HEIGHT / p->height()); else sc.scale(PICVIEW_WIDTH / p->width(), PICVIEW_WIDTH / p->width()); if (!_pixmap) _pixmap = new QPixmap(this->size()); QPixmap* tempPxm = new QPixmap; *tempPxm = p->xForm(sc); _pixmap->fill(black); bitBlt(_pixmap,QPoint(0,0),tempPxm,tempPxm->rect()); _vRectSize = tempPxm->size(); _realPixmapSize = tempPxm->size(); int newWidth = (int) (_vRectSize.width() * ((float) VISIBLE_PIXMAP_SIZE / p->width())); if (newWidth < _vRectSize.width()) /* Rectangle must be shown */ _vRectSize.setWidth(newWidth); int newHeight = (int) (_vRectSize.height() * ((float) VISIBLE_PIXMAP_SIZE / p->height())); if (newHeight < _vRectSize.height()) /* Rectangle must be shown */ _vRectSize.setHeight(newHeight); _gamePixmapSize = p->size(); } update(udRect); } /* Update the pixmap this widget is showing. This function * is used when the player has correctly placed a piece. */ void CPicview::addPiece(QPixmap* piece,QPoint pos) { QWMatrix sc; sc.scale(scaleX(),scaleY()); QPixmap np = piece->xForm(sc); QSize realPieceSize = ((KPuzzleView*) parentWidget())->game()->pieceSize(); int displace = ((KPuzzleView*) parentWidget())->game()->displace(); float pieceWidth = realPieceSize.width() * scaleX(); float pieceHeight = realPieceSize.height() * scaleY(); QPoint newPos((int) (pos.x() * pieceWidth - displace * scaleX()), (int) (pos.y() * pieceHeight - displace * scaleY())); bitBlt(_pixmap,newPos,&np,np.rect(),CopyROP,false); update(QRect(newPos,np.size()).unite(vRect())); } /* Called when the area of the game pixmap visible in the * KGameWidget changes. Implies the change of the * _vRect variables. */ void CPicview::slotChangeViewPos(QPoint pos) { _vRectTopLeft = translateFromGamePixmap(pos); update(); } /* Convent a position in this widget to a position on * the game pixmap. This is essentially a scaling. */ QPoint CPicview::translate2GamePixmap(QPoint p) { float x = (float) p.x() / realPixmapSize().width(); float y = (float) p.y() / realPixmapSize().height(); if (x > 1.0) x = 1.0; if (y > 1.0) x = 1.0; QPoint res((int) (x * gamePixmapSize().width()), (int) (y * gamePixmapSize().height())); return res; } /* Convent a position on the game pixmap to a position in * this widget. This is essentially a scaling. */ QPoint CPicview::translateFromGamePixmap(QPoint p) { float x = (float) p.x() / gamePixmapSize().width(); float y = (float) p.y() / gamePixmapSize().height(); QPoint res((int) (x * realPixmapSize().width()),(int) (y * realPixmapSize().height())); return res; }