AlbumShaper 1.0a3
splitViewInterface.cpp
Go to the documentation of this file.
1//==============================================
2// copyright : (C) 2003-2005 by Will Stokes
3//==============================================
4// This program is free software; you can redistribute it
5// and/or modify it under the terms of the GNU General
6// Public License as published by the Free Software
7// Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//==============================================
10
11//Systemwide includes
12#include <qpainter.h>
13#include <qcursor.h>
14//Added by qt3to4:
15#include <QPixmap>
16#include <QMouseEvent>
17#include <QPaintEvent>
18
19//Projectwide includes
20#include "splitViewInterface.h"
21#include "../cursors.h"
23
24#define TEXT_BACKGROUND_MARGIN 2
25#define TEXT_INSET 4
26
27//a mouse press within DRAG_THRESHOLD will move split point
28#define DRAG_THRESHOLD 8
29
30//==============================================
31SplitViewInterface::SplitViewInterface( QWidget *parent, const char* name ) :
32 QWidget (parent, name )
33{
34 //setup split point
35 dragOffset = 0.5;
38
39 //set default mode to adjusted image
41
42 //don't force draw labels by default. this is useful when
43 //the user pressed the Ctrl button or other key to toggle between opposite views
44 //and drop down menu for choosing display type disagrees with actuall image being shown.
45 forceDrawLabel = false;
46
47 //setup strings and fonts
48 originalString = QString( tr("Original") );
49 adjustedString = QString( tr("Adjusted") );
50
51 textFont = this->font();
52 textFont.setPointSize( textFont.pointSize() + 7 );
53
54 //watch mouse movements in order to drag selection
55 //watch mouse movements in order to move split point between adjusted and original image
56 setMouseTracking(true);
57
58 //accept focus when clicked on
59 setFocusPolicy( Qt::ClickFocus );
60}
61//==============================================
63{
64 //if orig image not setup yet then return immediately
65 if(origImage.isNull()) { return; }
66
67 //if viewing adjusted or split view and adjusted image is null bail
68 if(
70 adjustedImage.isNull()
71 )
72 { return; }
73
74 //create buffer to draw in
75 QPixmap buffer( size() );
76
77 //create a painter pointing to the buffer
78 QPainter bufferPainter( &buffer );
79
80 //turn off clipping to make painting operations faster
81 bufferPainter.setClipping(false);
82
83 //initialize buffer with background brush
84 bufferPainter.fillRect( buffer.rect(), backgroundBrush() );
85
86 //setup pen color
87 QPen pen;
88 pen.setStyle( Qt::SolidLine );
89 pen.setColor( Qt::white );
90 pen.setWidth( 2 );
91 bufferPainter.setPen( pen);
92
93 int xOffset = (width() - origImage.width()) / 2;
94 int yOffset = (height() - origImage.height()) / 2;
95
96 //setup font metrics
97 bufferPainter.setFont( textFont );
98 QFontMetrics fm( textFont );
99
100 //paint the adjusted image
102 {
103 bufferPainter.drawImage( QPoint(xOffset, yOffset), adjustedImage );
104
105 //"Adjusted" label
107 {
108 int x = xOffset + (origImage.width()-fm.width(adjustedString))/2;
109 int y = yOffset + fm.ascent() + TEXT_INSET;
110
111 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN,
112 y - TEXT_BACKGROUND_MARGIN - fm.ascent(),
114 fm.height() + 2*TEXT_BACKGROUND_MARGIN),
115 QBrush(Qt::darkGray) );
116 bufferPainter.drawText( x, y,
118 }
119 }
120 //paint the original image
121 else if(previewMode == ORIGINAL_IMAGE)
122 {
123 bufferPainter.drawImage( QPoint(xOffset, yOffset), origImage );
124
125 //"Original" label
127 {
128 int x = xOffset + (origImage.width()-fm.width(originalString))/2;
129 int y = yOffset + fm.ascent() + TEXT_INSET;
130
131 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN,
132 y - TEXT_BACKGROUND_MARGIN - fm.ascent(),
134 fm.height() + 2*TEXT_BACKGROUND_MARGIN),
135 QBrush(Qt::darkGray) );
136 bufferPainter.drawText( x, y,
138 }
139 }
140 //if using split view also draw line down center and original image on left
141 else if(previewMode == SPLIT_VIEW ||
143 {
144 //determine what left/right or top/bottom strings are
145 QString label1, label2;
147 {
148 label1 = originalString;
149 label2 = adjustedString;
150 }
151 else
152 {
153 label2 = originalString;
154 label1 = adjustedString;
155 }
156
157 //find split point in screen coordinates
158 int halfWay = worldToDisplay( dragOffset );
159
160 //paint the original image
161 bufferPainter.drawImage( QPoint(xOffset, yOffset), origImage );
162
163 //-------
164 if(origImage.width() > origImage.height() )
165 {
166 //paint the adjusted image
168 {
169 bufferPainter.drawImage( xOffset + halfWay,
170 yOffset,
172 halfWay,0,
173 origImage.width() - halfWay,
174 origImage.height() );
175 }
176 else
177 {
178 bufferPainter.drawImage( xOffset,
179 yOffset,
181 0,0,
182 halfWay,
183 origImage.height() );
184 }
185
186
187 //paint white line
188 bufferPainter.drawLine( xOffset + halfWay,
189 yOffset,
190 xOffset + halfWay,
191 yOffset + origImage.height() );
192
193 //Left label
194 int x = xOffset + (halfWay-fm.width(label1))/2;
195 int y = yOffset + fm.ascent() + TEXT_INSET;
196
197 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN,
198 y - TEXT_BACKGROUND_MARGIN - fm.ascent(),
199 fm.width(label1) + 2*TEXT_BACKGROUND_MARGIN,
200 fm.height() + 2*TEXT_BACKGROUND_MARGIN),
201 QBrush(Qt::darkGray) );
202 bufferPainter.drawText( x, y,
203 label1 );
204
205 //Right label
206 x = xOffset + halfWay + (origImage.width() - halfWay - fm.width(label2))/2;
207
208 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN,
209 y - TEXT_BACKGROUND_MARGIN - fm.ascent(),
210 fm.width(label2) + 2*TEXT_BACKGROUND_MARGIN,
211 fm.height() + 2*TEXT_BACKGROUND_MARGIN),
212 QBrush(Qt::darkGray) );
213 bufferPainter.drawText( x, y,
214 label2 );
215 }
216 //-------
217 else
218 {
219 //paint the adjusted image
221 {
222 bufferPainter.drawImage( xOffset,
223 yOffset + halfWay,
225 0,halfWay,
226 origImage.width(),
227 origImage.height()-halfWay );
228 }
229 else
230 {
231 bufferPainter.drawImage( xOffset,
232 yOffset,
234 0,0,
235 origImage.width(),
236 halfWay );
237 }
238
239 //paint white line
240 bufferPainter.drawLine( xOffset,
241 yOffset + halfWay,
242 xOffset + origImage.width(),
243 yOffset + halfWay );
244
245 //Top label
246 int x = xOffset + (origImage.width()-fm.width(label1))/2;
247 int y = yOffset + fm.ascent() + TEXT_INSET;
248
249 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN,
250 y - TEXT_BACKGROUND_MARGIN - fm.ascent(),
251 fm.width(label1) + 2*TEXT_BACKGROUND_MARGIN,
252 fm.height() + 2*TEXT_BACKGROUND_MARGIN),
253 QBrush(Qt::darkGray) );
254 bufferPainter.drawText( x, y,
255 label1 );
256
257 //Bottom label
258 x = xOffset + (origImage.width()-fm.width(label2))/2;
259 y = yOffset + halfWay + fm.height();
260
261 bufferPainter.fillRect( QRect(x - TEXT_BACKGROUND_MARGIN,
262 y - TEXT_BACKGROUND_MARGIN - fm.ascent(),
263 fm.width(label2) + 2*TEXT_BACKGROUND_MARGIN,
264 fm.height() + 2*TEXT_BACKGROUND_MARGIN),
265 QBrush(Qt::darkGray) );
266 bufferPainter.drawText( x, y,
267 label2 );
268 }
269 //-------
270 }
271
272 //end painter
273 bufferPainter.end();
274
275 //blit buffer to screen
276 bitBlt( this,
277 e->rect().x(), e->rect().y(),
278 &buffer,
279 e->rect().x(), e->rect().y(),
280 e->rect().width(), e->rect().height() );
281}
282//==============================================
283void SplitViewInterface::setPreviewMode( PREVIEW_MODE mode, bool forceDrawLabel )
284{
285 //set mode and repaint
286 previewMode = mode;
287 this->forceDrawLabel = forceDrawLabel;
288 repaint(false);
289}
290//==============================================
292{
293 //always false if not in split view mode
294 if( previewMode != SPLIT_VIEW )
295 return false;
296
297 //compute painting offset and get important mouse coordinate
298 int paintingOffset;
299 int mousePos;
300 if(origImage.width() > origImage.height())
301 {
302 paintingOffset = (width() - origImage.width()) / 2;
303 mousePos = p.x();
304 }
305 else
306 {
307 paintingOffset = (height() - origImage.height()) / 2;
308 mousePos = p.y();
309 }
310
311 //convert drag offset to display coordinates
312 int displayCoor = worldToDisplay( dragOffset) + paintingOffset;
313
314 //check if within threshold of split point
315 return ( mousePos > displayCoor - DRAG_THRESHOLD &&
316 mousePos < displayCoor + DRAG_THRESHOLD);
317}
318//==============================================
320{
321 //if within threshold of split point enter drag split mode
322 if( nearSplitPoint(e->pos()) )
324}
325//==============================================
327{
328 //if not dragging split point update mosue cursor
330 {
331 if( !nearSplitPoint(e->pos()) && currentMouseShape == DRAG_SPLIT )
332 {
334 setCursor( Qt::ArrowCursor );
335 }
336 else if( nearSplitPoint(e->pos()) && currentMouseShape == NO_EFFECT_ON_SPLIT )
337 {
339 if( origImage.width() > origImage.height() )
340 {
341 setCursor( getCursor(MOVE_HOR_CURSOR) );
342 }
343 else
344 {
345 setCursor( getCursor(MOVE_VERT_CURSOR) );
346 }
347 }
348
349 return;
350 }
351
352 //compute painting offset, get important mouse
353 //coordinate and clamp to valid range
354 QFontMetrics fm( textFont );
355 int paintingOffset;
356 int mousePos;
357 if(origImage.width() > origImage.height())
358 {
359 paintingOffset = (width() - origImage.width()) / 2;
360 mousePos = e->pos().x();
361 mousePos = QMAX( mousePos, paintingOffset + 4*TEXT_BACKGROUND_MARGIN + fm.width(originalString) );
362 mousePos = QMIN( mousePos, paintingOffset + origImage.width() -
364 }
365 else
366 {
367 paintingOffset = (height() - origImage.height()) / 2;
368 mousePos = e->pos().y();
369 mousePos = QMAX( mousePos, paintingOffset + 4*TEXT_BACKGROUND_MARGIN + fm.height() );
370 mousePos = QMIN( mousePos, paintingOffset + origImage.height() -
371 fm.height() - 2*TEXT_BACKGROUND_MARGIN - 2*TEXT_INSET);
372 }
373
374 //update location of split point and repaint
375 dragOffset = displayToWorld(mousePos - paintingOffset);
376 repaint(false);
377}
378//==============================================
380{
381 //disable dragging
383
384 //update mouse cursor if necessary
385 if( !nearSplitPoint(e->pos()) && currentMouseShape == DRAG_SPLIT )
386 {
388 setCursor( Qt::ArrowCursor );
389 }
390}
391//==============================================
393{
394 if( origImage.width() > origImage.height() )
395 { return ((double) (coordinate+1))/origImage.width(); }
396 else
397 { return ((double) (coordinate+1))/origImage.height(); }
398}
399//==============================================
401{
402 if( origImage.width() > origImage.height() )
403 { return (int) (coordinate*(origImage.width() -1) ); }
404 else
405 { return (int) (coordinate*(origImage.height()-1) ); }
406}
407//==============================================
409{
410 QFontMetrics fm( textFont );
411 int w = 5*TEXT_BACKGROUND_MARGIN + fm.width(originalString) + fm.width(adjustedString);
412 int h = 2*TEXT_BACKGROUND_MARGIN + fm.height();
413 return QSize( w, h );
414}
415//==============================================
418//==============================================
419void SplitViewInterface::setImages( QImage origImage,
420 QImage adjustedImage )
421{
422 this->origImage = origImage;
423 this->adjustedImage = adjustedImage;
424 repaint(false);
425}
426//==============================================
427void SplitViewInterface::setAdjustedImage( QImage adjustedImage )
428{
429 this->adjustedImage = adjustedImage;
430 repaint(false);
431}
432//==============================================
433
int width
Definition blur.cpp:79
int height
Definition blur.cpp:79
float * buffer
Definition blur.cpp:80
PREVIEW_MOUSE_MODE mouseMode
current mouse move mode
int worldToDisplay(double coordinate)
convert world coordinates to display coordinates (int from 0 to origImage width-1)
virtual QSize minimumSizeHint() const
bool nearSplitPoint(QPoint p)
determines if mouse is near split point
QString originalString
Original and adjusted strings.
double displayToWorld(int coordinate)
convert display coordinates to world coordinates (double from 0.0 - 1.0)
void mousePressEvent(QMouseEvent *e)
bool forceDrawLabel
Draw original/adjusted lables outside of split view mode?
QImage adjustedImage
Scaled adjusted image.
void paintEvent(QPaintEvent *e)
double dragOffset
x (or y) coordinate of split between drawn adjusted and original images
QFont textFont
Larger font used for drawing text.
QImage & getOrigImage()
returns orig image object
void setImages(QImage origImage, QImage adjustedImage)
QImage origImage
Scaled original image.
PREVIEW_MODE previewMode
Current display setting (adjusted or split screen)
SplitViewInterface(QWidget *parent=0, const char *name=0)
Creates layout.
void mouseReleaseEvent(QMouseEvent *)
void mouseMoveEvent(QMouseEvent *e)
void setAdjustedImage(QImage adjustedImage)
sets adjusted image and repaints
PREVIEW_MOUSE_MODE currentMouseShape
current mouse shape.
void setPreviewMode(PREVIEW_MODE mode, bool forceDrawLabel=false)
Sets preview mode.
const QCursor & getCursor(CUSTOM_CURSOR_TYPE type)
Definition cursors.cpp:52
@ MOVE_VERT_CURSOR
Definition cursors.h:21
@ MOVE_HOR_CURSOR
Definition cursors.h:20
#define DRAG_THRESHOLD
#define TEXT_INSET
#define TEXT_BACKGROUND_MARGIN
@ DRAG_SPLIT
@ NO_EFFECT_ON_SPLIT
PREVIEW_MODE
current preview mode
@ SPLIT_VIEW
@ ORIGINAL_IMAGE
@ ADJUSTED_IMAGE
@ INV_SPLIT_VIEW