AlbumShaper
1.0a3
|
00001 //============================================== 00002 // copyright : (C) 2003-2005 by Will Stokes 00003 //============================================== 00004 // This program is free software; you can redistribute it 00005 // and/or modify it under the terms of the GNU General 00006 // Public License as published by the Free Software 00007 // Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 //============================================== 00010 00011 //Systemwide includes 00012 #include <qapplication.h> 00013 #include <qpainter.h> 00014 #include <qcursor.h> 00015 00016 //Projectwide includes 00017 #include "selectionPlacementInterface.h" 00018 #include "../../backend/tools/imageTools.h" 00019 #include "../cursors.h" 00020 00021 //============================================== 00022 SelectionPlacementInterface::SelectionPlacementInterface( QString imageFilename, 00023 QWidget *parent, const char* name ) 00024 : QWidget (parent, name ) 00025 { 00026 //store original image dimensions 00027 getImageSize( imageFilename, origImageSize ); 00028 00029 //construct scaled image 00030 scaleImage( imageFilename, scaledImage, 200, 200 ); 00031 00032 //construct an unselected scaled image 00033 unselectedScaledImage = scaledImage.copy(); 00034 int x, y; 00035 QRgb* rgb; 00036 uchar* scanLine; 00037 for( y=0; y<unselectedScaledImage.height(); y++) 00038 { 00039 //iterate over each selected pixel in scanline 00040 scanLine = unselectedScaledImage.scanLine(y); 00041 for( x=0; x<unselectedScaledImage.width(); x++) 00042 { 00043 //compress dynamic range to 25% of original 00044 rgb = ((QRgb*)scanLine+x); 00045 00046 double r = ((double)qRed(*rgb) )/255.0; 00047 double g = ((double)qGreen(*rgb) )/255.0; 00048 double b = ((double)qBlue(*rgb) )/255.0; 00049 00050 //convert to hsv 00051 double h,s,v; 00052 RGBtoHSV(r,g,b,&h,&s,&v); 00053 00054 //scale and clamp v 00055 v*=0.25; 00056 00057 //convert adjusted color back to rgb colorspace and clamp 00058 HSVtoRGB( &r,&g,&b, h,s,v); 00059 int rp = (int) QMIN( QMAX((r*255), 0), 255 ); 00060 int gp = (int) QMIN( QMAX((g*255), 0), 255 ); 00061 int bp = (int) QMIN( QMAX((b*255), 0), 255 ); 00062 00063 //set adjusted color value 00064 *rgb = qRgb(rp,gp,bp); 00065 } 00066 } 00067 00068 //watch mouse movements in order to drag selection 00069 //watch mouse movements in order to move split point between adjusted and original image 00070 setMouseTracking(true); 00071 00072 //by default no in dragging mode 00073 currentlyDragging = false; 00074 currentMouseShapeIsDrag = false; 00075 00076 //accept focus when clicked on 00077 setFocusPolicy( QWidget::ClickFocus ); 00078 00079 //init selection area 00080 selection.setTopLeft( QPoint( -1, -1 ) ); 00081 selection.setBottomRight( QPoint( -1, -1 ) ); 00082 } 00083 //============================================== 00084 SelectionPlacementInterface::~SelectionPlacementInterface() { } 00085 //============================================== 00086 void SelectionPlacementInterface::paintEvent(QPaintEvent *e) 00087 { 00088 //if no scaled image just return 00089 if(scaledImage.isNull()) { return; } 00090 00091 //create buffer to draw in 00092 QPixmap buffer( size() ); 00093 00094 //create a painter pointing to the buffer 00095 QPainter bufferPainter( &buffer ); 00096 00097 //turn off clipping to make painting operations faster 00098 bufferPainter.setClipping(false); 00099 00100 //initialize buffer with background brush 00101 bufferPainter.fillRect( buffer.rect(), backgroundBrush() ); 00102 00103 int xOffset = (width() - scaledImage.width()) / 2; 00104 int yOffset = (height() - scaledImage.height()) / 2; 00105 00106 //selection not set yet, simply paint the scaled image normally 00107 if(selection.width() == 0 || selection.height() == 0 ) 00108 { 00109 bufferPainter.drawImage( QPoint(xOffset, yOffset), scaledImage ); 00110 } 00111 //selection present... 00112 else 00113 { 00114 //first paint using unselected coloring 00115 bufferPainter.drawImage( QPoint(xOffset, yOffset), unselectedScaledImage ); 00116 00117 //convert selection coordinates to display space 00118 QRect displayRect = imageToDisplay( selection ); 00119 QPoint topLeft = displayRect.topLeft() + QPoint( xOffset, yOffset ); 00120 QPoint bottomRight = displayRect.bottomRight() + QPoint( xOffset, yOffset ); 00121 00122 //now paint selected region in color 00123 bufferPainter.drawImage( topLeft.x(), topLeft.y(), 00124 scaledImage, 00125 displayRect.left(), displayRect.top(), 00126 displayRect.width(), displayRect.height() ); 00127 00128 00129 //paint thin line around selected region to help it stand out even more 00130 if( selection.width() < origImageSize.width() || 00131 selection.height() < origImageSize.height() ) 00132 { 00133 QPen pen; 00134 pen.setColor( gray ); 00135 pen.setStyle( Qt::SolidLine ); 00136 pen.setWidth( 2 ); 00137 bufferPainter.setPen( pen); 00138 00139 QRect selctRect( topLeft, bottomRight ); 00140 bufferPainter.drawRect(selctRect); 00141 } 00142 } 00143 00144 //end painter 00145 bufferPainter.end(); 00146 00147 //blit buffer to screen 00148 bitBlt( this, 00149 e->rect().x(), e->rect().y(), 00150 &buffer, 00151 e->rect().x(), e->rect().y(), 00152 e->rect().width(), e->rect().height() ); 00153 } 00154 //============================================== 00155 QSize SelectionPlacementInterface::sizeHint() const 00156 { return minimumSizeHint(); } 00157 //============================================== 00158 QSize SelectionPlacementInterface::minimumSizeHint() const 00159 { return scaledImage.size(); } 00160 //============================================== 00161 bool SelectionPlacementInterface::overRegion( QPoint p ) 00162 { 00163 if( selection.width() == 0 || selection.height() == 0 ) 00164 { return false; } 00165 00166 QRect displayRect = imageToDisplay( selection ); 00167 00168 //if the entire image is visible then no rectangle can be dragged so just 00169 //return false so a drag cursor never becomes visible since it might 00170 //confuse the user into thinking s/he could actually drag it 00171 if( displayRect.width() == scaledImage.width() && 00172 displayRect.height() == scaledImage.height() ) 00173 return false; 00174 00175 //determine if mouse cursor is over region 00176 int xOffset = (width() - scaledImage.width() ) / 2; 00177 int yOffset = (height() - scaledImage.height()) / 2; 00178 00179 return ( p.x() >= xOffset + displayRect.left() && 00180 p.x() <= xOffset + displayRect.right() && 00181 p.y() >= yOffset + displayRect.top() && 00182 p.y() <= yOffset + displayRect.bottom() ); 00183 } 00184 //============================================== 00185 void SelectionPlacementInterface::recenterSelection(QPoint mousePosition) 00186 { 00187 //compute new viewing center 00188 QPoint center = QPoint( ((origImageSize.width()-1) * mousePosition.x()) / (width()-1), 00189 ((origImageSize.height()-1) * mousePosition.y()) / (height()-1) ); 00190 //move selection 00191 int sW = selection.width(); 00192 int sH = selection.height(); 00193 selection.setLeft( center.x() - sW/2 ); 00194 selection.setTop( center.y() - sH/2 ); 00195 selection.setRight( selection.left() + sW -1 ); 00196 selection.setBottom( selection.top() + sH -1 ); 00197 00198 //ensure selection window never goes out of bounds 00199 if(selection.left() < 0 ) 00200 selection.moveBy( -selection.left(), 0 ); 00201 00202 if(selection.right() > origImageSize.width() - 1 ) 00203 selection.moveBy( (origImageSize.width() - 1) - selection.right(), 0 ); 00204 00205 if(selection.top() < 0 ) 00206 selection.moveBy( 0, -selection.top() ); 00207 00208 if(selection.bottom() > origImageSize.height() - 1 ) 00209 selection.moveBy( 0, (origImageSize.height() - 1) - selection.bottom() ); 00210 00211 //repaint and emit placement changed signal 00212 repaint(false); 00213 emit placementChanged( selection ); 00214 } 00215 //============================================== 00216 void SelectionPlacementInterface::mousePressEvent( QMouseEvent *e) 00217 { 00218 //if mouse press is not over the region then center viewed area over mouse press 00219 if( !currentMouseShapeIsDrag ) 00220 { 00221 recenterSelection(e->pos()); 00222 currentMouseShapeIsDrag = true; 00223 setCursor( getCursor(MOVE_SELECTION_CURSOR) ); 00224 } 00225 00226 //enter dragging mode 00227 currentlyDragging = true; 00228 } 00229 //============================================== 00230 void SelectionPlacementInterface::mouseMoveEvent( QMouseEvent *e) 00231 { 00232 //if not dragging update mosue cursor 00233 if(!currentlyDragging) 00234 { 00235 if( !overRegion(e->pos() ) && currentMouseShapeIsDrag ) 00236 { 00237 currentMouseShapeIsDrag = false; 00238 setCursor( Qt::ArrowCursor ); 00239 } 00240 else if( overRegion(e->pos() ) && !currentMouseShapeIsDrag ) 00241 { 00242 currentMouseShapeIsDrag = true; 00243 setCursor( getCursor(MOVE_SELECTION_CURSOR) ); 00244 00245 } 00246 } 00247 //move selection 00248 else { recenterSelection(e->pos()); } 00249 } 00250 //============================================== 00251 void SelectionPlacementInterface::mouseReleaseEvent( QMouseEvent *) 00252 { 00253 //disable dragging 00254 currentlyDragging = false; 00255 } 00256 //============================================== 00257 QRect SelectionPlacementInterface::imageToDisplay( QRect r ) 00258 { 00259 //set top left 00260 QRect res; 00261 res.setTopLeft(QPoint( (int) (0.5+ (1.0*scaledImage.width()*r.left()) / origImageSize.width()), 00262 (int) (0.5+ (1.0*scaledImage.height()*r.top()) / origImageSize.height()) )); 00263 00264 //set width/height 00265 res.setWidth( (scaledImage.width() *r.width()) / origImageSize.width() ); 00266 res.setHeight( (scaledImage.height() *r.height()) / origImageSize.height() ); 00267 00268 //if against the right hand size make sure scaled display coordiantes are also 00269 //against edge. rounding prevents this from occuring and is noticeable since selection 00270 //rectangle appears to never be at every edge. 00271 if( r.right() == origImageSize.width() - 1) 00272 { res.moveBy( (scaledImage.width()-1) - res.right(), 0 ); } 00273 00274 if( r.bottom() == origImageSize.height() - 1) 00275 { res.moveBy( 0, (scaledImage.height()-1) - res.bottom() ); } 00276 00277 //return new rect 00278 return res; 00279 } 00280 //============================================== 00281 QRect SelectionPlacementInterface::getSelectedRegion() 00282 { 00283 return selection; 00284 } 00285 //============================================== 00286 void SelectionPlacementInterface::setSelectedRegion( QRect selection ) 00287 { 00288 this->selection = selection; 00289 repaint(false); 00290 } 00291 //==============================================