diff --git a/data/themes/default/fader_knob.png b/data/themes/default/fader_knob.png deleted file mode 100644 index 2190451d8..000000000 Binary files a/data/themes/default/fader_knob.png and /dev/null differ diff --git a/data/themes/default/fader_knob.svg b/data/themes/default/fader_knob.svg new file mode 100644 index 000000000..8a5d9e908 --- /dev/null +++ b/data/themes/default/fader_knob.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/include/Fader.h b/include/Fader.h index 9d6e21590..27e5e07a1 100644 --- a/include/Fader.h +++ b/include/Fader.h @@ -171,6 +171,7 @@ private: QElapsedTimer m_lastPeakTimer_R; QPixmap m_knob {embed::getIconPixmap("fader_knob")}; + QSize m_knobSize; /** * @brief Stores the offset to the knob center when the user drags the fader knob diff --git a/include/embed.h b/include/embed.h index 40a3622c6..f5156b02e 100644 --- a/include/embed.h +++ b/include/embed.h @@ -51,6 +51,24 @@ auto LMMS_EXPORT getIconPixmap(std::string_view name, int width = -1, int height = -1, const char* const* xpm = nullptr) -> QPixmap; auto LMMS_EXPORT getText(std::string_view name) -> QString; +/** + * @brief Temporary shim for QPixmap::deviceIndependentSize. + * @param pixmap The pixmap to get the size of. + * @return The device-independent size of the pixmap. + */ +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) +[[deprecated("Use QPixmap::deviceIndependentSize() instead; See " + "https://doc.qt.io/qt-6/qpixmap.html#deviceIndependentSize")]] +#endif +inline auto logicalSize(const QPixmap &pixmap) noexcept +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + return pixmap.deviceIndependentSize().toSize(); +#else + return pixmap.isNull() ? QSize() : pixmap.size() / pixmap.devicePixelRatio(); +#endif +} + } // namespace embed class PixmapLoader diff --git a/plugins/CrossoverEQ/CMakeLists.txt b/plugins/CrossoverEQ/CMakeLists.txt index 447c92c11..32e700d6a 100644 --- a/plugins/CrossoverEQ/CMakeLists.txt +++ b/plugins/CrossoverEQ/CMakeLists.txt @@ -1,3 +1,3 @@ INCLUDE(BuildPlugin) -BUILD_PLUGIN(crossovereq CrossoverEQ.cpp CrossoverEQControls.cpp CrossoverEQControlDialog.cpp MOCFILES CrossoverEQControls.h CrossoverEQControlDialog.h EMBEDDED_RESOURCES artwork.png fader_bg.png fader_empty.png fader_knob2.png logo.png) +BUILD_PLUGIN(crossovereq CrossoverEQ.cpp CrossoverEQControls.cpp CrossoverEQControlDialog.cpp MOCFILES CrossoverEQControls.h CrossoverEQControlDialog.h EMBEDDED_RESOURCES artwork.svg logo.svg) diff --git a/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp index e7202556b..93aaf0cff 100644 --- a/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp +++ b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp @@ -31,90 +31,89 @@ #include "LedCheckBox.h" #include "Knob.h" #include "Fader.h" +#include "PixmapButton.h" #include +#include +#include namespace lmms::gui { -CrossoverEQControlDialog::CrossoverEQControlDialog( CrossoverEQControls * controls ) : - EffectControlDialog( controls ) +CrossoverEQControlDialog::CrossoverEQControlDialog(CrossoverEQControls *controls) : + EffectControlDialog(controls) { - setAutoFillBackground( true ); + setAutoFillBackground(true); QPalette pal; - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); - setPalette( pal ); - setFixedSize( 167, 178 ); + pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); + setPalette(pal); + setFixedSize(167, 218); + auto layout = new QVBoxLayout(this); + + auto knobsLayout = new QHBoxLayout(); + layout->addLayout(knobsLayout); + + const auto makeKnob = [this, knobsLayout]( + FloatModel *model, + const QString &label, + const QString &txt_before + ) { + auto k = new Knob(KnobType::Bright26, this); + k->setModel(model); + k->setLabel(label); + k->setHintText(txt_before, "Hz"); + knobsLayout->addWidget(k, 0, Qt::AlignHCenter); + }; + + makeKnob(&controls->m_xover12, "1/2", tr("Band 1/2 crossover")); + makeKnob(&controls->m_xover23, "2/3", tr("Band 2/3 crossover")); + makeKnob(&controls->m_xover34, "3/4", tr("Band 3/4 crossover")); - // knobs - auto xover12 = new Knob(KnobType::Bright26, this); - xover12->move( 29, 11 ); - xover12->setModel( & controls->m_xover12 ); - xover12->setLabel( "1/2" ); - xover12->setHintText( tr( "Band 1/2 crossover:" ), " Hz" ); + auto bandsLayout = new QGridLayout(); + bandsLayout->setContentsMargins(4, 10, 4, 5); + layout->addLayout(bandsLayout); - auto xover23 = new Knob(KnobType::Bright26, this); - xover23->move( 69, 11 ); - xover23->setModel( & controls->m_xover23 ); - xover23->setLabel( "2/3" ); - xover23->setHintText( tr( "Band 2/3 crossover:" ), " Hz" ); + const auto makeFader = [this, bandsLayout]( + FloatModel *model, + const QString &label, + int column + ) { + auto f = new Fader(model, label, this, false); + f->setHintText(label, "dBFS"); + f->setDisplayConversion(false); + f->setRenderUnityLine(false); + bandsLayout->addWidget(f, 0, column, Qt::AlignHCenter); + }; - auto xover34 = new Knob(KnobType::Bright26, this); - xover34->move( 109, 11 ); - xover34->setModel( & controls->m_xover34 ); - xover34->setLabel( "3/4" ); - xover34->setHintText( tr( "Band 3/4 crossover:" ), " Hz" ); - - QPixmap const fader_knob(PLUGIN_NAME::getIconPixmap("fader_knob2")); - - // faders - auto gain1 = new Fader(&controls->m_gain1, tr("Band 1 gain"), this, fader_knob, false); - gain1->move( 7, 56 ); - gain1->setDisplayConversion( false ); - gain1->setHintText( tr( "Band 1 gain:" ), " dBFS" ); - gain1->setRenderUnityLine(false); + makeFader(&controls->m_gain1, tr("Band 1 gain"), 0); + makeFader(&controls->m_gain2, tr("Band 2 gain"), 1); + makeFader(&controls->m_gain3, tr("Band 3 gain"), 2); + makeFader(&controls->m_gain4, tr("Band 4 gain"), 3); - auto gain2 = new Fader(&controls->m_gain2, tr("Band 2 gain"), this, fader_knob, false); - gain2->move( 47, 56 ); - gain2->setDisplayConversion( false ); - gain2->setHintText( tr( "Band 2 gain:" ), " dBFS" ); - gain2->setRenderUnityLine(false); + const auto muteOn = embed::getIconPixmap("mute_active"); + const auto muteOff = embed::getIconPixmap("mute_inactive"); - auto gain3 = new Fader(&controls->m_gain3, tr("Band 3 gain"), this, fader_knob, false); - gain3->move( 87, 56 ); - gain3->setDisplayConversion( false ); - gain3->setHintText( tr( "Band 3 gain:" ), " dBFS" ); - gain3->setRenderUnityLine(false); + const auto makeMuteBtn = [this, bandsLayout, muteOn, muteOff]( + BoolModel *model, + const QString &label, + int column + ) { + auto b = new PixmapButton(this, label); + b->setActiveGraphic(muteOff); + b->setInactiveGraphic(muteOn); + b->setCheckable(true); + b->setModel(model); + b->setToolTip(label); + bandsLayout->addWidget(b, 1, column, Qt::AlignCenter); + }; - auto gain4 = new Fader(&controls->m_gain4, tr("Band 4 gain"), this, fader_knob, false); - gain4->move( 127, 56 ); - gain4->setDisplayConversion( false ); - gain4->setHintText( tr( "Band 4 gain:" ), " dBFS" ); - gain4->setRenderUnityLine(false); - - // leds - auto mute1 = new LedCheckBox("", this, tr("Band 1 mute"), LedCheckBox::LedColor::Green); - mute1->move( 15, 154 ); - mute1->setModel( & controls->m_mute1 ); - mute1->setToolTip(tr("Mute band 1")); - - auto mute2 = new LedCheckBox("", this, tr("Band 2 mute"), LedCheckBox::LedColor::Green); - mute2->move( 55, 154 ); - mute2->setModel( & controls->m_mute2 ); - mute2->setToolTip(tr("Mute band 2")); - - auto mute3 = new LedCheckBox("", this, tr("Band 3 mute"), LedCheckBox::LedColor::Green); - mute3->move( 95, 154 ); - mute3->setModel( & controls->m_mute3 ); - mute3->setToolTip(tr("Mute band 3")); - - auto mute4 = new LedCheckBox("", this, tr("Band 4 mute"), LedCheckBox::LedColor::Green); - mute4->move( 135, 154 ); - mute4->setModel( & controls->m_mute4 ); - mute4->setToolTip(tr("Mute band 4")); + makeMuteBtn(&controls->m_mute1, tr("Mute band 1"), 0); + makeMuteBtn(&controls->m_mute2, tr("Mute band 2"), 1); + makeMuteBtn(&controls->m_mute3, tr("Mute band 3"), 2); + makeMuteBtn(&controls->m_mute4, tr("Mute band 4"), 3); } -} // namespace lmms::gui \ No newline at end of file +} // namespace lmms::gui diff --git a/plugins/CrossoverEQ/CrossoverEQControls.cpp b/plugins/CrossoverEQ/CrossoverEQControls.cpp index 9758d804a..928797dc5 100644 --- a/plugins/CrossoverEQ/CrossoverEQControls.cpp +++ b/plugins/CrossoverEQ/CrossoverEQControls.cpp @@ -121,4 +121,4 @@ void CrossoverEQControls::sampleRateChanged() } -} // namespace lmms \ No newline at end of file +} // namespace lmms diff --git a/plugins/CrossoverEQ/artwork.png b/plugins/CrossoverEQ/artwork.png deleted file mode 100644 index ffd2788ab..000000000 Binary files a/plugins/CrossoverEQ/artwork.png and /dev/null differ diff --git a/plugins/CrossoverEQ/artwork.svg b/plugins/CrossoverEQ/artwork.svg new file mode 100644 index 000000000..59ccf992a --- /dev/null +++ b/plugins/CrossoverEQ/artwork.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/plugins/CrossoverEQ/fader_knob2.png b/plugins/CrossoverEQ/fader_knob2.png deleted file mode 100644 index b5238ac06..000000000 Binary files a/plugins/CrossoverEQ/fader_knob2.png and /dev/null differ diff --git a/plugins/CrossoverEQ/logo.png b/plugins/CrossoverEQ/logo.png deleted file mode 100644 index 9340da708..000000000 Binary files a/plugins/CrossoverEQ/logo.png and /dev/null differ diff --git a/plugins/CrossoverEQ/logo.svg b/plugins/CrossoverEQ/logo.svg new file mode 100644 index 000000000..7920fa6b0 --- /dev/null +++ b/plugins/CrossoverEQ/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index 61e6e753d..7ce85963b 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -73,6 +73,7 @@ SimpleTextFloat* Fader::s_textFloat = nullptr; Fader::Fader(FloatModel* model, const QString& name, QWidget* parent, bool modelIsLinear) : QWidget(parent), FloatModelView(model, this), + m_knobSize(embed::logicalSize(m_knob)), m_modelIsLinear(modelIsLinear) { if (s_textFloat == nullptr) @@ -198,7 +199,7 @@ void Fader::mousePressEvent(QMouseEvent* mouseEvent) const int localY = mouseEvent->y(); const auto knobLowerPosY = calculateKnobPosYFromModel(); - const auto knobUpperPosY = knobLowerPosY - m_knob.height(); + const auto knobUpperPosY = knobLowerPosY - m_knobSize.height(); const auto clickedOnKnob = localY >= knobUpperPosY && localY <= knobLowerPosY; @@ -207,7 +208,7 @@ void Fader::mousePressEvent(QMouseEvent* mouseEvent) // If the users clicked on the knob we want to compensate for the offset to the center line // of the knob when dealing with mouse move events. // This will make it feel like the users have grabbed the knob where they clicked. - const auto knobCenterPos = knobLowerPosY - (m_knob.height() / 2); + const auto knobCenterPos = knobLowerPosY - (m_knobSize.height() / 2); m_knobCenterOffset = localY - knobCenterPos; // In this case we also will not call setVolumeByLocalPixelValue, i.e. we do not make any immediate @@ -361,9 +362,9 @@ int Fader::calculateKnobPosYFromModel() const const auto scaledRatio = computeScaledRatio(actualDb); // This returns results between: - // * m_knob.height() for a ratio of 1 + // * m_knobSize.height() for a ratio of 1 // * height() for a ratio of 0 - return height() - (height() - m_knob.height()) * scaledRatio; + return height() - (height() - m_knobSize.height()) * scaledRatio; } } else @@ -375,9 +376,9 @@ int Fader::calculateKnobPosYFromModel() const auto const ratio = (clampedValue - minV) / (maxV - minV); // This returns results between: - // * m_knob.height() for a ratio of 1 + // * m_knobSize.height() for a ratio of 1 // * height() for a ratio of 0 - return height() - (height() - m_knob.height()) * ratio; + return height() - (height() - m_knobSize.height()) * ratio; } } @@ -391,11 +392,11 @@ void Fader::setVolumeByLocalPixelValue(int y) // The y parameter gives us where the mouse click went. // Assume that the middle of the fader should go there. - int const lowerFaderKnob = y + (m_knob.height() / 2); + int const lowerFaderKnob = y + (m_knobSize.height() / 2); // In some cases we need the clamped lower position of the fader knob so we can ensure // that we only set allowed values in the model range. - int const clampedLowerFaderKnob = std::clamp(lowerFaderKnob, m_knob.height(), height()); + int const clampedLowerFaderKnob = std::clamp(lowerFaderKnob, m_knobSize.height(), height()); if (modelIsLinear()) { @@ -411,7 +412,7 @@ void Fader::setVolumeByLocalPixelValue(int y) // First map the lower knob position to [0, 1] so that we can apply some curve mapping, e.g. // square, cube, etc. - LinearMap knobMap(float(m_knob.height()), 1., float(height()), 0.); + LinearMap knobMap(float(m_knobSize.height()), 1., float(height()), 0.); // Apply the inverse of what is done in calculateKnobPosYFromModel auto const knobPos = std::pow(knobMap.map(clampedLowerFaderKnob), 1./c_dBScalingExponent); @@ -433,7 +434,7 @@ void Fader::setVolumeByLocalPixelValue(int y) } else { - LinearMap valueMap(float(m_knob.height()), model()->maxValue(), float(height()), model()->minValue()); + LinearMap valueMap(float(m_knobSize.height()), model()->maxValue(), float(height()), model()->minValue()); model()->setValue(valueMap.map(clampedLowerFaderKnob)); } @@ -553,7 +554,7 @@ void Fader::paintEvent(QPaintEvent* ev) } // Draw the knob - painter.drawPixmap((width() - m_knob.width()) / 2, calculateKnobPosYFromModel() - m_knob.height(), m_knob); + painter.drawPixmap((width() - m_knobSize.width()) / 2, calculateKnobPosYFromModel() - m_knobSize.height(), m_knob); } void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear) @@ -727,7 +728,7 @@ void Fader::paintFaderTicks(QPainter& painter) for (float i = startValue; i >= c_faderMinDb; i-= stepSize) { const auto scaledRatio = computeScaledRatio(i); - const auto maxHeight = height() - (height() - m_knob.height()) * scaledRatio - (m_knob.height() / 2); + const auto maxHeight = height() - (height() - m_knobSize.height()) * scaledRatio - (m_knobSize.height() / 2); if (approximatelyEqual(i, 0.)) { diff --git a/src/gui/widgets/PixmapButton.cpp b/src/gui/widgets/PixmapButton.cpp index bd683ed71..b456926ad 100644 --- a/src/gui/widgets/PixmapButton.cpp +++ b/src/gui/widgets/PixmapButton.cpp @@ -102,17 +102,13 @@ void PixmapButton::mouseDoubleClickEvent( QMouseEvent * _me ) } - - -void PixmapButton::setActiveGraphic( const QPixmap & _pm ) +void PixmapButton::setActiveGraphic(const QPixmap &pm) { - m_activePixmap = _pm; - resize(m_activePixmap.size() / m_activePixmap.devicePixelRatio()); + m_activePixmap = pm; + resize(embed::logicalSize(m_activePixmap)); } - - void PixmapButton::setInactiveGraphic( const QPixmap & _pm, bool _update ) { m_inactivePixmap = _pm; @@ -129,9 +125,8 @@ QSize PixmapButton::sizeHint() const QSize PixmapButton::minimumSizeHint() const { - const auto activeSize = m_activePixmap.size() / m_activePixmap.devicePixelRatio(); - const auto inactiveSize = m_inactivePixmap.size() / m_inactivePixmap.devicePixelRatio(); - return activeSize.expandedTo(inactiveSize); + return embed::logicalSize(m_activePixmap) + .expandedTo(embed::logicalSize(m_inactivePixmap)); } bool PixmapButton::isActive() const