24 #include <QPropertyAnimation>
25 #include <QStyleOptionGraphicsItem>
26 #include <QToolButton>
28 #include <kcolorutils.h>
30 #include <kiconeffect.h>
31 #include <kmimetype.h>
36 #include "private/actionwidgetinterface_p.h"
37 #include "private/themedwidgetinterface_p.h"
43 class ToolButtonPrivate :
public ActionWidgetInterface<ToolButton>
46 ToolButtonPrivate(ToolButton *toolButton)
47 : ActionWidgetInterface<ToolButton>(toolButton),
61 if (imagePath.isEmpty()) {
67 KMimeType::Ptr mime = KMimeType::findByPath(absImagePath);
70 if (mime->is(
"image/svg+xml") || mime->is(
"image/svg+xml-compressed")) {
71 if (!svg || svg->imagePath() != absImagePath) {
74 svg->setImagePath(imagePath);
75 QObject::connect(svg, SIGNAL(repaintNeeded()), q, SLOT(setPixmap()));
76 if (!svgElement.isNull()) {
77 svg->setContainsMultipleImages(
true);
82 if (!svgElement.isNull() && svg->hasElement(svgElement)) {
83 QSizeF elementSize = svg->elementSize(svgElement);
84 float scale = pm.width() / qMax(elementSize.width(), elementSize.height());
86 svg->resize(svg->size() * scale);
87 pm = svg->pixmap(svgElement);
89 svg->resize(pm.size());
95 pm = QPixmap(absImagePath);
98 static_cast<QToolButton*
>(q->widget())->setIcon(KIcon(pm));
101 void syncActiveRect();
103 void animationUpdate(qreal progress);
105 FrameSvg *background;
111 QString absImagePath;
117 void ToolButtonPrivate::syncActiveRect()
119 background->setElementPrefix(
"normal");
121 qreal left, top, right, bottom;
122 background->getMargins(left, top, right, bottom);
124 background->setElementPrefix(
"active");
125 qreal activeLeft, activeTop, activeRight, activeBottom;
126 background->getMargins(activeLeft, activeTop, activeRight, activeBottom);
128 activeRect = QRectF(QPointF(0, 0), q->size());
129 activeRect.adjust(left - activeLeft, top - activeTop,
130 -(right - activeRight), -(bottom - activeBottom));
132 background->setElementPrefix(
"normal");
135 void ToolButtonPrivate::syncBorders()
138 qreal left, top, right, bottom;
140 background->setElementPrefix(
"normal");
141 background->getMargins(left, top, right, bottom);
142 q->setContentsMargins(left, top, right, bottom);
148 void ToolButtonPrivate::animationUpdate(qreal progress)
158 d(new ToolButtonPrivate(this))
161 d->background->setImagePath(
"widgets/button");
162 d->background->setCacheAllRenderedFrames(
true);
163 d->background->setElementPrefix(
"normal");
165 QToolButton *native =
new QToolButton;
170 native->setWindowIcon(QIcon());
171 native->setAttribute(Qt::WA_NoSystemBackground);
172 native->setAutoRaise(
true);
175 setAcceptHoverEvents(
true);
176 connect(d->background, SIGNAL(repaintNeeded()), SLOT(syncBorders()));
178 d->animation =
new QPropertyAnimation(
this,
"animationUpdate");
179 d->animation->setStartValue(0);
180 d->animation->setEndValue(1);
191 void ToolButton::setAnimationUpdate(qreal progress)
193 d->animationUpdate(progress);
223 static_cast<QToolButton*
>(widget())->
setText(
text);
229 return static_cast<QToolButton*
>(widget())->
text();
234 if (d->imagePath == path) {
242 bool absolutePath = !path.isEmpty() &&
244 !QDir::isRelativePath(path)
246 (path[0] ==
'/' || path.startsWith(QLatin1String(
":/")))
251 d->absImagePath = path;
262 d->svgElement = elementid;
293 widget()->setStyleSheet(stylesheet);
298 return widget()->styleSheet();
303 return static_cast<QToolButton*
>(widget());
312 d->background->setElementPrefix(
"pressed");
313 d->background->resizeFrame(size());
314 d->background->setElementPrefix(
"focus");
315 d->background->resizeFrame(size());
319 d->background->setElementPrefix(
"active");
320 d->background->resizeFrame(d->activeRect.size());
322 d->background->setElementPrefix(
"normal");
323 d->background->resizeFrame(size());
326 QGraphicsProxyWidget::resizeEvent(event);
334 QGraphicsProxyWidget::paint(painter, option, widget);
340 QStyleOptionToolButton buttonOpt;
341 buttonOpt.initFrom(button);
342 buttonOpt.icon = button->icon();
343 buttonOpt.text = button->text();
344 buttonOpt.iconSize = button->iconSize();
345 buttonOpt.toolButtonStyle = button->toolButtonStyle();
347 bool animationState = (d->animation->state() == QAbstractAnimation::Running)? \
349 if (button->isEnabled() && (animationState || !button->autoRaise() || d->underMouse || (buttonOpt.state & QStyle::State_On) || button->isChecked() || button->isDown())) {
350 if (button->isDown() || (buttonOpt.state & QStyle::State_On) || button->isChecked()) {
351 d->background->setElementPrefix(
"pressed");
353 d->background->setElementPrefix(
"normal");
355 d->background->resizeFrame(size());
357 if (animationState) {
358 QPixmap buffer = d->background->framePixmap();
360 QPainter bufferPainter(&buffer);
361 bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
362 QColor alphaColor(Qt::black);
363 alphaColor.setAlphaF(qMin(qreal(0.95), d->opacity));
364 bufferPainter.fillRect(buffer.rect(), alphaColor);
367 painter->drawPixmap(QPoint(0,0), buffer);
371 d->background->paintFrame(painter);
379 buttonOpt.font = font();
381 painter->setFont(buttonOpt.font);
382 button->style()->drawControl(QStyle::CE_ToolButtonLabel, &buttonOpt, painter, button);
387 d->underMouse =
true;
392 const int FadeInDuration = 75;
394 if (d->animation->state() != QAbstractAnimation::Stopped) {
395 d->animation->stop();
397 d->animation->setDuration(FadeInDuration);
398 d->animation->setDirection(QAbstractAnimation::Forward);
399 d->animation->start();
401 d->background->setElementPrefix(
"active");
403 QGraphicsProxyWidget::hoverEnterEvent(event);
408 d->underMouse =
false;
413 const int FadeOutDuration = 150;
415 if (d->animation->state() != QAbstractAnimation::Stopped) {
416 d->animation->stop();
419 d->animation->setDuration(FadeOutDuration);
420 d->animation->setDirection(QAbstractAnimation::Backward);
421 d->animation->start();
423 d->background->setElementPrefix(
"active");
425 QGraphicsProxyWidget::hoverLeaveEvent(event);
430 d->changeEvent(event);
432 if (event->type() == QEvent::EnabledChange && !isEnabled()) {
433 d->underMouse =
false;
436 QGraphicsProxyWidget::changeEvent(event);
443 if (change == ItemVisibleHasChanged){
444 d->underMouse =
false;
447 return QGraphicsProxyWidget::itemChange(change, value);
452 QSizeF hint = QGraphicsProxyWidget::sizeHint(which, constraint);
459 #include <toolbutton.moc>