selectionPlacementInterface.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 <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 //==============================================

Generated on Thu Jan 3 10:52:46 2008 for AlbumShaper by  doxygen 1.5.4