File indexing completed on 2024-12-22 04:40:20

0001 /*
0002     smplayer, GUI front-end for mplayer.
0003     SPDX-FileCopyrightText: 2006-2008 Ricardo Villalba <rvm@escomposlinux.org>
0004 
0005     modified for inclusion in Subtitle Composer
0006     SPDX-FileCopyrightText: 2007-2009 Sergio Pistone <sergio_pistone@yahoo.com.ar>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "attachablewidget.h"
0012 
0013 #include <QEvent>
0014 #include <QTimerEvent>
0015 #include <QMouseEvent>
0016 
0017 #include <QDebug>
0018 
0019 AttachableWidget::AttachableWidget(AttachableWidget::Place place, unsigned animStepDuration) :
0020     // QWidget(0, Qt::Window | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint),
0021     QWidget(0),
0022     m_targetWidget(0),
0023     m_place(place),
0024     m_animStepDuration(animStepDuration),
0025     m_animHiding(true)
0026 {
0027 //  m_animStepDuration = 0;
0028 
0029     hide();
0030 
0031 //  QPalette palette;
0032 //  palette.setColor(backgroundRole(), Qt::red);
0033 //  setPalette(palette);
0034 
0035 //  setAttribute(Qt::WA_TranslucentBackground, false);
0036 }
0037 
0038 AttachableWidget::~AttachableWidget()
0039 {}
0040 
0041 bool
0042 AttachableWidget::isAttached() const
0043 {
0044     return m_targetWidget != 0;
0045 }
0046 
0047 bool
0048 AttachableWidget::isAnimated() const
0049 {
0050     return m_animStepDuration > 0;
0051 }
0052 
0053 int
0054 AttachableWidget::animStepDuration() const
0055 {
0056     return m_animStepDuration;
0057 }
0058 
0059 void
0060 AttachableWidget::setAnimStepDuration(int duration)
0061 {
0062     m_animStepDuration = duration;
0063 }
0064 
0065 void
0066 AttachableWidget::attach(QWidget *targetWidget)
0067 {
0068     if(m_targetWidget != targetWidget) {
0069         if(m_targetWidget) {
0070             qWarning() << "attach attempted but already attached to another widget";
0071             return;
0072         }
0073 
0074         setParent(targetWidget);
0075 
0076         m_targetWidget = targetWidget;
0077 
0078         m_targetWidget->installEventFilter(this);
0079 
0080         show();
0081     }
0082 }
0083 
0084 void
0085 AttachableWidget::dettach()
0086 {
0087     if(m_targetWidget) {
0088         m_targetWidget->removeEventFilter(this);
0089         m_targetWidget = 0;
0090 
0091         m_animHiding = true;    // reset the flag
0092 
0093         hide();
0094 
0095         setParent(0);
0096     } else
0097         qWarning() << "dettach attempted but not attached to any widget";
0098 }
0099 
0100 void
0101 AttachableWidget::timerEvent(QTimerEvent *event)
0102 {
0103     if(event->timerId() == m_animTID) {     // Advance animation
0104         if(m_animCurrentY == m_animFinalY) {
0105             killTimer(m_animTID);
0106             m_animTID = 0;
0107             if(m_animHiding)
0108                 hide();
0109         } else {
0110             if(m_animDirection == Upward)
0111                 m_animCurrentY--;
0112             else
0113                 m_animCurrentY++;
0114             move(x(), m_animCurrentY);
0115         }
0116     }
0117 }
0118 
0119 void
0120 AttachableWidget::toggleVisible(bool visible)
0121 {
0122     toggleVisible(visible, false);
0123 }
0124 
0125 void
0126 AttachableWidget::toggleVisible(bool visible, bool force)
0127 {
0128     if(!force && visible != m_animHiding)
0129         return;
0130 
0131     if(m_animTID) {
0132         killTimer(m_animTID);
0133         m_animTID = 0;
0134     }
0135 
0136     m_animHiding = !visible;
0137 
0138     resize(m_targetWidget->width(), height());
0139 
0140     QPoint targetPos = m_targetWidget->mapToGlobal(QPoint(0, 0));
0141 
0142     if(visible) {                                   // we have to show the widget
0143         m_animFinalY = m_place == Top ? targetPos.y() : targetPos.y() + m_targetWidget->height() - height();
0144         m_animCurrentY = m_place == Top ? m_animFinalY - height() : m_animFinalY + height();
0145         m_animDirection = m_place == Top ? Downward : Upward;
0146     } else {                                        // we have to hide the widget
0147         m_animFinalY = m_place == Top ? targetPos.y() - height() : targetPos.y() + m_targetWidget->height();
0148         m_animCurrentY = m_place == Top ? m_animFinalY + height() : m_animFinalY - height();
0149         m_animDirection = m_place == Top ? Upward : Downward;
0150     }
0151 
0152     if(isAnimated()) {
0153         move(targetPos.x(), m_animCurrentY);
0154         show();
0155         raise();
0156 
0157         m_animTID = startTimer(m_animStepDuration);     // start the animation
0158     } else {
0159         move(targetPos.x(), m_animFinalY);
0160         show();
0161         raise();
0162     }
0163 }
0164 
0165 bool
0166 AttachableWidget::eventFilter(QObject *object, QEvent *event)
0167 {
0168     if(object == m_targetWidget) {
0169         if(event->type() == QEvent::Resize || event->type() == QEvent::Move) {
0170             if(isVisible()) {
0171                 // hide, and show with recalculated sizes and positions
0172                 hide();
0173                 toggleVisible(true, true);
0174             }
0175         }
0176     }
0177 
0178     return QWidget::eventFilter(object, event);
0179 }
0180 
0181