144 there is no need to handle theme and layout direction changes for this icon. |
144 there is no need to handle theme and layout direction changes for this icon. |
145 This is merely an optimization flag and must be set directly after creating the |
145 This is merely an optimization flag and must be set directly after creating the |
146 HbIcon instance (before the first paint of the icon) to have any performance |
146 HbIcon instance (before the first paint of the icon) to have any performance |
147 benefits. |
147 benefits. |
148 |
148 |
|
149 \b KeepDefaultQIconSize \b (0x20) This flag disables all scaling for icons constructed |
|
150 from QIcon. It has no effect on regular, native HbIcons. It only affects the |
|
151 painting: The size of the HbIcon will remain whatever was set via setSize(), but |
|
152 only a part of that area will be painted. This is similar to |
|
153 HbIconItem::setIconScaling(false) but in that case the underlying icon's size |
|
154 would also be changed to match the default size, while here size() remains |
|
155 unaffected. |
|
156 |
149 */ |
157 */ |
150 |
158 |
151 /*! |
159 /*! |
152 \enum HbIcon::MirroringMode |
160 \enum HbIcon::MirroringMode |
153 |
161 |
181 \internal |
189 \internal |
182 */ |
190 */ |
183 HbIconPrivate::HbIconPrivate() : |
191 HbIconPrivate::HbIconPrivate() : |
184 engine(new HbIconEngine(QString())), |
192 engine(new HbIconEngine(QString())), |
185 qicon(engine), |
193 qicon(engine), |
186 badgeInfo(0) |
194 badgeInfo(0), |
|
195 mQIconFlags(0), |
|
196 mQIconPixmapMode(QIcon::Normal), |
|
197 mQIconPixmapState(QIcon::Off) |
187 { |
198 { |
188 ref.ref(); // Need to do extra ref so the shared null does not get destructed |
199 ref.ref(); // Need to do extra ref so the shared null does not get destructed |
189 } |
200 } |
190 |
201 |
191 /*! |
202 /*! |
192 \internal |
203 \internal |
193 */ |
204 */ |
194 HbIconPrivate::HbIconPrivate(const QIcon &qicon) : |
205 HbIconPrivate::HbIconPrivate(const QIcon &qicon) : |
195 engine(0), |
206 engine(0), |
196 qicon(qicon), |
207 qicon(qicon), |
197 badgeInfo(0) |
208 badgeInfo(0), |
|
209 mQIconFlags(0), |
|
210 mQIconPixmapMode(QIcon::Normal), |
|
211 mQIconPixmapState(QIcon::Off) |
198 { |
212 { |
199 } |
213 } |
200 |
214 |
201 /*! |
215 /*! |
202 \internal |
216 \internal |
203 */ |
217 */ |
204 HbIconPrivate::HbIconPrivate(const QString &iconName) : |
218 HbIconPrivate::HbIconPrivate(const QString &iconName) : |
205 engine(new HbIconEngine(iconName)), |
219 engine(new HbIconEngine(iconName)), |
206 qicon(engine), |
220 qicon(engine), |
207 badgeInfo(0) |
221 badgeInfo(0), |
|
222 mQIconFlags(0), |
|
223 mQIconPixmapMode(QIcon::Normal), |
|
224 mQIconPixmapState(QIcon::Off) |
208 { |
225 { |
209 } |
226 } |
210 |
227 |
211 /*! |
228 /*! |
212 \internal |
229 \internal |
214 HbIconPrivate::HbIconPrivate(const HbIconPrivate &other) : |
231 HbIconPrivate::HbIconPrivate(const HbIconPrivate &other) : |
215 QSharedData(other), |
232 QSharedData(other), |
216 size(other.size), |
233 size(other.size), |
217 engine(0), |
234 engine(0), |
218 qicon(), |
235 qicon(), |
219 badgeInfo(0) |
236 badgeInfo(0), |
|
237 mQIconFlags(other.mQIconFlags), |
|
238 mQIconPixmap(other.mQIconPixmap), |
|
239 mQIconPixmapMode(other.mQIconPixmapMode), |
|
240 mQIconPixmapState(other.mQIconPixmapState) |
220 { |
241 { |
221 if (other.engine) { |
242 if (other.engine) { |
222 engine = new HbIconEngine(*other.engine); |
243 engine = new HbIconEngine(*other.engine); |
223 // Have to instantiate a temporary QIcon because |
244 // Have to instantiate a temporary QIcon because |
224 // QIcon's copy constructor shares the engine. |
245 // QIcon's copy constructor shares the engine. |
390 d = shared_null; |
432 d = shared_null; |
391 } |
433 } |
392 |
434 |
393 /*! Constructs a new icon with the icon name \a iconName. |
435 /*! Constructs a new icon with the icon name \a iconName. |
394 */ |
436 */ |
395 HbIcon::HbIcon(const QString &iconName) |
437 HbIcon::HbIcon(const QString &iconName) : d( new HbIconPrivate(iconName) ) |
396 { |
438 { |
397 d = new HbIconPrivate(iconName); |
439 } |
398 } |
440 |
399 |
441 /*! |
400 /*! Constructs a new icon to be a copy of the given QIcon. |
442 * Constructs a new icon to be a copy of the given QIcon. Due to the |
401 * Due to the limitations listed below, this constructor should be used only for |
443 * limitations listed below, this constructor should be used only for |
402 * compatibility reasons if a QIcon instance needs to be passed as a parameter |
444 * compatibility reasons if a QIcon instance needs to be passed as a parameter |
403 * to a method taking a HbIcon parameter. |
445 * to a method taking a HbIcon parameter. |
404 * \note If this constructor is used, there are the following limitations in the HbIcon methods. |
446 * |
405 * - HbIcon::defaultSize() may return QSizeF(). |
447 * \note If this constructor is used, the following limitations apply: |
406 * - HbIcon::paint() ignores the parameter aspectRatioMode and converts the given QRectF to QRect. |
448 * |
407 * - HbIcon::iconName() returns empty string by default. |
449 * - HbIcon::defaultSize() may return QSizeF(). |
408 * - HbIcon::pixmap() returns null pixmap. |
450 * - HbIcon::paint() ignores the parameter aspectRatioMode and converts the given QRectF to QRect. |
409 * - Colorization and mirroring support are not available. |
451 * - HbIcon::iconName() returns empty string by default. |
410 * This method should only be used if absolute necessary, as this is not ideal for hardware accelerated environment |
452 * - HbIcon::pixmap() returns null pixmap. |
411 * and there may be huge differences in painting performance when compared to a native HbIcon. |
453 * - Colorization and mirroring support are not available. |
412 */ |
454 * |
413 HbIcon::HbIcon(const QIcon &icon) |
455 * This method should only be used if absolute necessary, as this is not ideal |
414 { |
456 * for hardware accelerated environment and there may be huge differences in |
415 d = new HbIconPrivate(icon); |
457 * painting performance when compared to a native HbIcon. Some advanced resource |
|
458 * management features are not available for such icons either. |
|
459 */ |
|
460 HbIcon::HbIcon(const QIcon &icon) : d( new HbIconPrivate(icon) ) |
|
461 { |
416 } |
462 } |
417 |
463 |
418 /*! |
464 /*! |
419 * Copy constructs a new icon using the \a other icon. |
465 * Copy constructs a new icon using the \a other icon. |
420 * Copy-on-write semantics is used, so this only does a shallow copy. |
466 * Copy-on-write semantics is used, so this only does a shallow copy. |
516 * HbIcon::Colorized flag set. |
562 * HbIcon::Colorized flag set. |
517 * |
563 * |
518 * However it is possible to override this theme-specific color with a custom one |
564 * However it is possible to override this theme-specific color with a custom one |
519 * by calling this function. |
565 * by calling this function. |
520 * |
566 * |
521 * \warning Currently this method makes use of pixmap() routine in case of NVG icons. |
|
522 * pixmap() slows down the hardware accelerated rendering. |
|
523 * |
|
524 * \sa HbIcon::color(), HbIcon::Colorized |
567 * \sa HbIcon::color(), HbIcon::Colorized |
525 */ |
568 */ |
526 void HbIcon::setColor(const QColor &color) |
569 void HbIcon::setColor(const QColor &color) |
527 { |
570 { |
528 if (d->engine) { |
571 if (d->engine) { |
567 * \sa HbIcon::iconName() |
610 * \sa HbIcon::iconName() |
568 */ |
611 */ |
569 void HbIcon::setIconName(const QString &iconName) |
612 void HbIcon::setIconName(const QString &iconName) |
570 { |
613 { |
571 if (d->engine && d->engine->iconName() != iconName) { |
614 if (d->engine && d->engine->iconName() != iconName) { |
|
615 // Icon was normal HbIcon and the name is changed. |
572 d.detach(); |
616 d.detach(); |
573 d->engine->setIconName(iconName); |
617 d->engine->setIconName(iconName); |
574 } else { |
618 } else if (!d->engine) { |
575 // Icon was earlier copy constructed from QIcon, but now its name is set, |
619 // Icon was earlier copy constructed from QIcon, but now its name is set, |
576 // so it becomes a 'real' HbIcon. |
620 // so it becomes a 'real' HbIcon. |
577 d.detach(); |
621 d.detach(); |
578 d->engine = new HbIconEngine(iconName); |
622 d->engine = new HbIconEngine(iconName); |
579 d->engine->setSize(d->size); |
623 d->engine->setSize(d->size); |
580 // Have to instantiate a temporary QIcon because |
624 // Have to instantiate a temporary QIcon because |
581 // QIcon's assignment operator shares the engine. |
625 // QIcon's assignment operator shares the engine. |
582 QIcon temp(d->engine); |
626 QIcon temp(d->engine); |
583 d->qicon = temp; |
627 d->qicon = temp; |
584 } |
628 d->mQIconPixmap = QPixmap(); |
|
629 } |
|
630 // Otherwise icon was normal HbIcon and the name is same as before, so do nothing. |
585 } |
631 } |
586 |
632 |
587 /*! |
633 /*! |
588 * Returns the name of the icon in the specified \a mode and \a state. |
634 * Returns the name of the icon in the specified \a mode and \a state. |
589 * If there is no icon name set for the specified \a mode and \a state, |
635 * If there is no icon name set for the specified \a mode and \a state, |
635 if (d->engine) { |
681 if (d->engine) { |
636 d->engine->paint(painter, rect, aspectRatioMode, alignment, mode, state); |
682 d->engine->paint(painter, rect, aspectRatioMode, alignment, mode, state); |
637 } else { |
683 } else { |
638 // This HbIcon was copy constructed from QIcon and |
684 // This HbIcon was copy constructed from QIcon and |
639 // we cannot use HbIconEngine for painting. |
685 // we cannot use HbIconEngine for painting. |
|
686 |
|
687 // Find out the size: It can be the size set via setSize(), or, in case of |
|
688 // KeepDefaultQIconSize, the first available size, or, if none are set, the |
|
689 // target area's size. |
640 QSizeF size = this->size(); |
690 QSizeF size = this->size(); |
641 if (!size.isValid()) { |
691 if (flags().testFlag(KeepDefaultQIconSize)) { |
642 // If size is not set, have to use rect size because QIcon |
692 QList<QSize> sizes = d->qicon.availableSizes(); |
643 // does not provide defaultSize information. |
693 if (!sizes.isEmpty()) { |
644 size = rect.size(); |
694 size = sizes.at(0); |
|
695 } |
|
696 } else { |
|
697 if (!size.isValid()) { |
|
698 size = rect.size(); |
|
699 } |
645 } |
700 } |
646 |
701 |
647 QPixmap pixmap = d->qicon.pixmap(size.toSize(), mode, state); |
702 // Get the pixmap with the needed size. |
|
703 QPixmap pixmap; |
|
704 QSize intSize = size.toSize(); |
|
705 bool usingCached = false; |
|
706 if (d->mQIconPixmap.size() == intSize |
|
707 && mode == d->mQIconPixmapMode |
|
708 && state == d->mQIconPixmapState) |
|
709 { |
|
710 pixmap = d->mQIconPixmap; |
|
711 usingCached = true; |
|
712 } else { |
|
713 pixmap = d->qicon.pixmap(intSize, mode, state); |
|
714 d->mQIconPixmap = pixmap; |
|
715 d->mQIconPixmapMode = mode; |
|
716 d->mQIconPixmapState = state; |
|
717 } |
648 QSizeF pixmapSize = pixmap.size(); |
718 QSizeF pixmapSize = pixmap.size(); |
649 |
719 |
650 // QIcon::pixmap() will not do upscaling. |
720 // QIcon::pixmap() will not do upscaling, do it here if needed. |
651 if (pixmapSize.width() < size.width() || pixmapSize.height() < size.height()) { |
721 if (!pixmap.isNull() && !usingCached && !flags().testFlag(KeepDefaultQIconSize) |
|
722 && (pixmapSize.width() < size.width() || pixmapSize.height() < size.height())) |
|
723 { |
652 // Native HbIcons are scaled using SmoothTransformation so use the same. |
724 // Native HbIcons are scaled using SmoothTransformation so use the same. |
653 pixmap = pixmap.scaled(size.toSize(), aspectRatioMode, Qt::SmoothTransformation); |
725 pixmap = pixmap.scaled(size.toSize(), aspectRatioMode, Qt::SmoothTransformation); |
654 pixmapSize = pixmap.size(); |
726 pixmapSize = pixmap.size(); |
655 } |
727 } |
656 |
728 |
657 // Adjust the alignment |
729 // Adjust the alignment. |
658 QPointF topLeft = rect.topLeft(); |
730 QPointF topLeft = rect.topLeft(); |
659 |
731 |
660 if (alignment & Qt::AlignRight) { |
732 if (alignment & Qt::AlignRight) { |
661 topLeft.setX(rect.right() - pixmapSize.width()); |
733 topLeft.setX(rect.right() - pixmapSize.width()); |
662 } else if (alignment & Qt::AlignHCenter) { |
734 } else if (alignment & Qt::AlignHCenter) { |
667 topLeft.setY(rect.bottom() - pixmapSize.height()); |
739 topLeft.setY(rect.bottom() - pixmapSize.height()); |
668 } else if (alignment & Qt::AlignVCenter) { |
740 } else if (alignment & Qt::AlignVCenter) { |
669 topLeft.setY(topLeft.y() + (rect.height() - pixmapSize.height()) / 2); |
741 topLeft.setY(topLeft.y() + (rect.height() - pixmapSize.height()) / 2); |
670 } |
742 } |
671 |
743 |
|
744 // Draw. |
672 painter->drawPixmap(topLeft, pixmap, pixmap.rect()); |
745 painter->drawPixmap(topLeft, pixmap, pixmap.rect()); |
673 |
746 |
674 // Draw the badges on this icon |
747 // Draw the badges on this icon. |
675 if (d->badgeInfo) { |
748 if (d->badgeInfo) { |
676 d->badgeInfo->paint(painter, rect, mode, state, false); |
749 d->badgeInfo->paint(painter, rect, mode, state, false); |
677 } |
750 } |
678 } |
751 } |
679 } |
752 } |
1000 |
1076 |
1001 /*! |
1077 /*! |
1002 Clears the icon data (e.g. QPixmaps that are stored internally) but does not |
1078 Clears the icon data (e.g. QPixmaps that are stored internally) but does not |
1003 touch the settings, e.g. the size, state, flags, unlike clear(). |
1079 touch the settings, e.g. the size, state, flags, unlike clear(). |
1004 |
1080 |
1005 The call is simply forwarded to the underlying HbIconEngine. This function |
|
1006 has no effect when the icon was constructed from a QIcon. |
|
1007 |
|
1008 \internal |
1081 \internal |
1009 */ |
1082 */ |
1010 void HbIconPrivate::clearStoredIconContent() |
1083 void HbIconPrivate::clearStoredIconContent() |
1011 { |
1084 { |
|
1085 // No need to detach here, usually the more icon's data we drop, the better. There are |
|
1086 // no visual results anyway, icon data is reloaded next time the icon is painted. |
1012 if (engine) { |
1087 if (engine) { |
1013 engine->clearStoredIconContent(); |
1088 engine->clearStoredIconContent(); |
1014 } |
1089 } |
1015 } |
1090 mQIconPixmap = QPixmap(); |
|
1091 } |