AlbumShaper  1.0a3
subalbumPreviewWidget.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 <qpixmap.h>
13 #include <qstring.h>
14 #include <qpainter.h>
15 #include <q3iconview.h>
16 #include <qfontmetrics.h>
17 #include <qapplication.h>
18 //Added by qt3to4:
19 #include <QDropEvent>
20 #include <Q3ValueList>
21 
22 //Projectwide includes
23 #include "subalbumPreviewWidget.h"
24 #include "subalbumsIconView.h"
25 #include "../backend/subalbum.h"
26 #include "../backend/photo.h"
27 #include "../backend/tools/imageTools.h"
28 #include "subalbumsWidget.h"
29 #include "layoutWidget.h"
30 #include "subalbumWidget.h"
31 #include "photoPreviewWidget.h"
32 #include "../backend/tools/guiTools.h"
33 
34 #include "../backend/album.h"
35 
36 //==============================================
38  : Q3IconViewItem(parent,
39  clipText( salbum->getName(), 2, parent->getTextWidth()),
40  *salbum->getRepresentativeImage(MEDIUM) )
41 {
42  mousedOver = false;
43  this->parent = parent;
44  subalbum = salbum;
45 
46  //initialize item rectangle
48 }
49 //==============================================
51 {
52  return subalbum;
53 }
54 //==============================================
55 void SubalbumPreviewWidget::paintFocus( QPainter*, const QColorGroup& ) { }
56 //==============================================
57 void SubalbumPreviewWidget::paint( QPainter *p )
58 {
59  paintItem( p, QColorGroup() );
60 }
61 //==============================================
62 void SubalbumPreviewWidget::paintItem( QPainter* p, const QColorGroup&)
63 {
64  QColor lightLightBlue( 152, 180, 226 );
65  QColor darkLightBlue(193, 210, 238);
66  QColor darkBlue(35, 75, 139);
67  QColor background = darkLightBlue;
68 
69  //resize old static buffer to new needed size, fill with widget background color
70  static QPixmap buffer;
71  QRect r = rect();
72  QSize newSize = r.size().expandedTo(buffer.size() );
73  buffer.resize(newSize);
74  buffer.fill( background );
75 
76  //construct painter for buffer
77  QPainter bufferPainter(&buffer);
78  bufferPainter.translate( -r.x(), -r.y() );
79 
80  //turn off clipping to make painting operations faster
81  bufferPainter.setClipping(false);
82 
83  //paint mouse over or actual selection color
84  bool paintRect = false;
85  QColor paintColor;
86  if(isSelected()) { paintColor = darkBlue; paintRect = true; }
87  else if(mousedOver) { paintColor = lightLightBlue; paintRect = true; }
88 
89  if(paintRect)
90  {
91  //first paint alpha blended edges
92 
93  //-------------------------
94  //top and bottom edges
95  QRect r2 = r;
96  r2.setLeft( r.left() + 4);
97  r2.setRight( r.right() - 4);
98  r2.setTop( r.top() );
99  r2.setBottom( r.bottom() );
100  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40 ) );
101 
102  r2.setLeft( r2.left() + 1);
103  r2.setRight( r2.right() - 1);
104  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67 ) );
105  //-------------------------
106  //inner top and bottom edges
107  r2.setLeft( r2.left() - 3);
108  r2.setRight( r2.right() + 3);
109  r2.setTop( r2.top() + 1 );
110  r2.setBottom( r2.bottom() - 1);
111  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40 ) );
112 
113  r2.setLeft( r2.left() + 1);
114  r2.setRight( r2.right() - 1);
115  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67 ) );
116  //-------------------------
117  //left and right inner edges
118  r2.setLeft( r2.left() - 2);
119  r2.setRight( r2.right() + 2);
120  r2.setTop( r2.top() + 1 );
121  r2.setBottom( r2.bottom() - 1);
122  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40) );
123 
124  r2.setTop( r2.top() + 1);
125  r2.setBottom( r2.bottom() - 1);
126  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67) );
127  //-------------------------
128  // middle region
129  r2.setLeft( r2.left() - 1 );
130  r2.setRight( r2.right() + 1 );
131  r2.setTop( r2.top() + 1);
132  r2.setBottom( r2.bottom() - 1);
133  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.40) );
134 
135  r2.setTop( r2.top() + 1);
136  r2.setBottom( r2.bottom() - 1);
137  bufferPainter.fillRect( r2, blendColors( paintColor, background, 0.67) );
138  //-------------------------
139  //second paint inner selection
140  r2 = r;
141  r2.setLeft( r.left() + 1);
142  r2.setRight( r.right() - 1);
143  r2.setTop( r.top() + 4 );
144  r2.setBottom( r.bottom() - 4);
145  bufferPainter.fillRect( r2, paintColor );
146 
147  r2.setLeft( r2.left() + 1);
148  r2.setRight( r2.right() - 1);
149  r2.setTop( r2.top() - 2 );
150  r2.setBottom( r2.bottom() + 2 );
151  bufferPainter.fillRect( r2, paintColor );
152 
153  r2.setLeft( r2.left() + 2);
154  r2.setRight( r2.right() - 2);
155  r2.setTop( r2.top() - 1 );
156  r2.setBottom( r2.bottom() + 1 );
157  bufferPainter.fillRect( r2, paintColor );
158  }
159 
160  //paint pixmap
161  bufferPainter.drawPixmap( x()+4 , y() + 4, *pixmap());
162 
163  //paint text
164  int align = Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere;
165  if(isSelected())
166  bufferPainter.setPen( Qt::white );
167  else
168  bufferPainter.setPen( Qt::black );
169  bufferPainter.drawText( x() + 4 + pixmapRect().width(),
170  y() + 4,
171  textRect().width(), textRect().height(),
172  align, text() );
173 
174  //draw buffer to screen
175  p->drawPixmap( x(), y(), buffer );
176 }
177 //==============================================
178 void SubalbumPreviewWidget::dropped( QDropEvent *e, const Q3ValueList<Q3IconDragItem> & )
179 {
180  //if source is not from the application then ignore
181  if(e->source() == NULL)
182  return;
183 
184  //if source of drop event is from this widget when user is attempting to
185  //rearrange subalbums, move currently selected item to
186  //approximately where the cursor is before rearranging items
187  if(e->source()->parentWidget() == parent)
188  {
189  if(e->pos().y() < (y() + (height()/2)))
190  {
191  parent->currentItem()->move(x(), y() - 1);
192  }
193  else
194  {
195  parent->currentItem()->move(x(), y() + (height()/2) + 1);
196  }
197  }
198  //else check to see if user dropped photo(s) on subalbum
199  else
200  {
201  //if the source of the items is the current subalbum icon view and
202  //this is a different subalbum then
203  //move photos from that subalbum to this one
204  if(
205  !isSelected() &&
206  (
207  e->source()->parentWidget() ==
208  ((LayoutWidget*)(parent->parentWidget()->parentWidget()))->getSubalbum()->getPhotos()
209  )
210  )
211  {
212  //iterate over all selected photos, inserting each
213  //into this subalbum, removing from old subalbum,
214  //and deleting old photo widgets
215  SubalbumWidget* oldSubalbumWidget = ((LayoutWidget*)(parent->parentWidget()->parentWidget()))->getSubalbum();
216  Subalbum* oldSubalbum = oldSubalbumWidget->getSubalbum();
217  Q3IconViewItem* current = oldSubalbumWidget->getPhotos()->firstItem();
218  while(current != NULL)
219  {
220  //found a selected photo
221  if(current->isSelected())
222  {
223  //get pointer to photo
224  Photo* photo = ((PhotoPreviewWidget*)current)->getPhoto();
225 
226  //remove photo from that subalbum
227  oldSubalbum->photoMoved(photo);
228 
229  //add photo to this subalbum
230  subalbum->addPhoto(photo);
231 
232  //delete photo widget and rearrange photos
233  Q3IconViewItem* temp = current;
234  current = current->nextItem();
235  delete temp;
236  }
237  else
238  {
239  current = current->nextItem();
240  }
241  } //end while
242 
243  //reannarge photos once all photos have been removed
244  oldSubalbumWidget->getPhotos()->arrangeItemsInGrid();
245  }
246  }
247 }
248 //==============================================
249 bool SubalbumPreviewWidget::acceptDrop( const QMimeSource *) const
250 {
251  return true;
252 }
253 //==============================================
255 {
256  if(pos().y() >= i->pos().y())
257  { return 1; }
258  else
259  { return -1; }
260 }
261 //==============================================
262 QPixmap* SubalbumPreviewWidget::createSubalbumPixmap( QString imageName )
263 {
264  //load image
265  QImage icon(imageName);
266 
267  //if null then bail immediately
268  if( icon.isNull() )
269  return NULL;
270 
271  //----------------------------------------------
272  //resize image based on text properties. Find ideal hight
273  QFontMetrics fm( qApp->font() );
274 
275  //ideal image height is two text lines, 1 pixel inbetween
276  int idealImageHeight = fm.leading() + 2*fm.height();
277 
278  //ideal image width assuming 4:3 aspect ratio
279  int idealImageWidth = (4 * idealImageHeight ) / 3;
280  //----------------------------------------------
281  //resize image to fit within bounding rectangle, pad and center as necessary
282  int actualImageWidth = 0;
283  int actualImageHeight = 0;
284  calcScaledImageDimensions( icon.width(), icon.height(),
285  idealImageWidth, idealImageHeight,
286  actualImageWidth, actualImageHeight );
287 
288  //if off by one pixel fudge it so icon perfectly cenetered
289  if(actualImageHeight == idealImageHeight - 1)
290  {
291  actualImageHeight = idealImageHeight;
292  }
293 
294  QImage scaledIcon= icon.smoothScale( actualImageWidth, actualImageHeight );
295  QImage* paddedScaledIcon = new QImage(idealImageWidth, idealImageHeight, scaledIcon.depth());
296  paddedScaledIcon->setAlphaBuffer(true);
297 
298  //make entire image transparent
299  int x, y;
300  for(x=0; x< idealImageWidth; x++)
301  {
302  for(y=0; y<idealImageHeight; y++)
303  {
304  paddedScaledIcon->setPixel(x,y, qRgba(255, 255, 255,0) );
305  }
306  }
307 
308  //paint image in center of padded region
309  int xDiff = idealImageWidth - actualImageWidth;
310  int yDiff = idealImageHeight - actualImageHeight;
311  int x2 = 0;
312  for(x= xDiff/2; x < (xDiff/2) + actualImageWidth; x++)
313  {
314  int y2 = 0;
315  for(y= yDiff/2; y < (yDiff/2) + actualImageHeight; y++)
316  {
317  paddedScaledIcon->setPixel(x, y, scaledIcon.pixel(x2, y2));
318  y2++;
319  }
320  x2++;
321  }
322 
323  //clip corners if image takes up full width
324  if(xDiff == 0)
325  {
326  paddedScaledIcon->setPixel(0, 0, qRgba(255, 0,0,0) );
327  paddedScaledIcon->setPixel(idealImageWidth-1, 0, qRgba(255, 0,0,0) );
328  paddedScaledIcon->setPixel(0, idealImageHeight-1, qRgba(255, 0,0,0) );
329  paddedScaledIcon->setPixel(idealImageWidth-1, idealImageHeight-1, qRgba(255, 0,0,0) );
330  }
331 
332  QPixmap* padddedScaledPix = new QPixmap( paddedScaledIcon->width(), paddedScaledIcon->height() );
333  padddedScaledPix->convertFromImage( *paddedScaledIcon );
334  delete paddedScaledIcon;
335  return padddedScaledPix;
336  //----------------------------------------------
337 }
338 //==============================================
339 void SubalbumPreviewWidget::calcRect( const QString & text_ )
340 {
341  //setup default dimensions
342  Q3IconViewItem::calcRect( text_ );
343 
344  //update using init method
346 }
347 //==============================================
349 {
350  //reset pixmap rect
351  QRect pr = pixmapRect();
352  int prWidth = pr.width();
353  int prHeight = pr.height();
354  pr.setTopLeft( QPoint(3,3) );
355  pr.setBottomRight( QPoint(pr.left()+prWidth, pr.top()+prHeight) );
356  setPixmapRect( pr );
357 
358  //reset text rect
359  int textWidth = parent->getTextWidth();
360  QRect tr = textRect();
361  tr.setTop( pixmapRect().top() );
362  tr.setBottom( pixmapRect().bottom() );
363  tr.setLeft( pixmapRect().right() + 2 );
364  tr.setRight( tr.left() + textWidth );
365  setTextRect( tr );
366 
367  //reset item rect using pixmap and text rect dimensions
368  int itemW = 3 + pixmapRect().width() + (tr.left() - pr.right()) + textRect().width() + 3;
369  int itemH = 3 + pixmapRect().height() + 3;
370  setItemRect( QRect( pixmapRect().left() - 3, pixmapRect().top() - 3, itemW, itemH ) );
371 }
372 //==============================================
373 void SubalbumPreviewWidget::setText ( const QString & text )
374 {
375  Q3IconViewItem::setText( clipText(text, 2, parent->getTextWidth()), false );
376 }
377 //==============================================
379 {
380  mousedOver = val;
381 }
382 //==============================================
383 QColor SubalbumPreviewWidget::blendColors( QColor a, QColor b, double alpha)
384 {
385  double alpha2 = 1-alpha;
386  return QColor( (int)(alpha*a.red() + alpha2*b.red()),
387  (int)(alpha*a.green() + alpha2*b.green()),
388  (int)(alpha*a.blue() + alpha2*b.blue()) );
389 }
390 //==============================================
bool addPhoto(QString fileName, bool replaceDescription=false, Photo *newPhoto=NULL)
Adds a new photo to the Subalbum and appends it to the end, returns TRUE if successful.
Definition: subalbum.cpp:198
A photo consists of a full size image, a smaller slide show image, a very small thumbnail image...
Definition: photo.h:44
Subalbum * getSubalbum()
Returns subalbum pointer.
Extension of iconview, used to list all subalbums in album. Supports drag-n-drop within iconview such...
#define MEDIUM
Definition: album.h:18
Displays photo thumbnail and description.
long b
Definition: jpegInternal.h:125
void paintFocus(QPainter *p, const QColorGroup &cg)
Displays list of subalbums and a particular subalbum layout.
Definition: layoutWidget.h:39
int compare(Q3IconViewItem *i) const
A subalbum contains photos.
Definition: subalbum.h:48
int width
Definition: blur.cpp:79
Subalbum * subalbum
Pointer to subalbum backend object.
QColor blendColors(QColor a, QColor b, double alpha)
QString clipText(QString string, int lines, int lineWidth)
clip text to fit within numer of lines and max width
Definition: guiTools.cpp:72
SubalbumsIconView * parent
parent icon view
void photoMoved(Photo *val)
Removes a specified photo without deleting the object.
Definition: subalbum.cpp:484
static QPixmap * createSubalbumPixmap(QString imageName)
float * buffer
Definition: blur.cpp:80
Subalbum * getSubalbum()
returns a pointer to the backend subalbum
bool acceptDrop(const QMimeSource *e) const
Displays subalbum layout.
void calcRect(const QString &text_=QString::null)
bool mousedOver
is the mouse over the widget
SubalbumPreviewWidget(SubalbumsIconView *parent, Subalbum *salbum)
Sets subalbum pointer.
void dropped(QDropEvent *e, const Q3ValueList< Q3IconDragItem > &lst)
void paintItem(QPainter *p, const QColorGroup &cg)
void calcScaledImageDimensions(int origWidth, int origHeight, int idealWidth, int idealHeight, int &width, int &height)
Computes scale of image dimensions while respecting aspect ratio, equivalent to a QImage::scaleMin wi...
Definition: imageTools.cpp:39
Q3IconView * getPhotos()
Returns pointer to icon view.
int height
Definition: blur.cpp:79
void setText(const QString &text)