/**************************************************************************** ** $Id: qiconview.h,v 1.3 1999/06/10 13:29:46 reggie Exp $ ** ** Copyright (C) 1992-1999 Troll Tech AS. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #ifndef QTICONVIEW_H #define QTICONVIEW_H #include <qscrollview.h> #include <qiconset.h> #include <qstring.h> #include <qrect.h> #include <qpoint.h> #include <qsize.h> #include <qfont.h> #include <qlist.h> #include <qdragobject.h> #include <qmultilineedit.h> #include <qstringlist.h> class QtIconView; class QFontMetrics; class QPainter; class QMimeSource; class QDragObject; class QMouseEvent; class QDragEnterEvent; class QDragMoveEvent; class QDragLeaveEvent; class QKeyEvent; struct QtIconViewPrivate; class QtIconViewItem; /***************************************************************************** * * Class QtIconViewItemDrag * *****************************************************************************/ class QtIconViewItemDrag : public QDragObject { public: QtIconViewItemDrag( QWidget *source = 0, const char *name = 0 ) : QDragObject( source, name ) {} virtual const char *format( int ) const { return 0L; } virtual QByteArray encodedData( const char * ) const { return QByteArray(); } }; /***************************************************************************** * * Class QtIconViewItemLineEdit * *****************************************************************************/ class QtIconViewItemLineEdit : public QMultiLineEdit { Q_OBJECT public: QtIconViewItemLineEdit( const QString &text, QWidget *parent, QtIconViewItem *theItem, const char *name = 0 ); signals: void escapePressed(); protected: void keyPressEvent( QKeyEvent *e ); protected: QtIconViewItem *item; QString startText; }; /***************************************************************************** * * Class QtIconViewItem * *****************************************************************************/ class QtIconViewItem : public QObject { friend class QtIconView; Q_OBJECT public: QtIconViewItem( QtIconView *parent ); QtIconViewItem( QtIconView *parent, QtIconViewItem *after ); QtIconViewItem( QtIconView *parent, const QString &text ); QtIconViewItem( QtIconView *parent, QtIconViewItem *after, const QString &text ); QtIconViewItem( QtIconView *parent, const QString &text, const QIconSet &icon ); QtIconViewItem( QtIconView *parent, QtIconViewItem *after, const QString &text, const QIconSet &icon ); virtual ~QtIconViewItem(); virtual void setAllowRename( bool allow ); virtual void setAllowDrag( bool allow ); virtual void setAllowDrop( bool allow ); virtual QString text(); virtual QIconSet icon(); virtual bool allowRename(); virtual bool allowDrag(); virtual bool allowDrop(); virtual QtIconView *iconView() const; virtual QtIconViewItem *prevItem() const; virtual QtIconViewItem *nextItem() const; virtual int index(); virtual void setSelected( bool s, bool cb = FALSE ); virtual void setSelectable( bool s ); virtual bool isSelected(); virtual bool isSelectable(); virtual void repaint(); virtual void move( int x, int y ); virtual void moveBy( int dx, int dy ); virtual void move( const QPoint &pnt ); virtual void moveBy( const QPoint &pnt ); virtual QRect rect(); virtual int x(); virtual int y(); virtual int width(); virtual int height(); virtual QSize size(); virtual QPoint pos(); virtual QRect textRect( bool relative = TRUE ); virtual QRect iconRect( bool relative = TRUE ); virtual bool contains( QPoint pnt ); virtual bool intersects( QRect r ); virtual void setFont( const QFont &font ); virtual QFont font(); virtual void setViewMode( QIconSet::Size mode ); virtual bool acceptDrop( QMimeSource *mime ); virtual QDragObject *dragObject(); virtual void rename(); public slots: virtual void setText( const QString &text ); virtual void setIcon( const QIconSet &icon ); protected slots: virtual void renameItem(); virtual void cancelRenameItem(); protected: virtual void removeRenameBox(); virtual void calcRect(); virtual void paintItem( QPainter *p ); virtual void paintFocus( QPainter *p ); virtual void makeActiveIcon(); virtual void dropped( QMimeSource *mime ); virtual void breakLines( const QString text, QStringList &lst, int width ); virtual void dragEntered(); virtual void dragLeft(); QtIconView *view; QString itemText; QIconSet itemIcon; QtIconViewItem *prev, *next; bool allow_rename, allow_drag, allow_drop; bool selected, selectable; QRect itemRect, itemTextRect, itemIconRect; QFontMetrics *fm; QFont f; QIconSet::Size viewMode; QtIconViewItemLineEdit *renameBox; }; /***************************************************************************** * * Class QtIconView * *****************************************************************************/ class QtIconView : public QScrollView { friend class QtIconViewItem; friend struct QtIconViewPrivate; Q_OBJECT public: enum SelectionMode { Single = 0, Multi, StrictMulti }; QtIconView( QWidget *parent = 0, const char *name = 0 ); virtual ~QtIconView(); virtual void insertItem( QtIconViewItem *item, QtIconViewItem *after = 0L ); virtual void removeItem( QtIconViewItem *item ); virtual int index( QtIconViewItem *item ); virtual QtIconViewItem *firstItem() const; virtual QtIconViewItem *lastItem() const; virtual QtIconViewItem *currentItem() const; virtual void setCurrentItem( QtIconViewItem *item ); virtual unsigned int count(); virtual void setViewMode( QIconSet::Size mode ); virtual QIconSet::Size viewMode(); virtual void orderItemsInGrid(); virtual void show(); virtual void setSelectionMode( SelectionMode m ); virtual SelectionMode selectionMode(); virtual QtIconViewItem *findItem( const QPoint &pos ); virtual void selectAll( bool select ); virtual void repaintItem( QtIconViewItem *item ); virtual void ensureItemVisible( QtIconViewItem *item ); virtual void clear(); virtual void setRastX( int rx ); virtual void setRastY( int ry ); virtual int rastX(); virtual int rastY(); virtual void setSpacing( int sp ); virtual int spacing(); signals: void dropped( QMimeSource *mime ); void moved(); void doubleClicked( QtIconViewItem *item ); void itemRightClicked( QtIconViewItem *item ); void viewportRightClicked(); void selectionChanged(); void selectionChanged( int numItems ); void currentChanged(); void currentChanged( QtIconViewItem *item ); protected slots: virtual void doAutoScroll(); protected: virtual void drawContents( QPainter *p, int cx, int cy, int cw, int ch ); virtual void contentsMousePressEvent( QMouseEvent *e ); virtual void contentsMouseReleaseEvent( QMouseEvent *e ); virtual void contentsMouseMoveEvent( QMouseEvent *e ); virtual void contentsMouseDoubleClickEvent( QMouseEvent *e ); virtual void contentsDragEnterEvent( QDragEnterEvent *e ); virtual void contentsDragMoveEvent( QDragMoveEvent *e ); virtual void contentsDragLeaveEvent( QDragLeaveEvent *e ); virtual void contentsDropEvent( QDropEvent *e ); virtual void keyPressEvent( QKeyEvent *e ); virtual void selectByRubber( QRect oldRubber ); virtual void drawRubber( QPainter *p ); virtual QDragObject *dragObject(); virtual void startDrag( bool move = FALSE ); virtual void insertInGrid( QtIconViewItem *item ); void emitSelectionChanged(); void emitNewSelectionNumber(); QtIconViewPrivate *d; }; #endif
/**************************************************************************** ** $Id: qiconview.cpp,v 1.6 1999/06/24 16:40:07 reggie Exp $ ** ** Copyright (C) 1992-1999 Troll Tech AS. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #include "qiconview.h" #include <qpixmap.h> #include <qfontmetrics.h> #include <qpainter.h> #include <qevent.h> #include <qpalette.h> #include <qmime.h> #include <qimage.h> #include <qpen.h> #include <qbrush.h> #include <qtimer.h> #include <qcursor.h> #include <qkeycode.h> static const char *unknown[] = { "32 32 11 1", "c c #ffffff", "g c #c0c0c0", "a c #c0ffc0", "h c #a0a0a4", "d c #585858", "f c #303030", "i c #400000", "b c #00c000", "e c #000000", "# c #000000", ". c None", "...###..........................", "...#aa##........................", ".###baaa##......................", ".#cde#baaa##....................", ".#cccdeebaaa##..##f.............", ".#cccccdeebaaa##aaa##...........", ".#cccccccdeebaaaaaaaa##.........", ".#cccccccccdeebaaaaaaa#.........", ".#cccccgcgghhebbbbaaaaa#........", ".#ccccccgcgggdebbbbbbaa#........", ".#cccgcgcgcgghdeebiebbba#.......", ".#ccccgcggggggghdeddeeba#.......", ".#cgcgcgcggggggggghghdebb#......", ".#ccgcggggggggghghghghd#b#......", ".#cgcgcggggggggghghghhd#b#......", ".#gcggggggggghghghhhhhd#b#......", ".#cgcggggggggghghghhhhd#b#......", ".#ggggggggghghghhhhhhhdib#......", ".#gggggggggghghghhhhhhd#b#......", ".#hhggggghghghhhhhhhhhd#b#......", ".#ddhhgggghghghhhhhhhhd#b#......", "..##ddhhghghhhhhhhhhhhdeb#......", "....##ddhhhghhhhhhhhhhd#b#......", "......##ddhhhhhhhhhhhhd#b#......", "........##ddhhhhhhhhhhd#b#......", "..........##ddhhhhhhhhd#b#......", "............##ddhhhhhhd#b###....", "..............##ddhhhhd#b#####..", "................##ddhhd#b######.", "..................##dddeb#####..", "....................##d#b###....", "......................####......"}; /***************************************************************************** * * Struct QtIconViewPrivate * *****************************************************************************/ struct QtIconViewPrivate { QtIconViewItem *firstItem, *lastItem; unsigned int count; QIconSet::Size mode; bool mousePressed, startDrag; QtIconView::SelectionMode selectionMode; QtIconViewItem *currentItem, *tmpCurrentItem; QRect *rubber; QTimer *scrollTimer; int rastX, rastY, spacing; bool cleared; }; /***************************************************************************** * * Class QtIconViewItemLineEdit * *****************************************************************************/ QtIconViewItemLineEdit::QtIconViewItemLineEdit( const QString &text, QWidget *parent, QtIconViewItem *theItem, const char *name ) : QMultiLineEdit( parent, name ), item( theItem ), startText( text ) { setText( text ); clearTableFlags(); } void QtIconViewItemLineEdit::keyPressEvent( QKeyEvent *e ) { if ( e->key() == Key_Escape ) { item->QtIconViewItem::setText( startText ); // item->iconView()->repaintContents( item->iconView()->contentsX(), item->iconView()->contentsY(), // item->iconView()->contentsWidth(), item->iconView()->contentsHeight() ); emit escapePressed(); } else if ( e->key() == Key_Enter || e->key() == Key_Return ) emit returnPressed(); else QMultiLineEdit::keyPressEvent( e ) ; } /***************************************************************************** * * Class QtIconViewItem * *****************************************************************************/ QtIconViewItem::QtIconViewItem( QtIconView *parent ) : view( parent ), itemText(), itemIcon( QPixmap( unknown ) ), prev( 0L ), next( 0L ), allow_rename( TRUE ), allow_drag( TRUE ), allow_drop( TRUE ), selected( FALSE ), selectable( TRUE ), fm( 0L ), renameBox( 0L ) { if ( view ) { fm = new QFontMetrics( view->font() ); viewMode = view->viewMode(); makeActiveIcon(); calcRect(); view->insertItem( this ); } } QtIconViewItem::QtIconViewItem( QtIconView *parent, QtIconViewItem *after ) : view( parent ), itemText(), itemIcon( QPixmap( unknown ) ), prev( 0L ), next( after ), allow_rename( TRUE ), allow_drag( TRUE ), allow_drop( TRUE ), selected( FALSE ), selectable( TRUE ), fm( 0L ), renameBox( 0L ) { if ( view ) { fm = new QFontMetrics( view->font() ); viewMode = view->viewMode(); makeActiveIcon(); calcRect(); view->insertItem( this ); } } QtIconViewItem::QtIconViewItem( QtIconView *parent, const QString &text ) : view( parent ), itemText( text ), itemIcon( QPixmap( unknown ) ), prev( 0L ), next( 0L ), allow_rename( TRUE ), allow_drag( TRUE ), allow_drop( TRUE ), selected( FALSE ), selectable( TRUE ), fm( 0L ), renameBox( 0L ) { if ( view ) { fm = new QFontMetrics( view->font() ); viewMode = view->viewMode(); makeActiveIcon(); calcRect(); view->insertItem( this ); } } QtIconViewItem::QtIconViewItem( QtIconView *parent, QtIconViewItem *after, const QString &text ) : view( parent ), itemText( text ), itemIcon( QPixmap( unknown ) ), prev( 0L ), next( after ), allow_rename( TRUE ), allow_drag( TRUE ), allow_drop( TRUE ), selected( FALSE ), selectable( TRUE ), fm( 0L ), renameBox( 0L ) { if ( view ) { fm = new QFontMetrics( view->font() ); viewMode = view->viewMode(); makeActiveIcon(); calcRect(); view->insertItem( this ); } } QtIconViewItem::QtIconViewItem( QtIconView *parent, const QString &text, const QIconSet &icon ) : view( parent ), itemText( text ), itemIcon( icon ), prev( 0L ), next( 0L ), allow_rename( TRUE ), allow_drag( TRUE ), allow_drop( TRUE ), selected( FALSE ), selectable( TRUE ), fm( 0L ), renameBox( 0L ) { if ( view ) { fm = new QFontMetrics( view->font() ); viewMode = view->viewMode(); makeActiveIcon(); calcRect(); view->insertItem( this ); } } QtIconViewItem::QtIconViewItem( QtIconView *parent, QtIconViewItem *after, const QString &text, const QIconSet &icon ) : view( parent ), itemText( text ), itemIcon( icon ), prev( 0L ), next( after ), allow_rename( TRUE ), allow_drag( TRUE ), allow_drop( TRUE ), selected( FALSE ), selectable( TRUE ), fm( 0L ), renameBox( 0L ) { if ( view ) { fm = new QFontMetrics( view->font() ); viewMode = view->viewMode(); makeActiveIcon(); calcRect(); view->insertItem( this ); } } QtIconViewItem::~QtIconViewItem() { view->removeItem( this ); removeRenameBox(); } void QtIconViewItem::setText( const QString &text ) { if ( text == itemText ) return; itemText = text; calcRect(); repaint(); } void QtIconViewItem::setIcon( const QIconSet &icon ) { itemIcon = icon; calcRect(); repaint(); } void QtIconViewItem::setAllowRename( bool allow ) { allow_rename = allow; } void QtIconViewItem::setAllowDrag( bool allow ) { allow_drag = allow; } void QtIconViewItem::setAllowDrop( bool allow ) { allow_drop = allow; } QString QtIconViewItem::text() { return itemText; } QIconSet QtIconViewItem::icon() { return itemIcon; } bool QtIconViewItem::allowRename() { return allow_rename; } bool QtIconViewItem::allowDrag() { return allow_drag; } bool QtIconViewItem::allowDrop() { return allow_drop; } QtIconView *QtIconViewItem::iconView() const { return view; } QtIconViewItem *QtIconViewItem::prevItem() const { return prev; } QtIconViewItem *QtIconViewItem::nextItem() const { return next; } int QtIconViewItem::index() { if ( view ) return view->index( this ); return -1; } void QtIconViewItem::setSelected( bool s, bool cb ) { if ( selectable && s != selected ) { if ( !s ) selected = FALSE; else { if ( view->d->selectionMode == QtIconView::Single && view->d->currentItem ) view->d->currentItem->setSelected( FALSE ); else if ( view->d->selectionMode == QtIconView::StrictMulti && !cb ) view->selectAll( FALSE ); } selected = s; repaint(); view->emitSelectionChanged(); } } void QtIconViewItem::setSelectable( bool s ) { selectable = s; if ( selected ) selected = FALSE; } bool QtIconViewItem::isSelected() { return selected; } bool QtIconViewItem::isSelectable() { return selectable; } void QtIconViewItem::repaint() { if ( view ) view->repaintItem( this ); } void QtIconViewItem::move( int x, int y ) { itemRect.setRect( x, y, itemRect.width(), itemRect.height() ); } void QtIconViewItem::moveBy( int dx, int dy ) { itemRect.moveBy( dx, dy ); } void QtIconViewItem::move( const QPoint &pnt ) { move( pnt.x(), pnt.y() ); } void QtIconViewItem::moveBy( const QPoint &pnt ) { moveBy( pnt.x(), pnt.y() ); } QRect QtIconViewItem::rect() { return itemRect; } int QtIconViewItem::x() { return itemRect.x(); } int QtIconViewItem::y() { return itemRect.y(); } int QtIconViewItem::width() { return itemRect.width(); } int QtIconViewItem::height() { return itemRect.height(); } QSize QtIconViewItem::size() { return QSize( itemRect.width(), itemRect.height() ); } QPoint QtIconViewItem::pos() { return QPoint( itemRect.x(), itemRect.y() ); } /*! * If relative is TRUE, the returned rectangle is relative to the origin of the viewport's * coordinate system, else the rectangle is relative to the origin of the item's rectangle */ QRect QtIconViewItem::textRect( bool relative ) { if ( relative ) return itemTextRect; else return QRect( x() + itemTextRect.x(), y() + itemTextRect.y(), itemTextRect.width(), itemTextRect.height() ); } /*! * If relative is TRUE, the returned rectangle is relative to the origin of the viewport's * coordinate system, else the rectangle is relative to the origin of the item's rectangle */ QRect QtIconViewItem::iconRect( bool relative ) { if ( relative ) return itemIconRect; else return QRect( x() + itemIconRect.x(), y() + itemIconRect.y(), itemIconRect.width(), itemIconRect.height() ); } bool QtIconViewItem::contains( QPoint pnt ) { return ( textRect( FALSE ).contains( pnt ) || iconRect( FALSE ).contains( pnt ) ); } bool QtIconViewItem::intersects( QRect r ) { return ( textRect( FALSE ).intersects( r ) || iconRect( FALSE ).intersects( r ) ); } void QtIconViewItem::setFont( const QFont &font ) { f = font; if ( fm ) delete fm; fm = new QFontMetrics( f ); calcRect(); repaint(); } QFont QtIconViewItem::font() { return f; } void QtIconViewItem::setViewMode( QIconSet::Size mode ) { viewMode = mode; calcRect(); } bool QtIconViewItem::acceptDrop( QMimeSource * ) { return FALSE; } QDragObject *QtIconViewItem::dragObject() { return 0L; } void QtIconViewItem::rename() { renameBox = new QtIconViewItemLineEdit( itemText, view->viewport(), this ); renameBox->resize( textRect().width() - 2, textRect().height() - 2 ); view->addChild( renameBox, textRect( FALSE ).x() + 1, textRect( FALSE ).y() + 1 ); renameBox->setFrameStyle( QFrame::NoFrame );//Box | QFrame::Plain ); renameBox->selectAll(); renameBox->setFocus(); renameBox->show(); view->viewport()->setFocusProxy( renameBox ); connect( renameBox, SIGNAL( returnPressed() ), this, SLOT( renameItem() ) ); connect( renameBox, SIGNAL( escapePressed() ), this, SLOT( cancelRenameItem() ) ); } void QtIconViewItem::renameItem() { if ( !renameBox ) return; QRect r = itemRect; setText( renameBox->text() ); view->repaintContents( r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2 ); removeRenameBox(); } void QtIconViewItem::cancelRenameItem() { if ( !renameBox ) return; removeRenameBox(); } void QtIconViewItem::removeRenameBox() { if ( !renameBox ) return; delete renameBox; renameBox = 0L; view->viewport()->setFocusProxy( view ); view->setFocus(); } void QtIconViewItem::calcRect() { if ( !fm ) return; int w = 0, h = 0; if ( view->rastX() != -1 && fm->width( itemText ) > view->rastX() - 4 ) { QStringList lst; breakLines( itemText, lst, view->rastX() - 4 ); QValueListIterator<QString> it = lst.begin(); for ( ; it != lst.end(); ++it ) { w = QMAX( w, fm->width( *it ) ); h += fm->height(); } w += 6; h += 2; } else { w = fm->width( itemText ) + 6; h = fm->height() + 2; } itemTextRect.setWidth( w ); itemTextRect.setHeight( h ); w = itemIcon.pixmap( viewMode, QIconSet::Normal ).width() + 2; h = itemIcon.pixmap( viewMode, QIconSet::Normal ).height() + 2; itemIconRect.setWidth( w ); itemIconRect.setHeight( h ); w = QMAX( itemTextRect.width(), itemIconRect.width() ); h = itemTextRect.height() + itemIconRect.height() + 1; itemRect.setWidth( w ); itemRect.setHeight( h ); itemTextRect = QRect( ( width() - itemTextRect.width() ) / 2, height() - itemTextRect.height(), itemTextRect.width(), itemTextRect.height() ); itemIconRect = QRect( ( width() - itemIconRect.width() ) / 2, 0, itemIconRect.width(), itemIconRect.height() ); } void QtIconViewItem::paintItem( QPainter *p ) { QIconSet::Mode m = QIconSet::Normal; if ( isSelected() ) m = QIconSet::Active; else if ( !isSelectable() ) m = QIconSet::Disabled; int w = itemIcon.pixmap( viewMode, QIconSet::Normal ).width(); if ( isSelected() ) p->fillRect( iconRect( FALSE ), view->colorGroup().highlight() ); p->drawPixmap( x() + ( width() - w ) / 2, y(), itemIcon.pixmap( viewMode, m ) ); p->save(); if ( isSelected() ) { p->fillRect( textRect( FALSE ), view->colorGroup().highlight() ); p->setPen( QPen( view->colorGroup().highlightedText() ) ); } else p->setPen( view->colorGroup().text() ); if ( view->rastX() != -1 && fm->width( itemText ) > view->rastX() - 4 ) { QStringList lst; breakLines( itemText, lst, view->rastX() - 4 ); QValueListIterator<QString> it = lst.begin(); int h = 0; for ( ; it != lst.end(); ++it ) { p->drawText( QRect( textRect( FALSE ).x(), h + textRect( FALSE ).y(), textRect( FALSE ).width(), fm->height() ), Qt::AlignCenter, *it); h += fm->height(); } } else { p->drawText( textRect( FALSE ), Qt::AlignCenter, itemText ); } p->restore(); } void QtIconViewItem::paintFocus( QPainter *p ) { view->style().drawFocusRect( p, QRect( textRect( FALSE ).x(), textRect( FALSE ).y(), textRect( FALSE ).width(), textRect( FALSE ).height() ), view->colorGroup(), isSelected() ? &view->colorGroup().highlight() : &view->colorGroup().base(), isSelected() ); view->style().drawFocusRect( p, QRect( iconRect( FALSE ).x(), iconRect( FALSE ).y(), iconRect( FALSE ).width(), iconRect( FALSE ).height() ), view->colorGroup(), isSelected() ? &view->colorGroup().highlight() : &view->colorGroup().base(), isSelected() ); } void QtIconViewItem::makeActiveIcon() { } void QtIconViewItem::dropped( QMimeSource * ) { } void QtIconViewItem::breakLines( const QString text, QStringList &lst, int width ) { lst.clear(); if ( !fm ) return; if ( text.isEmpty() ) { lst.append( text ); return; } QStringList words; QString line = text; if ( line.simplifyWhiteSpace().find( QChar( ' ') ) == -1 ) { // we have only one word - do some ugly line breaking QString txt; for ( unsigned int i = 0; i < line.length(); i++ ) { if ( fm->width( txt ) + fm->width( line.at( i ) ) <= width ) { txt += line.at( i ); } else { lst.append( txt ); txt = line.at( i ); } } if ( !txt.isEmpty() ) lst.append( txt ); return; } int i = text.find( QChar( ' ' ), 0 ); while ( i != -1 ) { words.append( line.left( i ) ); line.remove( 0, i + 1 ); i = line.find( QChar( ' ' ), 0 ); } if ( !line.simplifyWhiteSpace().isEmpty() ) words.append( line.simplifyWhiteSpace() ); QValueListIterator<QString> it = words.begin(); int w = 0; line = QString::null; for ( ; it != words.end(); ++it ) { if ( w == 0 ) { line = *it; line += QChar( ' ' ); w = fm->width( line ); } else { if ( fm->width( line + *it ) <= width ) { line += *it; line += QChar( ' ' ); w = fm->width( line ); } else { lst.append( line ); w = 0; --it; } } } if ( !line.isEmpty() ) lst.append( line ); } void QtIconViewItem::dragEntered() { } void QtIconViewItem::dragLeft() { } /***************************************************************************** * * Class QtIconView * *****************************************************************************/ QtIconView::QtIconView( QWidget *parent, const char *name ) : QScrollView( parent, name, WNorthWestGravity ) { d = new QtIconViewPrivate; d->firstItem = 0L; d->lastItem = 0L; d->count = 0; d->mode = QIconSet::Automatic; d->mousePressed = FALSE; d->selectionMode = Single; d->currentItem = 0L; d->rubber = 0L; d->scrollTimer = 0L; d->startDrag = FALSE; d->tmpCurrentItem = 0L; d->rastX = d->rastY = -1; d->spacing = 5; d->cleared = FALSE; setAcceptDrops( TRUE ); viewport()->setAcceptDrops( TRUE ); setMouseTracking( TRUE ); viewport()->setMouseTracking( TRUE ); setFocusPolicy( QWidget::StrongFocus ); viewport()->setFocusPolicy( QWidget::StrongFocus ); setBackgroundMode( NoBackground ); viewport()->setFocusProxy( this ); } QtIconView::~QtIconView() { delete d; } void QtIconView::insertItem( QtIconViewItem *item, QtIconViewItem *after ) { if ( !item ) return; if ( !d->firstItem ) { d->firstItem = d->lastItem = item; item->prev = 0L; item->next = 0L; } else { if ( !after || after == d->lastItem ) { d->lastItem->next = item; item->prev = d->lastItem; d->lastItem = item; } else { QtIconViewItem *i = d->firstItem; while ( i != after ) i = i->next; if ( i ) { QtIconViewItem *next = i->next; item->next = next; item->prev = i; i->next = item; next->prev = item; } } } if ( isVisible() ) { insertInGrid( item ); resizeContents( QMAX( contentsWidth(), item->x() + item->width() + 5 ), QMAX( contentsHeight(), item->y() + item->height() + 5 ) ); } d->count++; } void QtIconView::removeItem( QtIconViewItem *item ) { if ( !item ) return; if ( item == d->firstItem ) d->firstItem = d->firstItem->next; else if ( item == d->lastItem ) d->lastItem = d->lastItem->prev; else { QtIconViewItem *i = d->firstItem; while ( i != item ) i = i->next; if ( i ) { i->prev->next = i->next; i->next->prev = i->prev; } } d->count--; } int QtIconView::index( QtIconViewItem *item ) { if ( !item ) return -1; if ( item == d->firstItem ) return 0; else if ( item == d->lastItem ) return d->count - 1; else { QtIconViewItem *i = d->firstItem; unsigned int j = 0; while ( i != item ) { i = i->next; ++j; } return j; } } QtIconViewItem *QtIconView::firstItem() const { return d->firstItem; } QtIconViewItem *QtIconView::lastItem() const { return d->lastItem; } QtIconViewItem *QtIconView::currentItem() const { return d->currentItem; } void QtIconView::setCurrentItem( QtIconViewItem *item ) { d->currentItem = item; emit currentChanged(); emit currentChanged( d->currentItem ); emitNewSelectionNumber(); } unsigned int QtIconView::count() { return d->count; } void QtIconView::setViewMode( QIconSet::Size mode ) { d->mode = mode; if ( !d->firstItem ) return; QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) item->setViewMode( mode ); repaintContents( contentsX(), contentsY(), contentsWidth(), contentsHeight() ); } QIconSet::Size QtIconView::viewMode() { return d->mode; } void QtIconView::doAutoScroll() { QPoint pos = QCursor::pos(); pos = viewport()->mapFromGlobal( pos ); pos = viewportToContents( pos ); QPainter p; p.begin( viewport() ); p.setRasterOp( NotROP ); p.setPen( QPen( Qt::black, 1, Qt::DotLine ) ); p.setBrush( Qt::NoBrush ); drawRubber( &p ); p.end(); ensureVisible( pos.x(), pos.y() ); pos = QCursor::pos(); pos = viewport()->mapFromGlobal( pos ); pos = viewportToContents( pos ); QRect oldRubber = QRect( *d->rubber ); d->rubber->setRight( pos.x() ); d->rubber->setBottom( pos.y() ); selectByRubber( oldRubber ); p.begin( viewport() ); p.setRasterOp( NotROP ); p.setPen( QPen( Qt::black, 1, Qt::DotLine ) ); p.setBrush( Qt::NoBrush ); drawRubber( &p ); p.end(); pos = QCursor::pos(); pos = mapFromGlobal( pos ); if ( !QRect( 0, 0, viewport()->width(), viewport()->height() ).contains( pos ) && !d->scrollTimer ) { d->scrollTimer = new QTimer( this ); connect( d->scrollTimer, SIGNAL( timeout() ), this, SLOT( doAutoScroll() ) ); d->scrollTimer->start( 100, FALSE ); } else if ( QRect( 0, 0, viewport()->width(), viewport()->height() ).contains( pos ) && d->scrollTimer ) { disconnect( d->scrollTimer, SIGNAL( timeout() ), this, SLOT( doAutoScroll() ) ); d->scrollTimer->stop(); delete d->scrollTimer; d->scrollTimer = 0L; } } void QtIconView::drawContents( QPainter *p, int cx, int cy, int cw, int ch ) { p->fillRect( cx, cy, cw, ch, colorGroup().base() ); if ( !d->firstItem ) return; QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) if ( item->rect().intersects( QRect( cx, cy, cw, ch ) ) ) item->paintItem( p ); if ( d->currentItem && d->currentItem->rect().intersects( QRect( cx, cy, cw, ch ) ) ) d->currentItem->paintFocus( p ); } void QtIconView::orderItemsInGrid() { int w = 0, h = 0; resizeContents( viewport()->width(), viewport()->height() ); QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) { insertInGrid( item ); w = QMAX( w, item->x() + item->width() ); h = QMAX( h, item->y() + item->height() ); } resizeContents( w /*+ 5*/, h /*+ 5*/ ); } void QtIconView::show() { QScrollView::show(); orderItemsInGrid(); } void QtIconView::setSelectionMode( SelectionMode m ) { d->selectionMode = m; } QtIconView::SelectionMode QtIconView::selectionMode() { return d->selectionMode; } QtIconViewItem *QtIconView::findItem( const QPoint &pos ) { if ( !d->firstItem ) return 0L; QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) if ( item->contains( pos ) ) return item; return 0L; } void QtIconView::selectAll( bool select ) { QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) item->setSelected( select ); } void QtIconView::repaintItem( QtIconViewItem *item ) { if ( !item ) return; if ( QRect( contentsX(), contentsY(), contentsWidth(), contentsHeight() ). intersects( QRect( item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2 ) ) ) repaintContents( item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2 ); } void QtIconView::ensureItemVisible( QtIconViewItem *item ) { if ( !item ) return; ensureVisible( item->x(), item->y(), item->width(), item->height() ); } void QtIconView::clear() { if ( !d->firstItem ) return; QtIconViewItem *item = d->firstItem, *tmp; while ( item ) { tmp = item->next; delete item; item = tmp; } d->count = 0; d->firstItem = 0L; d->lastItem = 0L; setCurrentItem( 0L ); d->tmpCurrentItem = 0L; setContentsPos( 0, 0 ); resizeContents( viewport()->width(), viewport()->height() ); viewport()->repaint( TRUE ); d->cleared = TRUE; } void QtIconView::setRastX( int rx ) { d->rastX = rx; } void QtIconView::setRastY( int ry ) { d->rastY = ry; } int QtIconView::rastX() { return d->rastX; } int QtIconView::rastY() { return d->rastY; } void QtIconView::setSpacing( int sp ) { d->spacing = sp; } int QtIconView::spacing() { return d->spacing; } void QtIconView::contentsMousePressEvent( QMouseEvent *e ) { if ( d->currentItem ) d->currentItem->renameItem(); if ( e->button() == LeftButton ) { d->startDrag = FALSE; QtIconViewItem *item = findItem( e->pos() ); QtIconViewItem *oldCurrent = d->currentItem; if ( item && item->isSelected() && item->textRect( FALSE ).contains( e->pos() ) ) { if ( !item->allowRename() ) return; ensureItemVisible( item ); setCurrentItem( item ); repaintItem( item ); item->rename(); return; } if ( item && item->isSelectable() ) if ( d->selectionMode == Single ) item->setSelected( TRUE, e->state() & ControlButton ); else item->setSelected( !item->isSelected(), e->state() & ControlButton ); else selectAll( FALSE ); setCurrentItem( item ); repaintItem( oldCurrent ); repaintItem( d->currentItem ); if ( !d->currentItem && d->selectionMode != Single ) { if ( d->rubber ) delete d->rubber; d->rubber = 0L; d->rubber = new QRect( e->x(), e->y(), 0, 0 ); if ( d->selectionMode == StrictMulti && !( e->state() & ControlButton ) ) selectAll( FALSE ); } d->mousePressed = TRUE; } else if ( e->button() == RightButton ) { QtIconViewItem *item = findItem( e->pos() ); if ( item ) emit itemRightClicked( item ); else emit viewportRightClicked(); } } void QtIconView::contentsMouseReleaseEvent( QMouseEvent * ) { d->mousePressed = FALSE; d->startDrag = FALSE; if ( d->rubber ) { QPainter p; p.begin( viewport() ); p.setRasterOp( NotROP ); p.setPen( QPen( Qt::black, 1, Qt::DotLine ) ); p.setBrush( Qt::NoBrush ); drawRubber( &p ); p.end(); delete d->rubber; d->rubber = 0L; } if ( d->scrollTimer ) { disconnect( d->scrollTimer, SIGNAL( timeout() ), this, SLOT( doAutoScroll() ) ); d->scrollTimer->stop(); delete d->scrollTimer; d->scrollTimer = 0L; } } void QtIconView::contentsMouseMoveEvent( QMouseEvent *e ) { if ( d->mousePressed && d->currentItem && d->currentItem->allowDrag() ) { if ( !d->startDrag ) { d->currentItem->setSelected( TRUE, TRUE ); d->startDrag = TRUE; } else { d->mousePressed = FALSE; d->cleared = FALSE; startDrag( e->state() & ControlButton ); if ( d->tmpCurrentItem ) repaintItem( d->tmpCurrentItem ); } } else if ( d->mousePressed && !d->currentItem && d->rubber ) doAutoScroll(); } void QtIconView::contentsMouseDoubleClickEvent( QMouseEvent *e ) { QtIconViewItem *item = findItem( e->pos() ); if ( item ) { selectAll( FALSE ); item->setSelected( TRUE, TRUE ); emit doubleClicked( item ); } } void QtIconView::contentsDragEnterEvent( QDragEnterEvent * ) { d->tmpCurrentItem = 0L; } void QtIconView::contentsDragMoveEvent( QDragMoveEvent *e ) { if ( d->tmpCurrentItem ) repaintItem( d->tmpCurrentItem ); QtIconViewItem *old = d->tmpCurrentItem; d->tmpCurrentItem = 0L; QtIconViewItem *item = findItem( e->pos() ); if ( item ) { if ( item != old ) { if ( old ) old->dragLeft(); item->dragEntered(); } if ( item->acceptDrop( e ) ) e->accept(); else e->ignore(); d->tmpCurrentItem = item; QPainter p; p.begin( viewport() ); p.translate( -contentsX(), -contentsY() ); item->paintFocus( &p ); p.end(); } else { e->accept(); if ( old ) old->dragLeft(); } } void QtIconView::contentsDragLeaveEvent( QDragLeaveEvent * ) { if ( d->tmpCurrentItem ) { repaintItem( d->tmpCurrentItem ); d->tmpCurrentItem->dragLeft(); } d->tmpCurrentItem = 0L; } void QtIconView::contentsDropEvent( QDropEvent *e ) { if ( d->tmpCurrentItem ) repaintItem( d->tmpCurrentItem ); QtIconViewItem *i = findItem( e->pos() ); if ( !i && e->source() == viewport() && d->currentItem && !d->cleared ) { QRect r = d->currentItem->rect(); d->currentItem->move( QPoint( e->pos().x() - d->currentItem->iconRect().width() / 2, e->pos().y() - d->currentItem->iconRect().height() / 2 ) ); int w = d->currentItem->x() + d->currentItem->width() + 1; int h = d->currentItem->y() + d->currentItem->height() + 1; repaintItem( d->currentItem ); repaintContents( r.x(), r.y(), r.width(), r.height() ); if ( d->selectionMode != Single ) { int dx = d->currentItem->x() - r.x(); int dy = d->currentItem->y() - r.y(); QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) if ( item->isSelected() && item != d->currentItem ) { QRect or = item->rect(); item->moveBy( dx, dy ); repaintItem( item ); repaintContents( or.x(), or.y(), or.width(), or.height() ); w = QMAX( w, item->x() + item->width() + 1 ); h = QMAX( h, item->y() + item->height() + 1 ); } } bool fullRepaint = FALSE; if ( w > contentsWidth() || h > contentsHeight() ) fullRepaint = TRUE; int oldw = contentsWidth(); int oldh = contentsHeight(); resizeContents( QMAX( contentsWidth(), w ), QMAX( contentsHeight(), h ) ); if ( fullRepaint ) { repaintContents( oldw, 0, contentsWidth() - oldw, contentsHeight() ); repaintContents( 0, oldh, contentsWidth(), contentsHeight() - oldh ); } } else if ( !i && e->source() != viewport() || d->cleared ) emit dropped( e ); else if ( i ) i->dropped( e ); } void QtIconView::keyPressEvent( QKeyEvent *e ) { if ( !d->firstItem ) return; if ( !d->currentItem ) { if ( e->key() == Key_Control ) return; setCurrentItem( d->firstItem ); if ( d->selectionMode == Single ) d->currentItem->setSelected( TRUE, TRUE ); repaintItem( d->currentItem ); return; } switch ( e->key() ) { case Key_Home: { if ( !d->firstItem ) return; QtIconViewItem *item = d->currentItem; setCurrentItem( d->firstItem ); if ( d->selectionMode == Single ) { item->setSelected( FALSE ); d->currentItem->setSelected( TRUE, TRUE ); } else { if ( e->state() & ShiftButton ) d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE ); } repaintItem( item ); repaintItem( d->currentItem ); } break; case Key_End: { if ( !d->lastItem ) return; QtIconViewItem *item = d->currentItem; setCurrentItem( d->lastItem ); if ( d->selectionMode == Single ) { item->setSelected( FALSE ); d->currentItem->setSelected( TRUE, TRUE ); } else { if ( e->state() & ShiftButton ) d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE ); } repaintItem( item ); repaintItem( d->currentItem ); } break; case Key_Right: { if ( !d->currentItem->next ) return; QtIconViewItem *item = d->currentItem; setCurrentItem( d->currentItem->next ); if ( d->selectionMode == Single ) { item->setSelected( FALSE ); d->currentItem->setSelected( TRUE, TRUE ); } else { if ( e->state() & ShiftButton ) d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE ); } repaintItem( item ); repaintItem( d->currentItem ); } break; case Key_Left: { if ( !d->currentItem->prev ) return; QtIconViewItem *item = d->currentItem; setCurrentItem( d->currentItem->prev ); if ( d->selectionMode == Single ) { item->setSelected( FALSE ); d->currentItem->setSelected( TRUE, TRUE ); } else { if ( e->state() & ShiftButton ) d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE ); } repaintItem( item ); repaintItem( d->currentItem ); } break; case Key_Space: { if ( d->selectionMode == Single ) return; d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE ); } break; case Key_Enter: case Key_Return: emit doubleClicked( d->currentItem ); break; } ensureItemVisible( d->currentItem ); } void QtIconView::selectByRubber( QRect oldRubber ) { if ( !d->rubber ) return; oldRubber = oldRubber.normalize(); int minx = contentsWidth(), miny = contentsHeight(); int maxx = 0, maxy = 0; int selected = 0; QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) { if ( item->intersects( oldRubber ) && !item->intersects( d->rubber->normalize() ) ) item->setSelected( FALSE ); else if ( item->intersects( d->rubber->normalize() ) ) { item->setSelected( TRUE, TRUE ); ++selected; minx = QMIN( minx, item->x() - 1 ); miny = QMIN( miny, item->y() - 1 ); maxx = QMAX( maxx, item->x() + item->width() + 1 ); maxy = QMAX( maxy, item->y() + item->height() + 1 ); } } emit selectionChanged(); emit selectionChanged( selected ); } void QtIconView::drawRubber( QPainter *p ) { if ( !p || !d->rubber ) return; QPoint pnt( d->rubber->x(), d->rubber->y() ); pnt = contentsToViewport( pnt ); p->drawRect( QRect( pnt.x(), pnt.y(), d->rubber->width(), d->rubber->height() ) ); } QDragObject *QtIconView::dragObject() { if ( !d->currentItem ) return 0L; QtIconViewItemDrag *drag = new QtIconViewItemDrag( viewport() ); drag->setPixmap( QPixmap( d->currentItem->icon().pixmap( d->mode, QIconSet::Normal ) ), QPoint( d->currentItem->iconRect().width() / 2, d->currentItem->iconRect().height() / 2 ) ); return drag; } void QtIconView::startDrag( bool move ) { QDragObject *drag = dragObject(); if ( !drag ) return; if ( move ) { if ( drag->dragMove() ) if ( drag->target() != viewport() ) emit moved(); } else drag->dragCopy(); } void QtIconView::insertInGrid( QtIconViewItem *item ) { if ( !item ) return; int px = d->spacing; int py = d->spacing; int pw = d->rastX == -1 ? 1 : d->rastX / 2; int ph = d->rastY == -1 ? 1 : d->rastY / 2; bool isFirst = item == d->firstItem; if ( item->prev ) { px = item->prev->x(); py = item->prev->y(); pw = item->prev->width(); ph = item->prev->height(); if ( d->rastX != - 1 && pw > d->rastX - 1 ) { px = px + pw - d->rastX; pw = d->rastX - 1; } if ( d->rastY != - 1 && ph > d->rastY - 1 ) { py = py + ph - d->rastY; ph = d->rastY - 1; } } int xpos = 0; int ypos = 0; bool nextRow = FALSE; if ( d->rastX == -1 ) { xpos = px + pw + d->spacing; if ( xpos + item->width() >= contentsWidth() ) { xpos = d->spacing; nextRow = TRUE; } } else { int fact = px / d->rastX; if ( !isFirst ) xpos = ( fact + 1 ) * d->rastX; else xpos = fact * d->rastX; if ( xpos + d->rastX >= contentsWidth() ) { xpos = d->spacing; nextRow = TRUE; } xpos += ( d->rastX - item->width() ) / 2 + d->spacing; } if ( d->rastY == -1 ) { if ( !nextRow ) ypos = py; else ypos = py + ph + d->spacing; } else { int fact = py / d->rastY; if ( !nextRow ) ypos = fact * d->rastY; else ypos = ( fact + 1 ) * d->rastY; ypos += ( d->rastY - item->height() ) / 2; } item->move( xpos, ypos ); } void QtIconView::emitSelectionChanged() { emit selectionChanged(); emitNewSelectionNumber(); } void QtIconView::emitNewSelectionNumber() { int num = 0; QtIconViewItem *item = d->firstItem; for ( ; item; item = item->next ) if ( item->isSelected() ) ++num; emit selectionChanged( num ); }
/**************************************************************************** ** $Id: main.cpp,v 1.2 1999/06/09 23:03:51 reggie Exp $ ** ** Copyright (C) 1992-1999 Troll Tech AS. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #include "qiconview.h" #include <qapplication.h> #include <qdragobject.h> #include <qpixmap.h> #include <qiconset.h> #include <qmime.h> #include <stdio.h> class ListenDND : public QObject { Q_OBJECT public: ListenDND( QWidget *w ) : view( w ) {} public slots: void dropped( QMimeSource *mime ) { printf( "Dropped Mimesource %p into the view %p\n", mime, view ); printf( " Formats:\n" ); int i = 0; const char *str = mime->format( i ); printf( " %s\n", str ); while ( str ) { str = mime->format( ++i ); printf( " %s\n", str ); } }; void moved() { printf( "All selected items were moved to another widget\n" ); } protected: QWidget *view; }; int main( int argc, char **argv ) { QApplication a( argc, argv ); QtIconView qiconview; qiconview.setSelectionMode( QtIconView::Multi ); qiconview.setViewMode( QIconSet::Large ); qiconview.resize( 600, 480 ); for ( unsigned int i = 0; i < 350; i++ ) ( void )new QtIconViewItem( &qiconview, QString( "Item %1" ).arg( i + 1 ) ); qiconview.setCaption( "Iconview" ); ListenDND listen_dnd( &qiconview ); QObject::connect( &qiconview, SIGNAL( dropped( QMimeSource * ) ), &listen_dnd, SLOT( dropped( QMimeSource * ) ) ); QObject::connect( &qiconview, SIGNAL( moved() ), &listen_dnd, SLOT( moved() ) ); a.setMainWidget( &qiconview ); qiconview.show(); return a.exec(); } #include "main.moc"
Copyright © 1999 Troll Tech | Trademarks | Qt version 2.00
|