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