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

0001 // krazy:excludeall=qclasses
0002 
0003 //////////////////////////////////////////////////////////////////////////////
0004 // oxygenheaderviewdata.cpp
0005 // data container for QHeaderView animations
0006 // -------------------
0007 //
0008 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0009 //
0010 // SPDX-License-Identifier: MIT
0011 //////////////////////////////////////////////////////////////////////////////
0012 
0013 #include "oxygenheaderviewdata.h"
0014 
0015 #include <QHoverEvent>
0016 #include <QTextStream>
0017 
0018 namespace Oxygen
0019 {
0020 //______________________________________________
0021 HeaderViewData::HeaderViewData(QObject *parent, QWidget *target, int duration)
0022     : AnimationData(parent, target)
0023 {
0024     _current._animation = new Animation(duration, this);
0025     setupAnimation(currentIndexAnimation(), "currentOpacity");
0026     currentIndexAnimation().data()->setDirection(Animation::Forward);
0027 
0028     _previous._animation = new Animation(duration, this);
0029     setupAnimation(previousIndexAnimation(), "previousOpacity");
0030     previousIndexAnimation().data()->setDirection(Animation::Backward);
0031 }
0032 
0033 //______________________________________________
0034 bool HeaderViewData::updateState(const QPoint &position, bool hovered)
0035 {
0036     if (!enabled())
0037         return false;
0038 
0039     const QHeaderView *local(qobject_cast<const QHeaderView *>(target().data()));
0040     if (!local)
0041         return false;
0042 
0043     const int index(local->logicalIndexAt(position));
0044     if (index < 0)
0045         return false;
0046 
0047     if (hovered) {
0048         if (index != currentIndex()) {
0049             if (currentIndex() >= 0) {
0050                 setPreviousIndex(currentIndex());
0051                 setCurrentIndex(-1);
0052                 previousIndexAnimation().data()->restart();
0053             }
0054 
0055             setCurrentIndex(index);
0056 
0057             /*
0058             for now animation is only triggered when hovering the sorting section,
0059             since no hover effect is implemented for all other sections
0060             */
0061             if (index == local->sortIndicatorSection()) {
0062                 currentIndexAnimation().data()->restart();
0063             }
0064 
0065             return true;
0066 
0067         } else
0068             return false;
0069 
0070     } else if (index == currentIndex()) {
0071         setPreviousIndex(currentIndex());
0072         setCurrentIndex(-1);
0073         previousIndexAnimation().data()->restart();
0074         return true;
0075 
0076     } else
0077         return false;
0078 }
0079 
0080 //______________________________________________
0081 Animation::Pointer HeaderViewData::animation(const QPoint &position) const
0082 {
0083     if (!enabled())
0084         return Animation::Pointer();
0085 
0086     const QHeaderView *local(qobject_cast<const QHeaderView *>(target().data()));
0087     if (!local)
0088         return Animation::Pointer();
0089 
0090     int index(local->logicalIndexAt(position));
0091     if (index < 0)
0092         return Animation::Pointer();
0093     else if (index == currentIndex())
0094         return currentIndexAnimation();
0095     else if (index == previousIndex())
0096         return previousIndexAnimation();
0097     else
0098         return Animation::Pointer();
0099 }
0100 
0101 //______________________________________________
0102 qreal HeaderViewData::opacity(const QPoint &position) const
0103 {
0104     if (!enabled())
0105         return OpacityInvalid;
0106 
0107     const QHeaderView *local(qobject_cast<const QHeaderView *>(target().data()));
0108     if (!local)
0109         return OpacityInvalid;
0110 
0111     int index(local->logicalIndexAt(position));
0112     if (index < 0)
0113         return OpacityInvalid;
0114     else if (index == currentIndex())
0115         return currentOpacity();
0116     else if (index == previousIndex())
0117         return previousOpacity();
0118     else
0119         return OpacityInvalid;
0120 }
0121 
0122 //__________________________________________________________
0123 void HeaderViewData::setDirty(void) const
0124 {
0125     QHeaderView *header = qobject_cast<QHeaderView *>(target().data());
0126     if (!header)
0127         return;
0128 
0129     // get first and last index, sorted
0130     const int lastIndex(qMax(previousIndex(), currentIndex()));
0131     if (lastIndex < 0)
0132         return;
0133 
0134     int firstIndex(qMin(previousIndex(), currentIndex()));
0135     if (firstIndex < 0)
0136         firstIndex = lastIndex;
0137 
0138     // find relevant rectangle to be updated, in viewport coordinate
0139     QWidget *viewport(header->viewport());
0140     const int left = header->sectionViewportPosition(firstIndex);
0141     const int right = header->sectionViewportPosition(lastIndex) + header->sectionSize(lastIndex);
0142 
0143     // trigger update
0144     if (header->orientation() == Qt::Horizontal)
0145         viewport->update(left, 0, right - left, header->height());
0146     else
0147         viewport->update(0, left, header->width(), right - left);
0148 }
0149 }