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);
196 qreal ToolButton::animationUpdate()
const 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> Q_INVOKABLE QString imagePath(const QString &name) const
Retrieve the path for an SVG image in the current theme.
the text color to be used by items resting on the background
Provides an SVG with borders.
Namespace for everything in libplasma.
QScriptValue animation(const QString &anim)
static Theme * defaultTheme()
Singleton pattern accessor.