lib Library API Documentation

koIconChooser.cc

00001 /* This file is part of the KDE project
00002   Copyright (c) 1999 Carsten Pfeiffer (pfeiffer@kde.org)
00003   Copyright (c) 2002 Igor Jansen (rm@kde.org)
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #include <kdebug.h>
00022 #include <koIconChooser.h>
00023 #include <kglobal.h>
00024 
00025 #include <qpainter.h>
00026 #include <qcursor.h>
00027 #include <qapplication.h>
00028 #include <qhbox.h>
00029 #include <qlayout.h>
00030 #include <kdebug.h>
00031 
00032 KoPixmapWidget::KoPixmapWidget(const QPixmap &aPixmap, QWidget *parent, const char *name):
00033 QFrame(parent, name, WStyle_Customize | WStyle_NoBorder)
00034 {
00035   setFrameStyle(QFrame::WinPanel | QFrame::Raised);
00036   mPixmap = aPixmap;
00037   int w = mPixmap.width() + 2 * lineWidth();
00038   int h = mPixmap.height() + 2 * lineWidth();
00039   resize(w, h);
00040 
00041   // center widget under mouse cursor
00042   QPoint p = QCursor::pos();
00043   move(p.x() - w / 2, p.y() - h / 2);
00044   show();
00045 }
00046 
00047 KoPixmapWidget::~KoPixmapWidget()
00048 {
00049 }
00050 
00051 // paint the centered pixmap; don't overpaint the frame
00052 void KoPixmapWidget::paintEvent(QPaintEvent *e)
00053 {
00054   QFrame::paintEvent(e);
00055   QPainter p(this);
00056   p.setClipRect(e->rect());
00057   p.drawPixmap(lineWidth(), lineWidth(), mPixmap);
00058 }
00059 
00060 
00061 
00062 KoIconChooser::KoIconChooser(QSize aIconSize, QWidget *parent, const char *name):
00063 QGridView(parent, name)
00064 {
00065   QGridView::setBackgroundColor(Qt::white);
00066 
00067   mMargin = 2;
00068   setCellWidth(aIconSize.width() + 2 * mMargin);
00069   setCellHeight(aIconSize.height() + 2 * mMargin);
00070 
00071   mIconList.clear();
00072   mPixmapWidget = 0L;
00073   nCols = 0;
00074   mCurRow = 0;
00075   mCurCol = 0;
00076   mItemCount = 0;
00077   mItemWidth = aIconSize.width();
00078   mItemHeight = aIconSize.height();
00079   mMouseButtonDown = false;
00080   mDragEnabled = false;
00081 }
00082 
00083 KoIconChooser::~KoIconChooser()
00084 {
00085   mIconList.clear();
00086   if(mPixmapWidget)
00087     delete mPixmapWidget;
00088 }
00089 
00090 void KoIconChooser::addItem(KoIconItem *item)
00091 {
00092   Q_INT32 n = mItemCount;
00093 
00094   Q_ASSERT(item);
00095   mIconList.insert(mItemCount++, item);
00096   calculateCells();
00097   updateCell(n / numCols(), n - (n / numCols()) * numCols());
00098 }
00099 
00100 bool KoIconChooser::removeItem(KoIconItem *item)
00101 {
00102   int index = mIconList.find(item);
00103   bool ok = mIconList.remove(item);
00104   if( ok )
00105   {
00106     mItemCount--;
00107     // select same cell as deleted cell, or new last cell if we deleted
00108     // last cell.
00109     setCurrentItem(itemAt(kMin(index, mItemCount - 1)));
00110     calculateCells();
00111   }
00112   return ok;
00113 }
00114 
00115 void KoIconChooser::clear()
00116 {
00117   mItemCount = 0;
00118   mIconList.clear();
00119   calculateCells();
00120 }
00121 
00122 // return 0L if there is no current item
00123 KoIconItem *KoIconChooser::currentItem()
00124 {
00125   return itemAt(mCurRow, mCurCol);
00126 }
00127 
00128 // sets the current item to item
00129 // does NOT emit selected()  (should it?)
00130 void KoIconChooser::setCurrentItem(KoIconItem *item)
00131 {
00132   int index = mIconList.find(item);
00133 
00134   // item is available
00135   if(index != -1 && nCols > 0)
00136   {
00137     int oldRow = mCurRow;
00138     int oldCol = mCurCol;
00139 
00140     mCurRow = index / nCols;
00141     mCurCol = index % nCols;
00142 
00143     // repaint the old and the new item
00144     updateCell(oldRow, oldCol);
00145     updateCell(mCurRow, mCurCol);
00146   }
00147 }
00148 
00149 // eventually select the item, clicked on
00150 void KoIconChooser::mousePressEvent(QMouseEvent *e)
00151 {
00152   QGridView::mousePressEvent(e);
00153   mMouseButtonDown = true;
00154   if(e->button() == LeftButton)
00155   {
00156     QPoint p = e->pos();
00157     mDragStartPos = p;
00158     int row = rowAt(contentsY() + p.y());
00159     int col = columnAt(contentsX() + p.x());
00160 
00161     KoIconItem *item = itemAt(row, col);
00162     if(item)
00163     {
00164       const QPixmap &pix = item->pixmap();
00165       if(pix.width() > mItemWidth || pix.height() > mItemHeight)
00166       showFullPixmap(pix, p);
00167 
00168       int oldRow = mCurRow;
00169       int oldCol = mCurCol;
00170 
00171       mCurRow = row;
00172       mCurCol = col;
00173 
00174       updateCell(oldRow, oldCol);
00175       updateCell(mCurRow, mCurCol);
00176 
00177       emit selected( item );
00178     }
00179   }
00180 }
00181 
00182 void KoIconChooser::mouseMoveEvent(QMouseEvent *e)
00183 {
00184   if(mMouseButtonDown && mDragEnabled )
00185   {
00186     if(mPixmapWidget)
00187     {
00188       delete mPixmapWidget;
00189       mPixmapWidget = 0L;
00190     }
00191     if( ( mDragStartPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() )
00192       startDrag();
00193   }
00194 }
00195 
00196 void
00197 KoIconChooser::startDrag()
00198 {
00199   mMouseButtonDown = false;
00200 }
00201 
00202 // when a big item is shown in full size, delete it on mouseRelease
00203 void KoIconChooser::mouseReleaseEvent(QMouseEvent * /*e*/)
00204 {
00205   mMouseButtonDown = false;
00206   if(mPixmapWidget)
00207   {
00208     delete mPixmapWidget;
00209     mPixmapWidget = 0L;
00210   }
00211 }
00212 
00213 // FIXME: implement keyboard navigation
00214 void KoIconChooser::keyPressEvent(QKeyEvent *e)
00215 {
00216   QGridView::keyPressEvent(e);
00217 }
00218 
00219 // recalculate the number of items that fit into one row
00220 // set the current item again after calculating the new grid
00221 void KoIconChooser::resizeEvent(QResizeEvent *e)
00222 {
00223   QGridView::resizeEvent(e);
00224 
00225   KoIconItem *item = currentItem();
00226   int oldNCols = nCols;
00227   nCols = numCols();
00228 
00229   if(nCols != oldNCols)
00230   {
00231     setNumCols(nCols);
00232     calculateCells();
00233     setCurrentItem(item);
00234   }
00235 }
00236 
00237 // paint one cell
00238 // mark the current item and center items smaller than the cellSize
00239 // TODO: scale down big pixmaps and paint the size as text into the pixmap
00240 void KoIconChooser::paintCell(QPainter *p, int row, int col)
00241 {
00242   KoIconItem *item = itemAt(row, col);
00243 
00244   if(item)
00245   {
00246     const QPixmap &pix = item->pixmap();
00247 
00248     int x = mMargin;
00249     int y = mMargin;
00250     int pw = pix.width();
00251     int ph = pix.height();
00252     int cw = cellWidth();
00253     int ch = cellHeight();
00254 
00255     // center small pixmaps
00256     if(pw < mItemWidth)
00257       x = (cw - pw) / 2;
00258     if(ph < mItemHeight)
00259       y = (cw - ph) / 2;
00260 
00261     if((!item->hasValidThumb()) || (pw <= mItemWidth && ph <= mItemHeight))
00262       p->drawPixmap(x, y, pix, 0, 0, mItemWidth, mItemHeight);
00263     else
00264     {
00265       const QPixmap &thumbpix = item->thumbPixmap();
00266       x = mMargin;
00267       y = mMargin;
00268       pw = thumbpix.width();
00269       ph = thumbpix.height();
00270       cw = cellWidth();
00271       ch = cellHeight();
00272 
00273       // center small pixmaps
00274       if(pw < mItemWidth)
00275         x = (cw - pw) / 2;
00276       if(ph < mItemHeight)
00277         y = (cw - ph) / 2;
00278       p->drawPixmap(x, y, thumbpix, 0, 0, mItemWidth, mItemHeight);
00279     }
00280 
00281     // highlight current item
00282     if(row == mCurRow && col == mCurCol)
00283     {
00284       p->setPen(blue);
00285       p->drawRect(0, 0, cw, ch);
00286     }
00287     else
00288     {
00289       p->setPen(gray);
00290       //p->drawRect(0, 0, cw, ch);
00291       p->drawLine(cw-1, 0, cw-1, ch-1);
00292       p->drawLine(0, ch-1, cw-1, ch-1);
00293     }
00294   }
00295   else
00296   {
00297     // empty cell
00298     p->fillRect(0, 0, cellWidth(), cellHeight(), QBrush(Qt::white));
00299   }
00300 }
00301 
00302 // return the pointer of the item at (row,col) - beware, resizing disturbs
00303 // rows and cols!
00304 // return 0L if item is not found
00305 KoIconItem *KoIconChooser::itemAt(int row, int col)
00306 {
00307   return itemAt(cellIndex(row, col));
00308 }
00309 
00310 // return the pointer of the item at position index
00311 // return 0L if item is not found
00312 KoIconItem *KoIconChooser::itemAt(int index)
00313 {
00314   return mIconList.count() > index ? mIconList.at(index) : 0;
00315 }
00316 
00317 // return the index of a cell, given row and column position
00318 // maps directly to the position in the itemlist
00319 // return -1 on failure
00320 int KoIconChooser::cellIndex(int row, int col)
00321 {
00322   if(row < 0 || col < 0)
00323     return -1;
00324   else
00325     return((row * nCols) + col);
00326 }
00327 
00328 // calculate the grid and set the number of rows and columns
00329 // reorder all items approrpriately
00330 void KoIconChooser::calculateCells()
00331 {
00332   if(nCols == 0)
00333     return;
00334   bool update = isUpdatesEnabled();
00335   int rows = mItemCount / nCols;
00336   setUpdatesEnabled(false);
00337   if((rows * nCols) < mItemCount)
00338     rows++;
00339   setNumRows(rows);
00340   setUpdatesEnabled(update);
00341   repaint();
00342 }
00343 
00344 // show the full pixmap of a large item in an extra widget
00345 void KoIconChooser::showFullPixmap(const QPixmap &pix, const QPoint &/*p*/)
00346 {
00347   mPixmapWidget = new KoPixmapWidget(pix, 0L);
00348 }
00349 
00350 KoPatternChooser::KoPatternChooser( const QPtrList<KoIconItem> &list, QWidget *parent, const char *name )
00351  : QWidget( parent, name )
00352 {
00353     // only serves as beautifier for the iconchooser
00354     //frame = new QHBox( this );
00355     //frame->setFrameStyle( QFrame::Panel | QFrame::Sunken );
00356     chooser = new KoIconChooser( QSize(30,30), this, "pattern chooser" );
00357 
00358     QObject::connect( chooser, SIGNAL(selected( KoIconItem * ) ),
00359                                 this, SIGNAL( selected( KoIconItem * )));
00360 
00361     QPtrListIterator<KoIconItem> itr( list );
00362     for( itr.toFirst(); itr.current(); ++itr )
00363         chooser->addItem( itr.current() );
00364 
00365     QVBoxLayout *mainLayout = new QVBoxLayout( this, 1, -1, "main layout" );
00366     mainLayout->addWidget( chooser, 10 );
00367 }
00368 
00369 
00370 KoPatternChooser::~KoPatternChooser()
00371 {
00372   delete chooser;
00373   //delete frame;
00374 }
00375 
00376 // set the active pattern in the chooser - does NOT emit selected() (should it?)
00377 void KoPatternChooser::setCurrentPattern( KoIconItem *pattern )
00378 {
00379     chooser->setCurrentItem( pattern );
00380 }
00381 
00382 void KoPatternChooser::addPattern( KoIconItem *pattern )
00383 {
00384     chooser->addItem( pattern );
00385 }
00386 
00387 // return the active pattern
00388 KoIconItem *KoPatternChooser::currentPattern()
00389 {
00390     return chooser->currentItem();
00391 }
00392 
00393 #include "koIconChooser.moc"
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Nov 17 13:19:23 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2003