AlbumShaper  1.0a3
Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes
SplitViewInterface Class Reference

A split view interface provides a means to show before and after versions of an image while adjustments are being made, in addition to dragging this split point left/right or up/down. This abtract class must be subclassed in order to properly handle resize events, in addition to actually setting the original and adjusted images. More...

#include <splitViewInterface.h>

Inheritance diagram for SplitViewInterface:
Inheritance graph
[legend]
Collaboration diagram for SplitViewInterface:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 SplitViewInterface (QWidget *parent=0, const char *name=0)
 Creates layout.
void setPreviewMode (PREVIEW_MODE mode, bool forceDrawLabel=false)
 Sets preview mode.
virtual QSize sizeHint () const =0
virtual QSize minimumSizeHint () const
void setImages (QImage origImage, QImage adjustedImage)
void setAdjustedImage (QImage adjustedImage)
 sets adjusted image and repaints
QImage & getOrigImage ()
 returns orig image object

Protected Member Functions

void paintEvent (QPaintEvent *e)
void mousePressEvent (QMouseEvent *e)
void mouseReleaseEvent (QMouseEvent *)
void mouseMoveEvent (QMouseEvent *e)
virtual void resizeEvent (QResizeEvent *)=0

Private Member Functions

double displayToWorld (int coordinate)
 convert display coordinates to world coordinates (double from 0.0 - 1.0)
int worldToDisplay (double coordinate)
 convert world coordinates to display coordinates (int from 0 to origImage width-1)
bool nearSplitPoint (QPoint p)
 determines if mouse is near split point

Private Attributes

PREVIEW_MODE previewMode
 Current display setting (adjusted or split screen)
bool forceDrawLabel
 Draw original/adjusted lables outside of split view mode?
QString originalString
 Original and adjusted strings.
QString adjustedString
QFont textFont
 Larger font used for drawing text.
double dragOffset
 x (or y) coordinate of split between drawn adjusted and original images
PREVIEW_MOUSE_MODE mouseMode
 current mouse move mode
PREVIEW_MOUSE_MODE currentMouseShape
 current mouse shape.
QImage origImage
 Scaled original image.
QImage adjustedImage
 Scaled adjusted image.

Detailed Description

A split view interface provides a means to show before and after versions of an image while adjustments are being made, in addition to dragging this split point left/right or up/down. This abtract class must be subclassed in order to properly handle resize events, in addition to actually setting the original and adjusted images.

Definition at line 43 of file splitViewInterface.h.


Constructor & Destructor Documentation

SplitViewInterface::SplitViewInterface ( QWidget parent = 0,
const char *  name = 0 
)

Creates layout.

Definition at line 27 of file splitViewInterface.cpp.

References adjustedString, currentMouseShape, dragOffset, forceDrawLabel, mouseMode, NO_EFFECT_ON_SPLIT, originalString, previewMode, SPLIT_VIEW, and textFont.

                                                                          : 
                                        QWidget (parent, name )
{                  
  //setup split point                                          
  dragOffset = 0.5;                                          
  mouseMode = NO_EFFECT_ON_SPLIT;  
  currentMouseShape = NO_EFFECT_ON_SPLIT;
  
  //set default mode to adjusted image
  previewMode = SPLIT_VIEW;
  
  //don't force draw labels by default. this is useful when
  //the user pressed the Ctrl button or other key to toggle between opposite views
  //and drop down menu for choosing display type disagrees with actuall image being shown.
  forceDrawLabel = false;
  
  //setup strings and fonts
  originalString = QString( tr("Original") );
  adjustedString = QString( tr("Adjusted") );          
  
  textFont = this->font();
  textFont.setPointSize( textFont.pointSize() + 7 );  
  
  //watch mouse movements in order to drag selection
  //watch mouse movements in order to move split point between adjusted and original image
  setMouseTracking(true);
  
  //accept focus when clicked on
  setFocusPolicy( QWidget::ClickFocus );
}

Member Function Documentation

double SplitViewInterface::displayToWorld ( int  coordinate) [private]

convert display coordinates to world coordinates (double from 0.0 - 1.0)

Definition at line 388 of file splitViewInterface.cpp.

References origImage.

Referenced by mouseMoveEvent().

{
  if( origImage.width() > origImage.height() )
  { return ((double) (coordinate+1))/origImage.width(); }
  else
  { return ((double) (coordinate+1))/origImage.height(); }
}
QImage & SplitViewInterface::getOrigImage ( )

returns orig image object

Definition at line 412 of file splitViewInterface.cpp.

References origImage.

Referenced by GrainEditor::generateAdjustedPreviewImage(), and HistogramEditor::generateAdjustedPreviewImage().

{ return origImage; }
QSize SplitViewInterface::minimumSizeHint ( ) const [virtual]

Reimplemented in ScaledPreviewInterface.

Definition at line 404 of file splitViewInterface.cpp.

References adjustedString, originalString, TEXT_BACKGROUND_MARGIN, and textFont.

{
  QFontMetrics fm( textFont );
  int w = 5*TEXT_BACKGROUND_MARGIN + fm.width(originalString) + fm.width(adjustedString);
  int h = 2*TEXT_BACKGROUND_MARGIN + fm.height(); 
  return QSize( w, h );
}
void SplitViewInterface::mouseMoveEvent ( QMouseEvent *  e) [protected]

Definition at line 322 of file splitViewInterface.cpp.

References adjustedString, currentMouseShape, displayToWorld(), DRAG_SPLIT, dragOffset, getCursor(), height, mouseMode, MOVE_HOR_CURSOR, MOVE_VERT_CURSOR, nearSplitPoint(), NO_EFFECT_ON_SPLIT, origImage, originalString, TEXT_BACKGROUND_MARGIN, TEXT_INSET, textFont, and width.

{
  //if not dragging split point update mosue cursor
  if(mouseMode == NO_EFFECT_ON_SPLIT)
  {
    if( !nearSplitPoint(e->pos()) && currentMouseShape == DRAG_SPLIT )
    { 
      currentMouseShape = NO_EFFECT_ON_SPLIT;
      setCursor( Qt::ArrowCursor ); 
    }
    else if( nearSplitPoint(e->pos()) && currentMouseShape == NO_EFFECT_ON_SPLIT )
    {
      currentMouseShape = DRAG_SPLIT;
      if( origImage.width() > origImage.height() )
      {
        setCursor( getCursor(MOVE_HOR_CURSOR) );
      }
      else
      {
        setCursor( getCursor(MOVE_VERT_CURSOR) );
      }
    }

    return;
  }
  
  //compute painting offset, get important mouse
  //coordinate and clamp to valid range
  QFontMetrics fm( textFont );
  int paintingOffset;
  int mousePos;
  if(origImage.width() > origImage.height())
  {
    paintingOffset = (width() - origImage.width()) / 2;
    mousePos = e->pos().x();
    mousePos = QMAX( mousePos, paintingOffset + 4*TEXT_BACKGROUND_MARGIN + fm.width(originalString) );
    mousePos = QMIN( mousePos, paintingOffset + origImage.width() - 
                     fm.width(adjustedString) - 2*TEXT_BACKGROUND_MARGIN - 2*TEXT_INSET);
  }
  else
  {
    paintingOffset = (height() - origImage.height()) / 2;
    mousePos = e->pos().y();
    mousePos = QMAX( mousePos, paintingOffset + 4*TEXT_BACKGROUND_MARGIN + fm.height() );
    mousePos = QMIN( mousePos, paintingOffset + origImage.height() - 
                     fm.height() - 2*TEXT_BACKGROUND_MARGIN - 2*TEXT_INSET);
  }
  
  //update location of split point and repaint
  dragOffset = displayToWorld(mousePos - paintingOffset);   
  repaint(false);  
}
void SplitViewInterface::mousePressEvent ( QMouseEvent *  e) [protected]

Definition at line 315 of file splitViewInterface.cpp.

References DRAG_SPLIT, mouseMode, and nearSplitPoint().

{ 
  //if within threshold of split point enter drag split mode
  if( nearSplitPoint(e->pos()) )  
    mouseMode = DRAG_SPLIT;
}
void SplitViewInterface::mouseReleaseEvent ( QMouseEvent *  e) [protected]

Definition at line 375 of file splitViewInterface.cpp.

References currentMouseShape, DRAG_SPLIT, mouseMode, nearSplitPoint(), and NO_EFFECT_ON_SPLIT.

{
  //disable dragging
  mouseMode = NO_EFFECT_ON_SPLIT;  

  //update mouse cursor if necessary
  if( !nearSplitPoint(e->pos()) && currentMouseShape == DRAG_SPLIT )
  { 
    currentMouseShape = NO_EFFECT_ON_SPLIT;
    setCursor( Qt::ArrowCursor ); 
  }  
}
bool SplitViewInterface::nearSplitPoint ( QPoint  p) [private]

determines if mouse is near split point

Definition at line 287 of file splitViewInterface.cpp.

References DRAG_THRESHOLD, dragOffset, height, origImage, previewMode, SPLIT_VIEW, width, and worldToDisplay().

Referenced by mouseMoveEvent(), mousePressEvent(), and mouseReleaseEvent().

{
  //always false if not in split view mode
  if( previewMode != SPLIT_VIEW )
    return false;
  
  //compute painting offset and get important mouse coordinate
  int paintingOffset;
  int mousePos;
  if(origImage.width() > origImage.height())
  {
    paintingOffset = (width() - origImage.width()) / 2;
    mousePos = p.x();
  }
  else
  {
    paintingOffset = (height() - origImage.height()) / 2;
    mousePos = p.y();
  }
  
  //convert drag offset to display coordinates
  int displayCoor = worldToDisplay( dragOffset) + paintingOffset;
  
  //check if within threshold of split point
  return ( mousePos > displayCoor - DRAG_THRESHOLD &&
           mousePos < displayCoor + DRAG_THRESHOLD);
}
void SplitViewInterface::paintEvent ( QPaintEvent *  e) [protected]

Definition at line 58 of file splitViewInterface.cpp.

References ADJUSTED_IMAGE, adjustedImage, adjustedString, buffer, dragOffset, forceDrawLabel, height, INV_SPLIT_VIEW, origImage, ORIGINAL_IMAGE, originalString, previewMode, SPLIT_VIEW, TEXT_BACKGROUND_MARGIN, TEXT_INSET, textFont, width, and worldToDisplay().

{ 
  //if orig image not setup yet then return immediately
  if(origImage.isNull()) { return; }

  //if viewing adjusted or split view and adjusted image is null bail  
  if( 
      (previewMode == ADJUSTED_IMAGE || previewMode == SPLIT_VIEW ) &&
      adjustedImage.isNull() 
    )
  { return; }
  
  //create buffer to draw in
  QPixmap buffer( size() );
  
  //create a painter pointing to the buffer
  QPainter bufferPainter( &buffer );
  
  //turn off clipping to make painting operations faster
  bufferPainter.setClipping(false);

  //initialize buffer with background brush
  bufferPainter.fillRect( buffer.rect(), backgroundBrush() );

  //setup pen color
  QPen pen;
  pen.setStyle( Qt::SolidLine );
  pen.setColor( white );
  pen.setWidth( 2 );
  bufferPainter.setPen( pen);  

  int xOffset = (width() - origImage.width()) / 2;
  int yOffset = (height() - origImage.height()) / 2;

  //setup font metrics
  bufferPainter.setFont( textFont );
  QFontMetrics fm( textFont );

  //paint the adjusted image
  if(previewMode == ADJUSTED_IMAGE)
  {
    bufferPainter.drawImage( QPoint(xOffset, yOffset), adjustedImage );

    //"Adjusted" label
    if(forceDrawLabel)
    {
      int x = xOffset + (origImage.width()-fm.width(adjustedString))/2;
      int y = yOffset + fm.ascent() + TEXT_INSET;
    
      bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 
                                    y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 
                                    fm.width(adjustedString) + 2*TEXT_BACKGROUND_MARGIN, 
                                    fm.height() + 2*TEXT_BACKGROUND_MARGIN),
                              QBrush(darkGray) );    
      bufferPainter.drawText( x, y,
                              adjustedString );    
    }
  }
  //paint the original image
  else if(previewMode == ORIGINAL_IMAGE)
  {
    bufferPainter.drawImage( QPoint(xOffset, yOffset), origImage );

    //"Original" label
    if(forceDrawLabel)
    {
      int x = xOffset + (origImage.width()-fm.width(originalString))/2;
      int y = yOffset + fm.ascent() + TEXT_INSET;
    
      bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 
                                    y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 
                                    fm.width(originalString) + 2*TEXT_BACKGROUND_MARGIN, 
                                    fm.height() + 2*TEXT_BACKGROUND_MARGIN),
                              QBrush(darkGray) );    
      bufferPainter.drawText( x, y,
                              originalString );    
    }
  }
  //if using split view also draw line down center and original image on left
  else if(previewMode == SPLIT_VIEW ||
          previewMode == INV_SPLIT_VIEW )
  {
    //determine what left/right or top/bottom strings are
    QString label1, label2;
    if(previewMode == SPLIT_VIEW)
    {
      label1 = originalString;
      label2 = adjustedString;
    }
    else
    {
      label2 = originalString;
      label1 = adjustedString;
    }
    
    //find split point in screen coordinates
    int halfWay = worldToDisplay( dragOffset );
    
    //paint the original image
    bufferPainter.drawImage( QPoint(xOffset, yOffset), origImage );

    //-------
    if(origImage.width() > origImage.height() )
    {    
      //paint the adjusted image
      if(previewMode == SPLIT_VIEW)
      {
        bufferPainter.drawImage( xOffset + halfWay, 
                                 yOffset,
                                 adjustedImage,
                                 halfWay,0,
                                 origImage.width() - halfWay,
                                 origImage.height() );  
      }
      else
      {
        bufferPainter.drawImage( xOffset, 
                                 yOffset,
                                 adjustedImage,
                                 0,0,
                                 halfWay,
                                 origImage.height() );  
      }

      
      //paint white line
      bufferPainter.drawLine( xOffset + halfWay,
                              yOffset,
                              xOffset + halfWay,
                              yOffset + origImage.height() );

      //Left label
      int x = xOffset + (halfWay-fm.width(label1))/2;
      int y = yOffset + fm.ascent() + TEXT_INSET;
      
      bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 
                                    y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 
                                    fm.width(label1) + 2*TEXT_BACKGROUND_MARGIN, 
                                    fm.height() + 2*TEXT_BACKGROUND_MARGIN),
                              QBrush(darkGray) );    
      bufferPainter.drawText( x, y,
                              label1 );    

      //Right label
      x = xOffset + halfWay + (origImage.width() - halfWay - fm.width(label2))/2;
      
      bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 
                                    y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 
                                    fm.width(label2) + 2*TEXT_BACKGROUND_MARGIN, 
                                    fm.height() + 2*TEXT_BACKGROUND_MARGIN),
                              QBrush(darkGray) );    
      bufferPainter.drawText( x, y,
                              label2 );
    }
    //-------
    else
    {
      //paint the adjusted image
      if(previewMode == SPLIT_VIEW)
      {
        bufferPainter.drawImage( xOffset, 
                                 yOffset + halfWay,
                                 adjustedImage,
                                 0,halfWay,
                                 origImage.width(),
                                 origImage.height()-halfWay );  
      }
      else
      {
        bufferPainter.drawImage( xOffset, 
                                 yOffset,
                                 adjustedImage,
                                 0,0,
                                 origImage.width(),
                                 halfWay );  
      }
      
      //paint white line
      bufferPainter.drawLine( xOffset,
                              yOffset + halfWay,
                              xOffset + origImage.width(),
                              yOffset + halfWay );

      //Top label
      int x = xOffset + (origImage.width()-fm.width(label1))/2;
      int y = yOffset + fm.ascent() + TEXT_INSET;
      
      bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 
                                    y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 
                                    fm.width(label1) + 2*TEXT_BACKGROUND_MARGIN, 
                                    fm.height() + 2*TEXT_BACKGROUND_MARGIN),
                              QBrush(darkGray) );    
      bufferPainter.drawText( x, y,
                              label1 );    
      
      //Bottom label
      x = xOffset + (origImage.width()-fm.width(label2))/2;
      y = yOffset + halfWay + fm.height();
      
      bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN, 
                                    y - TEXT_BACKGROUND_MARGIN - fm.ascent(), 
                                    fm.width(label2) + 2*TEXT_BACKGROUND_MARGIN, 
                                    fm.height() + 2*TEXT_BACKGROUND_MARGIN),
                              QBrush(darkGray) );    
      bufferPainter.drawText( x, y,
                              label2 );
    }
    //-------    
  }

  //end painter  
  bufferPainter.end();
  
  //blit buffer to screen
  bitBlt( this,
          e->rect().x(), e->rect().y(),
          &buffer, 
          e->rect().x(), e->rect().y(),
          e->rect().width(), e->rect().height() );
}
virtual void SplitViewInterface::resizeEvent ( QResizeEvent *  ) [protected, pure virtual]
void SplitViewInterface::setAdjustedImage ( QImage  adjustedImage)

sets adjusted image and repaints

Definition at line 423 of file splitViewInterface.cpp.

References adjustedImage.

Referenced by GrainEditor::generateAdjustedPreviewImage(), and HistogramEditor::generateAdjustedPreviewImage().

{
  this->adjustedImage = adjustedImage;
  repaint(false);
}
void SplitViewInterface::setImages ( QImage  origImage,
QImage  adjustedImage 
)
void SplitViewInterface::setPreviewMode ( PREVIEW_MODE  mode,
bool  forceDrawLabel = false 
)
virtual QSize SplitViewInterface::sizeHint ( ) const [pure virtual]
int SplitViewInterface::worldToDisplay ( double  coordinate) [private]

convert world coordinates to display coordinates (int from 0 to origImage width-1)

Definition at line 396 of file splitViewInterface.cpp.

References origImage.

Referenced by nearSplitPoint(), and paintEvent().

{
  if( origImage.width() > origImage.height() )
  { return (int) (coordinate*(origImage.width() -1) ); }
  else
  { return (int) (coordinate*(origImage.height()-1) ); }
}

Member Data Documentation

Scaled adjusted image.

Definition at line 112 of file splitViewInterface.h.

Referenced by paintEvent(), setAdjustedImage(), and setImages().

current mouse shape.

by caching this value we avoid resetting the mouse cursor every time it moves etc.

Definition at line 106 of file splitViewInterface.h.

Referenced by mouseMoveEvent(), mouseReleaseEvent(), and SplitViewInterface().

x (or y) coordinate of split between drawn adjusted and original images

Definition at line 99 of file splitViewInterface.h.

Referenced by mouseMoveEvent(), nearSplitPoint(), paintEvent(), and SplitViewInterface().

Draw original/adjusted lables outside of split view mode?

Definition at line 89 of file splitViewInterface.h.

Referenced by paintEvent(), setPreviewMode(), and SplitViewInterface().

current mouse move mode

Definition at line 102 of file splitViewInterface.h.

Referenced by mouseMoveEvent(), mousePressEvent(), mouseReleaseEvent(), and SplitViewInterface().

Scaled original image.

Definition at line 109 of file splitViewInterface.h.

Referenced by displayToWorld(), getOrigImage(), mouseMoveEvent(), nearSplitPoint(), paintEvent(), setImages(), and worldToDisplay().

Original and adjusted strings.

Definition at line 92 of file splitViewInterface.h.

Referenced by minimumSizeHint(), mouseMoveEvent(), paintEvent(), and SplitViewInterface().

Current display setting (adjusted or split screen)

Definition at line 86 of file splitViewInterface.h.

Referenced by nearSplitPoint(), paintEvent(), setPreviewMode(), and SplitViewInterface().

Larger font used for drawing text.

Definition at line 96 of file splitViewInterface.h.

Referenced by minimumSizeHint(), mouseMoveEvent(), paintEvent(), and SplitViewInterface().


The documentation for this class was generated from the following files: