29 #include <KGlobalSettings>
31 #include <QApplication>
33 #include <QDesktopWidget>
34 #include <QMouseEvent>
54 class FloatingToolBarPrivate
60 , offsetPlaceHolder(
new QWidget(qq))
74 QPoint getInnerPoint()
const;
75 QPoint getOuterPoint()
const;
84 QTimer *autoHideTimer;
85 QPoint currentPosition;
94 QPixmap backgroundPixmap;
98 :
QToolBar(parent), d(new FloatingToolBarPrivate(this))
101 addWidget(d->offsetPlaceHolder);
103 setMouseTracking(
true);
105 d->anchorWidget = anchorWidget;
107 d->animTimer =
new QTimer(
this);
108 connect(d->animTimer, SIGNAL(timeout()),
this, SLOT(animate()));
110 d->autoHideTimer =
new QTimer(
this);
111 connect(d->autoHideTimer, SIGNAL(timeout()),
this, SLOT(hide()));
114 d->anchorWidget->installEventFilter(
this);
124 QToolBar::addAction(action);
134 d->anchorSide = side;
145 d->autoHideTimer->stop();
161 d->animTimer->start(20);
170 if (d->animState ==
Hiding)
176 d->endPosition = d->getOuterPoint();
179 d->animTimer->start(20);
182 void FloatingToolBar::hide()
189 switch (d->anchorSide) {
204 d->endPosition = d->getOuterPoint() + diff;
207 d->animTimer->start(20);
213 if (obj == d->anchorWidget && e->type() == QEvent::Resize) {
215 d->queuedShow =
false;
221 d->animTimer->stop();
222 if ((d->animState ==
Hiding || !d->visible) && d->toDelete)
228 return QToolBar::eventFilter(obj, e);
233 QToolBar::paintEvent(e);
237 p.setOpacity(d->opacity);
238 p.drawImage(e->rect().topLeft(), d->backgroundPixmap.toImage(), e->rect());
243 if (e->button() == Qt::LeftButton)
244 setCursor(Qt::SizeAllCursor);
246 QToolBar::mousePressEvent(e);
257 if ((QApplication::mouseButtons() & Qt::LeftButton) != Qt::LeftButton)
261 const QPoint parentPos = mapToParent(e->pos());
262 const float nX = (float)parentPos.x() / (float)d->anchorWidget->width();
263 const float nY = (float)parentPos.y() / (float)d->anchorWidget->height();
264 if (nX > 0.3 && nX < 0.7 && nY > 0.3 && nY < 0.7)
266 bool LT = nX < (1.0 - nY);
271 if (side == d->anchorSide)
274 d->anchorSide = side;
278 QToolBar::mouseMoveEvent(e);
284 d->autoHideTimer->stop();
288 QToolBar::enterEvent(e);
295 QToolBar::leaveEvent(e);
300 if (e->button() == Qt::LeftButton)
301 setCursor(Qt::ArrowCursor);
303 QToolBar::mouseReleaseEvent(e);
310 const qreal diff = e->delta() / 100.0 / 15.0;
312 if (((d->opacity <= 1) && (diff > 0)) || ((d->opacity >= 0) && (diff < 0)))
317 QToolBar::wheelEvent(e);
320 void FloatingToolBarPrivate::buildToolBar()
322 const bool prevUpdates = q->updatesEnabled();
323 q->setUpdatesEnabled(
false);
330 offsetPlaceHolder->setFixedSize(1, 7);
331 q->setOrientation(Qt::Vertical);
333 offsetPlaceHolder->setFixedSize(7, 1);
334 q->setOrientation(Qt::Horizontal);
338 const int myWidth = q->sizeHint().width() - 1;
339 const int myHeight = q->sizeHint().height() - 1;
342 QBitmap mask(myWidth + 1, myHeight + 1);
343 backgroundPixmap = QPixmap(myWidth + 1, myHeight + 1);
344 backgroundPixmap.fill(Qt::transparent);
346 q->resize(myWidth + 1, myHeight + 1);
349 QPainter maskPainter(&mask);
350 mask.fill(Qt::white);
351 maskPainter.setBrush(Qt::black);
353 maskPainter.drawRoundRect(topLeft ? -10 : 0, 0, myWidth + 10, myHeight, 2000 / (myWidth + 10), 2000 / myHeight);
355 maskPainter.drawRoundRect(0, topLeft ? -10 : 0, myWidth, myHeight + 10, 2000 / myWidth, 2000 / (myHeight + 10));
360 QPainter bufferPainter(&backgroundPixmap);
361 bufferPainter.translate(0.5, 0.5);
362 QPalette pal = q->palette();
364 QLinearGradient grad;
365 switch (anchorSide) {
367 grad = QLinearGradient(0, 1, myWidth + 1, 1);
370 grad = QLinearGradient(myWidth + 1, 1, 0, 1);
373 grad = QLinearGradient(1, 0, 1, myHeight + 1);
376 grad = QLinearGradient(1, myHeight + 1, 0, 1);
379 grad.setColorAt(0, pal.color(QPalette::Active, QPalette::Button));
380 grad.setColorAt(1, pal.color(QPalette::Active, QPalette::Light));
381 bufferPainter.setBrush(QBrush(grad));
383 bufferPainter.setPen( pal.color(QPalette::Active, QPalette::Dark).lighter(40));
384 bufferPainter.setRenderHints(QPainter::Antialiasing);
386 bufferPainter.drawRoundRect(topLeft ? -10 : 0, 0, myWidth + 10, myHeight, 2000 / (myWidth + 10), 2000 / myHeight);
388 bufferPainter.drawRoundRect(0, topLeft ? -10 : 0, myWidth, myHeight + 10, 2000 / myWidth, 2000 / (myHeight + 10));
390 bufferPainter.translate(-0.5, -0.5);
391 bufferPainter.setPen(pal.color(QPalette::Active, QPalette::Mid));
394 bufferPainter.drawLine(dx, 6, dx + myWidth - 8, 6);
395 bufferPainter.drawLine(dx, 9, dx + myWidth - 8, 9);
396 bufferPainter.setPen(pal.color(QPalette::Active, QPalette::Light));
397 bufferPainter.drawLine(dx + 1, 7, dx + myWidth - 7, 7);
398 bufferPainter.drawLine(dx + 1, 10, dx + myWidth - 7, 10);
401 bufferPainter.drawLine(6, dy, 6, dy + myHeight - 8);
402 bufferPainter.drawLine(9, dy, 9, dy + myHeight - 8);
403 bufferPainter.setPen(pal.color(QPalette::Active, QPalette::Light));
404 bufferPainter.drawLine(7, dy + 1, 7, dy + myHeight - 7);
405 bufferPainter.drawLine(10, dy + 1, 10, dy + myHeight - 7);
408 q->setUpdatesEnabled(prevUpdates);
411 void FloatingToolBarPrivate::reposition()
417 currentPosition = getOuterPoint();
418 endPosition = getInnerPoint();
420 currentPosition = getInnerPoint();
421 endPosition = getOuterPoint();
423 q->move(currentPosition);
426 QPoint FloatingToolBarPrivate::getInnerPoint()
const
430 return QPoint(0, (anchorWidget->height() - q->height()) / 2);
432 return QPoint((anchorWidget->width() - q->width()) / 2, 0);
434 return QPoint(anchorWidget->width() - q->width() +
toolBarRBMargin, (anchorWidget->height() - q->height()) / 2);
435 return QPoint((anchorWidget->width() - q->width()) / 2, anchorWidget->height() - q->height() +
toolBarRBMargin);
438 QPoint FloatingToolBarPrivate::getOuterPoint()
const
442 return QPoint(-q->width(), (anchorWidget->height() - q->height()) / 2);
444 return QPoint((anchorWidget->width() - q->width()) / 2, -q->height());
446 return QPoint(anchorWidget->width() +
toolBarRBMargin, (anchorWidget->height() - q->height()) / 2);
447 return QPoint((anchorWidget->width() - q->width()) / 2, anchorWidget->height() +
toolBarRBMargin);
450 void FloatingToolBar::animate()
452 if (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) {
454 int dX = d->endPosition.x() - d->currentPosition.x();
455 int dY = d->endPosition.y() - d->currentPosition.y();
456 dX = dX / 6 + qMax(-1, qMin(1, dX));
457 dY = dY / 6 + qMax(-1, qMin(1, dY));
458 d->currentPosition.setX(d->currentPosition.x() + dX);
459 d->currentPosition.setY(d->currentPosition.y() + dY);
461 d->currentPosition = d->endPosition;
464 move(d->currentPosition);
467 if (d->currentPosition == d->endPosition) {
468 d->animTimer->stop();
469 switch (d->animState) {
472 d->animState =
Still;
478 d->animState =
Still;
481 kDebug(5010) <<
"Illegal state";
486 #include "floatingtoolbar.moc"