00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <math.h>
00026 #include <iostream>
00027
00028 #include <QMouseEvent>
00029 #include <QPainter>
00030 #include <QScrollArea>
00031 #include <QScrollBar>
00032 #include <QGLWidget>
00033 #include <QToolButton>
00034 #include <QStatusBar>
00035 #include <QHBoxLayout>
00036 #include <QGridLayout>
00037
00038 #include <qwt_scale_widget.h>
00039 #include <qwt_scale_engine.h>
00040 #include <qwt_scale_div.h>
00041
00042 #include <qvcore/qvimage.h>
00043 #include <qvgui/qvcanvas.h>
00044
00045 void QVPainter::drawQVImage(QVGenericImage *image,bool adaptSize,float low,float high)
00046 {
00047 imageArea->drawQVImage(image,adaptSize,low,high);
00048 }
00049
00050
00051 void QVPainter::drawTextUnscaled(const QPointF & position, const QString & text)
00052 {
00053 save();
00054 resetMatrix();
00055 translate(-imageArea->topLeft);
00056 drawText(imageArea->zoom*position,text);
00057 restore();
00058 }
00059
00060 void QVPainter::drawTextUnscaled(const QPoint & position, const QString & text)
00061 {
00062 save();
00063 resetMatrix();
00064 translate(-imageArea->topLeft);
00065 drawText(imageArea->zoom*position,text);
00066 restore();
00067 }
00068
00069 void QVPainter::drawTextUnscaled(const QRectF & rectangle, int flags,
00070 const QString & text, QRectF * boundingRect)
00071 {
00072 save();
00073 resetMatrix();
00074 translate(-imageArea->topLeft);
00075 drawText(QRectF(imageArea->zoom*rectangle.topLeft(),
00076 imageArea->zoom*rectangle.size()),flags,text,boundingRect);
00077 if(boundingRect != 0)
00078 *boundingRect = QRectF(imageArea->zoom*boundingRect->topLeft(),
00079 imageArea->zoom*boundingRect->size());
00080 restore();
00081 }
00082
00083 void QVPainter::drawTextUnscaled(const QRect & rectangle, int flags,
00084 const QString & text, QRect * boundingRect)
00085 {
00086 save();
00087 resetMatrix();
00088 translate(-imageArea->topLeft);
00089 drawText(QRect(imageArea->zoom*rectangle.topLeft(),
00090 imageArea->zoom*rectangle.size()),flags,text,boundingRect);
00091 if(boundingRect != 0)
00092 *boundingRect = QRect(imageArea->zoom*boundingRect->topLeft(),
00093 imageArea->zoom*boundingRect->size());
00094 restore();
00095 }
00096
00097 void QVPainter::drawTextUnscaled(int x, int y, const QString & text)
00098 {
00099 save();
00100 resetMatrix();
00101 translate(-imageArea->topLeft);
00102 drawText(imageArea->zoom*x,imageArea->zoom*y,text);
00103 restore();
00104 }
00105
00106 void QVPainter::drawTextUnscaled(int x, int y, int width, int height, int flags,
00107 const QString & text, QRect * boundingRect)
00108 {
00109 save();
00110 resetMatrix();
00111 translate(-imageArea->topLeft);
00112 drawText(imageArea->zoom*x,imageArea->zoom*y,imageArea->zoom*width,
00113 imageArea->zoom*height,flags,text,boundingRect);
00114 if(boundingRect != 0)
00115 *boundingRect = QRect(imageArea->zoom*boundingRect->topLeft(),
00116 imageArea->zoom*boundingRect->size());
00117 restore();
00118 }
00119
00120 void QVPainter::drawTextUnscaled(const QRectF & rectangle, const QString & text,
00121 const QTextOption & option)
00122 {
00123 save();
00124 resetMatrix();
00125 translate(-imageArea->topLeft);
00126 drawText(QRectF(imageArea->zoom*rectangle.topLeft(),
00127 imageArea->zoom*rectangle.size()),text,option);
00128 restore();
00129 }
00130
00131
00132 void QVImageArea::initObject(int w, int h)
00133 {
00134 zoom = 1;
00135 origwidth = w;
00136 origheight = h;
00137 topLeft = QPoint(0,0);
00138 selRect = QRect();
00139 zoomRect = QRect();
00140 setAttribute(Qt::WA_NoSystemBackground);
00141 setMouseTracking(TRUE);
00142 setMinimumSize(qMin(w,max_zoom),qMin(h,max_zoom));
00143 setMaximumSize(w,h);
00144 resize(w,h);
00145 mouseMode = noneMode;
00146 dragging = FALSE;
00147 emit newGeometry(origwidth,origheight,topLeft.x(),topLeft.y(),width(),height(),zoom);
00148 }
00149
00150 QVImageArea::QVImageArea(int w, int h,QWidget *parent)
00151 : QGLWidget(QGLFormat(QGL::DoubleBuffer|QGL::NoDepthBuffer|
00152 QGL::DirectRendering|QGL::HasOverlay), parent), max_zoom(128)
00153 {
00154 initObject(w,h);
00155 }
00156
00157 QVImageArea::QVImageArea(int w, int h,QWidget *parent,QGLWidget *other)
00158 : QGLWidget(parent,other), max_zoom(128)
00159 {
00160 initObject(w,h);
00161 }
00162
00163 QVImageArea::QVImageArea *first_image_area=NULL;
00164
00165 void QVImageArea::centerZoom(int zoom)
00166 {
00167 if((zoom != this->zoom) and (zoom >= 1) and (zoom <= max_zoom)) {
00168 int old_zoom = this->zoom;
00169 this->zoom = zoom;
00170 setMaximumSize(zoom*origwidth,zoom*origheight);
00171 QPoint newTopLeft = zoom*(topLeft+QPoint(width(),height())/2)/old_zoom
00172 - QPoint(width(),height())/2;
00173 if(newTopLeft.x() < 0)
00174 newTopLeft.setX(0);
00175 if(newTopLeft.y() < 0)
00176 newTopLeft.setY(0);
00177 if(newTopLeft.x()+width() > origwidth*zoom)
00178 newTopLeft.setX(origwidth*zoom-width());
00179 if(newTopLeft.y()+height() > origheight*zoom)
00180 newTopLeft.setY(origheight*zoom-height());
00181 topLeft = newTopLeft;
00182 update();
00183 emit newGeometry(origwidth,origheight,topLeft.x(),topLeft.y(),width(),height(),zoom);
00184 }
00185 }
00186
00187 void QVImageArea::resizeGL(int width, int height)
00188 {
00189 QPoint newTopLeft = topLeft,newBottomRight = topLeft+QPoint(width,height);
00190 if(newBottomRight.x() > origwidth*zoom)
00191 newTopLeft.setX(origwidth*zoom-width);
00192 if(newBottomRight.y() > origheight*zoom)
00193 newTopLeft.setY(origheight*zoom-height);
00194 topLeft = newTopLeft;
00195 update();
00196 emit newGeometry(origwidth,origheight,topLeft.x(),topLeft.y(),width,height,zoom);
00197 }
00198
00199
00200 void QVImageArea::wheelEvent(QWheelEvent *event)
00201 {
00202 if (event->delta() > 0) {
00203 centerZoom(2*zoom);
00204 } else {
00205 centerZoom(zoom/2);
00206 }
00207 }
00208
00209
00210
00211 QRectF QVImageArea::intuitiveRect(QRect rect)
00212 {
00213 return QRectF(rect.x(),rect.y()+1.0/zoom,
00214 rect.width()-1.0/zoom,rect.height()-1.0/zoom);
00215 }
00216
00217
00218 QRect QVImageArea::innerRect()
00219 {
00220 QPoint q1(static_cast<int>(ceilf(static_cast<float>(topLeft.x())/zoom)),
00221 static_cast<int>(ceilf(static_cast<float>(topLeft.y())/zoom))),
00222 q2(static_cast<int>(floor(static_cast<float>((topLeft.x()+width()))/zoom)-1),
00223 (static_cast<int>(floor(static_cast<float>(topLeft.y()+height()))/zoom))-1);
00224 return QRect(q1,q2);
00225 }
00226
00227 QRect QVImageArea::outerRect()
00228 {
00229 QPoint q1(static_cast<int>(ceilf(static_cast<float>(topLeft.x())/zoom)-1),
00230 static_cast<int>(ceilf(static_cast<float>(topLeft.y())/zoom))-1),
00231 q2(static_cast<int>(floor(static_cast<float>((topLeft.x()+width()))/zoom)),
00232 (static_cast<int>(floor(static_cast<float>(topLeft.y()+height()))/zoom)));
00233
00234 return QRect(q1,q2) & QRect(0,0,origwidth,origheight);
00235 }
00236
00237 void QVImageArea::paintEvent(QPaintEvent *event)
00238 {
00239 Q_UNUSED(event);
00240
00241 painter = new QVPainter(this);
00242
00243 painter->begin(this);
00244
00245
00246 painter->setViewport(0,0,width(),height());
00247 painter->resetMatrix();
00248 painter->translate(-topLeft);
00249 painter->scale(zoom,zoom);
00250
00251
00252 QVCanvas *image_viewer = qobject_cast<QVCanvas *>(parent());
00253 if(image_viewer == 0) {
00254 qFatal("Error interno de QVision: El padre de una QVImageArea deberÃa ser un QVCanvas");
00255 } else {
00256 glClearColor(0,0,1,0);
00257 glClear(GL_COLOR_BUFFER_BIT);
00258 image_viewer->viewer();
00259 }
00260
00261
00262 if(selRect != QRect()) {
00263 painter->setPen(QColor(Qt::red));
00264
00265
00266 painter->drawRect(intuitiveRect(selRect));
00267 }
00268 if(zoomRect != QRect()) {
00269 painter->setPen(QColor(Qt::blue));
00270
00271
00272 painter->drawRect(intuitiveRect(zoomRect));
00273 }
00274
00275
00276 if(zoom >= 32) {
00277 painter->setPen(QColor(Qt::green));
00278 QRect outer = outerRect();
00279 for(int j=outer.y();j<outer.y()+outer.height();j++) {
00280 for(int i=outer.x();i<outer.x()+outer.width();i++) {
00281 if(not imageList.isEmpty()) {
00282 QString value_string;
00283 int k;
00284 for(k=0;k<imageList.size();k++) {
00285 QRect img_rect = QRect(imageList[k]->getAnchor()+imageList[k]->getROI().topLeft(),
00286 QSize(imageList[k]->getROI().width(),imageList[k]->getROI().height()));
00287 if(i>=img_rect.left() and i<=img_rect.right() and j>=img_rect.top() and j<=img_rect.bottom()) {
00288
00289 if(imageList[k]->isCompatibleWith("QVImage<uChar,1>")) {
00290 value_string = QString("%1").arg((*(QVImage<uChar,1>*)imageList[k])(i-img_rect.topLeft().x()+imageList[k]->getROI().topLeft().x(),j-img_rect.topLeft().y()+imageList[k]->getROI().topLeft().y()));
00291 } else if(imageList[k]->isCompatibleWith("QVImage<sFloat,1>")) {
00292 if(zoom >= 64) {
00293 value_string = QString("%1").arg((*(QVImage<sFloat,1>*)imageList[k])(i-img_rect.topLeft().x()+imageList[k]->getROI().topLeft().x(),j-img_rect.topLeft().y()+imageList[k]->getROI().topLeft().y()),0,'g',-1);
00294 }
00295 }else if(imageList[k]->isCompatibleWith("QVImage<uChar,3>")) {
00296 int red,green,blue;
00297 if(zoom >= 64) {
00298 red = (*(QVImage<uChar,3>*)imageList[k])(i-img_rect.topLeft().x()+imageList[k]->getROI().topLeft().x(),j-img_rect.topLeft().y()+imageList[k]->getROI().topLeft().y(),0);
00299 green = (*(QVImage<uChar,3>*)imageList[k])(i-img_rect.topLeft().x()+imageList[k]->getROI().topLeft().x(),j-img_rect.topLeft().y()+imageList[k]->getROI().topLeft().y(),1);
00300 blue = (*(QVImage<uChar,3>*)imageList[k])(i-img_rect.topLeft().x()+imageList[k]->getROI().topLeft().x(),j-img_rect.topLeft().y()+imageList[k]->getROI().topLeft().y(),2);
00301 value_string = QString("R:%1\nG:%2\nB:%3").arg(red).arg(green).arg(blue);
00302 }
00303 } else {
00304
00305 qFatal("Type of QVGenericImage still not supported in paintEvent");
00306 }
00307 break;
00308 }
00309 }
00310 if(k==imageList.size()) {
00311 value_string = QString("X");
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 painter->drawTextUnscaled(
00335 QRect(QPoint(i,j),QSize(1,1)),
00336 Qt::AlignCenter|Qt::TextDontClip,value_string);
00337 }
00338 }
00339 }
00340 }
00341
00342
00343 painter->end();
00344 delete painter;
00345
00346
00347 while (!imageList.isEmpty())
00348 delete imageList.takeFirst();
00349 }
00350
00351 void QVImageArea::resizeImageArea(int w,int h)
00352 {
00353 if(w != origwidth or h != origheight) {
00354 zoom = 1;
00355 origwidth = w;
00356 origheight = h;
00357 topLeft = QPoint(0,0);
00358 selRect = QRect();
00359 zoomRect = QRect();
00360 setMinimumSize(qMin(w,max_zoom),qMin(h,max_zoom));
00361 setMaximumSize(w,h);
00362 resize(w,h);
00363 emit newGeometry(origwidth,origheight,topLeft.x(),topLeft.y(),width(),height(),zoom);
00364 }
00365 }
00366
00367 void QVImageArea::drawQVImage(QVGenericImage *image,bool adaptSize,float low, float high)
00368 {
00369
00370 QVGenericImage *imagecopy=NULL;
00371 if(image->isCompatibleWith("QVImage<uChar,1>")) {
00372 imagecopy = new QVImage<uChar,1>;
00373 *(dynamic_cast<QVImage<uChar,1>*>(imagecopy)) = *(dynamic_cast<QVImage<uChar,1>*>(image));
00374 } else if(image->isCompatibleWith("QVImage<sFloat,1>")) {
00375 imagecopy = new QVImage<sFloat,1>;
00376 *(dynamic_cast<QVImage<sFloat,1>*>(imagecopy)) = *(dynamic_cast<QVImage<sFloat,1>*>(image));
00377 }else if(image->isCompatibleWith("QVImage<uChar,3>")) {
00378 imagecopy = new QVImage<uChar,3>;
00379 *(dynamic_cast<QVImage<uChar,3>*>(imagecopy)) = *(dynamic_cast<QVImage<uChar,3>*>(image));
00380 } else {
00381
00382 qFatal("Type of QVGenericImage still not supported in drawQVImage");
00383 }
00384
00385
00386 imageList.push_front(imagecopy);
00387
00388 if(adaptSize) {
00389 this->resizeImageArea(image->getAnchor().x()+image->getROI().x()+image->getROI().width(),image->getAnchor().y()+image->getROI().y()+image->getROI().height());
00390 }
00391
00392
00393
00394 glPushAttrib(GL_ALL_ATTRIB_BITS);
00395 glPushClientAttrib(GL_ALL_ATTRIB_BITS);
00396 glMatrixMode(GL_PROJECTION);
00397 glPushMatrix();
00398 glMatrixMode(GL_MODELVIEW);
00399 glPushMatrix();
00400
00401
00402
00403 glViewport(0,0,width(),height());
00404 glMatrixMode(GL_PROJECTION);
00405 glLoadIdentity();
00406 glOrtho(topLeft.x(),topLeft.x()+width(),
00407 topLeft.y()+height(),topLeft.y(),-1,1);
00408 glMatrixMode(GL_MODELVIEW);
00409 glLoadIdentity();
00410
00411
00412 QRect final_rect,outer_rect = outerRect(),
00413 img_rect = QRect(imagecopy->getAnchor()+imagecopy->getROI().topLeft(),
00414 QSize(imagecopy->getROI().width(),imagecopy->getROI().height()));
00415 final_rect = outer_rect & img_rect;
00416
00417
00418
00419
00420 QPoint where,dirty;
00421 if(outer_rect.topLeft().x() >= img_rect.topLeft().x()) {
00422 where.setX(outer_rect.topLeft().x());
00423 dirty.setX(1);
00424 } else {
00425 where.setX(img_rect.topLeft().x());
00426 dirty.setX(0);
00427 }
00428 if(outer_rect.topLeft().y() >= img_rect.topLeft().y()) {
00429 where.setY(outer_rect.topLeft().y());
00430 dirty.setY(1);
00431 } else {
00432 where.setY(img_rect.topLeft().y());
00433 dirty.setY(0);
00434 }
00435
00436 glRasterPos2f(zoom*(where.x()+dirty.x()+0.0001),zoom*(where.y()+dirty.y()+0.0001));
00437 glBitmap(0, 0, 0, 0, -zoom*dirty.x(), +zoom*dirty.y(), NULL);
00438
00439
00440 QRect what;
00441 int img_step = imagecopy->getStep();
00442 glPixelZoom(zoom,-zoom);
00443 if(outer_rect.topLeft().x() >= img_rect.topLeft().x()) {
00444 what.setX(outer_rect.topLeft().x() - img_rect.topLeft().x() + imagecopy->getROI().topLeft().x());
00445 } else {
00446 what.setX(imagecopy->getROI().topLeft().x());
00447 }
00448 what.setWidth(final_rect.width());
00449 if(outer_rect.topLeft().y() >= img_rect.topLeft().y()) {
00450 what.setY(outer_rect.topLeft().y() - img_rect.topLeft().y() + imagecopy->getROI().topLeft().y());
00451 } else {
00452 what.setY(imagecopy->getROI().topLeft().y());
00453 }
00454 what.setHeight(final_rect.height());
00455
00456 if(image->isCompatibleWith("QVImage<uChar,1>")) {
00457 glPixelStorei(GL_UNPACK_ROW_LENGTH,img_step);
00458 glDrawPixels(what.width(),what.height(),
00459 GL_LUMINANCE,GL_UNSIGNED_BYTE,
00460 static_cast<QVImage<uchar,1> *>(imagecopy)->getReadData() +
00461 what.y()*img_step+what.x());
00462 } else if(image->isCompatibleWith("QVImage<sFloat,1>")) {
00463 glPixelStorei(GL_UNPACK_ROW_LENGTH,img_step/sizeof(sFloat));
00464
00465 float scale=1.0/(high-low),bias=-low*scale;
00466
00467
00468 glPixelTransferf(GL_RED_BIAS,bias);
00469 glPixelTransferf(GL_GREEN_BIAS,bias);
00470 glPixelTransferf(GL_BLUE_BIAS,bias);
00471 glPixelTransferf(GL_RED_SCALE,scale);
00472 glPixelTransferf(GL_GREEN_SCALE,scale);
00473 glPixelTransferf(GL_BLUE_SCALE,scale);
00474
00475
00476
00477
00478
00479
00480
00481 glDrawPixels(what.width(),what.height(),
00482 GL_LUMINANCE,GL_FLOAT,
00483 static_cast<QVImage<sFloat,1> *>(imagecopy)->getReadData() +
00484 what.y()*img_step/sizeof(sFloat)+what.x());
00485 } else if(image->isCompatibleWith("QVImage<uChar,3>")) {
00486 glPixelStorei(GL_UNPACK_ROW_LENGTH,img_step/3);
00487 glDrawPixels(what.width(),what.height(),
00488 GL_RGB,GL_UNSIGNED_BYTE,
00489 static_cast<QVImage<uchar,3> *>(imagecopy)->getReadData() +
00490 what.y()*img_step+3*what.x());
00491 } else {
00492
00493 qFatal("Type of QVGenericImage still not supported in drawQVImage");
00494 }
00495
00496
00497
00498 glPopClientAttrib();
00499 glPopAttrib();
00500 glMatrixMode(GL_MODELVIEW);
00501 glPopMatrix();
00502 glMatrixMode(GL_PROJECTION);
00503 glPopMatrix();
00504 }
00505
00506
00507 void QVImageArea::mousePressEvent(QMouseEvent *event)
00508 {
00509 firstPos = event->pos();
00510 dragging = TRUE;
00511 if(mouseMode == dragMode) {
00512
00513 }
00514 }
00515
00516 void QVImageArea::mouseMoveEvent(QMouseEvent *event)
00517 {
00518 if(dragging) {
00519 lastPos = event->pos();
00520 switch(mouseMode) {
00521 case dragMode: {
00522 QPoint minDesp = -topLeft,
00523 maxDesp = QPoint(origwidth*zoom,origheight*zoom) -
00524 (topLeft + QPoint(width(),height()));
00525 QPoint desp = firstPos-lastPos,
00526 boundDesp = QPoint(qBound(minDesp.x(),desp.x(),maxDesp.x()),
00527 qBound(minDesp.y(),desp.y(),maxDesp.y()));
00528 if(boundDesp != QPoint(0,0)) {
00529 topLeft = topLeft+boundDesp;
00530 update();
00531 emit newGeometry(origwidth,origheight,topLeft.x(),topLeft.y(),width(),height(),zoom);
00532 }
00533 firstPos = lastPos;
00534 emit mouseLeavesImageArea(FALSE);
00535 emit newMousePosition(static_cast<float>(event->x()+topLeft.x())/zoom,static_cast<float>(event->y()+topLeft.y())/zoom);
00536 break;
00537 }
00538 case zoomMode:
00539 case selMode:
00540 {
00541 QPoint p1(qRound(static_cast<float>(firstPos.x()+topLeft.x())/zoom),
00542 qRound(static_cast<float>(firstPos.y()+topLeft.y())/zoom)),
00543 p2(qRound(static_cast<float>(lastPos.x()+topLeft.x())/zoom)-1,
00544 qRound(static_cast<float>(lastPos.y()+topLeft.y())/zoom)-1);
00545 if(mouseMode == zoomMode) {
00546
00547
00548
00549 zoomRect = QRect(p1,p2) & innerRect();
00550 emit mouseLeavesImageArea(FALSE);
00551 emit newMousePosition(lastPos.x()>firstPos.x()?zoomRect.right():zoomRect.left(),
00552 lastPos.y()>firstPos.y()?zoomRect.bottom():zoomRect.top());
00553 } else {
00554 selRect = QRect(p1,p2) & innerRect();
00555 emit mouseLeavesImageArea(FALSE);
00556 emit newMousePosition(lastPos.x()>firstPos.x()?selRect.right():selRect.left(),
00557 lastPos.y()>firstPos.y()?selRect.bottom():selRect.top());
00558 }
00559 update();
00560 break;
00561 }
00562 case noneMode: {
00563 break;
00564 }
00565 }
00566 } else {
00567 emit mouseLeavesImageArea(FALSE);
00568 emit newMousePosition(static_cast<float>(event->x()+topLeft.x())/zoom,static_cast<float>(event->y()+topLeft.y())/zoom);
00569 }
00570 }
00571
00572
00573 void QVImageArea::mouseReleaseEvent(QMouseEvent *event)
00574 {
00575
00576 if(mouseMode == dragMode) {
00577
00578 }
00579 dragging = FALSE;
00580 lastPos = event->pos();
00581 switch(mouseMode) {
00582 case dragMode: {
00583 break;
00584 }
00585 case zoomMode: {
00586 int newzoom = zoom;
00587 do {
00588 newzoom = 2*newzoom;
00589 } while(newzoom*zoomRect.width() < minimumWidth() or
00590 newzoom*zoomRect.height() < minimumHeight());
00591 if(newzoom <= max_zoom) {
00592 zoom = newzoom;
00593 topLeft = zoom*zoomRect.topLeft();
00594 setMaximumSize(zoom*origwidth,zoom*origheight);
00595 resize(zoom*zoomRect.width(),zoom*zoomRect.height());
00596 zoomRect = QRect();
00597 update();
00598 emit newGeometry(origwidth,origheight,topLeft.x(),topLeft.y(),width(),height(),zoom);
00599 } else {
00600 zoomRect = QRect();
00601 update();
00602 }
00603 break;
00604 }
00605 case selMode: {
00606 if(firstPos == lastPos) {
00607 selRect = QRect();
00608 update();
00609 }
00610 break;
00611 }
00612 case noneMode: {
00613 break;
00614 }
00615 }
00616 }
00617
00618 void QVImageArea::leaveEvent(QEvent *event)
00619 {
00620 Q_UNUSED(event);
00621 emit mouseLeavesImageArea(TRUE);
00622 }
00623
00624
00625
00626
00627 void QVCanvas::resizeEvent(QResizeEvent *event)
00628 {
00629 QFontMetrics fm(font());
00630
00631 int w = event->size().width() - scaleWidgetsFixedWidth - 1;
00632 int h = event->size().height() - scaleWidgetsFixedWidth - statusBarWidgetFixedHeight - 1;
00633 imageArea->setGeometry(scaleWidgetsFixedWidth,scaleWidgetsFixedWidth,w,h);
00634 }
00635
00636 QString QVCanvas::statusMessage()
00637 {
00638 if(mouseIsOut) {
00639 return QString("z=%1").arg(imageArea->zoom);
00640 } else {
00641 return QString("(%1,%2) z=%3").arg(mousePosX).arg(mousePosY).arg(imageArea->zoom);
00642 }
00643 }
00644
00645 QVCanvas::QVCanvas(QWidget *parent) : QWidget(parent)
00646 {
00647 mouseIsOut = TRUE;
00648 int w = 1, h = 1;
00649
00650 QFontMetrics fm(font());
00651 scaleWidgetsFixedWidth = 5*fm.height()/3;
00652
00653
00654 scaleWidgetX = new QwtScaleWidget(QwtScaleDraw::TopScale,this);
00655
00656 scaleWidgetX->setLabelAlignment(Qt::AlignHCenter|Qt::AlignTop);
00657 scaleWidgetX->setMargin(1);
00658
00659
00660
00661 scaleWidgetX->setBorderDist(scaleWidgetsFixedWidth,scaleWidgetsFixedWidth);
00662
00663 scaleWidgetY = new QwtScaleWidget(QwtScaleDraw::LeftScale,this);
00664 scaleWidgetY->setLabelRotation(-90.0);
00665 scaleWidgetY->setLabelAlignment(Qt::AlignVCenter|Qt::AlignTop);
00666 scaleWidgetY->setMargin(1);
00667
00668
00669
00670 scaleWidgetY->setBorderDist(scaleWidgetsFixedWidth,scaleWidgetsFixedWidth);
00671
00672
00673 scaleEngineX = new QwtLinearScaleEngine;
00674 scaleEngineY = new QwtLinearScaleEngine;
00675
00676
00677 if(first_image_area == NULL) {
00678
00679 imageArea = new QVImageArea(w,h,this);
00680 first_image_area = imageArea;
00681 } else {
00682
00683 imageArea = new QVImageArea(w,h,this,first_image_area);
00684 }
00685
00686 statusBar = new QStatusBar(this);
00687 statusBar->addPermanentWidget(buttonZoomIn = new QToolButton(statusBar));
00688 statusBar->addPermanentWidget(buttonZoomOut = new QToolButton(statusBar));
00689 statusBar->addPermanentWidget(buttonZoomOriginal = new QToolButton(statusBar));
00690 statusBar->addPermanentWidget(buttonZoomRect = new QToolButton(statusBar));
00691 statusBar->addPermanentWidget(buttonSelRect = new QToolButton(statusBar));
00692 statusBar->addPermanentWidget(buttonDrag = new QToolButton(statusBar));
00693 buttonZoomIn->setCheckable(FALSE);
00694 buttonZoomIn->setIcon(QIcon(":/images/zoom-in.png"));
00695 buttonZoomOut->setCheckable(FALSE);
00696 buttonZoomOut->setIcon(QIcon(":/images/zoom-out.png"));
00697 buttonZoomOriginal->setCheckable(FALSE);
00698 buttonZoomOriginal->setIcon(QIcon(":/images/zoom-original.png"));
00699 buttonZoomRect->setCheckable(TRUE);
00700 buttonZoomRect->setIcon(QIcon(":/images/zoom-best-fit.png"));
00701 buttonSelRect->setCheckable(TRUE);
00702 buttonSelRect->setIcon(QIcon(":/images/select.png"));
00703 buttonDrag->setCheckable(TRUE);
00704 buttonDrag->setIcon(QIcon(":/images/hand.png"));
00705
00706 statusBar->showMessage(statusMessage());
00707 statusBarWidgetFixedHeight = statusBar->height();
00708
00709 setMinimumSize(scaleWidgetsFixedWidth + imageArea->minimumWidth() + 1,
00710 scaleWidgetsFixedWidth + imageArea->minimumHeight() + 1 +
00711 statusBarWidgetFixedHeight);
00712 setMaximumSize(scaleWidgetsFixedWidth + w + 1,
00713 scaleWidgetsFixedWidth + h + 1 +
00714 statusBarWidgetFixedHeight);
00715 resize(scaleWidgetsFixedWidth + w + 1,
00716 scaleWidgetsFixedWidth + h + 1 +
00717 statusBarWidgetFixedHeight);
00718 connect(imageArea,SIGNAL(newGeometry(int,int,int,int,int,int,int)),
00719 this,SLOT(setGeometry(int,int,int,int,int,int,int)));
00720 connect(imageArea,SIGNAL(newMousePosition(float,float)),
00721 this,SLOT(newMousePositionSlot(float,float)));
00722 connect(imageArea,SIGNAL(mouseLeavesImageArea(bool)),
00723 this,SLOT(mouseLeavesImageAreaSlot(bool)));
00724 connect(buttonZoomRect,SIGNAL(clicked(bool)),this,SLOT(zoomRectClicked(bool)));
00725 connect(buttonSelRect,SIGNAL(clicked(bool)),this,SLOT(selRectClicked(bool)));
00726 connect(buttonDrag,SIGNAL(clicked(bool)),this,SLOT(dragClicked(bool)));
00727 connect(buttonZoomIn,SIGNAL(clicked()),this,SLOT(zoomInClicked()));
00728 connect(buttonZoomOut,SIGNAL(clicked()),this,SLOT(zoomOutClicked()));
00729 connect(buttonZoomOriginal,SIGNAL(clicked()),this,SLOT(zoomOriginalClicked()));
00730
00731 }
00732
00733 void QVCanvas::zoomInClicked() {
00734 imageArea->centerZoom(2*imageArea->zoom);
00735 }
00736
00737 void QVCanvas::zoomOutClicked() {
00738 imageArea->centerZoom(imageArea->zoom/2);
00739 }
00740
00741 void QVCanvas::zoomOriginalClicked() {
00742
00743 int w = imageArea->origwidth, h = imageArea->origheight;
00744 imageArea->origwidth = imageArea->origheight = 0;
00745 QRect saveSelRect = imageArea->selRect;
00746 imageArea->resizeImageArea(w,h);
00747 imageArea->selRect = saveSelRect;
00748 }
00749
00750
00751 void QVCanvas::zoomRectClicked(bool checked) {
00752 if(checked)
00753 imageArea->setCursor(Qt::CrossCursor);
00754 else
00755 imageArea->setCursor(Qt::ArrowCursor);
00756 imageArea->mouseMode = (checked ? QVImageArea::zoomMode :
00757 QVImageArea::noneMode);
00758 buttonSelRect->setChecked(false);
00759 buttonDrag->setChecked(false);
00760 }
00761
00762 void QVCanvas::selRectClicked(bool checked) {
00763 if(checked)
00764 imageArea->setCursor(Qt::CrossCursor);
00765 else
00766 imageArea->setCursor(Qt::ArrowCursor);
00767 imageArea->mouseMode = (checked ? QVImageArea::selMode :
00768 QVImageArea::noneMode);
00769 buttonZoomRect->setChecked(false);
00770 buttonDrag->setChecked(false);
00771 }
00772
00773 void QVCanvas::dragClicked(bool checked) {
00774 if(checked)
00775 ;
00776 else
00777 imageArea->setCursor(Qt::ArrowCursor);
00778
00779 imageArea->mouseMode = (checked ? QVImageArea::dragMode :
00780 QVImageArea::noneMode);
00781 buttonSelRect->setChecked(false);
00782 buttonZoomRect->setChecked(false);
00783 }
00784
00785
00786 void QVCanvas::newMousePositionSlot(float x,float y) {
00787 mousePosX = x;
00788 mousePosY = y;
00789 statusBar->showMessage(statusMessage());
00790 }
00791
00792 void QVCanvas::mouseLeavesImageAreaSlot(bool leaves) {
00793
00794
00795
00796
00797 mouseIsOut = leaves;
00798 statusBar->showMessage(statusMessage());
00799 }
00800
00801
00802 QVCanvas::~QVCanvas()
00803 {
00804 delete scaleEngineX;
00805 delete scaleEngineY;
00806 }
00807
00808 void QVCanvas::refreshImageArea()
00809 {
00810 imageArea->update();
00811 }
00812
00813
00814 void QVCanvas::setGeometry(int origwidth,int origheight,int topleftx,int toplefty,int width,int height, int zoom)
00815 {
00816 Q_UNUSED(origwidth);
00817 Q_UNUSED(origheight);
00818
00819 QFontMetrics fm(font());
00820
00821
00822
00823 QwtScaleDiv scaleDivX = scaleEngineX->divideScale(
00824 ((double)topleftx)/zoom,((double)(topleftx+width))/zoom,
00825 qMin(width/zoom+1,static_cast<int>(width/(fm.width("999")))),
00826 10,0);
00827 scaleWidgetX->setScaleDiv(scaleEngineX->transformation(),scaleDivX);
00828
00829 QwtScaleDiv scaleDivY = scaleEngineY->divideScale(
00830 ((double)toplefty+height)/zoom,((double)(toplefty))/zoom,
00831 qMin(height/zoom+1,static_cast<int>(height/(fm.width("999")))),
00832 10,0);
00833 scaleWidgetY->setScaleDiv(scaleEngineY->transformation(),scaleDivY);
00834
00835
00836 setMinimumSize(scaleWidgetsFixedWidth + imageArea->minimumWidth() + 1,
00837 scaleWidgetsFixedWidth + imageArea->minimumHeight() + 1 +
00838 statusBarWidgetFixedHeight);
00839
00840
00841
00842 setMaximumSize(scaleWidgetsFixedWidth+zoom*imageArea->origwidth + 1,
00843 scaleWidgetsFixedWidth+zoom*imageArea->origheight + 1 +
00844 statusBarWidgetFixedHeight);
00845
00846 resize(scaleWidgetsFixedWidth+width+1,
00847 scaleWidgetsFixedWidth+height+1+statusBarWidgetFixedHeight);
00848
00849
00850
00851 scaleWidgetX->setGeometry(0,0,
00852 2*scaleWidgetsFixedWidth+width+1,scaleWidgetsFixedWidth);
00853 scaleWidgetY->setGeometry(0,0,
00854 scaleWidgetsFixedWidth,2*scaleWidgetsFixedWidth+height+1);
00855
00856 statusBar->setGeometry(
00857 0,scaleWidgetsFixedWidth+height+1,
00858 scaleWidgetsFixedWidth+width+1,statusBarWidgetFixedHeight);
00859
00860 statusBar->showMessage(statusMessage());
00861
00862
00863 }