File indexing completed on 2024-05-19 05:35:21

0001 //////////////////////////////////////////////////////////////////////////////
0002 // oxygenscrollbardata.cpp
0003 // data container for QTabBar animations
0004 // -------------------
0005 //
0006 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0007 //
0008 // SPDX-License-Identifier: MIT
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #include "oxygenscrollbardata.h"
0012 
0013 #include <QHoverEvent>
0014 #include <QScrollBar>
0015 #include <QStyleOptionSlider>
0016 
0017 Q_GUI_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *);
0018 
0019 namespace Oxygen
0020 {
0021 //______________________________________________
0022 ScrollBarData::ScrollBarData(QObject *parent, QWidget *target, int duration)
0023     : WidgetStateData(parent, target, duration)
0024     , _position(-1, -1)
0025 {
0026     target->installEventFilter(this);
0027 
0028     _addLineData._animation = new Animation(duration, this);
0029     _subLineData._animation = new Animation(duration, this);
0030 
0031     connect(addLineAnimation().data(), SIGNAL(finished()), SLOT(clearAddLineRect()));
0032     connect(subLineAnimation().data(), SIGNAL(finished()), SLOT(clearSubLineRect()));
0033 
0034     // setup animation
0035     setupAnimation(addLineAnimation(), "addLineOpacity");
0036     setupAnimation(subLineAnimation(), "subLineOpacity");
0037 }
0038 
0039 //______________________________________________
0040 bool ScrollBarData::eventFilter(QObject *object, QEvent *event)
0041 {
0042     if (object != target().data()) {
0043         return WidgetStateData::eventFilter(object, event);
0044     }
0045 
0046     // check event type
0047     switch (event->type()) {
0048     case QEvent::HoverEnter:
0049     case QEvent::HoverMove:
0050         hoverMoveEvent(object, event);
0051         break;
0052 
0053     case QEvent::HoverLeave:
0054         hoverLeaveEvent(object, event);
0055         break;
0056 
0057     default:
0058         break;
0059     }
0060 
0061     return WidgetStateData::eventFilter(object, event);
0062 }
0063 
0064 //______________________________________________
0065 const Animation::Pointer &ScrollBarData::animation(QStyle::SubControl subcontrol) const
0066 {
0067     switch (subcontrol) {
0068     default:
0069     case QStyle::SC_ScrollBarSlider:
0070         return animation();
0071 
0072     case QStyle::SC_ScrollBarAddLine:
0073         return addLineAnimation();
0074 
0075     case QStyle::SC_ScrollBarSubLine:
0076         return subLineAnimation();
0077     }
0078 }
0079 
0080 //______________________________________________
0081 qreal ScrollBarData::opacity(QStyle::SubControl subcontrol) const
0082 {
0083     switch (subcontrol) {
0084     default:
0085     case QStyle::SC_ScrollBarSlider:
0086         return opacity();
0087 
0088     case QStyle::SC_ScrollBarAddLine:
0089         return addLineOpacity();
0090 
0091     case QStyle::SC_ScrollBarSubLine:
0092         return subLineOpacity();
0093     }
0094 }
0095 
0096 //______________________________________________
0097 void ScrollBarData::hoverMoveEvent(QObject *object, QEvent *event)
0098 {
0099     // try cast object to scrollbar
0100     QScrollBar *scrollBar(qobject_cast<QScrollBar *>(object));
0101     if (!scrollBar || scrollBar->isSliderDown())
0102         return;
0103 
0104     // retrieve scrollbar option
0105     QStyleOptionSlider opt(qt_qscrollbarStyleOption(qobject_cast<QScrollBar *>(object)));
0106 
0107     // cast event
0108     QHoverEvent *hoverEvent = static_cast<QHoverEvent *>(event);
0109     QStyle::SubControl hoverControl = scrollBar->style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, hoverEvent->pos(), scrollBar);
0110 
0111     // update hover state
0112     updateAddLineArrow(hoverControl);
0113     updateSubLineArrow(hoverControl);
0114 
0115     // store position
0116     _position = hoverEvent->pos();
0117 }
0118 
0119 //______________________________________________
0120 void ScrollBarData::hoverLeaveEvent(QObject *object, QEvent *event)
0121 {
0122     Q_UNUSED(object);
0123     Q_UNUSED(event);
0124 
0125     // reset hover state
0126     updateSubLineArrow(QStyle::SC_None);
0127     updateAddLineArrow(QStyle::SC_None);
0128 
0129     // reset mouse position
0130     _position = QPoint(-1, -1);
0131 }
0132 
0133 //_____________________________________________________________________
0134 void ScrollBarData::updateSubLineArrow(QStyle::SubControl hoverControl)
0135 {
0136     if (hoverControl == QStyle::SC_ScrollBarSubLine) {
0137         if (!subLineArrowHovered()) {
0138             setSubLineArrowHovered(true);
0139             if (enabled()) {
0140                 subLineAnimation().data()->setDirection(Animation::Forward);
0141                 if (!subLineAnimation().data()->isRunning())
0142                     subLineAnimation().data()->start();
0143             } else
0144                 setDirty();
0145         }
0146 
0147     } else {
0148         if (subLineArrowHovered()) {
0149             setSubLineArrowHovered(false);
0150             if (enabled()) {
0151                 subLineAnimation().data()->setDirection(Animation::Backward);
0152                 if (!subLineAnimation().data()->isRunning())
0153                     subLineAnimation().data()->start();
0154             } else
0155                 setDirty();
0156         }
0157     }
0158 }
0159 
0160 //_____________________________________________________________________
0161 void ScrollBarData::updateAddLineArrow(QStyle::SubControl hoverControl)
0162 {
0163     if (hoverControl == QStyle::SC_ScrollBarAddLine) {
0164         if (!addLineArrowHovered()) {
0165             setAddLineArrowHovered(true);
0166             if (enabled()) {
0167                 addLineAnimation().data()->setDirection(Animation::Forward);
0168                 if (!addLineAnimation().data()->isRunning())
0169                     addLineAnimation().data()->start();
0170             } else
0171                 setDirty();
0172         }
0173 
0174     } else {
0175         if (addLineArrowHovered()) {
0176             setAddLineArrowHovered(false);
0177             if (enabled()) {
0178                 addLineAnimation().data()->setDirection(Animation::Backward);
0179                 if (!addLineAnimation().data()->isRunning())
0180                     addLineAnimation().data()->start();
0181             } else
0182                 setDirty();
0183         }
0184     }
0185 }
0186 }