File indexing completed on 2024-06-16 04:16:03

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_equalizer_widget.h"
0008 
0009 #include <QMouseEvent>
0010 #include <QApplication>
0011 #include <QHBoxLayout>
0012 #include <QMenu>
0013 
0014 #include <klocalizedstring.h>
0015 
0016 #include "kis_equalizer_column.h"
0017 #include "kis_signal_compressor.h"
0018 
0019 #include "KisAnimTimelineColors.h"
0020 
0021 #include "kis_debug.h"
0022 
0023 struct KisEqualizerWidget::Private
0024 {
0025     Private()
0026         : maxDistance(0),
0027           updateCompressor(300, KisSignalCompressor::FIRST_ACTIVE)
0028     {
0029     }
0030 
0031     QMap<int, KisEqualizerColumn*> columns;
0032     int maxDistance;
0033     KisSignalCompressor updateCompressor;
0034     QMenu *contextMenu; 
0035 };
0036 
0037 KisEqualizerWidget::KisEqualizerWidget(int maxDistance, QWidget *parent)
0038     : QWidget(parent),
0039       m_d(new Private)
0040 {
0041     m_d->maxDistance = maxDistance;
0042 
0043     QHBoxLayout *layout = new QHBoxLayout(this);
0044     layout->setSpacing(0);
0045     layout->setMargin(0);
0046 
0047     for (int i = -m_d->maxDistance; i <= m_d->maxDistance; i++) {
0048         KisEqualizerColumn *c = new KisEqualizerColumn(this, i, QString::number(i));
0049         layout->addWidget(c, i == 0 ? 2 : 1);
0050 
0051         if (i == m_d->maxDistance) {
0052             c->setRightmost(true);
0053         }
0054 
0055         m_d->columns.insert(i, c);
0056 
0057         connect(c, SIGNAL(sigColumnChanged(int,bool,int)),
0058                 &m_d->updateCompressor, SLOT(start()));
0059     }
0060 
0061     connect(&m_d->updateCompressor, SIGNAL(timeout()), SIGNAL(sigConfigChanged()));
0062     connect(m_d->columns[0], SIGNAL(sigColumnChanged(int,bool,int)), this, SLOT(slotMasterColumnChanged(int,bool,int)));
0063 }
0064 
0065 KisEqualizerWidget::~KisEqualizerWidget()
0066 {
0067 }
0068 
0069 KisEqualizerWidget::EqualizerValues KisEqualizerWidget::getValues() const
0070 {
0071     EqualizerValues v;
0072     v.maxDistance = m_d->maxDistance;
0073 
0074     for (int i = -m_d->maxDistance; i <= m_d->maxDistance; i++) {
0075         v.value.insert(i, m_d->columns[i]->value());
0076         v.state.insert(i, m_d->columns[i]->state());
0077     }
0078 
0079     return v;
0080 }
0081 
0082 void KisEqualizerWidget::setValues(const EqualizerValues &v)
0083 {
0084     for (int i = -m_d->maxDistance; i <= m_d->maxDistance; i++) {
0085         if (qAbs(i) <= v.maxDistance) {
0086             m_d->columns[i]->setValue(v.value[i]);
0087             m_d->columns[i]->setState(v.state[i]);
0088         } else {
0089             m_d->columns[i]->setState(false);
0090         }
0091     }
0092 }
0093 
0094 void KisEqualizerWidget::toggleMasterSwitch()
0095 {
0096     const bool currentState = m_d->columns[0]->state();
0097     m_d->columns[0]->setState(!currentState);
0098 }
0099 
0100 void KisEqualizerWidget::resizeEvent(QResizeEvent *event)
0101 {
0102     Q_UNUSED(event);
0103     const QSize newSize = m_d->columns[1]->size();
0104 
0105     QFont font =
0106         KisAnimTimelineColors::instance()->getOnionSkinsFont(
0107             QString::number(100), newSize);
0108 
0109     if (font.pointSize() != this->font().pointSize()) {
0110         setFont(font);
0111 
0112         for (int i = -m_d->maxDistance; i <= m_d->maxDistance; i++) {
0113             m_d->columns[i]->setFont(font);
0114         }
0115 
0116     }
0117 }
0118 
0119 void KisEqualizerWidget::mouseMoveEvent(QMouseEvent *ev)
0120 {
0121     if (!(ev->modifiers() & Qt::ShiftModifier)) return;
0122 
0123     QPoint globalPos = ev->globalPos();
0124     QWidget *w = qApp->widgetAt(globalPos);
0125 
0126     if (w && w->inherits("QAbstractSlider")) {
0127         QMouseEvent newEv(ev->type(),
0128                           w->mapFromGlobal(globalPos),
0129                           globalPos,
0130                           ev->button(),
0131                           ev->buttons(),
0132                           ev->modifiers() & ~Qt::ShiftModifier);
0133         qApp->sendEvent(w, &newEv);
0134     }
0135 }
0136 
0137 void KisEqualizerWidget::contextMenuEvent(QContextMenuEvent *event)
0138 {
0139         KIS_ASSERT_RECOVER_RETURN(event);
0140 
0141         if (!m_d->contextMenu) { // Lazy create and populate context menu.
0142             m_d->contextMenu = new QMenu(this);
0143 
0144             QAction *actReset = m_d->contextMenu->addAction(i18nc("Reset to default", "Reset"));
0145             connect(actReset, &QAction::triggered, this, &KisEqualizerWidget::sigReset);
0146         }
0147 
0148         KIS_ASSERT_RECOVER_RETURN(m_d->contextMenu);
0149 
0150         if (m_d->contextMenu) {
0151             m_d->contextMenu->exec(QCursor::pos());
0152         }
0153 }
0154 
0155 void KisEqualizerWidget::slotMasterColumnChanged(int, bool state, int)
0156 {
0157     for (int i = 1; i <= m_d->maxDistance; i++) {
0158         m_d->columns[i]->setForceDisabled(!state);
0159         m_d->columns[-i]->setForceDisabled(!state);
0160     }
0161 }