Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

splitViewInterface.cpp

Go to the documentation of this file.
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 <qpainter.h> 00013 #include <qcursor.h> 00014 00015 //Projectwide includes 00016 #include "splitViewInterface.h" 00017 #include "../cursors.h" 00018 #include "../../backend/tools/imageTools.h" 00019 00020 #define TEXT_BACKGROUND_MARGIN 2 00021 #define TEXT_INSET 4 00022 00023 //a mouse press within DRAG_THRESHOLD will move split point 00024 #define DRAG_THRESHOLD 8 00025 00026 //============================================== 00027 SplitViewInterface::SplitViewInterface( QWidget *parent, const char* name ) : 00028 QWidget (parent, name ) 00029 { 00030 //setup split point 00031 dragOffset = 0.5; 00032 mouseMode = NO_EFFECT_ON_SPLIT; 00033 currentMouseShape = NO_EFFECT_ON_SPLIT; 00034 00035 //set default mode to adjusted image 00036 previewMode = SPLIT_VIEW; 00037 00038 //don't force draw labels by default. this is useful when 00039 //the user pressed the Ctrl button or other key to toggle between opposite views 00040 //and drop down menu for choosing display type disagrees with actuall image being shown. 00041 forceDrawLabel = false; 00042 00043 //setup strings and fonts 00044 originalString = QString( tr("Original") ); 00045 adjustedString = QString( tr("Adjusted") ); 00046 00047 textFont = this->font(); 00048 textFont.setPointSize( textFont.pointSize() + 7 ); 00049 00050 //watch mouse movements in order to drag selection 00051 //watch mouse movements in order to move split point between adjusted and original image 00052 setMouseTracking(true); 00053 00054 //accept focus when clicked on 00055 setFocusPolicy( QWidget::ClickFocus ); 00056 } 00057 //============================================== 00058 void SplitViewInterface::paintEvent(QPaintEvent *e) 00059 { 00060 //if orig image not setup yet then return immediately 00061 if(origImage.isNull()) { return; } 00062 00063 //if viewing adjusted or split view and adjusted image is null bail 00064 if( 00065 (previewMode == ADJUSTED_IMAGE || previewMode == SPLIT_VIEW ) && 00066 adjustedImage.isNull() 00067 ) 00068 { return; } 00069 00070 //create buffer to draw in 00071 QPixmap buffer( size() ); 00072 00073 //create a painter pointing to the buffer 00074 QPainter bufferPainter( &buffer ); 00075 00076 //turn off clipping to make painting operations faster 00077 bufferPainter.setClipping(false); 00078 00079 //initialize buffer with background brush 00080 bufferPainter.fillRect( buffer.rect(), backgroundBrush() ); 00081 00082 //setup pen color 00083 QPen pen; 00084 pen.setStyle( Qt::SolidLine ); 00085 pen.setColor( white ); 00086 pen.setWidth( 2 ); 00087 bufferPainter.setPen( pen); 00088 00089 int xOffset = (width() - origImage.width()) / 2; 00090 int yOffset = (height() - origImage.height()) / 2; 00091 00092 //setup font metrics 00093 bufferPainter.setFont( textFont ); 00094 QFontMetrics fm( textFont ); 00095 00096 //paint the adjusted image 00097 if(previewMode == ADJUSTED_IMAGE) 00098 { 00099 bufferPainter.drawImage( QPoint(xOffset, yOffset), adjustedImage ); 00100 00101 //"Adjusted" label 00102 if(forceDrawLabel) 00103 { 00104 int x = xOffset + (origImage.width()-fm.width(adjustedString))/2; 00105 int y = yOffset + fm.ascent() + TEXT_INSET; 00106 00107 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 00108 y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 00109 fm.width(adjustedString) + 2*TEXT_BACKGROUND_MARGIN, 00110 fm.height() + 2*TEXT_BACKGROUND_MARGIN), 00111 QBrush(darkGray) ); 00112 bufferPainter.drawText( x, y, 00113 adjustedString ); 00114 } 00115 } 00116 //paint the original image 00117 else if(previewMode == ORIGINAL_IMAGE) 00118 { 00119 bufferPainter.drawImage( QPoint(xOffset, yOffset), origImage ); 00120 00121 //"Original" label 00122 if(forceDrawLabel) 00123 { 00124 int x = xOffset + (origImage.width()-fm.width(originalString))/2; 00125 int y = yOffset + fm.ascent() + TEXT_INSET; 00126 00127 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 00128 y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 00129 fm.width(originalString) + 2*TEXT_BACKGROUND_MARGIN, 00130 fm.height() + 2*TEXT_BACKGROUND_MARGIN), 00131 QBrush(darkGray) ); 00132 bufferPainter.drawText( x, y, 00133 originalString ); 00134 } 00135 } 00136 //if using split view also draw line down center and original image on left 00137 else if(previewMode == SPLIT_VIEW || 00138 previewMode == INV_SPLIT_VIEW ) 00139 { 00140 //determine what left/right or top/bottom strings are 00141 QString label1, label2; 00142 if(previewMode == SPLIT_VIEW) 00143 { 00144 label1 = originalString; 00145 label2 = adjustedString; 00146 } 00147 else 00148 { 00149 label2 = originalString; 00150 label1 = adjustedString; 00151 } 00152 00153 //find split point in screen coordinates 00154 int halfWay = worldToDisplay( dragOffset ); 00155 00156 //paint the original image 00157 bufferPainter.drawImage( QPoint(xOffset, yOffset), origImage ); 00158 00159 //------- 00160 if(origImage.width() > origImage.height() ) 00161 { 00162 //paint the adjusted image 00163 if(previewMode == SPLIT_VIEW) 00164 { 00165 bufferPainter.drawImage( xOffset + halfWay, 00166 yOffset, 00167 adjustedImage, 00168 halfWay,0, 00169 origImage.width() - halfWay, 00170 origImage.height() ); 00171 } 00172 else 00173 { 00174 bufferPainter.drawImage( xOffset, 00175 yOffset, 00176 adjustedImage, 00177 0,0, 00178 halfWay, 00179 origImage.height() ); 00180 } 00181 00182 00183 //paint white line 00184 bufferPainter.drawLine( xOffset + halfWay, 00185 yOffset, 00186 xOffset + halfWay, 00187 yOffset + origImage.height() ); 00188 00189 //Left label 00190 int x = xOffset + (halfWay-fm.width(label1))/2; 00191 int y = yOffset + fm.ascent() + TEXT_INSET; 00192 00193 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 00194 y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 00195 fm.width(label1) + 2*TEXT_BACKGROUND_MARGIN, 00196 fm.height() + 2*TEXT_BACKGROUND_MARGIN), 00197 QBrush(darkGray) ); 00198 bufferPainter.drawText( x, y, 00199 label1 ); 00200 00201 //Right label 00202 x = xOffset + halfWay + (origImage.width() - halfWay - fm.width(label2))/2; 00203 00204 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 00205 y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 00206 fm.width(label2) + 2*TEXT_BACKGROUND_MARGIN, 00207 fm.height() + 2*TEXT_BACKGROUND_MARGIN), 00208 QBrush(darkGray) ); 00209 bufferPainter.drawText( x, y, 00210 label2 ); 00211 } 00212 //------- 00213 else 00214 { 00215 //paint the adjusted image 00216 if(previewMode == SPLIT_VIEW) 00217 { 00218 bufferPainter.drawImage( xOffset, 00219 yOffset + halfWay, 00220 adjustedImage, 00221 0,halfWay, 00222 origImage.width(), 00223 origImage.height()-halfWay ); 00224 } 00225 else 00226 { 00227 bufferPainter.drawImage( xOffset, 00228 yOffset, 00229 adjustedImage, 00230 0,0, 00231 origImage.width(), 00232 halfWay ); 00233 } 00234 00235 //paint white line 00236 bufferPainter.drawLine( xOffset, 00237 yOffset + halfWay, 00238 xOffset + origImage.width(), 00239 yOffset + halfWay ); 00240 00241 //Top label 00242 int x = xOffset + (origImage.width()-fm.width(label1))/2; 00243 int y = yOffset + fm.ascent() + TEXT_INSET; 00244 00245 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 00246 y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 00247 fm.width(label1) + 2*TEXT_BACKGROUND_MARGIN, 00248 fm.height() + 2*TEXT_BACKGROUND_MARGIN), 00249 QBrush(darkGray) ); 00250 bufferPainter.drawText( x, y, 00251 label1 ); 00252 00253 //Bottom label 00254 x = xOffset + (origImage.width()-fm.width(label2))/2; 00255 y = yOffset + halfWay + fm.height(); 00256 00257 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 00258 y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 00259 fm.width(label2) + 2*TEXT_BACKGROUND_MARGIN, 00260 fm.height() + 2*TEXT_BACKGROUND_MARGIN), 00261 QBrush(darkGray) ); 00262 bufferPainter.drawText( x, y, 00263 label2 ); 00264 } 00265 //------- 00266 } 00267 00268 //end painter 00269 bufferPainter.end(); 00270 00271 //blit buffer to screen 00272 bitBlt( this, 00273 e->rect().x(), e->rect().y(), 00274 &buffer, 00275 e->rect().x(), e->rect().y(), 00276 e->rect().width(), e->rect().height() ); 00277 } 00278 //============================================== 00279 void SplitViewInterface::setPreviewMode( PREVIEW_MODE mode, bool forceDrawLabel ) 00280 { 00281 //set mode and repaint 00282 previewMode = mode; 00283 this->forceDrawLabel = forceDrawLabel; 00284 repaint(false); 00285 } 00286 //============================================== 00287 bool SplitViewInterface::nearSplitPoint( QPoint p ) 00288 { 00289 //always false if not in split view mode 00290 if( previewMode != SPLIT_VIEW ) 00291 return false; 00292 00293 //compute painting offset and get important mouse coordinate 00294 int paintingOffset; 00295 int mousePos; 00296 if(origImage.width() > origImage.height()) 00297 { 00298 paintingOffset = (width() - origImage.width()) / 2; 00299 mousePos = p.x(); 00300 } 00301 else 00302 { 00303 paintingOffset = (height() - origImage.height()) / 2; 00304 mousePos = p.y(); 00305 } 00306 00307 //convert drag offset to display coordinates 00308 int displayCoor = worldToDisplay( dragOffset) + paintingOffset; 00309 00310 //check if within threshold of split point 00311 return ( mousePos > displayCoor - DRAG_THRESHOLD && 00312 mousePos < displayCoor + DRAG_THRESHOLD); 00313 } 00314 //============================================== 00315 void SplitViewInterface::mousePressEvent( QMouseEvent *e) 00316 { 00317 //if within threshold of split point enter drag split mode 00318 if( nearSplitPoint(e->pos()) ) 00319 mouseMode = DRAG_SPLIT; 00320 } 00321 //============================================== 00322 void SplitViewInterface::mouseMoveEvent( QMouseEvent *e) 00323 { 00324 //if not dragging split point update mosue cursor 00325 if(mouseMode == NO_EFFECT_ON_SPLIT) 00326 { 00327 if( !nearSplitPoint(e->pos()) && currentMouseShape == DRAG_SPLIT ) 00328 { 00329 currentMouseShape = NO_EFFECT_ON_SPLIT; 00330 setCursor( Qt::ArrowCursor ); 00331 } 00332 else if( nearSplitPoint(e->pos()) && currentMouseShape == NO_EFFECT_ON_SPLIT ) 00333 { 00334 currentMouseShape = DRAG_SPLIT; 00335 if( origImage.width() > origImage.height() ) 00336 { 00337 setCursor( getCursor(MOVE_HOR_CURSOR) ); 00338 } 00339 else 00340 { 00341 setCursor( getCursor(MOVE_VERT_CURSOR) ); 00342 } 00343 } 00344 00345 return; 00346 } 00347 00348 //compute painting offset, get important mouse 00349 //coordinate and clamp to valid range 00350 QFontMetrics fm( textFont ); 00351 int paintingOffset; 00352 int mousePos; 00353 if(origImage.width() > origImage.height()) 00354 { 00355 paintingOffset = (width() - origImage.width()) / 2; 00356 mousePos = e->pos().x(); 00357 mousePos = QMAX( mousePos, paintingOffset + 4*TEXT_BACKGROUND_MARGIN + fm.width(originalString) ); 00358 mousePos = QMIN( mousePos, paintingOffset + origImage.width() - 00359 fm.width(adjustedString) - 2*TEXT_BACKGROUND_MARGIN - 2*TEXT_INSET); 00360 } 00361 else 00362 { 00363 paintingOffset = (height() - origImage.height()) / 2; 00364 mousePos = e->pos().y(); 00365 mousePos = QMAX( mousePos, paintingOffset + 4*TEXT_BACKGROUND_MARGIN + fm.height() ); 00366 mousePos = QMIN( mousePos, paintingOffset + origImage.height() - 00367 fm.height() - 2*TEXT_BACKGROUND_MARGIN - 2*TEXT_INSET); 00368 } 00369 00370 //update location of split point and repaint 00371 dragOffset = displayToWorld(mousePos - paintingOffset); 00372 repaint(false); 00373 } 00374 //============================================== 00375 void SplitViewInterface::mouseReleaseEvent( QMouseEvent *e) 00376 { 00377 //disable dragging 00378 mouseMode = NO_EFFECT_ON_SPLIT; 00379 00380 //update mouse cursor if necessary 00381 if( !nearSplitPoint(e->pos()) && currentMouseShape == DRAG_SPLIT ) 00382 { 00383 currentMouseShape = NO_EFFECT_ON_SPLIT; 00384 setCursor( Qt::ArrowCursor ); 00385 } 00386 } 00387 //============================================== 00388 double SplitViewInterface::displayToWorld( int coordinate ) 00389 { 00390 if( origImage.width() > origImage.height() ) 00391 { return ((double) (coordinate+1))/origImage.width(); } 00392 else 00393 { return ((double) (coordinate+1))/origImage.height(); } 00394 } 00395 //============================================== 00396 int SplitViewInterface::worldToDisplay( double coordinate ) 00397 { 00398 if( origImage.width() > origImage.height() ) 00399 { return (int) (coordinate*(origImage.width() -1) ); } 00400 else 00401 { return (int) (coordinate*(origImage.height()-1) ); } 00402 } 00403 //============================================== 00404 QSize SplitViewInterface::minimumSizeHint() const 00405 { 00406 QFontMetrics fm( textFont ); 00407 int w = 5*TEXT_BACKGROUND_MARGIN + fm.width(originalString) + fm.width(adjustedString); 00408 int h = 2*TEXT_BACKGROUND_MARGIN + fm.height(); 00409 return QSize( w, h ); 00410 } 00411 //============================================== 00412 QImage& SplitViewInterface::getOrigImage() 00413 { return origImage; } 00414 //============================================== 00415 void SplitViewInterface::setImages( QImage origImage, 00416 QImage adjustedImage ) 00417 { 00418 this->origImage = origImage; 00419 this->adjustedImage = adjustedImage; 00420 repaint(false); 00421 } 00422 //============================================== 00423 void SplitViewInterface::setAdjustedImage( QImage adjustedImage ) 00424 { 00425 this->adjustedImage = adjustedImage; 00426 repaint(false); 00427 } 00428 //============================================== 00429

Generated on Sun Mar 4 19:42:57 2007 for AlbumShaper by doxygen 1.3.7