00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "canvas.h"
00012
00013 #include <math.h>
00014
00015 #include <qinputdialog.h>
00016 #include <qevent.h>
00017 #include <qpainter.h>
00018 #include <qtooltip.h>
00019 #include <qrect.h>
00020 #include <qpoint.h>
00021 #include <qcolordialog.h>
00022 #include <qfiledialog.h>
00023 #include <qcursor.h>
00024 #include <qimage.h>
00025 #include <qstrlist.h>
00026
00027 #define min(a,b) (((a)<(b))?(a):(b))
00028 #define max(a,b) (((a)<(b))?(b):(a))
00029 #define abs(a) (((a)<0)?(-(a)):(a))
00030
00031 const bool no_writing = FALSE;
00032
00033 Canvas::Canvas( QWidget *parent, const char *name )
00034 : QWidget( parent, name, WStaticContents ), pen( Qt::red, 3 ), eraser(colorGroup().base(),3),
00035 mousePressed( FALSE ), buffer( width(), height() ) {
00036 setBackgroundMode( QWidget::PaletteBase );
00037 #ifndef QT_NO_CURSOR
00038
00039 setCursor( Qt::crossCursor );
00040 #endif
00041
00042 clearScreen();
00043 shape = LINE;
00044 }
00045
00046 void Canvas::save( const QString &filename, const QString &format ) {
00047 if ( !no_writing )
00048 buffer.save( filename, format.upper() );
00049 }
00050
00051 void Canvas::clearScreen() {
00052 buffer.fill( colorGroup().base() );
00053 repaint( FALSE );
00054 }
00055
00056 void Canvas::mousePressEvent( QMouseEvent *e ) {
00057 mousePressed = TRUE;
00058 start = e->pos();
00059 }
00060
00061 void Canvas::mouseReleaseEvent( QMouseEvent *e ) {
00062 mousePressed = FALSE;
00063 draw(start,e->pos());
00064 repaint(true);
00065 }
00066
00067 void Canvas::draw(const QPoint & q, const QPoint & p, bool definitive, bool erase) {
00068 QPainter painter;
00069 if (definitive)
00070 painter.begin( &buffer );
00071 else {
00072 over = buffer;
00073 painter.begin(&over);
00074 }
00075 painter.setPen( erase?eraser:pen );
00076
00077 QPointArray parray(2);
00078 QString description;
00079
00080 switch (shape) {
00081 case LINE:
00082 if(definitive)
00083
00084 description = QString("}L %1 %2 %3 %4 %5 %6").arg(penColor().rgb())
00085 .arg(q.x()).arg(q.y()).arg(p.x()).arg(p.y()).arg(penWidth());
00086 painter.drawLine(q,p);
00087 parray[1] = q;
00088 parray[0] = p;
00089 break;
00090 case CIRCLE:
00091 {
00092 int dist = (int)sqrt(pow(q.x() - p.x(),2) + pow(q.y() - p.y(),2));
00093 painter.drawEllipse(q.x()-dist,q.y()-dist,2*dist,2*dist);
00094 QPoint tmp1(q.x()-dist, q.y()-dist);
00095 QPoint tmp2(q.x()+dist, q.y()+dist);
00096 parray[1] = tmp1;
00097 parray[0] = tmp2;
00098 if(definitive)
00099
00100 description = QString("}C %1 %2 %3 %4 %5").arg(penColor().rgb())
00101 .arg(q.x()).arg(q.y()).arg(dist).arg(penWidth());
00102
00103 }
00104 break;
00105 case TEXT:
00106 if(definitive) {
00107 QString text = QInputDialog::getText("Text Input","Enter text");
00108 painter.drawText(min(q.x(),p.x()),min(q.y(),p.y()),abs(q.x()-p.x()),abs(q.y()-p.y()),
00109 Qt::AlignAuto|Qt::AlignVCenter|Qt::BreakAnywhere,text);
00110
00111 description = QString("}T %1 %2 %3 %4").arg(penColor().rgb())
00112 .arg(min(q.x(),p.x())).arg(min(q.y(),p.y())).arg(abs(q.x()-p.x())).arg(abs(q.y()-p.y())).arg(text);
00113 }
00114 else {
00115 painter.drawRect(min(q.x(),p.x()),min(q.y(),p.y()),abs(q.x()-p.x()),abs(q.y()-p.y()));
00116 }
00117 parray[1] = q;
00118 parray[0] = p;
00119 break;
00120 }
00121
00122 painter.end();
00123
00124 QRect r = parray.boundingRect();
00125 r = r.normalize();
00126 r.setLeft( r.left() - penWidth() );
00127 r.setTop( r.top() - penWidth() );
00128 r.setRight( r.right() + penWidth() );
00129 r.setBottom( r.bottom() + penWidth() );
00130
00131 bitBlt( this, r.x(), r.y(), definitive?(&buffer):(&over), r.x(), r.y(), r.width(), r.height() );
00132 if(definitive) emit drawing(description);
00133 }
00134
00135 void Canvas::draw(Shape s, const QColor & col, const QPoint & q, const QPoint & p, int width, const QString & text) {
00136
00137 if (max(q.x(),p.x()) > buffer.width() || max(q.y(),p.y()) > buffer.height()) {
00138 QPixmap tmp( buffer );
00139 buffer.resize(max(q.x(),p.x()),max(q.y(),p.y()));
00140 buffer.fill( colorGroup().base() );
00141 bitBlt( &buffer, 0, 0, &tmp, 0, 0, tmp.width(), tmp.height() );
00142 }
00143
00144 QPainter painter;
00145 painter.begin( &buffer );
00146 QPen mpen(col,width);
00147 painter.setPen(mpen);
00148
00149
00150 QPointArray parray(2);
00151
00152 switch (s) {
00153 case LINE:
00154 painter.drawLine(q,p);
00155 parray[1] = q;
00156 parray[0] = p;
00157 break;
00158 case CIRCLE:
00159 {
00160 int dist = (int)sqrt(pow(q.x() - p.x(),2) + pow(q.y() - p.y(),2));
00161 painter.drawEllipse(q.x()-dist,q.y()-dist,2*dist,2*dist);
00162 QPoint tmp1(q.x()-dist, q.y()-dist);
00163 QPoint tmp2(q.x()+dist, q.y()+dist);
00164 parray[1] = tmp1;
00165 parray[0] = tmp2;
00166 }
00167 break;
00168 case TEXT:
00169 painter.drawText(min(q.x(),p.x()),min(q.y(),p.y()),abs(q.x()-p.x()),abs(q.y()-p.y()),
00170 Qt::AlignAuto|Qt::AlignVCenter|Qt::BreakAnywhere,text);
00171 parray[1] = q;
00172 parray[0] = p;
00173 break;
00174 }
00175
00176 painter.end();
00177
00178 QRect r = parray.boundingRect();
00179 r = r.normalize();
00180 r.setLeft( r.left() - width );
00181 r.setTop( r.top() - width );
00182 r.setRight( r.right() + width );
00183 r.setBottom( r.bottom() + width );
00184
00185 bitBlt( this, r.x(), r.y(),&buffer, r.x(), r.y(), r.width(), r.height() );
00186 }
00187
00188 void Canvas::mouseMoveEvent( QMouseEvent *e ) {
00189 if(mousePressed) {
00190 draw(start,tmp,false,true);
00191 draw(start,e->pos(),false);
00192 tmp=e->pos();
00193 }
00194 }
00195
00196 void Canvas::resizeEvent( QResizeEvent *e ) {
00197 QWidget::resizeEvent( e );
00198
00199 int w = width() > buffer.width() ?
00200 width() : buffer.width();
00201 int h = height() > buffer.height() ?
00202 height() : buffer.height();
00203
00204 QPixmap tmp( buffer );
00205 buffer.resize( w, h );
00206 buffer.fill( colorGroup().base() );
00207 bitBlt( &buffer, 0, 0, &tmp, 0, 0, tmp.width(), tmp.height() );
00208 }
00209
00210 void Canvas::paintEvent( QPaintEvent *e ) {
00211 QWidget::paintEvent( e );
00212
00213 QMemArray<QRect> rects = e->region().rects();
00214 for ( uint i = 0; i < rects.count(); i++ ) {
00215 QRect r = rects[(int)i];
00216 bitBlt( this, r.x(), r.y(), &buffer, r.x(), r.y(), r.width(), r.height() );
00217 }
00218 }