source: vendor/trolltech/current/src/kernel/qiconset.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 26.2 KB
Line 
1/****************************************************************************
2** $Id: qiconset.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QIconSet class
5**
6** Created : 980318
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qiconset.h"
39
40#ifndef QT_NO_ICONSET
41
42#include "qapplication.h"
43#include "qbitmap.h"
44#include "qcleanuphandler.h"
45#include "qimage.h"
46#include "qpainter.h"
47
48enum { NumSizes = 2, NumModes = 3, NumStates = 2 };
49
50static QIconFactory *defaultFac = 0;
51static QSingleCleanupHandler<QIconFactory> q_cleanup_icon_factory;
52
53static short widths[2] = { 22, 32 };
54static short heights[2] = { 22, 32 };
55
56enum QIconSetIconOrigin {
57 SuppliedFileName, // 'fileName' contains the name of the file
58 SuppliedPixmap, // 'pixmap' is a pointer to the user-supplied pixmap
59 Manufactured, // 'pixmap' is a factory-generated pixmap (or 0)
60 Generated // 'pixmap' is a QIconSet-generated pixmap (or 0)
61};
62
63struct QIconSetIcon
64{
65 QIconSetIconOrigin origin;
66 union {
67 QString *fileName;
68 QPixmap *pixmap;
69 };
70
71 QIconSetIcon() : origin( Generated ) { pixmap = 0; }
72 QIconSetIcon( const QIconSetIcon& other )
73 : origin( Generated ) {
74 pixmap = 0;
75 operator=( other );
76 }
77 ~QIconSetIcon() {
78 if ( origin == SuppliedFileName ) {
79 delete fileName;
80 } else {
81 delete pixmap;
82 }
83 }
84
85 QIconSetIcon& operator=( const QIconSetIcon& other );
86
87 void clearCached() {
88 if ( pixmap && (origin == Manufactured || origin == Generated) ) {
89 origin = Generated;
90 delete pixmap;
91 pixmap = 0;
92 }
93 }
94};
95
96QIconSetIcon& QIconSetIcon::operator=( const QIconSetIcon& other )
97{
98 QPixmap *oldPixmap = 0;
99 QString *oldFileName = 0;
100 if ( origin == SuppliedFileName ) {
101 oldFileName = fileName;
102 } else {
103 oldPixmap = pixmap;
104 }
105
106 origin = other.origin;
107 if ( other.origin == SuppliedFileName ) {
108 fileName = new QString( *other.fileName );
109 } else {
110 if ( other.pixmap ) {
111 pixmap = new QPixmap( *other.pixmap );
112 } else {
113 pixmap = 0;
114 }
115 }
116 delete oldPixmap;
117 delete oldFileName;
118 return *this;
119}
120
121class QIconSetPrivate : public QShared
122{
123public:
124 QIconSetIcon icons[NumSizes][NumModes][NumStates];
125 QPixmap defaultPix;
126 QIconFactory *factory;
127
128 QIconSetPrivate() : factory( 0 ) { }
129 QIconSetPrivate( const QIconSetPrivate& other ) : QShared() {
130 count = 1;
131 for ( int i = 0; i < NumSizes; i++ ) {
132 for ( int j = 0; j < NumModes; j++ ) {
133 for ( int k = 0; k < NumStates; k++ ) {
134 icons[i][j][k] = other.icons[i][j][k];
135 }
136 }
137 }
138 defaultPix = other.defaultPix;
139 factory = other.factory;
140 if ( factory )
141 factory->ref();
142 }
143 ~QIconSetPrivate() {
144 setFactory( 0 );
145 }
146
147 QIconSetIcon *icon( const QIconSet *iconSet, QIconSet::Size size,
148 QIconSet::Mode mode, QIconSet::State state );
149 void setFactory( QIconFactory *newFactory ) {
150 if ( newFactory )
151 newFactory->ref();
152 if ( factory && factory->deref() && factory->autoDelete() )
153 delete factory;
154 factory = newFactory;
155 }
156
157 Q_DUMMY_COMPARISON_OPERATOR( QIconSetPrivate )
158};
159
160QIconSetIcon *QIconSetPrivate::icon( const QIconSet *iconSet,
161 QIconSet::Size size, QIconSet::Mode mode,
162 QIconSet::State state )
163{
164 QIconSetIcon *ik = &icons[(int) size - 1][(int) mode][(int) state];
165
166 if ( iconSet ) {
167 if ( ik->origin == SuppliedFileName ) {
168 QPixmap *newPixmap = new QPixmap( *ik->fileName );
169 delete ik->fileName;
170
171 if ( newPixmap->isNull() ) {
172 delete newPixmap;
173 ik->origin = Generated;
174 ik->pixmap = 0;
175 } else {
176 ik->origin = SuppliedPixmap;
177 ik->pixmap = newPixmap;
178 }
179 }
180
181 if ( !ik->pixmap && ik->origin == Generated ) {
182 QIconFactory *f = factory;
183 if ( !f )
184 f = defaultFac;
185
186 if ( f ) {
187 /*
188 We set 'origin' to Manufactured half a second too
189 early to prevent recursive calls to this function.
190 (This can happen if createPixmap() calls
191 QIconSet::pixmap(), which in turn calls this
192 function.)
193 */
194 ik->origin = Manufactured;
195 ik->pixmap = f->createPixmap( *iconSet, size, mode, state );
196 if ( !ik->pixmap )
197 ik->origin = Generated;
198 }
199 }
200 }
201 return ik;
202}
203
204/*! \class QIconSet
205
206 \brief The QIconSet class provides a set of icons with different
207 styles and sizes.
208
209 \ingroup graphics
210 \ingroup images
211 \ingroup shared
212 \mainclass
213
214 A QIconSet can generate smaller, larger, active, and disabled pixmaps
215 from the set of icons it is given. Such pixmaps are used by
216 QToolButton, QHeader, QPopupMenu, etc. to show an icon representing a
217 particular action.
218
219 The simplest use of QIconSet is to create one from a QPixmap and then
220 use it, allowing Qt to work out all the required icon styles and
221 sizes. For example:
222
223 \code
224 QToolButton *but = new QToolButton( QIconSet( QPixmap("open.xpm") ), ... );
225 \endcode
226
227 Using whichever pixmaps you specify as a base, QIconSet provides a
228 set of six icons, each with a \l Size and a \l Mode: Small Normal,
229 Small Disabled, Small Active, Large Normal, Large Disabled, and
230 Large Active.
231
232 An additional set of six icons can be provided for widgets that have
233 an "On" or "Off" state, like checkable menu items or toggleable
234 toolbuttons. If you provide pixmaps for the "On" state, but not for
235 the "Off" state, the QIconSet will provide the "Off" pixmaps. You may
236 specify icons for both states in you wish.
237
238 You can set any of the icons using setPixmap().
239
240 When you retrieve a pixmap using pixmap(Size, Mode, State),
241 QIconSet will return the icon that has been set or previously
242 generated for that size, mode and state combination. If none is
243 available, QIconSet will ask the icon factory. If the icon factory
244 cannot provide any (the default), QIconSet generates a pixmap based
245 on the pixmaps it has been given and returns it.
246
247 The \c Disabled appearance is computed using an algorithm that
248 produces results very similar to those used in Microsoft Windows
249 95. The \c Active appearance is identical to the \c Normal
250 appearance unless you use setPixmap() to set it to something
251 special.
252
253 When scaling icons, QIconSet uses \link QImage::smoothScale()
254 smooth scaling\endlink, which can partially blend the color component
255 of pixmaps. If the results look poor, the best solution
256 is to supply pixmaps in both large and small sizes.
257
258 You can use the static function setIconSize() to set the preferred
259 size of the generated large/small icons. The default small size is
260 22 x 22, while the default large size is 32 x 32. These sizes only
261 affect generated icons.
262
263 The isGenerated() function returns TRUE if an icon was generated by
264 QIconSet or by a factory; clearGenerated() clears all cached
265 pixmaps.
266
267 \section1 Making Classes that Use QIconSet
268
269 If you write your own widgets that have an option to set a small
270 pixmap, consider allowing a QIconSet to be set for that pixmap. The
271 Qt class QToolButton is an example of such a widget.
272
273 Provide a method to set a QIconSet, and when you draw the icon, choose
274 whichever icon is appropriate for the current state of your widget.
275 For example:
276 \code
277 void MyWidget::drawIcon( QPainter* p, QPoint pos )
278 {
279 p->drawPixmap( pos, icons->pixmap(
280 QIconSet::Small,
281 isEnabled() ? QIconSet::Normal :
282 QIconSet::Disabled,
283 isEnabled() ? QIconSet::On :
284 QIconSet::Off));
285 }
286 \endcode
287
288 You might also make use of the \c Active mode, perhaps making your
289 widget \c Active when the mouse is over the widget (see \l
290 QWidget::enterEvent()), while the mouse is pressed pending the
291 release that will activate the function, or when it is the currently
292 selected item. If the widget can be toggled, the "On" mode might be
293 used to draw a different icon.
294
295 \img iconset.png QIconSet
296
297 \sa QIconFactory QPixmap QMainWindow::setUsesBigPixmaps()
298 \link guibooks.html#fowler GUI Design Handbook: Iconic Label \endlink
299*/
300
301
302/*!
303 \enum QIconSet::Size
304
305 This enum type describes the size at which a pixmap is intended to be
306 used.
307 The currently defined sizes are:
308
309 \value Automatic The size of the pixmap is determined from its
310 pixel size. This is a useful default.
311 \value Small The pixmap is the smaller of two.
312 \value Large The pixmap is the larger of two.
313
314 If a Small pixmap is not set by QIconSet::setPixmap(), the Large
315 pixmap will be automatically scaled down to the size of a small pixmap
316 to generate the Small pixmap when required. Similarly, a Small pixmap
317 will be automatically scaled up to generate a Large pixmap. The
318 preferred sizes for large/small generated icons can be set using
319 setIconSize().
320
321 \sa setIconSize() iconSize() setPixmap() pixmap() QMainWindow::setUsesBigPixmaps()
322*/
323
324/*!
325 \enum QIconSet::Mode
326
327 This enum type describes the mode for which a pixmap is intended to be
328 used.
329 The currently defined modes are:
330
331 \value Normal
332 Display the pixmap when the user is
333 not interacting with the icon, but the
334 functionality represented by the icon is available.
335 \value Disabled
336 Display the pixmap when the
337 functionality represented by the icon is not available.
338 \value Active
339 Display the pixmap when the
340 functionality represented by the icon is available and
341 the user is interacting with the icon, for example, moving the
342 mouse over it or clicking it.
343*/
344
345/*!
346 \enum QIconSet::State
347
348 This enum describes the state for which a pixmap is intended to be
349 used. The \e state can be:
350
351 \value Off Display the pixmap when the widget is in an "off" state
352 \value On Display the pixmap when the widget is in an "on" state
353
354 \sa setPixmap() pixmap()
355*/
356
357/*!
358 Constructs a null icon set.
359
360 \sa setPixmap(), reset()
361*/
362QIconSet::QIconSet()
363 : d( 0 )
364{
365}
366
367/*!
368 Constructs an icon set for which the Normal pixmap is \a pixmap,
369 which is assumed to be of size \a size.
370
371 The default for \a size is \c Automatic, which means that QIconSet
372 will determine whether the pixmap is Small or Large from its pixel
373 size. Pixmaps less than the width of a small generated icon are
374 considered to be Small. You can use setIconSize() to set the
375 preferred size of a generated icon.
376
377 \sa setIconSize() reset()
378*/
379QIconSet::QIconSet( const QPixmap& pixmap, Size size )
380 : d( 0 )
381{
382 reset( pixmap, size );
383}
384
385/*! Creates an iconset which uses the pixmap \a smallPix for for
386 displaying a small icon, and the pixmap \a largePix for displaying a
387 large icon.
388*/
389QIconSet::QIconSet( const QPixmap& smallPix, const QPixmap& largePix )
390 : d( 0 )
391{
392 reset( smallPix, Small );
393 reset( largePix, Large );
394}
395
396/*!
397 Constructs a copy of \a other. This is very fast.
398*/
399QIconSet::QIconSet( const QIconSet& other )
400 : d( other.d )
401{
402 if ( d )
403 d->ref();
404}
405
406/*!
407 Destroys the icon set and frees any allocated resources.
408*/
409QIconSet::~QIconSet()
410{
411 if ( d && d->deref() )
412 delete d;
413}
414
415/*!
416 Sets this icon set to use pixmap \a pixmap for the Normal pixmap,
417 assuming it to be of size \a size.
418
419 This is equivalent to assigning QIconSet(\a pixmap, \a size) to this
420 icon set.
421
422 This function does nothing if \a pixmap is a null pixmap.
423*/
424void QIconSet::reset( const QPixmap& pixmap, Size size )
425{
426 if ( pixmap.isNull() )
427 return;
428
429 detach();
430 normalize( size, pixmap.size() );
431 setPixmap( pixmap, size, Normal );
432 d->defaultPix = pixmap;
433 d->setFactory( 0 );
434}
435
436/*!
437 Sets this icon set to provide pixmap \a pixmap for size \a size, mode \a
438 mode and state \a state. The icon set may also use \a pixmap for
439 generating other pixmaps if they are not explicitly set.
440
441 The \a size can be one of Automatic, Large or Small. If Automatic is
442 used, QIconSet will determine if the pixmap is Small or Large from its
443 pixel size.
444
445 Pixmaps less than the width of a small generated icon are
446 considered to be Small. You can use setIconSize() to set the preferred
447 size of a generated icon.
448
449 This function does nothing if \a pixmap is a null pixmap.
450
451 \sa reset()
452*/
453void QIconSet::setPixmap( const QPixmap& pixmap, Size size, Mode mode,
454 State state )
455{
456 if ( pixmap.isNull() )
457 return;
458
459 normalize( size, pixmap.size() );
460
461 detach();
462 clearGenerated();
463
464 QIconSetIcon *icon = d->icon( 0, size, mode, state );
465 if ( icon->origin == SuppliedFileName ) {
466 delete icon->fileName;
467 icon->pixmap = 0;
468 }
469 icon->origin = SuppliedPixmap;
470 if ( icon->pixmap == 0 ) {
471 icon->pixmap = new QPixmap( pixmap );
472 } else {
473 *icon->pixmap = pixmap;
474 }
475}
476
477/*!
478 \overload
479
480 The pixmap is loaded from \a fileName when it becomes necessary.
481*/
482void QIconSet::setPixmap( const QString& fileName, Size size, Mode mode,
483 State state )
484{
485 if ( size == Automatic ) {
486 setPixmap( QPixmap(fileName), size, mode, state );
487 } else {
488 detach();
489 clearGenerated();
490
491 QIconSetIcon *icon = d->icon( 0, size, mode, state );
492 if ( icon->origin == SuppliedFileName ) {
493 *icon->fileName = fileName;
494 } else {
495 delete icon->pixmap;
496 icon->fileName = new QString( fileName );
497 icon->origin = SuppliedFileName;
498 }
499 }
500}
501
502/*!
503 Returns a pixmap with size \a size, mode \a mode and state \a
504 state, generating one if necessary. Generated pixmaps are cached.
505*/
506QPixmap QIconSet::pixmap( Size size, Mode mode, State state ) const
507{
508 if ( !d ) {
509 if ( defaultFac ) {
510 QIconSet *that = (QIconSet *) this;
511 that->detach();
512 } else {
513 return QPixmap();
514 }
515 }
516
517 if ( size == Automatic )
518 size = Small;
519
520 QIconSetIcon *icon = d->icon( this, size, mode, state );
521 if ( icon->pixmap )
522 return *icon->pixmap;
523 if ( icon->origin == Manufactured ) {
524 /*
525 This can only occur during the half a second's time when
526 the icon is being manufactured. If QIconFactory somehow
527 tries to access the pixmap it's supposed to be creating, it
528 will get a null pixmap.
529 */
530 return QPixmap();
531 }
532
533 if ( mode == Active )
534 return pixmap( size, Normal, state );
535
536 Size otherSize = ( size == Large ) ? Small : Large;
537 QIconSetIcon *otherSizeIcon = d->icon( this, otherSize, mode, state );
538
539 if ( state == Off ) {
540 if ( mode == Disabled &&
541 d->icon(this, size, Normal, Off)->origin != Generated ) {
542 icon->pixmap = createDisabled( size, Off );
543 } else if ( otherSizeIcon->origin != Generated ) {
544 icon->pixmap = createScaled( size, otherSizeIcon->pixmap );
545 } else if ( mode == Disabled ) {
546 icon->pixmap = createDisabled( size, Off );
547 } else if ( !d->defaultPix.isNull() ) {
548 icon->pixmap = new QPixmap( d->defaultPix );
549 } else {
550 /*
551 No icons are available for { TRUE, Normal, Off } and
552 { FALSE, Normal, Off }. Try the other 10 combinaisons,
553 best ones first.
554 */
555 const int N = 10;
556 static const struct {
557 bool sameSize;
558 Mode mode;
559 State state;
560 } tryList[N] = {
561 { TRUE, Active, Off },
562 { TRUE, Normal, On },
563 { TRUE, Active, On },
564 { FALSE, Active, Off },
565 { FALSE, Normal, On },
566 { FALSE, Active, On },
567 { TRUE, Disabled, Off },
568 { TRUE, Disabled, On },
569 { FALSE, Disabled, Off },
570 { FALSE, Disabled, On }
571 };
572
573 for ( int i = 0; i < N; i++ ) {
574 bool sameSize = tryList[i].sameSize;
575 QIconSetIcon *tryIcon =
576 d->icon( this, sameSize ? size : otherSize,
577 tryList[i].mode, tryList[i].state );
578 if ( tryIcon->origin != Generated ) {
579 if ( sameSize ) {
580 if ( tryIcon->pixmap )
581 icon->pixmap = new QPixmap( *tryIcon->pixmap );
582 } else {
583 icon->pixmap = createScaled( size, tryIcon->pixmap );
584 }
585 break;
586 }
587 }
588 }
589 } else { /* ( state == On ) */
590 if ( mode == Normal ) {
591 if ( otherSizeIcon->origin != Generated ) {
592 icon->pixmap = createScaled( size, otherSizeIcon->pixmap );
593 } else {
594 icon->pixmap = new QPixmap( pixmap(size, mode, Off) );
595 }
596 } else { /* ( mode == Disabled ) */
597 QIconSetIcon *offIcon = d->icon( this, size, mode, Off );
598 QIconSetIcon *otherSizeOffIcon = d->icon( this, otherSize, mode,
599 Off );
600
601 if ( offIcon->origin != Generated ) {
602 if ( offIcon->pixmap )
603 icon->pixmap = new QPixmap( *offIcon->pixmap );
604 } else if ( d->icon(this, size, Normal, On)->origin != Generated ) {
605 icon->pixmap = createDisabled( size, On );
606 } else if ( otherSizeIcon->origin != Generated ) {
607 icon->pixmap = createScaled( size, otherSizeIcon->pixmap );
608 } else if ( otherSizeOffIcon->origin != Generated ) {
609 icon->pixmap = createScaled( size, otherSizeOffIcon->pixmap );
610 } else {
611 icon->pixmap = createDisabled( size, On );
612 }
613 }
614 }
615 if ( icon->pixmap ) {
616 return *icon->pixmap;
617 } else {
618 return QPixmap();
619 }
620}
621
622/*! \overload
623 \obsolete
624
625 This is the same as pixmap(\a size, \a enabled, \a state).
626*/
627QPixmap QIconSet::pixmap( Size size, bool enabled, State state ) const
628{
629 return pixmap( size, enabled ? Normal : Disabled, state );
630}
631
632/*!
633 \overload
634
635 Returns the pixmap originally provided to the constructor or to
636 reset(). This is the Normal pixmap of unspecified Size.
637
638 \sa reset()
639*/
640QPixmap QIconSet::pixmap() const
641{
642 if ( !d )
643 return QPixmap();
644 return d->defaultPix;
645}
646
647/*!
648 Returns TRUE if the pixmap with size \a size, mode \a mode and
649 state \a state is generated from other pixmaps; otherwise returns
650 FALSE.
651
652 A pixmap obtained from a QIconFactory is considered non-generated.
653*/
654bool QIconSet::isGenerated( Size size, Mode mode, State state ) const
655{
656 if ( !d )
657 return TRUE;
658 return d->icon( this, size, mode, state )->origin == Generated;
659};
660
661/*!
662 Clears all cached pixmaps, including those obtained from an
663 eventual QIconFactory.
664*/
665void QIconSet::clearGenerated()
666{
667 if ( !d )
668 return;
669
670 for ( int i = 0; i < NumSizes; i++ ) {
671 for ( int j = 0; j < NumModes; j++ ) {
672 for ( int k = 0; k < NumStates; k++ ) {
673 d->icons[i][j][k].clearCached();
674 }
675 }
676 }
677}
678
679/*!
680 Installs \a factory as the icon factory for this iconset. The
681 icon factory is used to generates pixmaps not set by the user.
682
683 If no icon factory is installed, QIconFactory::defaultFactory()
684 is used.
685*/
686void QIconSet::installIconFactory( QIconFactory *factory )
687{
688 detach();
689 d->setFactory( factory );
690}
691
692/*!
693 Returns TRUE if the icon set is empty; otherwise returns FALSE.
694*/
695bool QIconSet::isNull() const
696{
697 return !d;
698}
699
700/*!
701 Detaches this icon set from others with which it may share data.
702
703 You will never need to call this function; other QIconSet functions
704 call it as necessary.
705*/
706void QIconSet::detach()
707{
708 if ( !d ) {
709 d = new QIconSetPrivate;
710 return;
711 }
712 if ( d->count != 1 ) {
713 d->deref();
714 d = new QIconSetPrivate( *d );
715 }
716}
717
718/*!
719 Assigns \a other to this icon set and returns a reference to this
720 icon set.
721
722 \sa detach()
723*/
724QIconSet& QIconSet::operator=( const QIconSet& other )
725{
726 if ( other.d )
727 other.d->ref();
728
729 if ( d && d->deref() )
730 delete d;
731 d = other.d;
732 return *this;
733}
734
735/*!
736 Set the preferred size for all small or large icons that are
737 generated after this call. If \a which is Small, sets the preferred
738 size of small generated icons to \a size. Similarly, if \a which is
739 Large, sets the preferred size of large generated icons to \a size.
740
741 Note that cached icons will not be regenerated, so it is recommended
742 that you set the preferred icon sizes before generating any icon sets.
743 Also note that the preferred icon sizes will be ignored for icon sets
744 that have been created using both small and large pixmaps.
745
746 \sa iconSize()
747*/
748void QIconSet::setIconSize( Size which, const QSize& size )
749{
750 widths[(int) which - 1] = size.width();
751 heights[(int) which - 1] = size.height();
752}
753
754/*!
755 If \a which is Small, returns the preferred size of a small
756 generated icon; if \a which is Large, returns the preferred size
757 of a large generated icon.
758
759 \sa setIconSize()
760*/
761const QSize& QIconSet::iconSize( Size which )
762{
763 // ### replace 'const QSize&' with QSize in Qt 4 and simply this code
764 static QSize size;
765 size = QSize( widths[(int) which - 1], heights[(int) which - 1] );
766 return size;
767}
768
769void QIconSet::normalize( Size& which, const QSize& pixSize )
770{
771 if ( which == Automatic )
772 which = pixSize.width() > iconSize( Small ).width() ? Large : Small;
773}
774
775/*!
776 Returns a new pixmap that is a copy of \a suppliedPix, scaled to
777 the icon size \a size.
778*/
779QPixmap *QIconSet::createScaled( Size size, const QPixmap *suppliedPix ) const
780{
781 if ( !suppliedPix || suppliedPix->isNull() )
782 return 0;
783
784 QImage img = suppliedPix->convertToImage();
785 QSize imgSize = iconSize( size );
786 if ( size == Small ) {
787 imgSize = imgSize.boundedTo( img.size() );
788 } else {
789 imgSize = imgSize.expandedTo( img.size() );
790 }
791 img = img.smoothScale( imgSize );
792
793 QPixmap *pixmap = new QPixmap( img );
794 if ( !pixmap->mask() ) {
795 QBitmap mask;
796 mask.convertFromImage( img.createHeuristicMask(),
797 Qt::MonoOnly | Qt::ThresholdDither );
798 pixmap->setMask( mask );
799 }
800 return pixmap;
801}
802
803/*!
804 Returns a new pixmap that has a 'disabled' look, taking as its
805 base the iconset's icon with size \a size and state \a state.
806*/
807QPixmap *QIconSet::createDisabled( Size size, State state ) const
808{
809 QPixmap normalPix = pixmap( size, Normal, state );
810 if ( normalPix.isNull() )
811 return 0;
812
813 QImage img;
814 QPixmap *pixmap = 0;
815 QBitmap normalMask;
816 if ( normalPix.mask() ) {
817 normalMask = *normalPix.mask();
818 } else {
819 img = normalPix.convertToImage();
820 normalMask.convertFromImage( img.createHeuristicMask(),
821 Qt::MonoOnly | Qt::ThresholdDither );
822 }
823
824 pixmap = new QPixmap( normalPix.width() + 1,
825 normalPix.height() + 1 );
826 const QColorGroup &dis = QApplication::palette().disabled();
827 pixmap->fill( dis.background() );
828
829 QPainter painter;
830 painter.begin( pixmap );
831 painter.setPen( dis.base() );
832 painter.drawPixmap( 1, 1, normalMask );
833 painter.setPen( dis.foreground() );
834 painter.drawPixmap( 0, 0, normalMask );
835 painter.end();
836
837 if ( !normalMask.mask() )
838 normalMask.setMask( normalMask );
839
840 QBitmap mask( pixmap->size() );
841 mask.fill( Qt::color0 );
842 painter.begin( &mask );
843 painter.drawPixmap( 0, 0, normalMask );
844 painter.drawPixmap( 1, 1, normalMask );
845 painter.end();
846 pixmap->setMask( mask );
847 return pixmap;
848}
849
850/*! \class QIconFactory
851 \ingroup advanced
852 \brief The QIconFactory class is used to create pixmaps for a QIconSet.
853
854 By reimplementing createPixmap(), you can override QIconSet's
855 default algorithm for computing pixmaps not supplied by the user.
856
857 Call setAutoDelete(TRUE) if you want the factory to automatically
858 delete itself when it is no longer needed by QIconSet.
859
860 \sa QIconSet
861*/
862
863/*!
864 Constructs an icon factory.
865*/
866QIconFactory::QIconFactory()
867 : autoDel( 0 )
868{
869 count = 0;
870}
871
872/*!
873 Destroys the object and frees any allocated resources.
874*/
875QIconFactory::~QIconFactory()
876{
877}
878
879/*!
880 Ceates a pixmap for \a iconSet with a certain \a size, \a mode, and
881 \a state. Returns 0 if the default QIconSet algorithm should be
882 used to create a pixmap that wasn't supplied by the user.
883
884 It is the caller's responsibility to delete the returned pixmap.
885
886 The default implementation always returns 0.
887*/
888QPixmap *QIconFactory::createPixmap( const QIconSet& /* iconSet */,
889 QIconSet::Size /* size */,
890 QIconSet::Mode /* mode */,
891 QIconSet::State /* state */ )
892{
893 return 0;
894}
895
896/*!
897 \fn void QIconFactory::setAutoDelete( bool autoDelete )
898
899 If \a autoDelete is TRUE, sets the icon factory to automatically
900 delete itself when it is no longer referenced by any QIconSet and
901 isn't the default factory. If \a autoDelete is FALSE (the default)
902 auto-deletion is disabled.
903
904 \sa autoDelete(), defaultFactory()
905*/
906
907/*!
908 \fn bool QIconFactory::autoDelete() const
909
910 Returns TRUE if auto-deletion is enabled; otherwise returns FALSE.
911
912 \sa setAutoDelete()
913*/
914
915/*!
916 Returns the default icon factory.
917
918 \sa installDefaultFactory()
919*/
920QIconFactory *QIconFactory::defaultFactory()
921{
922 if ( !defaultFac ) {
923 defaultFac = new QIconFactory;
924 defaultFac->setAutoDelete( TRUE );
925 defaultFac->ref();
926 q_cleanup_icon_factory.set( &defaultFac );
927 }
928 return defaultFac;
929}
930
931/*!
932 Replaces the default icon factory with \a factory.
933*/
934void QIconFactory::installDefaultFactory( QIconFactory *factory )
935{
936 if ( !factory )
937 return;
938
939 factory->ref();
940 if ( defaultFac && defaultFac->deref() && defaultFac->autoDelete() )
941 delete defaultFac;
942 defaultFac = factory;
943 q_cleanup_icon_factory.set( &defaultFac );
944}
945
946#endif // QT_NO_ICONSET
Note: See TracBrowser for help on using the repository browser.