summaryrefslogtreecommitdiffstats
path: root/lib/kopainter/koIconChooser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kopainter/koIconChooser.cc')
-rw-r--r--lib/kopainter/koIconChooser.cc482
1 files changed, 482 insertions, 0 deletions
diff --git a/lib/kopainter/koIconChooser.cc b/lib/kopainter/koIconChooser.cc
new file mode 100644
index 00000000..57fda8d8
--- /dev/null
+++ b/lib/kopainter/koIconChooser.cc
@@ -0,0 +1,482 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Carsten Pfeiffer ([email protected])
+ Copyright (c) 2002 Igor Jansen ([email protected])
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <kdebug.h>
+#include <koIconChooser.h>
+#include <kglobal.h>
+
+#include <qpainter.h>
+#include <qcursor.h>
+#include <qapplication.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <kdebug.h>
+
+KoPixmapWidget::KoPixmapWidget(const QPixmap &aPixmap, QWidget *parent, const char *name):
+QFrame(parent, name, WType_Popup)
+{
+ kdDebug() << "Popup created: " << name << "\n";
+ setFrameStyle(QFrame::WinPanel | QFrame::Raised);
+ mPixmap = aPixmap;
+ int w = mPixmap.width() + 2 * lineWidth();
+ int h = mPixmap.height() + 2 * lineWidth();
+ resize(w, h);
+
+}
+
+KoPixmapWidget::~KoPixmapWidget()
+{
+}
+
+// paint the centered pixmap; don't overpaint the frame
+void KoPixmapWidget::paintEvent(QPaintEvent *e)
+{
+ QFrame::paintEvent(e);
+ QPainter p(this);
+ p.setClipRect(e->rect());
+ p.drawPixmap(lineWidth(), lineWidth(), mPixmap);
+}
+
+
+void KoPixmapWidget::mouseReleaseEvent(QMouseEvent *)
+{
+ hide();
+}
+
+
+KoIconChooser::KoIconChooser(QSize aIconSize, QWidget *parent, const char *name, bool sort):
+QGridView(parent, name)
+{
+ QGridView::setBackgroundColor(Qt::white);
+
+ mMargin = 2;
+ setCellWidth(aIconSize.width() + 2 * mMargin);
+ setCellHeight(aIconSize.height() + 2 * mMargin);
+
+ mIconList.clear();
+ mPixmapWidget = 0L;
+ mNCols = 0;
+ mCurRow = 0;
+ mCurCol = 0;
+ mItemCount = 0;
+ mItemWidth = aIconSize.width();
+ mItemHeight = aIconSize.height();
+ mMouseButtonDown = false;
+ mDragEnabled = false;
+ mSort = sort;
+}
+
+KoIconChooser::~KoIconChooser()
+{
+ mIconList.clear();
+ if(mPixmapWidget)
+ delete mPixmapWidget;
+}
+
+void KoIconChooser::addItem(KoIconItem *item)
+{
+ Q_INT32 n = mItemCount;
+ KoIconItem *current = currentItem();
+
+ Q_ASSERT(item);
+
+ int i;
+
+ if (mSort)
+ {
+ i = sortInsertionIndex(item);
+ }
+ else
+ {
+ i = mItemCount;
+ }
+
+ mIconList.insert(i, item);
+ mItemCount++;
+ calculateCells();
+
+ if (mSort)
+ {
+ setCurrentItem(current);
+ updateContents();
+ }
+ else
+ {
+ updateCell(n / numCols(), n - (n / numCols()) * numCols());
+ }
+}
+
+bool KoIconChooser::removeItem(KoIconItem *item)
+{
+ int index = mIconList.find(item);
+ bool ok = mIconList.remove(item);
+ if( ok )
+ {
+ mItemCount--;
+ // select same cell as deleted cell, or new last cell if we deleted
+ // last cell.
+ setCurrentItem(itemAt(kMin(index, mItemCount - 1)));
+ calculateCells();
+ }
+ return ok;
+}
+
+void KoIconChooser::clear()
+{
+ mItemCount = 0;
+ mIconList.clear();
+ calculateCells();
+}
+
+// return 0L if there is no current item
+KoIconItem *KoIconChooser::currentItem()
+{
+ return itemAt(mCurRow, mCurCol);
+}
+
+// sets the current item to item
+// does NOT emit selected() (should it?)
+void KoIconChooser::setCurrentItem(KoIconItem *item)
+{
+ int index = mIconList.find(item);
+
+ // item is available
+ if(index != -1 && mNCols > 0)
+ {
+ int oldRow = mCurRow;
+ int oldCol = mCurCol;
+
+ mCurRow = index / mNCols;
+ mCurCol = index % mNCols;
+
+ // repaint the old and the new item
+ repaintCell(oldRow, oldCol);
+ repaintCell(mCurRow, mCurCol);
+
+ ensureCellVisible(mCurRow, mCurCol);
+ }
+}
+
+// eventually select the item, clicked on
+void KoIconChooser::mousePressEvent(QMouseEvent *e)
+{
+ QGridView::mousePressEvent(e);
+}
+
+void KoIconChooser::mouseMoveEvent(QMouseEvent *e)
+{
+ if(mMouseButtonDown && mDragEnabled )
+ {
+#if 0
+ if(mPixmapWidget)
+ {
+ delete mPixmapWidget;
+ mPixmapWidget = 0L;
+ }
+#endif
+ if( ( mDragStartPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() )
+ startDrag();
+ }
+}
+
+void
+KoIconChooser::startDrag()
+{
+ mMouseButtonDown = false;
+}
+
+void KoIconChooser::mouseReleaseEvent(QMouseEvent * e)
+{
+ mMouseButtonDown = true;
+ if(e->button() == LeftButton)
+ {
+ QPoint p = e->pos();
+ mDragStartPos = p;
+ int x = contentsX() + p.x();
+ int y = contentsY() + p.y();
+ QSize gridExtent = gridSize();
+
+ if (x < gridExtent.width() && y < gridExtent.height())
+ {
+ int row = rowAt(y);
+ int col = columnAt(x);
+
+ KoIconItem *item = itemAt(row, col);
+ if(item)
+ {
+ const QPixmap &pix = item->pixmap();
+ if(pix.width() > mItemWidth || pix.height() > mItemHeight)
+ showFullPixmap(pix, p);
+
+ setCurrentItem(item);
+ emit selected( item );
+ }
+ }
+ }
+}
+
+// FIXME: implement keyboard navigation
+void KoIconChooser::keyPressEvent(QKeyEvent *e)
+{
+ QGridView::keyPressEvent(e);
+}
+
+// recalculate the number of items that fit into one row
+// set the current item again after calculating the new grid
+void KoIconChooser::resizeEvent(QResizeEvent *e)
+{
+ QGridView::resizeEvent(e);
+
+ KoIconItem *item = currentItem();
+ int oldNCols = mNCols;
+
+ if (cellWidth() != 0)
+ {
+ mNCols = e -> size().width() / cellWidth();
+ }
+
+ if(mNCols != oldNCols)
+ {
+ setNumCols(mNCols);
+ calculateCells();
+ setCurrentItem(item);
+ updateContents();
+ }
+}
+
+// paint one cell
+// mark the current item and center items smaller than the cellSize
+// TODO: scale down big pixmaps and paint the size as text into the pixmap
+void KoIconChooser::paintCell(QPainter *p, int row, int col)
+{
+ KoIconItem *item = itemAt(row, col);
+
+ if(item)
+ {
+ const QPixmap &pix = item->pixmap();
+
+ int x = mMargin;
+ int y = mMargin;
+ int pw = pix.width();
+ int ph = pix.height();
+ int cw = cellWidth();
+ int ch = cellHeight();
+
+ // center small pixmaps
+ if(pw < mItemWidth)
+ x = (cw - pw) / 2;
+ if(ph < mItemHeight)
+ y = (cw - ph) / 2;
+
+ if((!item->hasValidThumb()) || (pw <= mItemWidth && ph <= mItemHeight))
+ p->drawPixmap(x, y, pix, 0, 0, mItemWidth, mItemHeight);
+ else
+ {
+ const QPixmap &thumbpix = item->thumbPixmap();
+ x = mMargin;
+ y = mMargin;
+ pw = thumbpix.width();
+ ph = thumbpix.height();
+ cw = cellWidth();
+ ch = cellHeight();
+
+ // center small pixmaps
+ if(pw < mItemWidth)
+ x = (cw - pw) / 2;
+ if(ph < mItemHeight)
+ y = (cw - ph) / 2;
+ p->drawPixmap(x, y, thumbpix, 0, 0, mItemWidth, mItemHeight);
+ }
+
+ // highlight current item
+ if(row == mCurRow && col == mCurCol)
+ {
+ p->setPen(blue);
+ p->drawRect(0, 0, cw, ch);
+ }
+ else
+ {
+ p->setPen(gray);
+ //p->drawRect(0, 0, cw, ch);
+ p->drawLine(cw-1, 0, cw-1, ch-1);
+ p->drawLine(0, ch-1, cw-1, ch-1);
+ }
+ }
+ else
+ {
+ // empty cell
+ p->fillRect(0, 0, cellWidth(), cellHeight(), QBrush(Qt::white));
+ }
+}
+
+// return the pointer of the item at (row,col) - beware, resizing disturbs
+// rows and cols!
+// return 0L if item is not found
+KoIconItem *KoIconChooser::itemAt(int row, int col)
+{
+ return itemAt(cellIndex(row, col));
+}
+
+// return the pointer of the item at position index
+// return 0L if item is not found
+KoIconItem *KoIconChooser::itemAt(int index)
+{
+ if(index < 0)
+ return 0L;
+ return mIconList.count() > uint(index) ? mIconList.at(index) : 0;
+}
+
+// return the index of a cell, given row and column position
+// maps directly to the position in the itemlist
+// return -1 on failure
+int KoIconChooser::cellIndex(int row, int col)
+{
+ if(row < 0 || col < 0)
+ return -1;
+ else
+ return((row * mNCols) + col);
+}
+
+// calculate the grid and set the number of rows and columns
+// reorder all items approrpriately
+void KoIconChooser::calculateCells()
+{
+ if(mNCols == 0)
+ return;
+ bool update = isUpdatesEnabled();
+ int rows = mItemCount / mNCols;
+ setUpdatesEnabled(false);
+ if((rows * mNCols) < mItemCount)
+ rows++;
+ setNumRows(rows);
+ setUpdatesEnabled(update);
+ updateContents();
+}
+
+// show the full pixmap of a large item in an extra widget
+void KoIconChooser::showFullPixmap(const QPixmap &pix, const QPoint &/*p*/)
+{
+ //delete mPixmapWidget;
+ mPixmapWidget = new KoPixmapWidget(pix, this);
+
+ // center widget under mouse cursor
+ QPoint p = QCursor::pos();
+ int w = mPixmapWidget->width();
+ int h = mPixmapWidget->height();
+ mPixmapWidget->move(p.x() - w / 2, p.y() - h / 2);
+ mPixmapWidget->show();
+}
+
+int KoIconChooser::sortInsertionIndex(const KoIconItem *item)
+{
+ int index = 0;
+
+ if (!mIconList.isEmpty())
+ {
+ // Binary insertion
+ int first = 0;
+ int last = mIconList.count() - 1;
+
+ while (first != last)
+ {
+ int middle = (first + last) / 2;
+
+ if (item -> compare(mIconList.at(middle)) < 0)
+ {
+ last = middle - 1;
+
+ if (last < first)
+ {
+ last = first;
+ }
+ }
+ else
+ {
+ first = middle + 1;
+
+ if (first > last)
+ {
+ first = last;
+ }
+ }
+ }
+
+ if (item -> compare(mIconList.at(first)) < 0)
+ {
+ index = first;
+ }
+ else
+ {
+ index = first + 1;
+ }
+ }
+
+ return index;
+}
+
+KoPatternChooser::KoPatternChooser( const QPtrList<KoIconItem> &list, QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ // only serves as beautifier for the iconchooser
+ //frame = new QHBox( this );
+ //frame->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ chooser = new KoIconChooser( QSize(30,30), this, "pattern chooser" );
+
+ QObject::connect( chooser, SIGNAL(selected( KoIconItem * ) ),
+ this, SIGNAL( selected( KoIconItem * )));
+
+ QPtrListIterator<KoIconItem> itr( list );
+ for( itr.toFirst(); itr.current(); ++itr )
+ chooser->addItem( itr.current() );
+
+ QVBoxLayout *mainLayout = new QVBoxLayout( this, 1, -1, "main layout" );
+ mainLayout->addWidget( chooser, 10 );
+}
+
+
+KoPatternChooser::~KoPatternChooser()
+{
+ delete chooser;
+ //delete frame;
+}
+
+// set the active pattern in the chooser - does NOT emit selected() (should it?)
+void KoPatternChooser::setCurrentPattern( KoIconItem *pattern )
+{
+ chooser->setCurrentItem( pattern );
+}
+
+void KoPatternChooser::addPattern( KoIconItem *pattern )
+{
+ chooser->addItem( pattern );
+}
+
+// return the active pattern
+KoIconItem *KoPatternChooser::currentPattern()
+{
+ return chooser->currentItem();
+}
+
+void KoPatternChooser::removePattern( KoIconItem *pattern )
+{
+ chooser->removeItem( pattern );
+}
+
+#include "koIconChooser.moc"