home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / examples / canvas / canvas.cpp.z / canvas.cpp
Encoding:
C/C++ Source or Header  |  2002-04-08  |  17.8 KB  |  748 lines

  1. #include <qdatetime.h>
  2. #include <qmainwindow.h>
  3. #include <qstatusbar.h>
  4. #include <qmessagebox.h>
  5. #include <qmenubar.h>
  6. #include <qapplication.h>
  7. #include <qpainter.h>
  8. #include <qprinter.h>
  9. #include <qlabel.h>
  10. #include <qimage.h>
  11. #include <qprogressdialog.h>
  12. #include "canvas.h"
  13.  
  14. #include <stdlib.h>
  15.  
  16. // We use a global variable to save memory - all the brushes and pens in
  17. // the mesh are shared.
  18. static QBrush *tb = 0;
  19. static QPen *tp = 0;
  20.  
  21. class EdgeItem;
  22. class NodeItem;
  23.  
  24. class EdgeItem: public QCanvasLine
  25. {
  26. public:
  27.     EdgeItem( NodeItem*, NodeItem*, QCanvas *canvas );
  28.     void setFromPoint( int x, int y ) ;
  29.     void setToPoint( int x, int y );
  30.     static int count() { return c; }
  31.     void moveBy(double dx, double dy);
  32. private:
  33.     static int c;
  34. };
  35.  
  36. static const int imageRTTI = 984376;
  37.  
  38.  
  39. class ImageItem: public QCanvasRectangle
  40. {
  41. public:
  42.     ImageItem( QImage img, QCanvas *canvas );
  43.     int rtti () const { return imageRTTI; }
  44.     bool hit( const QPoint&) const;
  45. protected:
  46.     void drawShape( QPainter & );
  47. private:
  48.     QImage image;
  49.     QPixmap pixmap;
  50. };
  51.  
  52.  
  53. ImageItem::ImageItem( QImage img, QCanvas *canvas )
  54.     : QCanvasRectangle( canvas ), image(img)
  55. {
  56.     setSize( image.width(), image.height() );
  57.  
  58. #if !defined(Q_WS_QWS)
  59.     pixmap.convertFromImage(image, OrderedAlphaDither);
  60. #endif
  61. }
  62.  
  63.  
  64. void ImageItem::drawShape( QPainter &p )
  65. {
  66. // On Qt/Embedded, we can paint a QImage as fast as a QPixmap,
  67. // but on other platforms, we need to use a QPixmap.
  68. #if defined(Q_WS_QWS)
  69.     p.drawImage( int(x()), int(y()), image, 0, 0, -1, -1, OrderedAlphaDither );
  70. #else
  71.     p.drawPixmap( int(x()), int(y()), pixmap );
  72. #endif
  73. }
  74.  
  75. bool ImageItem::hit( const QPoint &p ) const
  76. {
  77.     int ix = p.x()-int(x());
  78.     int iy = p.y()-int(y());
  79.     if ( !image.valid( ix , iy ) )
  80.     return FALSE;
  81.     QRgb pixel = image.pixel( ix, iy );
  82.     return qAlpha( pixel ) != 0;
  83. }
  84.  
  85. class NodeItem: public QCanvasEllipse
  86. {
  87. public:
  88.     NodeItem( QCanvas *canvas );
  89.     ~NodeItem() {}
  90.  
  91.     void addInEdge( EdgeItem *edge ) { inList.append( edge ); }
  92.     void addOutEdge( EdgeItem *edge ) { outList.append( edge ); }
  93.  
  94.     void moveBy(double dx, double dy);
  95.  
  96.     //    QPoint center() { return boundingRect().center(); }
  97. private:
  98.     QPtrList<EdgeItem> inList;
  99.     QPtrList<EdgeItem> outList;
  100. };
  101.  
  102.  
  103. int EdgeItem::c = 0;
  104.  
  105.  
  106. void EdgeItem::moveBy(double, double)
  107. {
  108.     //nothing
  109. }
  110.  
  111. EdgeItem::EdgeItem( NodeItem *from, NodeItem *to, QCanvas *canvas )
  112.     : QCanvasLine( canvas )
  113. {
  114.     c++;
  115.     setPen( *tp );
  116.     setBrush( *tb );
  117.     from->addOutEdge( this );
  118.     to->addInEdge( this );
  119.     setPoints( int(from->x()), int(from->y()), int(to->x()), int(to->y()) );
  120.     setZ( 127 );
  121. }
  122.  
  123. void EdgeItem::setFromPoint( int x, int y )
  124. {
  125.     setPoints( x,y, endPoint().x(), endPoint().y() );
  126. }
  127.  
  128. void EdgeItem::setToPoint( int x, int y )
  129. {
  130.     setPoints( startPoint().x(), startPoint().y(), x, y );
  131. }
  132.  
  133.  
  134.  
  135. void NodeItem::moveBy(double dx, double dy)
  136. {
  137.     QCanvasEllipse::moveBy( dx, dy );
  138.  
  139.     QPtrListIterator<EdgeItem> it1( inList );
  140.     EdgeItem *edge;
  141.     while (( edge = it1.current() )) {
  142.     ++it1;
  143.     edge->setToPoint( int(x()), int(y()) );
  144.     }
  145.     QPtrListIterator<EdgeItem> it2( outList );
  146.     while (( edge = it2.current() )) {
  147.     ++it2;
  148.     edge->setFromPoint( int(x()), int(y()) );
  149.     }
  150. }
  151.  
  152. NodeItem::NodeItem( QCanvas *canvas )
  153.     : QCanvasEllipse( 6, 6, canvas )
  154. {
  155.     setPen( *tp );
  156.     setBrush( *tb );
  157.     setZ( 128 );
  158. }
  159.  
  160. FigureEditor::FigureEditor(
  161.     QCanvas& c, QWidget* parent,
  162.     const char* name, WFlags f) :
  163.     QCanvasView(&c,parent,name,f)
  164. {
  165. }
  166.  
  167. void FigureEditor::contentsMousePressEvent(QMouseEvent* e)
  168. {
  169.     QPoint p = inverseWorldMatrix().map(e->pos());
  170.     QCanvasItemList l=canvas()->collisions(p);
  171.     for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
  172.     if ( (*it)->rtti() == imageRTTI ) {
  173.         ImageItem *item= (ImageItem*)(*it);
  174.         if ( !item->hit( p ) )
  175.          continue;
  176.     }
  177.     moving = *it;
  178.     moving_start = p;
  179.     return;
  180.     }
  181.     moving = 0;
  182. }
  183.  
  184. void FigureEditor::clear()
  185. {
  186.     QCanvasItemList list = canvas()->allItems();
  187.     QCanvasItemList::Iterator it = list.begin();
  188.     for (; it != list.end(); ++it) {
  189.     if ( *it )
  190.         delete *it;
  191.     }
  192. }
  193.  
  194. void FigureEditor::contentsMouseMoveEvent(QMouseEvent* e)
  195. {
  196.     if ( moving ) {
  197.     QPoint p = inverseWorldMatrix().map(e->pos());
  198.     moving->moveBy(p.x() - moving_start.x(),
  199.                p.y() - moving_start.y());
  200.     moving_start = p;
  201.     canvas()->update();
  202.     }
  203. }
  204.  
  205.  
  206.  
  207. BouncyLogo::BouncyLogo(QCanvas* canvas) :
  208.     QCanvasSprite(0,canvas)
  209. {
  210.     static QCanvasPixmapArray logo("qt-trans.xpm");
  211.     setSequence(&logo);
  212.     setAnimated(TRUE);
  213.     initPos();
  214. }
  215.  
  216.  
  217. const int logo_rtti = 1234;
  218.  
  219. int BouncyLogo::rtti() const
  220. {
  221.     return logo_rtti;
  222. }
  223.  
  224. void BouncyLogo::initPos()
  225. {
  226.     initSpeed();
  227.     int trial=1000;
  228.     do {
  229.     move(rand()%canvas()->width(),rand()%canvas()->height());
  230.     advance(0);
  231.     } while (trial-- && xVelocity()==0.0 && yVelocity()==0.0);
  232. }
  233.  
  234. void BouncyLogo::initSpeed()
  235. {
  236.     const double speed = 4.0;
  237.     double d = (double)(rand()%1024) / 1024.0;
  238.     setVelocity( d*speed*2-speed, (1-d)*speed*2-speed );
  239. }
  240.  
  241. void BouncyLogo::advance(int stage)
  242. {
  243.     switch ( stage ) {
  244.       case 0: {
  245.     double vx = xVelocity();
  246.     double vy = yVelocity();
  247.  
  248.     if ( vx == 0.0 && vy == 0.0 ) {
  249.         // stopped last turn
  250.         initSpeed();
  251.         vx = xVelocity();
  252.         vy = yVelocity();
  253.     }
  254.  
  255.     double nx = x() + vx;
  256.     double ny = y() + vy;
  257.  
  258.     if ( nx < 0 || nx >= canvas()->width() )
  259.         vx = -vx;
  260.     if ( ny < 0 || ny >= canvas()->height() )
  261.         vy = -vy;
  262.  
  263.     for (int bounce=0; bounce<4; bounce++) {
  264.         QCanvasItemList l=collisions(FALSE);
  265.         for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
  266.         QCanvasItem *hit = *it;
  267.         if ( hit->rtti()==logo_rtti && hit->collidesWith(this) ) {
  268.             switch ( bounce ) {
  269.               case 0:
  270.             vx = -vx;
  271.             break;
  272.               case 1:
  273.             vy = -vy;
  274.             vx = -vx;
  275.             break;
  276.               case 2:
  277.             vx = -vx;
  278.             break;
  279.               case 3:
  280.             // Stop for this turn
  281.             vx = 0;
  282.             vy = 0;
  283.             break;
  284.             }
  285.             setVelocity(vx,vy);
  286.             break;
  287.         }
  288.         }
  289.     }
  290.  
  291.     if ( x()+vx < 0 || x()+vx >= canvas()->width() )
  292.         vx = 0;
  293.     if ( y()+vy < 0 || y()+vy >= canvas()->height() )
  294.         vy = 0;
  295.  
  296.     setVelocity(vx,vy);
  297.       } break;
  298.       case 1:
  299.     QCanvasItem::advance(stage);
  300.     break;
  301.     }
  302. }
  303.  
  304. static uint mainCount = 0;
  305. static QImage *butterflyimg;
  306. static QImage *logoimg;
  307.  
  308. Main::Main(QCanvas& c, QWidget* parent, const char* name, WFlags f) :
  309.     QMainWindow(parent,name,f),
  310.     canvas(c)
  311. {
  312.     editor = new FigureEditor(canvas,this);
  313.     QMenuBar* menu = menuBar();
  314.  
  315.     QPopupMenu* file = new QPopupMenu( menu );
  316.     file->insertItem("&Fill canvas", this, SLOT(init()), CTRL+Key_F);
  317.     file->insertItem("&Erase canvas", this, SLOT(clear()), CTRL+Key_E);
  318.     file->insertItem("&New view", this, SLOT(newView()), CTRL+Key_N);
  319.     file->insertSeparator();
  320.     file->insertItem("&Print", this, SLOT(print()), CTRL+Key_P);
  321.     file->insertSeparator();
  322.     file->insertItem("E&xit", qApp, SLOT(quit()), CTRL+Key_Q);
  323.     menu->insertItem("&File", file);
  324.  
  325.     QPopupMenu* edit = new QPopupMenu( menu );
  326.     edit->insertItem("Add &Circle", this, SLOT(addCircle()), ALT+Key_C);
  327.     edit->insertItem("Add &Hexagon", this, SLOT(addHexagon()), ALT+Key_H);
  328.     edit->insertItem("Add &Polygon", this, SLOT(addPolygon()), ALT+Key_P);
  329.     edit->insertItem("Add Spl&ine", this, SLOT(addSpline()), ALT+Key_I);
  330.     edit->insertItem("Add &Text", this, SLOT(addText()), ALT+Key_T);
  331.     edit->insertItem("Add &Line", this, SLOT(addLine()), ALT+Key_L);
  332.     edit->insertItem("Add &Rectangle", this, SLOT(addRectangle()), ALT+Key_R);
  333.     edit->insertItem("Add &Sprite", this, SLOT(addSprite()), ALT+Key_S);
  334.     edit->insertItem("Create &Mesh", this, SLOT(addMesh()), ALT+Key_M );
  335.     edit->insertItem("Add &Alpha-blended image", this, SLOT(addButterfly()), ALT+Key_A);
  336.     menu->insertItem("&Edit", edit);
  337.  
  338.     QPopupMenu* view = new QPopupMenu( menu );
  339.     view->insertItem("&Enlarge", this, SLOT(enlarge()), SHIFT+CTRL+Key_Plus);
  340.     view->insertItem("Shr&ink", this, SLOT(shrink()), SHIFT+CTRL+Key_Minus);
  341.     view->insertSeparator();
  342.     view->insertItem("&Rotate clockwise", this, SLOT(rotateClockwise()), CTRL+Key_PageDown);
  343.     view->insertItem("Rotate &counterclockwise", this, SLOT(rotateCounterClockwise()), CTRL+Key_PageUp);
  344.     view->insertItem("&Zoom in", this, SLOT(zoomIn()), CTRL+Key_Plus);
  345.     view->insertItem("Zoom &out", this, SLOT(zoomOut()), CTRL+Key_Minus);
  346.     view->insertItem("Translate left", this, SLOT(moveL()), CTRL+Key_Left);
  347.     view->insertItem("Translate right", this, SLOT(moveR()), CTRL+Key_Right);
  348.     view->insertItem("Translate up", this, SLOT(moveU()), CTRL+Key_Up);
  349.     view->insertItem("Translate down", this, SLOT(moveD()), CTRL+Key_Down);
  350.     view->insertItem("&Mirror", this, SLOT(mirror()), CTRL+Key_Home);
  351.     menu->insertItem("&View", view);
  352.  
  353.     options = new QPopupMenu( menu );
  354.     dbf_id = options->insertItem("Double buffer", this, SLOT(toggleDoubleBuffer()));
  355.     options->setItemChecked(dbf_id, TRUE);
  356.     menu->insertItem("&Options",options);
  357.  
  358.     menu->insertSeparator();
  359.  
  360.     QPopupMenu* help = new QPopupMenu( menu );
  361.     help->insertItem("&About", this, SLOT(help()), Key_F1);
  362.     help->setItemChecked(dbf_id, TRUE);
  363.     menu->insertItem("&Help",help);
  364.  
  365.     statusBar();
  366.  
  367.     setCentralWidget(editor);
  368.  
  369.     printer = 0;
  370.  
  371.     init();
  372. }
  373.  
  374. void Main::init()
  375. {
  376.     clear();
  377.  
  378.     static int r=24;
  379.     srand(++r);
  380.  
  381.     mainCount++;
  382.     butterflyimg = 0;
  383.     logoimg = 0;
  384.  
  385.     int i;
  386.     for ( i=0; i<canvas.width() / 56; i++) {
  387.     addButterfly();
  388.     }
  389.     for ( i=0; i<canvas.width() / 85; i++) {
  390.     addHexagon();
  391.     }
  392.     for ( i=0; i<canvas.width() / 128; i++) {
  393.     addLogo();
  394.     }
  395. }
  396.  
  397. Main::~Main()
  398. {
  399.     delete printer;
  400.     if ( !--mainCount ) {
  401.     delete[] butterflyimg;
  402.     butterflyimg = 0;
  403.     delete[] logoimg;
  404.     logoimg = 0;
  405.     }
  406. }
  407.  
  408. void Main::newView()
  409. {
  410.     // Open a new view... have it delete when closed.
  411.     Main *m = new Main(canvas, 0, 0, WDestructiveClose);
  412.     qApp->setMainWidget(m);
  413.     m->show();
  414.     qApp->setMainWidget(0);
  415. }
  416.  
  417. void Main::clear()
  418. {
  419.     editor->clear();
  420. }
  421.  
  422. void Main::help()
  423. {
  424.     static QMessageBox* about = new QMessageBox( "Qt Canvas Example",
  425.         "<h3>The QCanvas classes example</h3>"
  426.         "<ul>"
  427.         "<li> Press ALT-S for some sprites."
  428.         "<li> Press ALT-C for some circles."
  429.         "<li> Press ALT-L for some lines."
  430.         "<li> Drag the objects around."
  431.         "<li> Read the code!"
  432.         "</ul>", QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
  433.     about->setButtonText( 1, "Dismiss" );
  434.     about->show();
  435. }
  436.  
  437. void Main::aboutQt()
  438. {
  439.     QMessageBox::aboutQt( this, "Qt Canvas Example" );
  440. }
  441.  
  442. void Main::toggleDoubleBuffer()
  443. {
  444.     bool s = !options->isItemChecked(dbf_id);
  445.     options->setItemChecked(dbf_id,s);
  446.     canvas.setDoubleBuffering(s);
  447. }
  448.  
  449. void Main::enlarge()
  450. {
  451.     canvas.resize(canvas.width()*4/3, canvas.height()*4/3);
  452. }
  453.  
  454. void Main::shrink()
  455. {
  456.     canvas.resize(canvas.width()*3/4, canvas.height()*3/4);
  457. }
  458.  
  459. void Main::rotateClockwise()
  460. {
  461.     QWMatrix m = editor->worldMatrix();
  462.     m.rotate( 22.5 );
  463.     editor->setWorldMatrix( m );
  464. }
  465.  
  466. void Main::rotateCounterClockwise()
  467. {
  468.     QWMatrix m = editor->worldMatrix();
  469.     m.rotate( -22.5 );
  470.     editor->setWorldMatrix( m );
  471. }
  472.  
  473. void Main::zoomIn()
  474. {
  475.     QWMatrix m = editor->worldMatrix();
  476.     m.scale( 2.0, 2.0 );
  477.     editor->setWorldMatrix( m );
  478. }
  479.  
  480. void Main::zoomOut()
  481. {
  482.     QWMatrix m = editor->worldMatrix();
  483.     m.scale( 0.5, 0.5 );
  484.     editor->setWorldMatrix( m );
  485. }
  486.  
  487. void Main::mirror()
  488. {
  489.     QWMatrix m = editor->worldMatrix();
  490.     m.scale( -1, 1 );
  491.     editor->setWorldMatrix( m );
  492. }
  493.  
  494. void Main::moveL()
  495. {
  496.     QWMatrix m = editor->worldMatrix();
  497.     m.translate( -16, 0 );
  498.     editor->setWorldMatrix( m );
  499. }
  500.  
  501. void Main::moveR()
  502. {
  503.     QWMatrix m = editor->worldMatrix();
  504.     m.translate( +16, 0 );
  505.     editor->setWorldMatrix( m );
  506. }
  507.  
  508. void Main::moveU()
  509. {
  510.     QWMatrix m = editor->worldMatrix();
  511.     m.translate( 0, -16 );
  512.     editor->setWorldMatrix( m );
  513. }
  514.  
  515. void Main::moveD()
  516. {
  517.     QWMatrix m = editor->worldMatrix();
  518.     m.translate( 0, +16 );
  519.     editor->setWorldMatrix( m );
  520. }
  521.  
  522. void Main::print()
  523. {
  524.     if ( !printer ) printer = new QPrinter;
  525.     if ( printer->setup(this) ) {
  526.     QPainter pp(printer);
  527.     canvas.drawArea(QRect(0,0,canvas.width(),canvas.height()),&pp,FALSE);
  528.     }
  529. }
  530.  
  531.  
  532. void Main::addSprite()
  533. {
  534.     QCanvasItem* i = new BouncyLogo(&canvas);
  535.     i->setZ(rand()%256);
  536.     i->show();
  537. }
  538.  
  539. QString butterfly_fn;
  540. QString logo_fn;
  541.  
  542.  
  543. void Main::addButterfly()
  544. {
  545.     if ( butterfly_fn.isEmpty() )
  546.     return;
  547.     if ( !butterflyimg ) {
  548.     butterflyimg = new QImage[4];
  549.     butterflyimg[0].load( butterfly_fn );
  550.     butterflyimg[1] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.75),
  551.         int(butterflyimg[0].height()*0.75) );
  552.     butterflyimg[2] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.5),
  553.         int(butterflyimg[0].height()*0.5) );
  554.     butterflyimg[3] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.25),
  555.         int(butterflyimg[0].height()*0.25) );
  556.     }
  557.     QCanvasPolygonalItem* i = new ImageItem(butterflyimg[rand()%4],&canvas);
  558.     i->move(rand()%(canvas.width()-butterflyimg->width()),
  559.         rand()%(canvas.height()-butterflyimg->height()));
  560.     i->setZ(rand()%256+250);
  561.     i->show();
  562. }
  563.  
  564. void Main::addLogo()
  565. {
  566.     if ( logo_fn.isEmpty() )
  567.     return;
  568.     if ( !logoimg ) {
  569.     logoimg = new QImage[4];
  570.     logoimg[0].load( logo_fn );
  571.     logoimg[1] = logoimg[0].smoothScale( int(logoimg[0].width()*0.75),
  572.         int(logoimg[0].height()*0.75) );
  573.     logoimg[2] = logoimg[0].smoothScale( int(logoimg[0].width()*0.5),
  574.         int(logoimg[0].height()*0.5) );
  575.     logoimg[3] = logoimg[0].smoothScale( int(logoimg[0].width()*0.25),
  576.         int(logoimg[0].height()*0.25) );
  577.     }
  578.     QCanvasPolygonalItem* i = new ImageItem(logoimg[rand()%4],&canvas);
  579.     i->move(rand()%(canvas.width()-logoimg->width()),
  580.         rand()%(canvas.height()-logoimg->width()));
  581.     i->setZ(rand()%256+256);
  582.     i->show();
  583. }
  584.  
  585.  
  586.  
  587. void Main::addCircle()
  588. {
  589.     QCanvasPolygonalItem* i = new QCanvasEllipse(50,50,&canvas);
  590.     i->setBrush( QColor(rand()%32*8,rand()%32*8,rand()%32*8) );
  591.     i->move(rand()%canvas.width(),rand()%canvas.height());
  592.     i->setZ(rand()%256);
  593.     i->show();
  594. }
  595.  
  596. void Main::addHexagon()
  597. {
  598.     QCanvasPolygon* i = new QCanvasPolygon(&canvas);
  599.     const int size = canvas.width() / 25;
  600.     QPointArray pa(6);
  601.     pa[0] = QPoint(2*size,0);
  602.     pa[1] = QPoint(size,-size*173/100);
  603.     pa[2] = QPoint(-size,-size*173/100);
  604.     pa[3] = QPoint(-2*size,0);
  605.     pa[4] = QPoint(-size,size*173/100);
  606.     pa[5] = QPoint(size,size*173/100);
  607.     i->setPoints(pa);
  608.     i->setBrush( QColor(rand()%32*8,rand()%32*8,rand()%32*8) );
  609.     i->move(rand()%canvas.width(),rand()%canvas.height());
  610.     i->setZ(rand()%256);
  611.     i->show();
  612. }
  613.  
  614. void Main::addPolygon()
  615. {
  616.     QCanvasPolygon* i = new QCanvasPolygon(&canvas);
  617.     const int size = canvas.width()/2;
  618.     QPointArray pa(6);
  619.     pa[0] = QPoint(0,0);
  620.     pa[1] = QPoint(size,size/5);
  621.     pa[2] = QPoint(size*4/5,size);
  622.     pa[3] = QPoint(size/6,size*5/4);
  623.     pa[4] = QPoint(size*3/4,size*3/4);
  624.     pa[5] = QPoint(size*3/4,size/4);
  625.     i->setPoints(pa);
  626.     i->setBrush( QColor(rand()%32*8,rand()%32*8,rand()%32*8) );
  627.     i->move(rand()%canvas.width(),rand()%canvas.height());
  628.     i->setZ(rand()%256);
  629.     i->show();
  630. }
  631.  
  632. void Main::addSpline()
  633. {
  634.     QCanvasSpline* i = new QCanvasSpline(&canvas);
  635.     const int size = canvas.width()/6;
  636.     QPointArray pa(12);
  637.     pa[0] = QPoint(0,0);
  638.     pa[1] = QPoint(size/2,0);
  639.     pa[2] = QPoint(size,size/2);
  640.     pa[3] = QPoint(size,size);
  641.     pa[4] = QPoint(size,size*3/2);
  642.     pa[5] = QPoint(size/2,size*2);
  643.     pa[6] = QPoint(0,size*2);
  644.     pa[7] = QPoint(-size/2,size*2);
  645.     pa[8] = QPoint(size/4,size*3/2);
  646.     pa[9] = QPoint(0,size);
  647.     pa[10]= QPoint(-size/4,size/2);
  648.     pa[11]= QPoint(-size/2,0);
  649.     i->setControlPoints(pa);
  650.     i->setBrush( QColor(rand()%32*8,rand()%32*8,rand()%32*8) );
  651.     i->move(rand()%canvas.width(),rand()%canvas.height());
  652.     i->setZ(rand()%256);
  653.     i->show();
  654. }
  655.  
  656. void Main::addText()
  657. {
  658.     QCanvasText* i = new QCanvasText(&canvas);
  659.     i->setText("QCanvasText");
  660.     i->move(rand()%canvas.width(),rand()%canvas.height());
  661.     i->setZ(rand()%256);
  662.     i->show();
  663. }
  664.  
  665. void Main::addLine()
  666. {
  667.     QCanvasLine* i = new QCanvasLine(&canvas);
  668.     i->setPoints( rand()%canvas.width(), rand()%canvas.height(),
  669.           rand()%canvas.width(), rand()%canvas.height() );
  670.     i->setPen( QPen(QColor(rand()%32*8,rand()%32*8,rand()%32*8), 6) );
  671.     i->setZ(rand()%256);
  672.     i->show();
  673. }
  674.  
  675. void Main::addMesh()
  676. {
  677.     int x0 = 0;
  678.     int y0 = 0;
  679.  
  680.     if ( !tb ) tb = new QBrush( Qt::red );
  681.     if ( !tp ) tp = new QPen( Qt::black );
  682.  
  683.     int nodecount = 0;
  684.  
  685.     int w = canvas.width();
  686.     int h = canvas.height();
  687.  
  688.     const int dist = 30;
  689.     int rows = h / dist;
  690.     int cols = w / dist;
  691.  
  692. #ifndef QT_NO_PROGRESSDIALOG
  693.     QProgressDialog progress( "Creating mesh...", "Abort", rows,
  694.                   this, "progress", TRUE );
  695. #endif
  696.  
  697.     QMemArray<NodeItem*> lastRow(cols);
  698.     for ( int j = 0; j < rows; j++ ) {
  699.     int n = j%2 ? cols-1 : cols;
  700.     NodeItem *prev = 0;
  701.     for ( int i = 0; i < n; i++ ) {
  702.         NodeItem *el = new NodeItem( &canvas );
  703.         nodecount++;
  704.         int r = rand();
  705.         int xrand = r %20;
  706.         int yrand = (r/20) %20;
  707.         el->move( xrand + x0 + i*dist + (j%2 ? dist/2 : 0 ),
  708.               yrand + y0 + j*dist );
  709.  
  710.         if ( j > 0 ) {
  711.         if ( i < cols-1 )
  712.             (new EdgeItem( lastRow[i], el, &canvas ))->show();
  713.         if ( j%2 )
  714.             (new EdgeItem( lastRow[i+1], el, &canvas ))->show();
  715.         else if ( i > 0 )
  716.             (new EdgeItem( lastRow[i-1], el, &canvas ))->show();
  717.         }
  718.         if ( prev ) {
  719.         (new EdgeItem( prev, el, &canvas ))->show();
  720.         }
  721.         if ( i > 0 ) lastRow[i-1] = prev;
  722.         prev = el;
  723.         el->show();
  724.     }
  725.     lastRow[n-1]=prev;
  726. #ifndef QT_NO_PROGRESSDIALOG
  727.     progress.setProgress( j );
  728.     if ( progress.wasCancelled() )
  729.         break;
  730. #endif
  731.     }
  732. #ifndef QT_NO_PROGRESSDIALOG
  733.     progress.setProgress( rows );
  734. #endif
  735.     // qDebug( "%d nodes, %d edges", nodecount, EdgeItem::count() );
  736. }
  737.  
  738. void Main::addRectangle()
  739. {
  740.     QCanvasPolygonalItem *i = new QCanvasRectangle( rand()%canvas.width(),rand()%canvas.height(),
  741.                 canvas.width()/5,canvas.width()/5,&canvas);
  742.     int z = rand()%256;
  743.     i->setBrush( QColor(z,z,z) );
  744.     i->setPen( QPen(QColor(rand()%32*8,rand()%32*8,rand()%32*8), 6) );
  745.     i->setZ(z);
  746.     i->show();
  747. }
  748.