00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qsize.h>
00013 #include <qapplication.h>
00014 #include <qpainter.h>
00015 #include <qevent.h>
00016 #include <qpoint.h>
00017 #include <qaccel.h>
00018 #include <qcursor.h>
00019
00020
00021 #include "selectionInterface.h"
00022 #include "../cursors.h"
00023 #include "../../config.h"
00024 #include "../../backend/tools/imageTools.h"
00025 #include "../window.h"
00026 #include "../../configuration/configuration.h"
00027
00028
00029
00030
00031 #define DRAG_THRESHOLD 8
00032
00033
00034
00035 #define MOVE_THRESHOLD 150
00036
00037
00038 #define MINIMUM_SELECTION_SIZE 3
00039
00040
00041 SelectionInterface::SelectionInterface(QWidget *parent, const char* name ) : QWidget(parent,name)
00042 {
00043
00044 setWFlags(WRepaintNoErase);
00045
00046
00047 mousePressPoint = QPoint(-1,-1);
00048 mouseDragPoint = QPoint(-1,-1);
00049
00050
00051 currentDragMode = NO_EFFECT;
00052 currentMouseShape = NO_EFFECT;
00053
00054 QAccel *keyAccel = new QAccel( this );
00055 keyAccel->connectItem( keyAccel->insertItem( CTRL + Key_A),
00056 this, SLOT(selectAll()) );
00057 keyAccel->connectItem( keyAccel->insertItem( CTRL + SHIFT + Key_A ),
00058 this, SLOT(selectNone()) );
00059
00060
00061 setMouseTracking(true);
00062
00063
00064 setFocusPolicy( QWidget::ClickFocus );
00065
00066
00067 cachedMousePosition = QPoint(-1,-1);
00068
00069
00070 cropMaxDimen = -1.0;
00071 }
00072
00073 SelectionInterface::~SelectionInterface() { }
00074
00075 void SelectionInterface::setPhoto(QString imageFilename, bool resetSelection)
00076 {
00077
00078 origImageFilename = imageFilename;
00079
00080
00081 getImageSize( origImageFilename, origImageSize );
00082
00083
00084
00085 QRect screenSize = qApp->desktop()->availableGeometry();
00086 scaleImage( origImageFilename, fullScreenImage, screenSize.width(), screenSize.height() );
00087
00088
00089 constructDisplayImages();
00090
00091
00092 if(resetSelection)
00093 {
00094 mousePressPoint = QPoint(-1,-1);
00095 mouseDragPoint = QPoint(-1,-1);
00096 cropMaxDimen = -1.0;
00097 SHIFT_Pressed = false;
00098 CTRL_Pressed = false;
00099 emit selectionChanged();
00100 }
00101
00102
00103
00104
00105 repaint(resetSelection);
00106 }
00107
00108 void SelectionInterface::resizeEvent( QResizeEvent * )
00109 {
00110
00111 if( fullScreenImage.isNull() ) return;
00112
00113
00114 constructDisplayImages();
00115 }
00116
00117 void SelectionInterface::constructDisplayImages()
00118 {
00119
00120 scaledImage = fullScreenImage.scale( width(), height(), QImage::ScaleMin );
00121
00122
00123 unselectedScaledImage = scaledImage.copy();
00124 int x, y;
00125 QRgb* rgb;
00126 uchar* scanLine;
00127 for( y=0; y<unselectedScaledImage.height(); y++)
00128 {
00129
00130 scanLine = unselectedScaledImage.scanLine(y);
00131 for( x=0; x<unselectedScaledImage.width(); x++)
00132 {
00133
00134 rgb = ((QRgb*)scanLine+x);
00135
00136 double r = ((double)qRed(*rgb) )/255.0;
00137 double g = ((double)qGreen(*rgb) )/255.0;
00138 double b = ((double)qBlue(*rgb) )/255.0;
00139
00140
00141 double h,s,v;
00142 RGBtoHSV(r,g,b,&h,&s,&v);
00143
00144
00145 v*=0.25;
00146
00147
00148 HSVtoRGB( &r,&g,&b, h,s,v);
00149 int rp = (int) QMIN( QMAX((r*255), 0), 255 );
00150 int gp = (int) QMIN( QMAX((g*255), 0), 255 );
00151 int bp = (int) QMIN( QMAX((b*255), 0), 255 );
00152
00153
00154 *rgb = qRgb(rp,gp,bp);
00155 }
00156 }
00157
00158
00159 }
00160
00161 void SelectionInterface::paintEvent(QPaintEvent *e)
00162 {
00163
00164 if(scaledImage.isNull()) { return; }
00165
00166
00167 QRect rct = rect();
00168 rct.moveBy(-x(), -y());
00169 QPixmap buffer( size() );
00170
00171
00172 QPainter bufferPainter( &buffer );
00173
00174
00175 bufferPainter.setClipping(false);
00176
00177
00178 bufferPainter.fillRect( buffer.rect(), backgroundBrush() );
00179
00180
00181 int xOffset = (width() - scaledImage.width()) / 2;
00182 int yOffset = (height() - scaledImage.height()) / 2;
00183
00184
00185
00186 if(currentDragMode == DRAW_LINE)
00187 {
00188
00189 bufferPainter.drawImage( QPoint(xOffset, yOffset), scaledImage );
00190
00191
00192 if( mousePressPoint.x() != -1 &&
00193 mouseDragPoint.x() != -1 )
00194 {
00195
00196 QPoint p1, p2;
00197 p1 = ConvertImageToDisplayCoordinate( mousePressPoint );
00198 p2 = ConvertImageToDisplayCoordinate( mouseDragPoint );
00199
00200
00201 QPen pen;
00202 pen.setStyle( Qt::SolidLine );
00203 pen.setCapStyle( Qt::RoundCap );
00204 pen.setWidth( 2 );
00205 pen.setColor( green );
00206 bufferPainter.setPen( pen);
00207
00208
00209 bufferPainter.drawLine( p1.x(), p1.y(), p2.x(), p2.y() );
00210 }
00211 }
00212
00213 else
00214 {
00215
00216 if( mousePressPoint.x() == -1 ||
00217 (
00218 currentDragMode == NO_EFFECT &&
00219 (
00220 mousePressPoint.x() - mouseDragPoint.x() == 0 ||
00221 mousePressPoint.y() - mouseDragPoint.y() == 0
00222 )
00223 ))
00224 {
00225 bufferPainter.drawImage( QPoint(xOffset, yOffset), scaledImage );
00226 }
00227
00228
00229 else
00230 {
00231
00232 bufferPainter.drawImage( QPoint(xOffset, yOffset), unselectedScaledImage );
00233
00234
00235 QPoint topLeft( QMIN(mousePressPoint.x(), mouseDragPoint.x()),
00236 QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
00237 QPoint bottomRight( QMAX(mousePressPoint.x(), mouseDragPoint.x()),
00238 QMAX(mousePressPoint.y(), mouseDragPoint.y()) );
00239
00240
00241 topLeft = ConvertImageToDisplayCoordinate( topLeft );
00242 bottomRight = ConvertImageToDisplayCoordinate( bottomRight );
00243
00244
00245 bufferPainter.drawImage( topLeft.x(),
00246 topLeft.y(),
00247 scaledImage,
00248 topLeft.x()-xOffset, topLeft.y()-yOffset,
00249 bottomRight.x() - topLeft.x(),
00250 bottomRight.y() - topLeft.y() );
00251
00252
00253
00254
00255
00256
00257 QPen pen;
00258 QColor selectionColor = gray;
00259 QColor textColor = white;
00260 int selectedWidth = QABS( mouseDragPoint.x() - mousePressPoint.x() ) + 1;
00261 int selectedHeight = QABS( mouseDragPoint.y() - mousePressPoint.y() ) + 1;
00262 if(selectedWidth == 1) selectedWidth = 0;
00263 if(selectedHeight == 1) selectedHeight = 0;
00264
00265 int DPI = -1;
00266 int minDPI = -1;
00267 if( cropMaxDimen != -1.0 )
00268 {
00269
00270 int maxDimen = QMAX( selectedWidth, selectedHeight );
00271 DPI = (int) (maxDimen / cropMaxDimen);
00272
00273
00274 minDPI = ((Window*)qApp->mainWidget())->getConfig()->getInt( "misc", "minDPI" );
00275 if( DPI < minDPI )
00276 { selectionColor = QColor( 200, 0, 0 ); }
00277
00278 else { selectionColor = QColor( 0, 200, 0 ); }
00279 }
00280 pen.setStyle( Qt::SolidLine );
00281 pen.setWidth( 2 );
00282 bufferPainter.setPen( pen);
00283
00284
00285 QString selectionText;
00286 if( cropMaxDimen != -1.0 &&
00287 DPI < minDPI )
00288 selectionText = QString("%1 x %2 (DPI: %3!)").arg(selectedWidth).arg(selectedHeight).arg(DPI);
00289 else
00290 selectionText = QString("%1 x %2").arg(selectedWidth).arg(selectedHeight);
00291
00292 QFontMetrics fm( this->font() );
00293 int stringWidth = fm.width(selectionText);
00294 int stringHeight = fm.ascent();
00295
00296 int textX = 0;
00297 int textY = 0;
00298 const int TEXT_MARGIN = 4;
00299 if( mouseDragPoint.x() > mousePressPoint.x() )
00300 {
00301 textX = QMIN( xOffset + unselectedScaledImage.width() - TEXT_MARGIN - stringWidth,
00302 bottomRight.x() + TEXT_MARGIN );
00303 }
00304 else
00305 {
00306 textX = QMAX( xOffset + TEXT_MARGIN,
00307 topLeft.x() - TEXT_MARGIN - stringWidth );
00308 }
00309
00310 if( mouseDragPoint.y() > mousePressPoint.y() )
00311 {
00312 textY = QMIN( yOffset + unselectedScaledImage.height() - TEXT_MARGIN,
00313 bottomRight.y() + TEXT_MARGIN + stringHeight);
00314 }
00315 else
00316 {
00317 textY = QMAX( yOffset + TEXT_MARGIN + stringHeight,
00318 topLeft.y() - TEXT_MARGIN );
00319 }
00320
00321
00322 pen.setColor( selectionColor );
00323 bufferPainter.setPen( pen);
00324 QRect selection( topLeft, bottomRight );
00325 bufferPainter.drawRect(selection);
00326
00327
00328 bufferPainter.drawImage( textX, textY-stringHeight,
00329 unselectedScaledImage,
00330 textX - xOffset, textY-stringHeight-yOffset,
00331 stringWidth, fm.height() );
00332
00333
00334
00335 pen.setColor( textColor );
00336 bufferPainter.setPen( pen);
00337 bufferPainter.drawText( textX, textY, selectionText );
00338 }
00339 }
00340
00341 bufferPainter.end();
00342
00343
00344 bitBlt( this,
00345 e->rect().x(), e->rect().y(),
00346 &buffer,
00347 e->rect().x(), e->rect().y(),
00348 e->rect().width(), e->rect().height() );
00349 }
00350
00351 DRAG_MODE SelectionInterface::mouseActionByPosition(QPoint p)
00352 {
00353
00354 if(SHIFT_Pressed) { return SCALE_SELECTION; }
00355
00356
00357 QPoint topLeft( QMIN(mousePressPoint.x(), mouseDragPoint.x()),
00358 QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
00359 QPoint bottomRight( QMAX(mousePressPoint.x(), mouseDragPoint.x()),
00360 QMAX(mousePressPoint.y(), mouseDragPoint.y()) );
00361
00362
00363 topLeft = ConvertImageToDisplayCoordinate( topLeft );
00364 bottomRight = ConvertImageToDisplayCoordinate( bottomRight );
00365
00366
00367 QPoint center( (topLeft.x() + bottomRight.x()) / 2,
00368 (topLeft.y() + bottomRight.y()) / 2);
00369
00370
00371 int xOffset = (width() - scaledImage.width() ) / 2;
00372 int yOffset = (height() - scaledImage.height() ) / 2;
00373 if(p.x() < xOffset || p.x() >= scaledImage.width() + xOffset ||
00374 p.y() < yOffset || p.y() >= scaledImage.height() + yOffset )
00375 { return NO_EFFECT; }
00376
00377
00378
00379 if( mousePressPoint.x() == -1 ||
00380 ( bottomRight.x() - topLeft.x() == origImageSize.width() - 1 &&
00381 bottomRight.y() - topLeft.y() == origImageSize.height() - 1 )
00382 )
00383 { return DRAW_SELECTION; }
00384
00385
00386
00387 else if( p.x() >= QMAX( center.x() - MOVE_THRESHOLD, topLeft.x() ) &&
00388 p.x() <= QMIN( center.x() + MOVE_THRESHOLD, bottomRight.x() ) &&
00389 p.y() >= QMAX( center.y() - MOVE_THRESHOLD, topLeft.y() ) &&
00390 p.y() <= QMIN( center.y() + MOVE_THRESHOLD, bottomRight.y() ) &&
00391 p.x() > topLeft.x() + DRAG_THRESHOLD &&
00392 p.x() < bottomRight.x() - DRAG_THRESHOLD &&
00393 p.y() > topLeft.y() + DRAG_THRESHOLD &&
00394 p.y() < bottomRight.y() - DRAG_THRESHOLD )
00395 { return MOVE_SELECTION; }
00396
00397 else if( QABS(topLeft.x() - p.x()) <= DRAG_THRESHOLD &&
00398 QABS(topLeft.y() - p.y()) <= DRAG_THRESHOLD )
00399 { return MOVE_TOP_LEFT_CORNER; }
00400
00401 else if( QABS(bottomRight.x() - p.x()) <= DRAG_THRESHOLD &&
00402 QABS(topLeft.y() - p.y()) <= DRAG_THRESHOLD )
00403 { return MOVE_TOP_RIGHT_CORNER; }
00404
00405 else if( QABS(topLeft.x() - p.x()) <= DRAG_THRESHOLD &&
00406 QABS(bottomRight.y() - p.y()) <= DRAG_THRESHOLD )
00407 { return MOVE_BOTTOM_LEFT_CORNER; }
00408
00409 else if( QABS(bottomRight.x() - p.x()) <= DRAG_THRESHOLD &&
00410 QABS(bottomRight.y() - p.y()) <= DRAG_THRESHOLD )
00411 { return MOVE_BOTTOM_RIGHT_CORNER; }
00412
00413 else if( QABS(topLeft.x() - p.x()) <= DRAG_THRESHOLD &&
00414 p.y() >= topLeft.y() &&
00415 p.y() <= bottomRight.y() )
00416 { return MOVE_LEFT_SIDE; }
00417
00418 else if( QABS(bottomRight.x() - p.x()) <= DRAG_THRESHOLD &&
00419 p.y() >= topLeft.y() &&
00420 p.y() <= bottomRight.y() )
00421 { return MOVE_RIGHT_SIDE; }
00422
00423 else if( QABS(topLeft.y() - p.y()) <= DRAG_THRESHOLD &&
00424 p.x() >= topLeft.x() &&
00425 p.x() <= bottomRight.x() )
00426 { return MOVE_TOP_SIDE; }
00427
00428 else if( QABS(bottomRight.y() - p.y()) <= DRAG_THRESHOLD &&
00429 p.x() >= topLeft.x() &&
00430 p.x() <= bottomRight.x() )
00431 { return MOVE_BOTTOM_SIDE; }
00432
00433 else { return DRAW_SELECTION; }
00434 }
00435
00436 void SelectionInterface::mousePressEvent(QMouseEvent *e)
00437 {
00438
00439 if( CTRL_Pressed)
00440 {
00441 emit ctrlClick();
00442 return;
00443 }
00444
00445
00446 QPoint p = ConvertDisplayToImageCoordinate( e->pos() );
00447
00448
00449
00450 if( currentDragMode == DRAW_LINE )
00451 { return; }
00452
00453
00454 QPoint topLeft( QMIN(mousePressPoint.x(), mouseDragPoint.x()),
00455 QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
00456 QPoint bottomRight( QMAX(mousePressPoint.x(), mouseDragPoint.x()),
00457 QMAX(mousePressPoint.y(), mouseDragPoint.y()) );
00458
00459
00460 currentDragMode = mouseActionByPosition(e->pos());
00461
00462 switch(currentDragMode)
00463 {
00464 case DRAW_SELECTION:
00465 mousePressPoint = p;
00466 mouseDragPoint = p;
00467 cropMaxDimen = -1.0;
00468 emit aspectRatioChanged();
00469 break;
00470 case MOVE_SELECTION:
00471
00472 break;
00473 case MOVE_TOP_LEFT_CORNER:
00474 mousePressPoint = bottomRight;
00475 mouseDragPoint = topLeft;
00476 break;
00477 case MOVE_BOTTOM_RIGHT_CORNER:
00478 mousePressPoint = topLeft;
00479 mouseDragPoint = bottomRight;
00480 break;
00481 case MOVE_TOP_RIGHT_CORNER:
00482 mousePressPoint = QPoint( topLeft.x(), bottomRight.y() );
00483 mouseDragPoint = QPoint( bottomRight.x(), topLeft.y() );
00484 break;
00485 case MOVE_BOTTOM_LEFT_CORNER:
00486 mousePressPoint = QPoint( bottomRight.x(), topLeft.y() );
00487 mouseDragPoint = QPoint( topLeft.x(), bottomRight.y() );
00488 break;
00489 case MOVE_LEFT_SIDE:
00490 mousePressPoint = bottomRight;
00491 mouseDragPoint = topLeft;
00492 break;
00493 case MOVE_RIGHT_SIDE:
00494 mousePressPoint = topLeft;
00495 mouseDragPoint = bottomRight;
00496 break;
00497 case MOVE_TOP_SIDE:
00498 mousePressPoint = bottomRight;
00499 mouseDragPoint = topLeft;
00500 break;
00501 case MOVE_BOTTOM_SIDE:
00502 mousePressPoint = topLeft;
00503 mouseDragPoint = bottomRight;
00504 break;
00505
00506 default:
00507 return;
00508 }
00509
00510
00511 repaint(false);
00512 emit selectionChanged();
00513 }
00514
00515 void SelectionInterface::updateCursorShape( QPoint rawP )
00516 {
00517
00518 if(SHIFT_Pressed)
00519 {
00520 setCursor( getCursor(SCALE_SELECTION_CURSOR) );
00521 return;
00522 }
00523
00524
00525 if(CTRL_Pressed)
00526 {
00527 setCursor( getCursor(ROTATE_CURSOR) );
00528 return;
00529 }
00530
00531
00532 if( currentDragMode == DRAW_LINE )
00533 {
00534 setCursor( getCursor(TARGET_CURSOR) );
00535 return;
00536 }
00537
00538
00539 currentMouseShape = mouseActionByPosition( rawP );
00540 switch(currentMouseShape)
00541 {
00542 case DRAW_SELECTION:
00543 setCursor( getCursor(CROSS_CURSOR) ); break;
00544 case MOVE_SELECTION:
00545 setCursor( getCursor(MOVE_SELECTION_CURSOR) ); break;
00546 case MOVE_TOP_LEFT_CORNER:
00547 case MOVE_BOTTOM_RIGHT_CORNER:
00548 setCursor( getCursor(MOVE_TL_CURSOR) ); break;
00549 case MOVE_TOP_RIGHT_CORNER:
00550 case MOVE_BOTTOM_LEFT_CORNER:
00551 setCursor( getCursor(MOVE_TR_CURSOR) ); break;
00552 case MOVE_LEFT_SIDE:
00553 case MOVE_RIGHT_SIDE:
00554 setCursor( getCursor(MOVE_HOR_CURSOR) ); break;
00555 case MOVE_TOP_SIDE:
00556 case MOVE_BOTTOM_SIDE:
00557 setCursor( getCursor(MOVE_VERT_CURSOR) ); break;
00558 break;
00559 default:
00560 setCursor( Qt::ArrowCursor );
00561 break;
00562 }
00563 }
00564
00565 bool SelectionInterface::scaleSelection( int delta )
00566 {
00567
00568 QPoint topLeft( QMIN(mousePressPoint.x(), mouseDragPoint.x()),
00569 QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
00570 QPoint bottomRight( QMAX(mousePressPoint.x(), mouseDragPoint.x()),
00571 QMAX(mousePressPoint.y(), mouseDragPoint.y()) );
00572
00573
00574 int curSelectionWidth = bottomRight.x() - topLeft.x() + 1;
00575 int curSelectionHeight = bottomRight.y()- topLeft.y() + 1;
00576 int newSelectionWidth = -1;
00577 int newSelectionHeight = -1;
00578
00579
00580 if( curSelectionWidth > curSelectionHeight )
00581 {
00582 newSelectionWidth = QMIN( curSelectionWidth + delta, origImageSize.width() );
00583 newSelectionHeight = (newSelectionWidth * cachedSelectionSize.height()) / cachedSelectionSize.width();
00584 }
00585 else
00586 {
00587 newSelectionHeight = QMIN( curSelectionHeight + delta, origImageSize.height() );
00588 newSelectionWidth = (newSelectionHeight * cachedSelectionSize.width()) / cachedSelectionSize.height();
00589 }
00590
00591
00592 if(delta > 0 &&
00593 ( curSelectionWidth == origImageSize.width() ||
00594 curSelectionHeight == origImageSize.height() ) )
00595 {
00596 return false;
00597 }
00598
00599
00600 if(newSelectionHeight > origImageSize.height())
00601 {
00602 newSelectionHeight = origImageSize.height();
00603 newSelectionWidth = (newSelectionHeight * cachedSelectionSize.width()) / cachedSelectionSize.height();
00604 }
00605
00606
00607 if(newSelectionWidth <= 0 || newSelectionHeight <= 0)
00608 {
00609 newSelectionWidth = curSelectionWidth;
00610 newSelectionHeight = curSelectionHeight;
00611 }
00612
00613
00614 topLeft = QPoint(QMAX( cachedSelctionCenter.x() - newSelectionWidth/2, 0 ),
00615 QMAX( cachedSelctionCenter.y() - newSelectionHeight/2, 0 ));
00616 bottomRight = QPoint( topLeft.x() + newSelectionWidth - 1,
00617 topLeft.y() + newSelectionHeight - 1 );
00618
00619
00620 if(bottomRight.x() > origImageSize.width() - 1 )
00621 {
00622 int diff = bottomRight.x() - (origImageSize.width() - 1);
00623 topLeft.setX( topLeft.x() - diff );
00624 bottomRight.setX( bottomRight.x() - diff );
00625
00626
00627 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00628 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00629 }
00630
00631
00632 if(bottomRight.y() > origImageSize.height() - 1 )
00633 {
00634 int diff = bottomRight.y() - (origImageSize.height() - 1);
00635 topLeft.setY( topLeft.y() - diff );
00636 bottomRight.setY( bottomRight.y() - diff );
00637
00638
00639 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00640 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00641 }
00642
00643
00644 mousePressPoint = topLeft;
00645 mouseDragPoint = bottomRight;
00646
00647
00648 return true;
00649 }
00650
00651 void SelectionInterface::mouseMoveEvent(QMouseEvent *e)
00652 {
00653
00654
00655 if( SHIFT_Pressed && !(e->state() & Qt::ShiftButton) )
00656 {
00657 SHIFT_Pressed = false;
00658 updateCursorShape( ConvertImageToDisplayCoordinate( e->pos() ) );
00659 }
00660
00661
00662
00663 if( CTRL_Pressed && !(e->state() & Qt::ControlButton) )
00664 {
00665 CTRL_Pressed = false;
00666 updateCursorShape( ConvertImageToDisplayCoordinate( e->pos() ) );
00667 }
00668
00669
00670
00671 if(currentDragMode == NO_EFFECT)
00672 {
00673
00674 if( mouseActionByPosition( e->pos() ) != currentMouseShape )
00675 updateCursorShape( e->pos() );
00676
00677 cachedMousePosition = ConvertDisplayToImageCoordinate( cropSelectedPoint(e->pos()) );
00678 }
00679
00680 else if(currentDragMode == DRAW_LINE)
00681 {
00682
00683 if( mousePressPoint.x() == -1 )
00684 return;
00685
00686
00687 mouseDragPoint = ConvertDisplayToImageCoordinate( cropSelectedPoint(e->pos()) );
00688
00689
00690 repaint(false);
00691 }
00692
00693 else
00694 {
00695
00696 QPoint p = ConvertDisplayToImageCoordinate( cropSelectedPoint(e->pos()) );
00697
00698
00699 QPoint topLeft( QMIN(mousePressPoint.x(), mouseDragPoint.x()),
00700 QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
00701 QPoint bottomRight( QMAX(mousePressPoint.x(), mouseDragPoint.x()),
00702 QMAX(mousePressPoint.y(), mouseDragPoint.y()) );
00703
00704
00705 if(SHIFT_Pressed &&
00706 bottomRight.x() > topLeft.x() &&
00707 bottomRight.y() > topLeft.y() )
00708 {
00709
00710 int delta = p.x() - cachedMousePosition.x();
00711 if( !scaleSelection( delta ) )
00712 {
00713
00714 cachedMousePosition = p;
00715 return;
00716 }
00717 }
00718
00719
00720 else if( currentDragMode == MOVE_SELECTION )
00721 {
00722
00723 QPoint offset( p.x() - cachedMousePosition.x(),
00724 p.y() - cachedMousePosition.y() );
00725
00726
00727 QPoint topLeft( QMIN(mousePressPoint.x(), mouseDragPoint.x()),
00728 QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
00729 QPoint bottomRight( QMAX(mousePressPoint.x(), mouseDragPoint.x()),
00730 QMAX(mousePressPoint.y(), mouseDragPoint.y()) );
00731
00732
00733
00734
00735 if(offset.x() < 0 && topLeft.x() + offset.x() < 0 )
00736 offset.setX( -topLeft.x() );
00737
00738
00739 if(offset.x() > 0 && bottomRight.x() + offset.x() >= origImageSize.width() )
00740 offset.setX( origImageSize.width() - 1 - bottomRight.x() );
00741
00742
00743 if(offset.y() < 0 && topLeft.y() + offset.y() < 0 )
00744 offset.setY( -topLeft.y() );
00745
00746
00747 if(offset.y() > 0 && bottomRight.y() + offset.y() >= origImageSize.height() )
00748 offset.setY( origImageSize.height() - 1 - bottomRight.y() );
00749
00750
00751 mousePressPoint+= offset;
00752 mouseDragPoint+= offset;
00753
00754
00755 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00756 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00757 }
00758
00759
00760 else if( currentDragMode == DRAW_SELECTION ||
00761 currentDragMode == MOVE_TOP_LEFT_CORNER ||
00762 currentDragMode == MOVE_TOP_RIGHT_CORNER ||
00763 currentDragMode == MOVE_BOTTOM_LEFT_CORNER ||
00764 currentDragMode == MOVE_BOTTOM_RIGHT_CORNER )
00765 {
00766 mouseDragPoint.setX( p.x() );
00767 mouseDragPoint.setY( p.y() );
00768 cropMaxDimen = -1.0;
00769
00770
00771 cachedSelectionSize = QSize( QABS( mouseDragPoint.x() - mousePressPoint.x() )+1,
00772 QABS( mouseDragPoint.y() - mousePressPoint.y() )+1);
00773 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00774 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00775
00776
00777 emit aspectRatioChanged();
00778 }
00779
00780
00781 else if( currentDragMode == MOVE_LEFT_SIDE ||
00782 currentDragMode == MOVE_RIGHT_SIDE )
00783 {
00784 mouseDragPoint.setX( p.x() );
00785 cropMaxDimen = -1.0;
00786 emit aspectRatioChanged();
00787
00788
00789 cachedSelectionSize = QSize( QABS( mouseDragPoint.x() - mousePressPoint.x() )+1,
00790 QABS( mouseDragPoint.y() - mousePressPoint.y() )+1);
00791 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00792 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00793 }
00794
00795
00796 else if( currentDragMode == MOVE_TOP_SIDE ||
00797 currentDragMode == MOVE_BOTTOM_SIDE )
00798 {
00799 mouseDragPoint.setY( p.y() );
00800 cropMaxDimen = -1.0;
00801 emit aspectRatioChanged();
00802
00803
00804 cachedSelectionSize = QSize( QABS( mouseDragPoint.x() - mousePressPoint.x() )+1,
00805 QABS( mouseDragPoint.y() - mousePressPoint.y() )+1);
00806 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00807 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00808
00809 }
00810
00811
00812 cachedMousePosition = p;
00813
00814
00815 repaint(false);
00816 emit selectionChanged();
00817
00818
00819 if( mouseActionByPosition( e->pos() ) != currentMouseShape )
00820 updateCursorShape( e->pos() );
00821 }
00822 }
00823
00824 void SelectionInterface::mouseReleaseEvent(QMouseEvent *e)
00825 {
00826
00827 if( currentDragMode == DRAW_LINE )
00828 {
00829
00830 QPoint p = ConvertDisplayToImageCoordinate( e->pos() );
00831
00832
00833 if( mousePressPoint.x() == -1 )
00834 {
00835 mousePressPoint = p;
00836 repaint(false);
00837 }
00838
00839 else
00840 {
00841
00842 QPoint p1 = mousePressPoint;
00843 QPoint p2 = p;
00844
00845
00846 currentDragMode = NO_EFFECT;
00847 selectNone();
00848 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
00849
00850
00851 emit lineSelected( p1, p2 );
00852 }
00853 return;
00854 }
00855
00856
00857 currentDragMode = NO_EFFECT;
00858
00859
00860 QPoint topLeft( QMIN(mousePressPoint.x(), mouseDragPoint.x()),
00861 QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
00862 QPoint bottomRight( QMAX(mousePressPoint.x(), mouseDragPoint.x()),
00863 QMAX(mousePressPoint.y(), mouseDragPoint.y()) );
00864
00865
00866 topLeft = ConvertImageToDisplayCoordinate( topLeft );
00867 bottomRight = ConvertImageToDisplayCoordinate( bottomRight );
00868
00869
00870 if( bottomRight.x() - topLeft.x() + 1 < MINIMUM_SELECTION_SIZE ||
00871 bottomRight.y() - topLeft.y() + 1 < MINIMUM_SELECTION_SIZE ) { selectNone(); }
00872 }
00873
00874 QPoint SelectionInterface::ConvertDisplayToImageCoordinate( QPoint p )
00875 {
00876 QPoint newPoint = p;
00877
00878
00879 int xOffset = (width() - scaledImage.width() ) / 2;
00880 int yOffset = (height() - scaledImage.height() ) / 2;
00881 newPoint.setX( newPoint.x() - xOffset );
00882 newPoint.setY( newPoint.y() - yOffset );
00883
00884
00885
00886 if(newPoint.x() == scaledImage.width() - 1)
00887 newPoint.setX( origImageSize.width() - 1);
00888 else
00889 newPoint.setX( (int) (0.5 + ((double)(newPoint.x() * (origImageSize.width()-1))) / (scaledImage.width()-1) ) );
00890
00891 if(newPoint.y() == scaledImage.height() - 1)
00892 newPoint.setY( origImageSize.height() - 1);
00893 else
00894 newPoint.setY( (int) (0.5 + ((double)(newPoint.y() * (origImageSize.height()-1))) / (scaledImage.height()-1) ) );
00895
00896
00897 return newPoint;
00898 }
00899
00900 QPoint SelectionInterface::ConvertImageToDisplayCoordinate( QPoint p )
00901 {
00902 QPoint newPoint = p;
00903
00904
00905
00906 if(newPoint.x() == origImageSize.width() - 1)
00907 newPoint.setX( scaledImage.width() - 1);
00908 else
00909 newPoint.setX( (newPoint.x() * (scaledImage.width()-1)) / (origImageSize.width()-1) );
00910
00911 if(newPoint.y() == origImageSize.height() - 1)
00912 newPoint.setY( scaledImage.height() - 1);
00913 else
00914 newPoint.setY( (newPoint.y() * (scaledImage.height()-1)) / (origImageSize.height()-1) );
00915
00916
00917 int xOffset = (width() - scaledImage.width() ) / 2;
00918 int yOffset = (height() - scaledImage.height() ) / 2;
00919 newPoint.setX( newPoint.x() + xOffset );
00920 newPoint.setY( newPoint.y() + yOffset );
00921
00922
00923 return newPoint;
00924 }
00925
00926 QPoint SelectionInterface::cropSelectedPoint(QPoint p)
00927 {
00928 int xOffset = (width() - scaledImage.width() ) / 2;
00929 int yOffset = (height() - scaledImage.height() ) / 2;
00930
00931 QPoint croppedPoint;
00932 croppedPoint.setX( QMIN( QMAX(xOffset, p.x()), xOffset + scaledImage.width() - 1 ) );
00933 croppedPoint.setY( QMIN( QMAX(yOffset, p.y()), yOffset + scaledImage.height() - 1 ) );
00934 return croppedPoint;
00935 }
00936
00937 bool SelectionInterface::selectionEmpty()
00938 {
00939 return (
00940 mousePressPoint.x() == -1 ||
00941 mouseDragPoint.x() - mousePressPoint.x() == 0 ||
00942 mouseDragPoint.y() - mousePressPoint.y() == 0
00943 );
00944 }
00945
00946 void SelectionInterface::selectAll()
00947 {
00948 mousePressPoint.setX( 0 );
00949 mousePressPoint.setY( 0 );
00950 mouseDragPoint.setX( origImageSize.width() - 1 );
00951 mouseDragPoint.setY( origImageSize.height() - 1);
00952
00953
00954 cachedSelectionSize = QSize( QABS( mouseDragPoint.x() - mousePressPoint.x() )+1,
00955 QABS( mouseDragPoint.y() - mousePressPoint.y() )+1);
00956 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00957 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00958
00959 cropMaxDimen = -1.0;
00960 repaint(false);
00961 emit selectionChanged();
00962 emit aspectRatioChanged();
00963 }
00964
00965 void SelectionInterface::selectNone()
00966 {
00967 mousePressPoint = QPoint(-1,-1);
00968 mouseDragPoint = QPoint(-1,-1);
00969 cropMaxDimen = -1.0;
00970 repaint(false);
00971 emit selectionChanged();
00972 emit aspectRatioChanged();
00973 }
00974
00975 void SelectionInterface::setSelection(QPoint topLeft, QPoint bottomRight,
00976 double cropMaxDimen)
00977 {
00978 mousePressPoint = topLeft;
00979 mouseDragPoint = bottomRight;
00980
00981 this->cropMaxDimen = cropMaxDimen;
00982
00983
00984 cachedSelectionSize = QSize( QABS( mouseDragPoint.x() - mousePressPoint.x() )+1,
00985 QABS( mouseDragPoint.y() - mousePressPoint.y() )+1);
00986 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
00987 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
00988
00989 repaint(false);
00990 emit selectionChanged();
00991 }
00992
00993 void SelectionInterface::getSelection(QPoint &topLeft, QPoint &bottomRight)
00994 {
00995
00996 if(mousePressPoint.x() == -1)
00997 {
00998 topLeft.setX(-1); topLeft.setY(-1);
00999 bottomRight.setX(-1); bottomRight.setY(-1);
01000 return;
01001 }
01002
01003
01004 topLeft.setX( QMIN(mousePressPoint.x(), mouseDragPoint.x()) );
01005 topLeft.setY( QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
01006 bottomRight.setX( QMAX( mousePressPoint.x(), mouseDragPoint.x()) );
01007 bottomRight.setY( QMAX( mousePressPoint.y(), mouseDragPoint.y()) );
01008 }
01009
01010 void SelectionInterface::getDisplaySize(int &width, int &height)
01011 {
01012 width = scaledImage.width();
01013 height = scaledImage.height();
01014 }
01015
01016 void SelectionInterface::keyPressEvent(QKeyEvent *e)
01017 {
01018
01019
01020
01021 if( currentDragMode == DRAW_LINE )
01022 {
01023 if(e->key() == Qt::Key_Escape )
01024 {
01025
01026 currentDragMode = NO_EFFECT;
01027 selectNone();
01028 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
01029
01030
01031 emit lineSelected( QPoint(-1,-1), QPoint(-1,-1) );
01032 }
01033
01034 return;
01035 }
01036
01037
01038
01039
01040 if(e->key() == Qt::Key_Shift && !selectionEmpty() )
01041 {
01042 SHIFT_Pressed = true;
01043 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
01044 return;
01045 }
01046
01047
01048
01049
01050 if(e->key() == Qt::Key_Control && !selectionEmpty() && !SHIFT_Pressed )
01051 {
01052 CTRL_Pressed = true;
01053 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
01054 return;
01055 }
01056
01057
01058 if(mousePressPoint.x() == -1 ||
01059 mousePressPoint.x() - mouseDragPoint.x() == 0 ||
01060 mousePressPoint.y() - mouseDragPoint.y() == 0)
01061 {
01062 e->ignore();
01063 return;
01064 }
01065
01066
01067
01068 if( currentDragMode != NO_EFFECT )
01069 {
01070 e->ignore();
01071 return;
01072 }
01073
01074
01075
01076 if( e->key() == Qt::Key_Plus ||
01077 e->key() == Qt::Key_Equal ||
01078 e->key() == Qt::Key_Minus ||
01079 e->key() == Qt::Key_Underscore )
01080 {
01081 int delta = 2*QMAX( origImageSize.width(), scaledImage.width() ) / scaledImage.width();
01082
01083 delta = 1;
01084
01085
01086 if( e->key() == Qt::Key_Minus ||
01087 e->key() == Qt::Key_Underscore )
01088 delta = -delta;
01089
01090 if( scaleSelection( delta ) )
01091 {
01092
01093 repaint(false);
01094 emit selectionChanged();
01095 }
01096 return;
01097 }
01098
01099
01100
01101 QPoint topLeft, bottomRight;
01102 topLeft.setX( QMIN(mousePressPoint.x(), mouseDragPoint.x()) );
01103 topLeft.setY( QMIN(mousePressPoint.y(), mouseDragPoint.y()) );
01104 bottomRight.setX( QMAX( mousePressPoint.x(), mouseDragPoint.x()) );
01105 bottomRight.setY( QMAX( mousePressPoint.y(), mouseDragPoint.y()) );
01106
01107
01108
01109 int moveBy = 0;
01110 if( e->key() == Qt::Key_Left ||
01111 e->key() == Qt::Key_Right )
01112 {
01113 moveBy = QMAX( origImageSize.width(), scaledImage.width() ) / scaledImage.width();
01114 }
01115 else
01116 {
01117 moveBy = QMAX( origImageSize.height(), scaledImage.height() ) / scaledImage.height();
01118 }
01119
01120
01121 int dx = 0;
01122 int dy = 0;
01123 switch( e->key() )
01124 {
01125 case Qt::Key_Left:
01126 dx = QMAX( topLeft.x() - moveBy, 0) - topLeft.x();
01127 break;
01128 case Qt::Key_Right:
01129 dx = QMIN( bottomRight.x() + moveBy, origImageSize.width() - 1) - bottomRight.x();
01130 break;
01131 case Qt::Key_Up:
01132 dy = QMAX( topLeft.y() - moveBy, 0) - topLeft.y();
01133 break;
01134 case Qt::Key_Down:
01135 dy = QMIN( bottomRight.y() + moveBy, origImageSize.height() - 1) - bottomRight.y();
01136 break;
01137 default:
01138 e->ignore();
01139 return;
01140 }
01141
01142
01143 mousePressPoint.setX( mousePressPoint.x() + dx );
01144 mouseDragPoint.setX( mouseDragPoint.x() + dx );
01145
01146
01147 mousePressPoint.setY( mousePressPoint.y() + dy );
01148 mouseDragPoint.setY( mouseDragPoint.y() + dy );
01149
01150
01151 cachedSelctionCenter = QPoint( ( mouseDragPoint.x() + mousePressPoint.x() )/2,
01152 ( mouseDragPoint.y() + mousePressPoint.y() )/2 );
01153
01154
01155 if(dx != 0 || dy != 0)
01156 {
01157 repaint(false);
01158 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
01159 }
01160 }
01161
01162 void SelectionInterface::keyReleaseEvent(QKeyEvent *e)
01163 {
01164
01165
01166 if(e->key() == Qt::Key_Shift)
01167 {
01168 SHIFT_Pressed = false;
01169 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
01170 }
01171
01172
01173 else if(e->key() == Qt::Key_Control)
01174 {
01175 CTRL_Pressed = false;
01176 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
01177 }
01178
01179 else { e->ignore(); }
01180 }
01181
01182 void SelectionInterface::enterDrawLineMode()
01183 {
01184
01185 currentDragMode = DRAW_LINE;
01186
01187
01188
01189 SHIFT_Pressed = false;
01190 CTRL_Pressed = false;
01191
01192
01193 mousePressPoint = QPoint( -1, -1 );
01194 mouseDragPoint = QPoint( -1, -1 );
01195
01196
01197 updateCursorShape( ConvertImageToDisplayCoordinate(cachedMousePosition) );
01198 repaint(false);
01199 }
01200
01201