sync the IconWidget changes made in trunk to the branch; not critical for the RC, but needs to be in 4.2.0 final so that we have header continuity.

svn path=/branches/KDE/4.2/kdelibs/; revision=906900
This commit is contained in:
Aaron J. Seigo 2009-01-07 01:17:31 +00:00
parent eb686845cb
commit e4e0337c1a
3 changed files with 105 additions and 103 deletions

View File

@ -49,6 +49,13 @@
#include "animator.h" #include "animator.h"
#include "svg.h" #include "svg.h"
/*
TODO:
Add these to a UrlIcon class
void setUrl(const KUrl& url);
KUrl url() const;
*/
namespace Plasma namespace Plasma
{ {
@ -56,9 +63,9 @@ IconWidgetPrivate::IconWidgetPrivate(IconWidget *i)
: q(i), : q(i),
iconSvg(0), iconSvg(0),
iconSvgElementChanged(false), iconSvgElementChanged(false),
m_fadeIn(false), fadeIn(false),
m_hoverAnimId(-1), hoverAnimId(-1),
m_hoverAlpha(20 / 255), hoverAlpha(20 / 255),
iconSize(48, 48), iconSize(48, 48),
states(IconWidgetPrivate::NoState), states(IconWidgetPrivate::NoState),
orientation(Qt::Vertical), orientation(Qt::Vertical),
@ -75,11 +82,10 @@ IconWidgetPrivate::~IconWidgetPrivate()
qDeleteAll(cornerActions); qDeleteAll(cornerActions);
} }
void IconWidget::readColors() void IconWidgetPrivate::readColors()
{ {
d->textColor = Plasma::Theme::defaultTheme()->color(Theme::TextColor); textColor = Plasma::Theme::defaultTheme()->color(Theme::TextColor);
d->shadowColor = Plasma::Theme::defaultTheme()->color(Theme::BackgroundColor); shadowColor = Plasma::Theme::defaultTheme()->color(Theme::BackgroundColor);
} }
IconAction::IconAction(IconWidget *icon, QAction *action) IconAction::IconAction(IconWidget *icon, QAction *action)
@ -262,14 +268,14 @@ IconWidget::IconWidget(QGraphicsItem *parent)
: QGraphicsWidget(parent), : QGraphicsWidget(parent),
d(new IconWidgetPrivate(this)) d(new IconWidgetPrivate(this))
{ {
init(); d->init();
} }
IconWidget::IconWidget(const QString &text, QGraphicsItem *parent) IconWidget::IconWidget(const QString &text, QGraphicsItem *parent)
: QGraphicsWidget(parent), : QGraphicsWidget(parent),
d(new IconWidgetPrivate(this)) d(new IconWidgetPrivate(this))
{ {
init(); d->init();
setText(text); setText(text);
} }
@ -277,7 +283,7 @@ IconWidget::IconWidget(const QIcon &icon, const QString &text, QGraphicsItem *pa
: QGraphicsWidget(parent), : QGraphicsWidget(parent),
d(new IconWidgetPrivate(this)) d(new IconWidgetPrivate(this))
{ {
init(); d->init();
setText(text); setText(text);
setIcon(icon); setIcon(icon);
} }
@ -287,27 +293,27 @@ IconWidget::~IconWidget()
delete d; delete d;
} }
void IconWidget::init() void IconWidgetPrivate::init()
{ {
readColors(); readColors();
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(readColors())); QObject::connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), q, SLOT(readColors()));
connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), SLOT(readColors())); QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), q, SLOT(readColors()));
// setAcceptedMouseButtons(Qt::LeftButton); // setAcceptedMouseButtons(Qt::LeftButton);
setAcceptsHoverEvents(true); q->setAcceptsHoverEvents(true);
// Margins for horizontal mode (list views, tree views, table views) // Margins for horizontal mode (list views, tree views, table views)
d->setHorizontalMargin(IconWidgetPrivate::TextMargin, 1, 1); setHorizontalMargin(IconWidgetPrivate::TextMargin, 1, 1);
d->setHorizontalMargin(IconWidgetPrivate::IconMargin, 1, 1); setHorizontalMargin(IconWidgetPrivate::IconMargin, 1, 1);
d->setHorizontalMargin(IconWidgetPrivate::ItemMargin, 0, 0); setHorizontalMargin(IconWidgetPrivate::ItemMargin, 0, 0);
// Margins for vertical mode (icon views) // Margins for vertical mode (icon views)
d->setVerticalMargin(IconWidgetPrivate::TextMargin, 6, 2); setVerticalMargin(IconWidgetPrivate::TextMargin, 6, 2);
d->setVerticalMargin(IconWidgetPrivate::IconMargin, 1, 1); setVerticalMargin(IconWidgetPrivate::IconMargin, 1, 1);
d->setVerticalMargin(IconWidgetPrivate::ItemMargin, 0, 0); setVerticalMargin(IconWidgetPrivate::ItemMargin, 0, 0);
d->setActiveMargins(); setActiveMargins();
d->currentSize = QSizeF(-1, -1); currentSize = QSizeF(-1, -1);
} }
void IconWidget::addIconAction(QAction *action) void IconWidget::addIconAction(QAction *action)
@ -346,18 +352,18 @@ QAction *IconWidget::action() const
return d->action; return d->action;
} }
void IconWidget::actionDestroyed(QObject *action) void IconWidgetPrivate::actionDestroyed(QObject *action)
{ {
QList<IconAction*>::iterator it = d->cornerActions.begin(); QList<IconAction*>::iterator it = cornerActions.begin();
while (it != d->cornerActions.end()) { while (it != cornerActions.end()) {
if ((*it)->action() == action) { if ((*it)->action() == action) {
d->cornerActions.erase(it); cornerActions.erase(it);
break; break;
} }
} }
update(); // redraw since an action has been deleted. q->update(); // redraw since an action has been deleted.
} }
int IconWidget::numDisplayLines() int IconWidget::numDisplayLines()
@ -411,6 +417,7 @@ QSizeF IconWidgetPrivate::displaySizeHint(const QStyleOptionGraphicsItem *option
if (text.isEmpty() && infoText.isEmpty()) { if (text.isEmpty() && infoText.isEmpty()) {
return QSizeF(.0, .0); return QSizeF(.0, .0);
} }
QString label = text; QString label = text;
// const qreal maxWidth = (orientation == Qt::Vertical) ? iconSize.width() + 10 : 32757; // const qreal maxWidth = (orientation == Qt::Vertical) ? iconSize.width() + 10 : 32757;
// NOTE: find a way to use the other layoutText, it currently returns nominal width, when // NOTE: find a way to use the other layoutText, it currently returns nominal width, when
@ -437,64 +444,64 @@ QSizeF IconWidgetPrivate::displaySizeHint(const QStyleOptionGraphicsItem *option
return addMargin(size, TextMargin); return addMargin(size, TextMargin);
} }
void IconWidget::layoutIcons(const QStyleOptionGraphicsItem *option) void IconWidgetPrivate::layoutIcons(const QStyleOptionGraphicsItem *option)
{ {
if (size() == d->currentSize) { if (q->size() == currentSize) {
return; return;
} }
d->currentSize = size(); currentSize = q->size();
d->setActiveMargins(); setActiveMargins();
//calculate icon size based on the available space //calculate icon size based on the available space
qreal iconWidth; qreal iconWidth;
if (d->orientation == Qt::Vertical) { if (orientation == Qt::Vertical) {
qreal heightAvail; qreal heightAvail;
//if there is text resize the icon in order to make room for the text //if there is text resize the icon in order to make room for the text
if (d->text.isEmpty() && d->infoText.isEmpty()) { if (text.isEmpty() && infoText.isEmpty()) {
heightAvail = d->currentSize.height(); heightAvail = currentSize.height();
} else { } else {
heightAvail = d->currentSize.height() - heightAvail = currentSize.height() -
d->displaySizeHint(option, d->currentSize.width()).height() - displaySizeHint(option, currentSize.width()).height() -
d->verticalMargin[IconWidgetPrivate::TextMargin].top - verticalMargin[IconWidgetPrivate::TextMargin].top -
d->verticalMargin[IconWidgetPrivate::TextMargin].bottom; verticalMargin[IconWidgetPrivate::TextMargin].bottom;
//never make a label higher than half the total height //never make a label higher than half the total height
heightAvail = qMax(heightAvail, d->currentSize.height() / 2); heightAvail = qMax(heightAvail, currentSize.height() / 2);
} }
//aspect ratio very "tall" //aspect ratio very "tall"
if (d->currentSize.width() < heightAvail) { if (currentSize.width() < heightAvail) {
iconWidth = d->currentSize.width() - iconWidth = currentSize.width() -
d->horizontalMargin[IconWidgetPrivate::IconMargin].left - horizontalMargin[IconWidgetPrivate::IconMargin].left -
d->horizontalMargin[IconWidgetPrivate::IconMargin].right; horizontalMargin[IconWidgetPrivate::IconMargin].right;
} else { } else {
iconWidth = heightAvail - iconWidth = heightAvail -
d->verticalMargin[IconWidgetPrivate::IconMargin].top - verticalMargin[IconWidgetPrivate::IconMargin].top -
d->verticalMargin[IconWidgetPrivate::IconMargin].bottom; verticalMargin[IconWidgetPrivate::IconMargin].bottom;
} }
} else { } else {
//Horizontal layout //Horizontal layout
QFontMetricsF fm(font()); QFontMetricsF fm(q->font());
//if there is text resize the icon in order to make room for the text //if there is text resize the icon in order to make room for the text
if (d->text.isEmpty() && d->infoText.isEmpty()) { if (text.isEmpty() && infoText.isEmpty()) {
// with no text, we just take up the whole geometry // with no text, we just take up the whole geometry
iconWidth = d->currentSize.height() - iconWidth = currentSize.height() -
d->horizontalMargin[IconWidgetPrivate::IconMargin].left - horizontalMargin[IconWidgetPrivate::IconMargin].left -
d->horizontalMargin[IconWidgetPrivate::IconMargin].right; horizontalMargin[IconWidgetPrivate::IconMargin].right;
} else { } else {
iconWidth = d->currentSize.height() - iconWidth = currentSize.height() -
d->verticalMargin[IconWidgetPrivate::IconMargin].top - verticalMargin[IconWidgetPrivate::IconMargin].top -
d->verticalMargin[IconWidgetPrivate::IconMargin].bottom; verticalMargin[IconWidgetPrivate::IconMargin].bottom;
} }
} }
d->iconSize = QSizeF(iconWidth, iconWidth); iconSize = QSizeF(iconWidth, iconWidth);
int count = 0; int count = 0;
foreach (IconAction *iconAction, d->cornerActions) { foreach (IconAction *iconAction, cornerActions) {
iconAction->setRect(d->actionRect((IconWidgetPrivate::ActionPosition)count)); iconAction->setRect(actionRect((IconWidgetPrivate::ActionPosition)count));
++count; ++count;
} }
} }
@ -513,42 +520,43 @@ void IconWidget::setSvg(const QString &svgFilePath, const QString &elementId)
update(); update();
} }
void IconWidget::hoverEffect(bool show) void IconWidgetPrivate::hoverEffect(bool show)
{ {
if (show) { if (show) {
d->states |= IconWidgetPrivate::HoverState; states |= IconWidgetPrivate::HoverState;
} }
d->m_fadeIn = show; fadeIn = show;
const int FadeInDuration = 150; const int FadeInDuration = 150;
if (d->m_hoverAnimId != -1) { if (hoverAnimId != -1) {
Animator::self()->stopCustomAnimation(d->m_hoverAnimId); Animator::self()->stopCustomAnimation(hoverAnimId);
} }
d->m_hoverAnimId = Animator::self()->customAnimation(
hoverAnimId = Animator::self()->customAnimation(
40 / (1000 / FadeInDuration), FadeInDuration, 40 / (1000 / FadeInDuration), FadeInDuration,
Animator::EaseOutCurve, this, "hoverAnimationUpdate"); Animator::EaseOutCurve, q, "hoverAnimationUpdate");
} }
void IconWidget::hoverAnimationUpdate(qreal progress) void IconWidgetPrivate::hoverAnimationUpdate(qreal progress)
{ {
if (d->m_fadeIn) { if (fadeIn) {
d->m_hoverAlpha = progress; hoverAlpha = progress;
} else { } else {
// If we mouse leaves before the fade in is done, fade out from where we were, // If we mouse leaves before the fade in is done, fade out from where we were,
// not from fully faded in // not from fully faded in
d->m_hoverAlpha = qMin(1 - progress, d->m_hoverAlpha); hoverAlpha = qMin(1 - progress, hoverAlpha);
} }
if (qFuzzyCompare(qreal(1.0), progress)) { if (qFuzzyCompare(qreal(1.0), progress)) {
d->m_hoverAnimId = -1; hoverAnimId = -1;
if (!d->m_fadeIn) { if (!fadeIn) {
d->states &= ~IconWidgetPrivate::HoverState; states &= ~IconWidgetPrivate::HoverState;
} }
} }
update(); q->update();
} }
void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state) void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state)
@ -566,23 +574,23 @@ void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state)
shadow.setHsv( shadow.setHsv(
shadow.hue(), shadow.hue(),
shadow.saturation(), shadow.saturation(),
shadow.value() + (int)(darkShadow ? 50 * m_hoverAlpha: -50 * m_hoverAlpha), shadow.value() + (int)(darkShadow ? 50 * hoverAlpha: -50 * hoverAlpha),
200 + (int)m_hoverAlpha * 55); // opacity 200 + (int)hoverAlpha * 55); // opacity
break; break;
case IconWidgetPrivate::PressedState: case IconWidgetPrivate::PressedState:
shadow.setHsv( shadow.setHsv(
shadow.hue(), shadow.hue(),
shadow.saturation(), shadow.saturation(),
shadow.value() + (darkShadow ? shadow.value() + (darkShadow ?
(int)(50 * m_hoverAlpha) : (int)(-50 * m_hoverAlpha)), (int)(50 * hoverAlpha) : (int)(-50 * hoverAlpha)),
204); //80% opacity 204); //80% opacity
break; break;
default: default:
break; break;
} }
border.setAlphaF(0.3 * m_hoverAlpha); border.setAlphaF(0.3 * hoverAlpha);
shadow.setAlphaF(0.6 * m_hoverAlpha); shadow.setAlphaF(0.6 * hoverAlpha);
painter->save(); painter->save();
painter->translate(0.5, 0.5); painter->translate(0.5, 0.5);
@ -630,13 +638,13 @@ QPixmap IconWidgetPrivate::decoration(const QStyleOptionGraphicsItem *option, bo
// We're assuming that the icon group is desktop/filemanager, since this // We're assuming that the icon group is desktop/filemanager, since this
// is KFileItemDelegate. // is KFileItemDelegate.
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) { if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
if (qFuzzyCompare(qreal(1.0), m_hoverAlpha)) { if (qFuzzyCompare(qreal(1.0), hoverAlpha)) {
result = effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState); result = effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState);
} else { } else {
result = PaintUtils::transition( result = PaintUtils::transition(
result, result,
effect->apply(result, KIconLoader::Desktop, effect->apply(result, KIconLoader::Desktop,
KIconLoader::ActiveState), m_hoverAlpha); KIconLoader::ActiveState), hoverAlpha);
} }
} }
} }
@ -898,7 +906,7 @@ void IconWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
Q_UNUSED(widget); Q_UNUSED(widget);
//Lay out the main icon and action icons //Lay out the main icon and action icons
layoutIcons(option); d->layoutIcons(option);
// Compute the metrics, and lay out the text items // Compute the metrics, and lay out the text items
// ======================================================================== // ========================================================================
@ -987,7 +995,7 @@ void IconWidget::setText(const QString &text)
//try to relayout, needed if an icon was never shown before //try to relayout, needed if an icon was never shown before
if (!isVisible()) { if (!isVisible()) {
QStyleOptionGraphicsItem styleoption; QStyleOptionGraphicsItem styleoption;
layoutIcons(&styleoption); d->layoutIcons(&styleoption);
} }
resize(sizeFromIconSize(d->iconSize.width())); resize(sizeFromIconSize(d->iconSize.width()));
} }
@ -1004,7 +1012,7 @@ void IconWidget::setInfoText(const QString &text)
d->currentSize = QSizeF(-1, -1); d->currentSize = QSizeF(-1, -1);
//try to relayout, needed if an icon was never shown before //try to relayout, needed if an icon was never shown before
if (!isVisible()) { if (!isVisible()) {
layoutIcons(new QStyleOptionGraphicsItem); d->layoutIcons(new QStyleOptionGraphicsItem);
} }
resize(sizeFromIconSize(d->iconSize.width())); resize(sizeFromIconSize(d->iconSize.width()));
} }
@ -1139,7 +1147,8 @@ void IconWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
action->show(); action->show();
action->event(event->type(), event->pos()); action->event(event->type(), event->pos());
} }
hoverEffect(true);
d->hoverEffect(true);
update(); update();
QGraphicsWidget::hoverEnterEvent(event); QGraphicsWidget::hoverEnterEvent(event);
@ -1152,7 +1161,7 @@ void IconWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
action->event(event->type(), event->pos()); action->event(event->type(), event->pos());
} }
// d->states &= ~IconWidgetPrivate::HoverState; // Will be set once progress is zero again ... // d->states &= ~IconWidgetPrivate::HoverState; // Will be set once progress is zero again ...
hoverEffect(false); d->hoverEffect(false);
update(); update();
QGraphicsWidget::hoverLeaveEvent(event); QGraphicsWidget::hoverLeaveEvent(event);

View File

@ -280,27 +280,14 @@ private:
Q_PRIVATE_SLOT(d, void syncToAction()) Q_PRIVATE_SLOT(d, void syncToAction())
Q_PRIVATE_SLOT(d, void clearAction()) Q_PRIVATE_SLOT(d, void clearAction())
Q_PRIVATE_SLOT(d, void svgChanged()) Q_PRIVATE_SLOT(d, void svgChanged())
void init(); Q_PRIVATE_SLOT(d, void actionDestroyed(QObject *obj))
void layoutIcons(const QStyleOptionGraphicsItem *option); Q_PRIVATE_SLOT(d, void readColors())
void hoverEffect(bool); Q_PRIVATE_SLOT(d, void hoverAnimationUpdate(qreal progress))
IconWidgetPrivate * const d; IconWidgetPrivate * const d;
friend class IconWidgetPrivate; friend class IconWidgetPrivate;
private Q_SLOTS:
void actionDestroyed(QObject *obj);
void readColors();
void hoverAnimationUpdate(qreal progress);
}; };
} // namespace Plasma } // namespace Plasma
/*
// Add these to UrlIcon
void setUrl(const KUrl& url);
KUrl url() const;
*/
#endif #endif

View File

@ -105,7 +105,6 @@ public:
}; };
Q_DECLARE_FLAGS(IconWidgetStates, IconWidgetState) Q_DECLARE_FLAGS(IconWidgetStates, IconWidgetState)
public:
IconWidgetPrivate(IconWidget *i); IconWidgetPrivate(IconWidget *i);
~IconWidgetPrivate(); ~IconWidgetPrivate();
@ -178,6 +177,13 @@ public:
void clearAction(); void clearAction();
void svgChanged(); void svgChanged();
void actionDestroyed(QObject *obj);
void readColors();
void hoverAnimationUpdate(qreal progress);
void init();
void layoutIcons(const QStyleOptionGraphicsItem *option);
void hoverEffect(bool);
IconWidget *q; IconWidget *q;
QString text; QString text;
QString infoText; QString infoText;
@ -187,9 +193,9 @@ public:
QPixmap iconSvgPixmap; QPixmap iconSvgPixmap;
QColor textColor; QColor textColor;
QColor shadowColor; QColor shadowColor;
bool m_fadeIn; bool fadeIn;
int m_hoverAnimId; int hoverAnimId;
qreal m_hoverAlpha; qreal hoverAlpha;
QSizeF iconSize; QSizeF iconSize;
QIcon icon; QIcon icon;
IconWidgetStates states; IconWidgetStates states;