00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "kgamecanvas.h"
00030
00031 #include <QPaintEvent>
00032 #include <QPainter>
00033 #include <QRegion>
00034 #include <QApplication>
00035 #include <QTimer>
00036 #include <QTime>
00037
00038
00039
00040
00041
00042
00043
00044 #define DEBUG_DONT_MERGE_UPDATES 0
00045 #define DEBUG_CANVAS_PAINTS 0
00046
00047
00048
00049
00050 KGameCanvasAbstract::KGameCanvasAbstract() {
00051
00052 }
00053
00054 KGameCanvasAbstract::~KGameCanvasAbstract() {
00055
00056 for(int i=0;i<m_items.size();i++)
00057 m_items[i]->m_canvas = NULL;
00058 }
00059
00060 KGameCanvasItem* KGameCanvasAbstract::itemAt(const QPoint &pt) const {
00061 for(int i=m_items.size()-1;i>=0;i--) {
00062 KGameCanvasItem *el = m_items[i];
00063 if(el->m_visible && el->rect().contains(pt))
00064 return el;
00065 }
00066 return NULL;
00067 }
00068
00069 QList<KGameCanvasItem*> KGameCanvasAbstract::itemsAt(const QPoint &pt) const {
00070 QList<KGameCanvasItem*> retv;
00071
00072 for(int i=m_items.size()-1;i>=0;i--) {
00073 KGameCanvasItem *el = m_items[i];
00074 if(el->m_visible && el->rect().contains(pt))
00075 retv.append(el);
00076 }
00077
00078 return retv;
00079 }
00080
00081
00082
00083
00084
00085 class KGameCanvasWidgetPrivate {
00086 public:
00087 QTimer m_anim_timer;
00088 QTime m_anim_time;
00089 bool m_pending_update;
00090 QRegion m_pending_update_reg;
00091
00092 #if DEBUG_CANVAS_PAINTS
00093 bool debug_paints;
00094 #endif //DEBUG_CANVAS_PAINTS
00095
00096 KGameCanvasWidgetPrivate()
00097 : m_pending_update(false)
00098 #if DEBUG_CANVAS_PAINTS
00099 , debug_paints(false)
00100 #endif
00101 {}
00102 };
00103
00104 KGameCanvasWidget::KGameCanvasWidget(QWidget* parent)
00105 : QWidget(parent)
00106 , priv(new KGameCanvasWidgetPrivate()) {
00107 priv->m_anim_time.start();
00108 connect(&priv->m_anim_timer, SIGNAL(timeout()), this, SLOT(processAnimations()));
00109 }
00110
00111 KGameCanvasWidget::~KGameCanvasWidget() {
00112 delete priv;
00113 }
00114
00115 void KGameCanvasWidget::ensureAnimating() {
00116 if(!priv->m_anim_timer.isActive() )
00117 priv->m_anim_timer.start();
00118 }
00119
00120 void KGameCanvasWidget::ensurePendingUpdate() {
00121 if(priv->m_pending_update)
00122 return;
00123 priv->m_pending_update = true;
00124
00125 #if DEBUG_DONT_MERGE_UPDATES
00126 updateChanges();
00127 #else //DEBUG_DONT_MERGE_UPDATES
00128 QTimer::singleShot( 0, this, SLOT(updateChanges()) );
00129 #endif //DEBUG_DONT_MERGE_UPDATES
00130 }
00131
00132 void KGameCanvasWidget::updateChanges() {
00133 for(int i=0;i<m_items.size();i++) {
00134 KGameCanvasItem *el = m_items.at(i);
00135
00136 if(el->m_changed)
00137 el->updateChanges();
00138 }
00139 priv->m_pending_update = false;
00140
00141 #if DEBUG_CANVAS_PAINTS
00142 repaint();
00143 priv->debug_paints = true;
00144 repaint( priv->m_pending_update_reg );
00145 QApplication::syncX();
00146 priv->debug_paints = false;
00147 usleep(100000);
00148 repaint( priv->m_pending_update_reg );
00149 QApplication::syncX();
00150 usleep(100000);
00151 #else //DEBUG_CANVAS_PAINTS
00152 repaint( priv->m_pending_update_reg );
00153 #endif //DEBUG_CANVAS_PAINTS
00154
00155 priv->m_pending_update_reg = QRegion();
00156 }
00157
00158 void KGameCanvasWidget::invalidate(const QRect& r, bool ) {
00159 priv->m_pending_update_reg |= r;
00160 ensurePendingUpdate();
00161 }
00162
00163 void KGameCanvasWidget::invalidate(const QRegion& r, bool ) {
00164 priv->m_pending_update_reg |= r;
00165 ensurePendingUpdate();
00166 }
00167
00168 void KGameCanvasWidget::paintEvent(QPaintEvent *event) {
00169 #if DEBUG_CANVAS_PAINTS
00170 if(priv->debug_paints)
00171 {
00172 QPainter p(this);
00173 p.fillRect(event->rect(), Qt::magenta);
00174 return;
00175 }
00176 #endif //DEBUG_CANVAS_PAINTS
00177
00178 {QPainter p(this);
00179 QRect evr = event->rect();
00180 QRegion evreg = event->region();
00181
00182 for(int i=0;i<m_items.size();i++) {
00183 KGameCanvasItem *el = m_items.at(i);
00184 if( el->m_visible && evr.intersects( el->rect() )
00185 && evreg.contains( el->rect() ) ) {
00186 el->m_last_rect = el->rect();
00187 el->paintInternal(&p, evr, evreg, QPoint(), 1.0 );
00188 }
00189 }}
00190
00191 QApplication::syncX();
00192 }
00193
00194 void KGameCanvasWidget::processAnimations() {
00195 if(m_animated_items.empty() ) {
00196 priv->m_anim_timer.stop();
00197 return;
00198 }
00199
00200 int tm = priv->m_anim_time.elapsed();
00201
00202
00203
00204
00205 QList<KGameCanvasItem*> ait = m_animated_items;
00206 for(int i=0;i<ait.size();i++) {
00207 KGameCanvasItem *el = ait[i];
00208 el->advance(tm);
00209 }
00210
00211 if(m_animated_items.empty() )
00212 priv->m_anim_timer.stop();
00213 }
00214
00215 void KGameCanvasWidget::setAnimationDelay(int d) {
00216 priv->m_anim_timer.setInterval(d);
00217 }
00218
00219 int KGameCanvasWidget::mSecs() {
00220 return priv->m_anim_time.elapsed();
00221 }
00222
00223 KGameCanvasWidget* KGameCanvasWidget::topLevelCanvas() {
00224 return this;
00225 }
00226
00227 QPoint KGameCanvasWidget::canvasPosition() const {
00228 return QPoint(0, 0);
00229 }
00230
00231
00232
00233
00234 KGameCanvasItem::KGameCanvasItem(KGameCanvasAbstract* KGameCanvas)
00235 : m_visible(false)
00236 , m_animated(false)
00237 , m_opacity(255)
00238 , m_pos(0,0)
00239 , m_canvas(KGameCanvas)
00240 , m_changed(false) {
00241 if(m_canvas) m_canvas->m_items.append(this);
00242 }
00243
00244 KGameCanvasItem::~KGameCanvasItem() {
00245 if(m_canvas) {
00246 m_canvas->m_items.removeAll(this);
00247 if(m_animated)
00248 m_canvas->m_animated_items.removeAll(this);
00249 if(m_visible)
00250 m_canvas->invalidate(m_last_rect, false);
00251 }
00252 }
00253
00254 void KGameCanvasItem::changed() {
00255 m_changed = true;
00256
00257
00258
00259 if(m_canvas)
00260 m_canvas->ensurePendingUpdate();
00261 }
00262
00263 void KGameCanvasItem::updateChanges() {
00264 if(!m_changed)
00265 return;
00266 if(m_canvas) {
00267 m_canvas->invalidate(m_last_rect, false);
00268 if(m_visible)
00269 m_canvas->invalidate(rect());
00270 }
00271 m_changed = false;
00272 }
00273
00274 QPixmap *KGameCanvasItem::transparence_pixmap_cache = NULL;
00275
00276 QPixmap* KGameCanvasItem::getTransparenceCache(const QSize &s) {
00277 if(!transparence_pixmap_cache)
00278 transparence_pixmap_cache = new QPixmap();
00279 if(s.width()>transparence_pixmap_cache->width() ||
00280 s.height()>transparence_pixmap_cache->height()) {
00281
00282
00283 *transparence_pixmap_cache = QPixmap::fromImage( QImage(
00284 s.expandedTo(transparence_pixmap_cache->size()), QImage::Format_ARGB32 ) );
00285 }
00286
00287 return transparence_pixmap_cache;
00288 }
00289
00290 void KGameCanvasItem::paintInternal(QPainter* pp, const QRect& ,
00291 const QRegion& , const QPoint& , double cumulative_opacity) {
00292 int opacity = int(cumulative_opacity*m_opacity + 0.5);
00293
00294 if(opacity <= 0)
00295 return;
00296
00297 if(opacity >= 255) {
00298 paint(pp);
00299 return;
00300 }
00301
00302 if(!layered()) {
00303 pp->setOpacity(opacity/255.0);
00304 paint(pp);
00305 pp->setOpacity(1.0);
00306 return;
00307 }
00308
00309 QRect mr = rect();
00310 QPixmap* cache = getTransparenceCache(mr.size());
00311
00312 {
00313 QPainter p(cache);
00314
00315
00316 p.setBrush(QColor(255,255,255,0));
00317 p.setPen(Qt::NoPen);
00318 p.setCompositionMode(QPainter::CompositionMode_Source);
00319 p.drawRect(QRect(QPoint(),mr.size()));
00320
00321
00322 p.translate(-mr.topLeft());
00323 paint(&p);
00324 p.translate(mr.topLeft());
00325
00326
00327 p.setBrush( QColor(255,255,255,255-opacity) );
00328 p.setPen( Qt::NoPen );
00329 p.setCompositionMode( QPainter::CompositionMode_DestinationOut );
00330 p.drawRect( QRect(QPoint(),mr.size()) );
00331 }
00332
00333 pp->drawPixmap(mr.topLeft(), *cache, QRect(QPoint(),mr.size()) );
00334 }
00335
00336 void KGameCanvasItem::putInCanvas(KGameCanvasAbstract *c) {
00337 if(m_canvas == c)
00338 return;
00339
00340 if(m_canvas) {
00341 if(m_visible)
00342 m_canvas->invalidate(m_last_rect, false);
00343 m_canvas->m_items.removeAll(this);
00344 if(m_animated)
00345 m_canvas->m_animated_items.removeAll(this);
00346 }
00347
00348 m_canvas = c;
00349
00350 if(m_canvas) {
00351 m_canvas->m_items.append(this);
00352 if(m_animated) {
00353 m_canvas->m_animated_items.append(this);
00354 m_canvas->ensureAnimating();
00355 }
00356 if(m_visible)
00357 changed();
00358 }
00359 }
00360
00361 void KGameCanvasItem::setVisible(bool v) {
00362 if(m_visible == v)
00363 return;
00364
00365 m_visible = v;
00366 if(m_canvas) {
00367 if(!v)
00368 m_canvas->invalidate(m_last_rect, false);
00369 else
00370 changed();
00371 }
00372 if(!v)
00373 m_last_rect = QRect();
00374 }
00375
00376 void KGameCanvasItem::setAnimated(bool a) {
00377 if(m_animated == a)
00378 return;
00379
00380 m_animated = a;
00381 if(m_canvas) {
00382 if(a) {
00383 m_canvas->m_animated_items.append(this);
00384 m_canvas->ensureAnimating();
00385 }
00386 else
00387 m_canvas->m_animated_items.removeAll(this);
00388 }
00389 }
00390
00391 void KGameCanvasItem::setOpacity(int o) {
00392 if (o<0) o=0;
00393 if (o>255) o = 255;
00394 m_opacity = o;
00395
00396 if(m_canvas && m_visible)
00397 changed();
00398 }
00399
00400 bool KGameCanvasItem::layered() const { return true; }
00401
00402 void KGameCanvasItem::advance(int ) { }
00403
00404 void KGameCanvasItem::updateAfterRestack(int from, int to)
00405 {
00406 int inc = from>to ? -1 : 1;
00407
00408 QRegion upd;
00409 for(int i=from; i!=to;i+=inc)
00410 {
00411 KGameCanvasItem *el = m_canvas->m_items.at(i);
00412 if(!el->m_visible)
00413 continue;
00414
00415 QRect r = el->rect() & rect();
00416 if(!r.isEmpty())
00417 upd |= r;
00418 }
00419
00420 if(!upd.isEmpty())
00421 m_canvas->invalidate(upd);
00422 }
00423
00424 void KGameCanvasItem::raise()
00425 {
00426 if(!m_canvas || m_canvas->m_items.last() == this)
00427 return;
00428
00429 int old_pos = m_canvas->m_items.indexOf(this);
00430 m_canvas->m_items.removeAt(old_pos);
00431 m_canvas->m_items.append(this);
00432 if(m_visible)
00433 updateAfterRestack(old_pos, m_canvas->m_items.size()-1);
00434 }
00435
00436 void KGameCanvasItem::lower()
00437 {
00438 if(!m_canvas || m_canvas->m_items.first() == this)
00439 return;
00440
00441 int old_pos = m_canvas->m_items.indexOf(this);
00442 m_canvas->m_items.removeAt(old_pos);
00443 m_canvas->m_items.prepend(this);
00444
00445 if(m_visible)
00446 updateAfterRestack(old_pos, 0);
00447 }
00448
00449 void KGameCanvasItem::stackOver(KGameCanvasItem* ref)
00450 {
00451 if(!m_canvas)
00452 return;
00453
00454 if(ref->m_canvas != m_canvas)
00455 {
00456 qCritical("KGameCanvasItem::stackOver: Argument must be a sibling item!\n");
00457 return;
00458 }
00459
00460 int i = m_canvas->m_items.indexOf( ref );
00461 if(i < m_canvas->m_items.size()-2 && m_canvas->m_items[i+1] == this)
00462 return;
00463
00464 int old_pos = m_canvas->m_items.indexOf(this);
00465 m_canvas->m_items.removeAt(old_pos);
00466 i = m_canvas->m_items.indexOf(ref);
00467 m_canvas->m_items.insert(i+1,this);
00468
00469 if(m_visible)
00470 updateAfterRestack(old_pos, i+1);
00471 }
00472
00473 void KGameCanvasItem::stackUnder(KGameCanvasItem* ref)
00474 {
00475 if(!m_canvas)
00476 return;
00477
00478
00479 if(ref->m_canvas != m_canvas)
00480 {
00481 qCritical("KGameCanvasItem::stackUnder: Argument must be a sibling item!\n");
00482 return;
00483 }
00484
00485 int i = m_canvas->m_items.indexOf( ref );
00486 if(i >= 1 && m_canvas->m_items[i-1] == this)
00487 return;
00488
00489 int old_pos = m_canvas->m_items.indexOf(this);
00490 m_canvas->m_items.removeAt(old_pos);
00491 i = m_canvas->m_items.indexOf(ref);
00492 m_canvas->m_items.insert(i,this);
00493
00494 if(m_visible)
00495 updateAfterRestack(old_pos, i);
00496 }
00497
00498 void KGameCanvasItem::moveTo(const QPoint &newpos)
00499 {
00500 if(m_pos == newpos)
00501 return;
00502 m_pos = newpos;
00503 if(m_visible && m_canvas)
00504 changed();
00505 }
00506
00507 QPoint KGameCanvasItem::absolutePosition() const
00508 {
00509 if (m_canvas) {
00510 return m_canvas->canvasPosition() + m_pos;
00511 }
00512 else {
00513 return m_pos;
00514 }
00515 }
00516
00517
00518
00519
00520 KGameCanvasGroup::KGameCanvasGroup(KGameCanvasAbstract* KGameCanvas)
00521 : KGameCanvasItem(KGameCanvas)
00522 , KGameCanvasAbstract()
00523 , m_child_rect_changed(true) {
00524
00525 }
00526
00527 KGameCanvasGroup::~KGameCanvasGroup() {
00528
00529 }
00530
00531 void KGameCanvasGroup::ensureAnimating() {
00532 setAnimated(true);
00533 }
00534
00535 void KGameCanvasGroup::ensurePendingUpdate() {
00536 if(!m_changed || !m_child_rect_changed) {
00537 m_child_rect_changed = true;
00538 KGameCanvasItem::changed();
00539 }
00540 }
00541
00542 void KGameCanvasGroup::updateChanges() {
00543 if(!m_changed)
00544 return;
00545 for(int i=0;i<m_items.size();i++) {
00546 KGameCanvasItem *el = m_items.at(i);
00547
00548 if(el->m_changed)
00549 el->updateChanges();
00550 }
00551 m_changed = false;
00552 }
00553
00554 void KGameCanvasGroup::changed() {
00555 if(!m_changed) {
00556 KGameCanvasItem::changed();
00557
00558 for(int i=0;i<m_items.size();i++)
00559 m_items[i]->changed();
00560 }
00561 }
00562
00563 void KGameCanvasGroup::invalidate(const QRect& r, bool translate) {
00564 if(m_canvas)
00565 m_canvas->invalidate(translate ? r.translated(m_pos) : r, translate);
00566 if(!m_changed)
00567 ensurePendingUpdate();
00568 }
00569
00570 void KGameCanvasGroup::invalidate(const QRegion& r, bool translate) {
00571 if(m_canvas)
00572 m_canvas->invalidate(translate ? r.translated(m_pos) : r, translate);
00573 if(!m_changed)
00574 ensurePendingUpdate();
00575 }
00576
00577 void KGameCanvasGroup::advance(int msecs) {
00578
00579
00580
00581
00582 QList<KGameCanvasItem*> ait = m_animated_items;
00583 for(int i=0;i<ait.size();i++)
00584 {
00585 KGameCanvasItem *el = ait[i];
00586 el->advance(msecs);
00587 }
00588
00589 if(m_animated_items.empty())
00590 setAnimated(false);
00591 }
00592
00593 void KGameCanvasGroup::paintInternal(QPainter* p, const QRect& prect,
00594 const QRegion& preg, const QPoint& delta, double cumulative_opacity) {
00595 cumulative_opacity *= (m_opacity/255.0);
00596
00597 QPoint adelta = delta;
00598 adelta += m_pos;
00599 p->translate(m_pos);
00600
00601 for(int i=0;i<m_items.size();i++) {
00602 KGameCanvasItem *el = m_items.at(i);
00603 QRect r = el->rect().translated(adelta);
00604
00605 if( el->m_visible && prect.intersects( r ) && preg.contains( r ) ) {
00606 el->m_last_rect = r;
00607 el->paintInternal(p,prect,preg,adelta,cumulative_opacity);
00608 }
00609 }
00610
00611 p->translate(-m_pos);
00612 }
00613
00614 void KGameCanvasGroup::paint(QPainter* ) {
00615 Q_ASSERT(!"This function should never be called");
00616 }
00617
00618 QRect KGameCanvasGroup::rect() const
00619 {
00620 if(!m_child_rect_changed)
00621 return m_last_child_rect.translated(m_pos);
00622
00623 m_child_rect_changed = false;
00624 m_last_child_rect = QRect();
00625 for(int i=0;i<m_items.size();i++)
00626 {
00627 KGameCanvasItem *el = m_items[i];
00628 if(el->m_visible)
00629 m_last_child_rect |= el->rect();
00630 }
00631
00632 return m_last_child_rect.translated(m_pos);
00633 }
00634
00635 KGameCanvasWidget* KGameCanvasGroup::topLevelCanvas()
00636 {
00637 return m_canvas ? m_canvas->topLevelCanvas() : NULL;
00638 }
00639
00640 QPoint KGameCanvasGroup::canvasPosition() const {
00641 return KGameCanvasItem::absolutePosition();
00642 }
00643
00644
00645
00646
00647 KGameCanvasDummy::KGameCanvasDummy(KGameCanvasAbstract* KGameCanvas)
00648 : KGameCanvasItem(KGameCanvas)
00649 {
00650
00651 }
00652
00653 KGameCanvasDummy::~KGameCanvasDummy()
00654 {
00655
00656 }
00657
00658 void KGameCanvasDummy::paint(QPainter* ) {
00659 }
00660
00661 QRect KGameCanvasDummy::rect() const
00662 {
00663 return QRect();
00664 }
00665
00666
00667
00668
00669
00670 KGameCanvasPixmap::KGameCanvasPixmap(const QPixmap& p, KGameCanvasAbstract* KGameCanvas)
00671 : KGameCanvasItem(KGameCanvas), m_pixmap(p) {
00672
00673 }
00674
00675 KGameCanvasPixmap::KGameCanvasPixmap(KGameCanvasAbstract* KGameCanvas)
00676 : KGameCanvasItem(KGameCanvas) {
00677
00678 }
00679
00680 KGameCanvasPixmap::~KGameCanvasPixmap() {
00681
00682 }
00683
00684 void KGameCanvasPixmap::setPixmap(const QPixmap& p) {
00685 m_pixmap = p;
00686 if(visible() && canvas() )
00687 changed();
00688 }
00689
00690 void KGameCanvasPixmap::paint(QPainter* p) {
00691 p->drawPixmap(pos(), m_pixmap);
00692 }
00693
00694 QRect KGameCanvasPixmap::rect() const {
00695 return QRect(pos(), m_pixmap.size());
00696 }
00697
00698
00699
00700
00701
00702 KGameCanvasTiledPixmap::KGameCanvasTiledPixmap(const QPixmap& pixmap, const QSize &size, const QPoint &origin,
00703 bool move_orig, KGameCanvasAbstract* KGameCanvas)
00704 : KGameCanvasItem(KGameCanvas)
00705 , m_pixmap(pixmap)
00706 , m_size(size)
00707 , m_origin(origin)
00708 , m_move_orig(move_orig) {
00709
00710 }
00711
00712 KGameCanvasTiledPixmap::KGameCanvasTiledPixmap(KGameCanvasAbstract* KGameCanvas)
00713 : KGameCanvasItem(KGameCanvas)
00714 , m_size(0,0)
00715 , m_origin(0,0)
00716 , m_move_orig(false) {
00717
00718 }
00719
00720 KGameCanvasTiledPixmap::~KGameCanvasTiledPixmap() {
00721
00722 }
00723
00724 void KGameCanvasTiledPixmap::setPixmap(const QPixmap& pixmap) {
00725 m_pixmap = pixmap;
00726 if(visible() && canvas() )
00727 changed();
00728 }
00729
00730 void KGameCanvasTiledPixmap::setSize(const QSize &size) {
00731 m_size = size;
00732 if(visible() && canvas() )
00733 changed();
00734 }
00735
00736 void KGameCanvasTiledPixmap::setOrigin(const QPoint &origin)
00737 {
00738 m_origin = m_move_orig ? origin - pos() : origin;
00739
00740 if(visible() && canvas() )
00741 changed();
00742 }
00743
00744
00745 void KGameCanvasTiledPixmap::setMoveOrigin(bool move_orig)
00746 {
00747 if(move_orig && !m_move_orig)
00748 m_origin -= pos();
00749 if(move_orig && !m_move_orig)
00750 m_origin += pos();
00751 m_move_orig = move_orig;
00752 }
00753
00754 void KGameCanvasTiledPixmap::paint(QPainter* p)
00755 {
00756 if(m_move_orig)
00757 p->drawTiledPixmap( rect(), m_pixmap, m_origin);
00758 else
00759 p->drawTiledPixmap( rect(), m_pixmap, m_origin+pos() );
00760 }
00761
00762 QRect KGameCanvasTiledPixmap::rect() const
00763 {
00764 return QRect(pos(), m_size);
00765 }
00766
00767
00768
00769
00770
00771 KGameCanvasRectangle::KGameCanvasRectangle(const QColor& color, const QSize &size, KGameCanvasAbstract* KGameCanvas)
00772 : KGameCanvasItem(KGameCanvas)
00773 , m_color(color)
00774 , m_size(size)
00775 {
00776
00777 }
00778
00779 KGameCanvasRectangle::KGameCanvasRectangle(KGameCanvasAbstract* KGameCanvas)
00780 : KGameCanvasItem(KGameCanvas)
00781 , m_size(0,0)
00782 {
00783
00784 }
00785
00786 KGameCanvasRectangle::~KGameCanvasRectangle()
00787 {
00788
00789 }
00790
00791 void KGameCanvasRectangle::setColor(const QColor& color)
00792 {
00793 m_color = color;
00794 if(visible() && canvas() )
00795 changed();
00796 }
00797
00798 void KGameCanvasRectangle::setSize(const QSize &size)
00799 {
00800 m_size = size;
00801 if(visible() && canvas() )
00802 changed();
00803 }
00804
00805 void KGameCanvasRectangle::paint(QPainter* p) {
00806 p->fillRect( rect(), m_color );
00807 }
00808
00809 QRect KGameCanvasRectangle::rect() const {
00810 return QRect(pos(), m_size);
00811 }
00812
00813
00814
00815
00816
00817 KGameCanvasText::KGameCanvasText(const QString& text, const QColor& color,
00818 const QFont& font, HPos hp, VPos vp,
00819 KGameCanvasAbstract* KGameCanvas)
00820 : KGameCanvasItem(KGameCanvas)
00821 , m_text(text)
00822 , m_color(color)
00823 , m_font(font)
00824 , m_hpos(hp)
00825 , m_vpos(vp) {
00826 calcBoundingRect();
00827 }
00828
00829 KGameCanvasText::KGameCanvasText(KGameCanvasAbstract* KGameCanvas)
00830 : KGameCanvasItem(KGameCanvas)
00831
00832 , m_color(Qt::black)
00833 , m_font(QApplication::font())
00834 , m_hpos(HStart)
00835 , m_vpos(VBaseline) {
00836
00837 }
00838
00839 KGameCanvasText::~KGameCanvasText() {
00840
00841 }
00842
00843 void KGameCanvasText::calcBoundingRect() {
00844 m_bounding_rect = QFontMetrics(m_font).boundingRect(m_text);
00845
00846
00847
00848
00849
00850 }
00851
00852 void KGameCanvasText::setText(const QString& text) {
00853 if(m_text == text)
00854 return;
00855 m_text = text;
00856 calcBoundingRect();
00857
00858 if(visible() && canvas() )
00859 changed();
00860 }
00861
00862 void KGameCanvasText::setColor(const QColor& color) {
00863 m_color = color;
00864 }
00865
00866 void KGameCanvasText::setFont(const QFont& font) {
00867 m_font = font;
00868 calcBoundingRect();
00869
00870 if(visible() && canvas() )
00871 changed();
00872 }
00873
00874 void KGameCanvasText::setPositioning(HPos hp, VPos vp) {
00875 pos() += offsetToDrawPos();
00876 m_hpos = hp;
00877 m_vpos = vp;
00878 pos() -= offsetToDrawPos();
00879 }
00880
00881 QPoint KGameCanvasText::offsetToDrawPos() const {
00882 QPoint retv;
00883
00884 switch(m_hpos) {
00885 case HStart:
00886 retv.setX(0);
00887 break;
00888 case HLeft:
00889 retv.setX(-m_bounding_rect.left());
00890 break;
00891 case HRight:
00892 retv.setX(-m_bounding_rect.right());
00893 break;
00894 case HCenter:
00895 retv.setX(-(m_bounding_rect.left()+m_bounding_rect.right())/2);
00896 break;
00897 }
00898
00899 switch(m_vpos) {
00900 case VBaseline:
00901 retv.setY(0);
00902 break;
00903 case VTop:
00904 retv.setY(-m_bounding_rect.top());
00905 break;
00906 case VBottom:
00907 retv.setY(-m_bounding_rect.bottom());
00908 break;
00909 case VCenter:
00910 retv.setY(-(m_bounding_rect.top()+m_bounding_rect.bottom())/2);
00911 break;
00912 }
00913
00914 return retv;
00915 }
00916
00917 void KGameCanvasText::paint(QPainter* p) {
00918 p->setPen(m_color);
00919 p->setFont(m_font);
00920 p->drawText( pos() + offsetToDrawPos(), m_text);
00921 }
00922
00923 QRect KGameCanvasText::rect() const {
00924 return m_bounding_rect.translated( pos() + offsetToDrawPos() );
00925 }
00926
00927
00928
00929
00930
00931 KGameCanvasPicture::KGameCanvasPicture(const QPicture& p, KGameCanvasAbstract* KGameCanvas)
00932 : KGameCanvasItem(KGameCanvas), m_picture(p)
00933 {
00934
00935 }
00936
00937 KGameCanvasPicture::KGameCanvasPicture(KGameCanvasAbstract* KGameCanvas)
00938 : KGameCanvasItem(KGameCanvas)
00939 {
00940
00941 }
00942
00943 KGameCanvasPicture::~KGameCanvasPicture()
00944 {