From 5c93d8da498e4fae2208bcf755b90278cee56b92 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 4 Apr 2024 11:25:23 +0200 Subject: [PATCH 1/7] Add class EnvelopeGraph Move the rendering of the envelope graph into it's own class. This is a preparation step to use layouts in `EnvelopeAndLfoView`. It does not work with the mixed in painting in the paint event. --- include/EnvelopeAndLfoParameters.h | 9 ++ include/EnvelopeAndLfoView.h | 3 +- include/EnvelopeGraph.h | 68 ++++++++++ src/gui/CMakeLists.txt | 1 + src/gui/instrument/EnvelopeAndLfoView.cpp | 86 +----------- src/gui/instrument/EnvelopeGraph.cpp | 157 ++++++++++++++++++++++ 6 files changed, 242 insertions(+), 82 deletions(-) create mode 100644 include/EnvelopeGraph.h create mode 100644 src/gui/instrument/EnvelopeGraph.cpp diff --git a/include/EnvelopeAndLfoParameters.h b/include/EnvelopeAndLfoParameters.h index 2a8d3a685e6..89d60406565 100644 --- a/include/EnvelopeAndLfoParameters.h +++ b/include/EnvelopeAndLfoParameters.h @@ -114,6 +114,15 @@ class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObj return m_rFrames; } + const FloatModel& getPredelayModel() const { return m_predelayModel; } + const FloatModel& getAttackModel() const { return m_attackModel; } + const FloatModel& getHoldModel() const { return m_holdModel; } + const FloatModel& getDecayModel() const { return m_decayModel; } + const FloatModel& getSustainModel() const { return m_sustainModel; } + const FloatModel& getReleaseModel() const { return m_releaseModel; } + const FloatModel& getAmountModel() const { return m_amountModel; } + FloatModel& getAmountModel() { return m_amountModel; } + public slots: void updateSampleVars(); diff --git a/include/EnvelopeAndLfoView.h b/include/EnvelopeAndLfoView.h index d545aaa0687..25f1e3a63f0 100644 --- a/include/EnvelopeAndLfoView.h +++ b/include/EnvelopeAndLfoView.h @@ -47,6 +47,7 @@ class Knob; class LedCheckBox; class PixmapButton; class TempoSyncKnob; +class EnvelopeGraph; @@ -72,13 +73,13 @@ protected slots: private: - QPixmap m_envGraph = embed::getIconPixmap("envelope_graph"); QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph"); EnvelopeAndLfoParameters * m_params; // envelope stuff + EnvelopeGraph* m_envelopeGraph; Knob * m_predelayKnob; Knob * m_attackKnob; Knob * m_holdKnob; diff --git a/include/EnvelopeGraph.h b/include/EnvelopeGraph.h new file mode 100644 index 00000000000..00a8d4a228b --- /dev/null +++ b/include/EnvelopeGraph.h @@ -0,0 +1,68 @@ +/* + * EnvelopeGraph.h - Displays envelope graphs + * + * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#pragma once + +#ifndef LMMS_GUI_ENVELOPE_GRAPH_H +#define LMMS_GUI_ENVELOPE_GRAPH_H + +#include + +#include "ModelView.h" +#include "embed.h" + +namespace lmms +{ + +class EnvelopeAndLfoParameters; + +namespace gui +{ + +class EnvelopeGraph : public QWidget, public ModelView +{ +public: + EnvelopeGraph(QWidget* parent); + +protected: + void modelChanged() override; + + void mousePressEvent(QMouseEvent* me) override; + void paintEvent(QPaintEvent* pe) override; + +private: + void toggleAmountModel(); + +private: + QPixmap m_envGraph = embed::getIconPixmap("envelope_graph"); + + EnvelopeAndLfoParameters * m_params; +}; + +} // namespace gui + +} // namespace lmms + +#endif // LMMS_GUI_ENVELOPE_GRAPH_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index e2342b46548..34d55d5168d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -62,6 +62,7 @@ SET(LMMS_SRCS gui/editors/TrackContainerView.cpp gui/instrument/EnvelopeAndLfoView.cpp + gui/instrument/EnvelopeGraph.cpp gui/instrument/InstrumentFunctionViews.cpp gui/instrument/InstrumentMidiIOView.cpp gui/instrument/InstrumentTuningView.cpp diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index 4043ea2295b..de120a558fb 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -27,6 +27,7 @@ #include #include "EnvelopeAndLfoView.h" +#include "EnvelopeGraph.h" #include "EnvelopeAndLfoParameters.h" #include "SampleLoader.h" #include "embed.h" @@ -68,8 +69,6 @@ const int SUSTAIN_KNOB_X = DECAY_KNOB_X+KNOB_X_SPACING; const int RELEASE_KNOB_X = SUSTAIN_KNOB_X+KNOB_X_SPACING; const int AMOUNT_KNOB_X = RELEASE_KNOB_X+KNOB_X_SPACING; -const int TIME_UNIT_WIDTH = 40; - const int LFO_GRAPH_X = 6; const int LFO_GRAPH_Y = ENV_KNOBS_LBL_Y+14; const int LFO_KNOB_Y = LFO_GRAPH_Y-2; @@ -85,6 +84,8 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : ModelView( nullptr, this ), m_params( nullptr ) { + m_envelopeGraph = new EnvelopeGraph(this); + m_envelopeGraph->move(ENV_GRAPH_X, ENV_GRAPH_Y); m_predelayKnob = new Knob( KnobType::Bright26, this ); m_predelayKnob->setLabel( tr( "DEL" ) ); @@ -221,7 +222,6 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : setAcceptDrops( true ); - } @@ -238,6 +238,7 @@ EnvelopeAndLfoView::~EnvelopeAndLfoView() void EnvelopeAndLfoView::modelChanged() { m_params = castModel(); + m_envelopeGraph->setModel(m_params); m_predelayKnob->setModel( &m_params->m_predelayModel ); m_attackKnob->setModel( &m_params->m_attackModel ); m_holdKnob->setModel( &m_params->m_holdModel ); @@ -264,18 +265,7 @@ void EnvelopeAndLfoView::mousePressEvent( QMouseEvent * _me ) return; } - if (QRect(ENV_GRAPH_X, ENV_GRAPH_Y, m_envGraph.width(), m_envGraph.height()).contains(_me->pos())) - { - if( m_params->m_amountModel.value() < 1.0f ) - { - m_params->m_amountModel.setValue( 1.0f ); - } - else - { - m_params->m_amountModel.setValue( 0.0f ); - } - } - else if (QRect(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph.width(), m_lfoGraph.height()).contains(_me->pos())) + if (QRect(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph.width(), m_lfoGraph.height()).contains(_me->pos())) { if( m_params->m_lfoAmountModel.value() < 1.0f ) { @@ -335,77 +325,11 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) QPainter p( this ); p.setRenderHint( QPainter::Antialiasing ); - // draw envelope-graph - p.drawPixmap(ENV_GRAPH_X, ENV_GRAPH_Y, m_envGraph); // draw LFO-graph p.drawPixmap(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph); p.setFont(pointSize(p.font(), 8)); - const float gray_amount = 1.0f - fabsf( m_amountKnob->value() ); - - p.setPen( QPen( QColor( static_cast( 96 * gray_amount ), - static_cast( 255 - 159 * gray_amount ), - static_cast( 128 - 32 * gray_amount ) ), - 2 ) ); - - const QColor end_points_color( 0x99, 0xAF, 0xFF ); - const QColor end_points_bg_color( 0, 0, 2 ); - - const int y_base = ENV_GRAPH_Y + m_envGraph.height() - 3; - const int avail_height = m_envGraph.height() - 6; - - int x1 = static_cast( m_predelayKnob->value() * TIME_UNIT_WIDTH ); - int x2 = x1 + static_cast( m_attackKnob->value() * TIME_UNIT_WIDTH ); - int x3 = x2 + static_cast( m_holdKnob->value() * TIME_UNIT_WIDTH ); - int x4 = x3 + static_cast( ( m_decayKnob->value() * - ( 1 - m_sustainKnob->value() ) ) * TIME_UNIT_WIDTH ); - int x5 = x4 + static_cast( m_releaseKnob->value() * TIME_UNIT_WIDTH ); - - if( x5 > 174 ) - { - x1 = ( x1 * 174 ) / x5; - x2 = ( x2 * 174 ) / x5; - x3 = ( x3 * 174 ) / x5; - x4 = ( x4 * 174 ) / x5; - x5 = ( x5 * 174 ) / x5; - } - x1 += ENV_GRAPH_X + 2; - x2 += ENV_GRAPH_X + 2; - x3 += ENV_GRAPH_X + 2; - x4 += ENV_GRAPH_X + 2; - x5 += ENV_GRAPH_X + 2; - - p.drawLine( x1, y_base, x2, y_base - avail_height ); - p.fillRect( x1 - 1, y_base - 2, 4, 4, end_points_bg_color ); - p.fillRect( x1, y_base - 1, 2, 2, end_points_color ); - - p.drawLine( x2, y_base - avail_height, x3, y_base - avail_height ); - p.fillRect( x2 - 1, y_base - 2 - avail_height, 4, 4, - end_points_bg_color ); - p.fillRect( x2, y_base - 1 - avail_height, 2, 2, end_points_color ); - - p.drawLine( x3, y_base-avail_height, x4, static_cast( y_base - - avail_height + - ( 1 - m_sustainKnob->value() ) * avail_height ) ); - p.fillRect( x3 - 1, y_base - 2 - avail_height, 4, 4, - end_points_bg_color ); - p.fillRect( x3, y_base - 1 - avail_height, 2, 2, end_points_color ); - - p.drawLine( x4, static_cast( y_base - avail_height + - ( 1 - m_sustainKnob->value() ) * - avail_height ), x5, y_base ); - p.fillRect( x4 - 1, static_cast( y_base - avail_height + - ( 1 - m_sustainKnob->value() ) * - avail_height ) - 2, 4, 4, - end_points_bg_color ); - p.fillRect( x4, static_cast( y_base - avail_height + - ( 1 - m_sustainKnob->value() ) * - avail_height ) - 1, 2, 2, - end_points_color ); - p.fillRect( x5 - 1, y_base - 2, 4, 4, end_points_bg_color ); - p.fillRect( x5, y_base - 1, 2, 2, end_points_color ); - int LFO_GRAPH_W = m_lfoGraph.width() - 3; // subtract border int LFO_GRAPH_H = m_lfoGraph.height() - 6; // subtract border int graph_x_base = LFO_GRAPH_X + 2; diff --git a/src/gui/instrument/EnvelopeGraph.cpp b/src/gui/instrument/EnvelopeGraph.cpp new file mode 100644 index 00000000000..4d866b3ccd1 --- /dev/null +++ b/src/gui/instrument/EnvelopeGraph.cpp @@ -0,0 +1,157 @@ +/* + * EnvelopeGraph.cpp - Displays envelope graphs + * + * Copyright (c) 2004-2014 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include +#include + +#include "EnvelopeGraph.h" + +#include "EnvelopeAndLfoParameters.h" + +namespace lmms +{ + +namespace gui +{ + +const int TIME_UNIT_WIDTH = 40; + + +EnvelopeGraph::EnvelopeGraph(QWidget* parent) : + QWidget(parent), + ModelView(nullptr, this), + m_params(nullptr) +{ + setFixedSize(m_envGraph.size()); +} + +void EnvelopeGraph::modelChanged() +{ + m_params = castModel(); +} + +void EnvelopeGraph::mousePressEvent(QMouseEvent* me) +{ + if(me->button() == Qt::LeftButton) + { + toggleAmountModel(); + } +} + +void EnvelopeGraph::paintEvent(QPaintEvent*) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + + // Draw the graph background + p.drawPixmap(rect(), m_envGraph); + + const auto * params = castModel(); + if (!params) + { + return; + } + + const float amount = params->getAmountModel().value(); + const float predelay = params->getPredelayModel().value(); + const float attack = params->getAttackModel().value(); + const float hold = params->getHoldModel().value(); + const float decay = params->getDecayModel().value(); + const float sustain = params->getSustainModel().value(); + const float release = params->getReleaseModel().value(); + + const float gray_amount = 1.0f - fabsf(amount); + + p.setPen(QPen(QColor(static_cast(96 * gray_amount), + static_cast(255 - 159 * gray_amount), + static_cast(128 - 32 * gray_amount)), + 2)); + + const QColor end_points_color(0x99, 0xAF, 0xFF); + const QColor end_points_bg_color(0, 0, 2); + + const int y_base = m_envGraph.height() - 3; + const int avail_height = m_envGraph.height() - 6; + + int x1 = static_cast(predelay * TIME_UNIT_WIDTH); + int x2 = x1 + static_cast(attack * TIME_UNIT_WIDTH); + int x3 = x2 + static_cast(hold * TIME_UNIT_WIDTH); + int x4 = x3 + static_cast((decay * (1 - sustain)) * TIME_UNIT_WIDTH); + int x5 = x4 + static_cast(release * TIME_UNIT_WIDTH); + + if (x5 > 174) + { + x1 = (x1 * 174) / x5; + x2 = (x2 * 174) / x5; + x3 = (x3 * 174) / x5; + x4 = (x4 * 174) / x5; + x5 = (x5 * 174) / x5; + } + x1 += 2; + x2 += 2; + x3 += 2; + x4 += 2; + x5 += 2; + + p.drawLine(x1, y_base, x2, y_base - avail_height); + p.fillRect(x1 - 1, y_base - 2, 4, 4, end_points_bg_color); + p.fillRect(x1, y_base - 1, 2, 2, end_points_color); + + p.drawLine(x2, y_base - avail_height, x3, y_base - avail_height); + p.fillRect(x2 - 1, y_base - 2 - avail_height, 4, 4, + end_points_bg_color); + p.fillRect(x2, y_base - 1 - avail_height, 2, 2, end_points_color); + + const int sustainHeight = static_cast(y_base - avail_height + (1 - sustain) * avail_height); + + p.drawLine(x3, y_base-avail_height, x4, sustainHeight); + p.fillRect(x3 - 1, y_base - 2 - avail_height, 4, 4, end_points_bg_color); + p.fillRect(x3, y_base - 1 - avail_height, 2, 2, end_points_color); + + p.drawLine(x4, sustainHeight, x5, y_base); + p.fillRect(x4 - 1, sustainHeight - 2, 4, 4, end_points_bg_color); + p.fillRect(x4, sustainHeight - 1, 2, 2, end_points_color); + p.fillRect(x5 - 1, y_base - 2, 4, 4, end_points_bg_color); + p.fillRect(x5, y_base - 1, 2, 2, end_points_color); +} + +void EnvelopeGraph::toggleAmountModel() +{ + auto* params = castModel(); + auto& amountModel = params->getAmountModel(); + + if (amountModel.value() < 1.0f ) + { + amountModel.setValue( 1.0f ); + } + else + { + amountModel.setValue( 0.0f ); + } +} + +} // namespace gui + +} // namespace lmms From b32c93488fd564d30074a051dd1c1219926af790 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 4 Apr 2024 12:09:07 +0200 Subject: [PATCH 2/7] Move LFO graph into its own class Move the LFO graph into its own class. This finally enables the removal of the mouse event and paint event code in `EnvelopeAndLfoView`. Make the enum `LfoShape` in `EnvelopeAndLfoParameters` public so that it can be used without friend declarations. Add accessor methods for the model of the LFO. --- include/EnvelopeAndLfoParameters.h | 36 +++-- include/EnvelopeAndLfoView.h | 13 +- include/LfoGraph.h | 70 +++++++++ src/gui/CMakeLists.txt | 1 + src/gui/instrument/EnvelopeAndLfoView.cpp | 141 +---------------- src/gui/instrument/LfoGraph.cpp | 176 ++++++++++++++++++++++ 6 files changed, 280 insertions(+), 157 deletions(-) create mode 100644 include/LfoGraph.h create mode 100644 src/gui/instrument/LfoGraph.cpp diff --git a/include/EnvelopeAndLfoParameters.h b/include/EnvelopeAndLfoParameters.h index 89d60406565..50bfdf78709 100644 --- a/include/EnvelopeAndLfoParameters.h +++ b/include/EnvelopeAndLfoParameters.h @@ -71,7 +71,18 @@ class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObj using LfoList = QList; LfoList m_lfos; - } ; + }; + + enum class LfoShape + { + SineWave, + TriangleWave, + SawWave, + SquareWave, + UserDefinedWave, + RandomWave, + Count + }; EnvelopeAndLfoParameters( float _value_for_zero_amount, Model * _parent ); @@ -114,6 +125,7 @@ class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObj return m_rFrames; } + // Envelope const FloatModel& getPredelayModel() const { return m_predelayModel; } const FloatModel& getAttackModel() const { return m_attackModel; } const FloatModel& getHoldModel() const { return m_holdModel; } @@ -124,6 +136,18 @@ class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObj FloatModel& getAmountModel() { return m_amountModel; } + // LFO + inline f_cnt_t getLfoPredelayFrames() const { return m_lfoPredelayFrames; } + inline f_cnt_t getLfoAttackFrames() const { return m_lfoAttackFrames; } + inline f_cnt_t getLfoOscillationFrames() const { return m_lfoOscillationFrames; } + + const FloatModel& getLfoAmountModel() const { return m_lfoAmountModel; } + FloatModel& getLfoAmountModel() { return m_lfoAmountModel; } + const TempoSyncKnobModel& getLfoSpeedModel() const { return m_lfoSpeedModel; } + const BoolModel& getX100Model() const { return m_x100Model; } + const IntModel& getLfoWaveModel() const { return m_lfoWaveModel; } + std::shared_ptr getLfoUserWave() const { return m_userWave; } + public slots: void updateSampleVars(); @@ -179,16 +203,6 @@ public slots: bool m_bad_lfoShapeData; std::shared_ptr m_userWave = SampleBuffer::emptyBuffer(); - enum class LfoShape - { - SineWave, - TriangleWave, - SawWave, - SquareWave, - UserDefinedWave, - RandomWave, - Count - } ; constexpr static auto NumLfoShapes = static_cast(LfoShape::Count); sample_t lfoShapeSample( fpp_t _frame_offset ); diff --git a/include/EnvelopeAndLfoView.h b/include/EnvelopeAndLfoView.h index 25f1e3a63f0..0063dc78815 100644 --- a/include/EnvelopeAndLfoView.h +++ b/include/EnvelopeAndLfoView.h @@ -29,10 +29,6 @@ #include #include "ModelView.h" -#include "embed.h" - -class QPaintEvent; -class QPixmap; namespace lmms { @@ -48,6 +44,7 @@ class LedCheckBox; class PixmapButton; class TempoSyncKnob; class EnvelopeGraph; +class LfoGraph; @@ -64,8 +61,6 @@ class EnvelopeAndLfoView : public QWidget, public ModelView void dragEnterEvent( QDragEnterEvent * _dee ) override; void dropEvent( QDropEvent * _de ) override; - void mousePressEvent( QMouseEvent * _me ) override; - void paintEvent( QPaintEvent * _pe ) override; protected slots: @@ -73,11 +68,8 @@ protected slots: private: - QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph"); - EnvelopeAndLfoParameters * m_params; - // envelope stuff EnvelopeGraph* m_envelopeGraph; Knob * m_predelayKnob; @@ -89,6 +81,7 @@ protected slots: Knob * m_amountKnob; // LFO stuff + LfoGraph* m_lfoGraph; Knob * m_lfoPredelayKnob; Knob * m_lfoAttackKnob; TempoSyncKnob * m_lfoSpeedKnob; @@ -98,8 +91,6 @@ protected slots: LedCheckBox * m_x100Cb; LedCheckBox * m_controlEnvAmountCb; - - float m_randomGraph; } ; } // namespace gui diff --git a/include/LfoGraph.h b/include/LfoGraph.h new file mode 100644 index 00000000000..486139f8b4d --- /dev/null +++ b/include/LfoGraph.h @@ -0,0 +1,70 @@ +/* + * EnvelopeGraph.h - Displays LFO graphs + * + * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#pragma once + +#ifndef LMMS_GUI_LFO_GRAPH_H +#define LMMS_GUI_LFO_GRAPH_H + +#include + +#include "ModelView.h" +#include "embed.h" + +namespace lmms +{ + +class EnvelopeAndLfoParameters; + +namespace gui +{ + +class LfoGraph : public QWidget, public ModelView +{ +public: + LfoGraph(QWidget* parent); + +protected: + void modelChanged() override; + + void mousePressEvent(QMouseEvent* me) override; + void paintEvent(QPaintEvent* pe) override; + +private: + void toggleAmountModel(); + +private: + QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph"); + + EnvelopeAndLfoParameters * m_params; + + float m_randomGraph {0.}; +}; + +} // namespace gui + +} // namespace lmms + +#endif // LMMS_GUI_LFO_GRAPH_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 34d55d5168d..791d6fbff1d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -69,6 +69,7 @@ SET(LMMS_SRCS gui/instrument/InstrumentSoundShapingView.cpp gui/instrument/InstrumentTrackWindow.cpp gui/instrument/InstrumentView.cpp + gui/instrument/LfoGraph.cpp gui/instrument/PianoView.cpp gui/menus/MidiPortMenu.cpp diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index de120a558fb..6b8dc33c961 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -23,21 +23,16 @@ * */ -#include -#include - #include "EnvelopeAndLfoView.h" + #include "EnvelopeGraph.h" +#include "LfoGraph.h" #include "EnvelopeAndLfoParameters.h" #include "SampleLoader.h" -#include "embed.h" -#include "Engine.h" #include "gui_templates.h" #include "Knob.h" #include "LedCheckBox.h" -#include "AudioEngine.h" #include "DataFile.h" -#include "Oscillator.h" #include "PixmapButton.h" #include "StringPairDrag.h" #include "TempoSyncKnob.h" @@ -47,14 +42,9 @@ namespace lmms { -extern const float SECS_PER_ENV_SEGMENT; -extern const float SECS_PER_LFO_OSCILLATION; - - namespace gui { - const int ENV_GRAPH_X = 6; const int ENV_GRAPH_Y = 6; @@ -130,6 +120,8 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : + m_lfoGraph = new LfoGraph(this); + m_lfoGraph->move(LFO_GRAPH_X, LFO_GRAPH_Y); m_lfoPredelayKnob = new Knob( KnobType::Bright26, this ); m_lfoPredelayKnob->setLabel( tr( "DEL" ) ); @@ -246,6 +238,8 @@ void EnvelopeAndLfoView::modelChanged() m_sustainKnob->setModel( &m_params->m_sustainModel ); m_releaseKnob->setModel( &m_params->m_releaseModel ); m_amountKnob->setModel( &m_params->m_amountModel ); + + m_lfoGraph->setModel(m_params); m_lfoPredelayKnob->setModel( &m_params->m_lfoPredelayModel ); m_lfoAttackKnob->setModel( &m_params->m_lfoAttackModel ); m_lfoSpeedKnob->setModel( &m_params->m_lfoSpeedModel ); @@ -258,29 +252,6 @@ void EnvelopeAndLfoView::modelChanged() -void EnvelopeAndLfoView::mousePressEvent( QMouseEvent * _me ) -{ - if( _me->button() != Qt::LeftButton ) - { - return; - } - - if (QRect(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph.width(), m_lfoGraph.height()).contains(_me->pos())) - { - if( m_params->m_lfoAmountModel.value() < 1.0f ) - { - m_params->m_lfoAmountModel.setValue( 1.0f ); - } - else - { - m_params->m_lfoAmountModel.setValue( 0.0f ); - } - } -} - - - - void EnvelopeAndLfoView::dragEnterEvent( QDragEnterEvent * _dee ) { StringPairDrag::processDragEnterEvent( _dee, @@ -320,101 +291,6 @@ void EnvelopeAndLfoView::dropEvent( QDropEvent * _de ) -void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) -{ - QPainter p( this ); - p.setRenderHint( QPainter::Antialiasing ); - - // draw LFO-graph - p.drawPixmap(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph); - - p.setFont(pointSize(p.font(), 8)); - - int LFO_GRAPH_W = m_lfoGraph.width() - 3; // subtract border - int LFO_GRAPH_H = m_lfoGraph.height() - 6; // subtract border - int graph_x_base = LFO_GRAPH_X + 2; - int graph_y_base = LFO_GRAPH_Y + 3 + LFO_GRAPH_H / 2; - - const float frames_for_graph = SECS_PER_LFO_OSCILLATION * - Engine::audioEngine()->baseSampleRate() / 10; - - const float lfo_gray_amount = 1.0f - fabsf( m_lfoAmountKnob->value() ); - p.setPen( QPen( QColor( static_cast( 96 * lfo_gray_amount ), - static_cast( 255 - 159 * lfo_gray_amount ), - static_cast( 128 - 32 * - lfo_gray_amount ) ), - 1.5 ) ); - - - float osc_frames = m_params->m_lfoOscillationFrames; - - if( m_params->m_x100Model.value() ) - { - osc_frames *= 100.0f; - } - - float old_y = 0; - for( int x = 0; x <= LFO_GRAPH_W; ++x ) - { - float val = 0.0; - float cur_sample = x * frames_for_graph / LFO_GRAPH_W; - if( static_cast( cur_sample ) > - m_params->m_lfoPredelayFrames ) - { - float phase = ( cur_sample -= - m_params->m_lfoPredelayFrames ) / - osc_frames; - switch( static_cast(m_params->m_lfoWaveModel.value()) ) - { - case EnvelopeAndLfoParameters::LfoShape::SineWave: - default: - val = Oscillator::sinSample( phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::TriangleWave: - val = Oscillator::triangleSample( - phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::SawWave: - val = Oscillator::sawSample( phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::SquareWave: - val = Oscillator::squareSample( phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::RandomWave: - if( x % (int)( 900 * m_lfoSpeedKnob->value() + 1 ) == 0 ) - { - m_randomGraph = Oscillator::noiseSample( 0.0f ); - } - val = m_randomGraph; - break; - case EnvelopeAndLfoParameters::LfoShape::UserDefinedWave: - val = Oscillator::userWaveSample(m_params->m_userWave.get(), phase); - break; - } - if( static_cast( cur_sample ) <= - m_params->m_lfoAttackFrames ) - { - val *= cur_sample / m_params->m_lfoAttackFrames; - } - } - float cur_y = -LFO_GRAPH_H / 2.0f * val; - p.drawLine( QLineF( graph_x_base + x - 1, graph_y_base + old_y, - graph_x_base + x, - graph_y_base + cur_y ) ); - old_y = cur_y; - } - - p.setPen( QColor( 201, 201, 225 ) ); - int ms_per_osc = static_cast( SECS_PER_LFO_OSCILLATION * - m_lfoSpeedKnob->value() * - 1000.0f ); - p.drawText(LFO_GRAPH_X + 4, LFO_GRAPH_Y + m_lfoGraph.height() - 6, tr("ms/LFO:")); - p.drawText(LFO_GRAPH_X + 52, LFO_GRAPH_Y + m_lfoGraph.height() - 6, QString::number(ms_per_osc)); -} - - - - void EnvelopeAndLfoView::lfoUserWaveChanged() { if( static_cast(m_params->m_lfoWaveModel.value()) == @@ -429,11 +305,6 @@ void EnvelopeAndLfoView::lfoUserWaveChanged() } } - - - - - } // namespace gui } // namespace lmms diff --git a/src/gui/instrument/LfoGraph.cpp b/src/gui/instrument/LfoGraph.cpp new file mode 100644 index 00000000000..458c335329a --- /dev/null +++ b/src/gui/instrument/LfoGraph.cpp @@ -0,0 +1,176 @@ +/* + * EnvelopeGraph.cpp - Displays LFO graphs + * + * Copyright (c) 2004-2014 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include +#include + +#include "LfoGraph.h" + +#include "EnvelopeAndLfoParameters.h" +#include "Oscillator.h" + +#include "gui_templates.h" + +namespace lmms +{ + +extern const float SECS_PER_LFO_OSCILLATION; + +namespace gui +{ + +LfoGraph::LfoGraph(QWidget* parent) : + QWidget(parent), + ModelView(nullptr, this), + m_params(nullptr) +{ + setFixedSize(m_lfoGraph.size()); +} + +void LfoGraph::modelChanged() +{ + m_params = castModel(); +} + +void LfoGraph::mousePressEvent(QMouseEvent* me) +{ + if (me->button() == Qt::LeftButton) + { + toggleAmountModel(); + } +} + +void LfoGraph::paintEvent(QPaintEvent*) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + + // Draw the graph background + p.drawPixmap(rect(), m_lfoGraph); + + const auto * params = castModel(); + if (!params) + { + return; + } + + const float amount = params->getLfoAmountModel().value(); + const float lfoSpeed = params->getLfoSpeedModel().value(); + const f_cnt_t predelayFrames = params->getLfoPredelayFrames(); + const f_cnt_t attackFrames = params->getLfoAttackFrames(); + const f_cnt_t oscillationFrames = params->getLfoOscillationFrames(); + const bool x100 = params->getX100Model().value(); + const int waveModel = params->getLfoWaveModel().value(); + + int LFO_GRAPH_W = m_lfoGraph.width() - 3; // subtract border + int LFO_GRAPH_H = m_lfoGraph.height() - 6; // subtract border + int graph_x_base = 2; + int graph_y_base = 3 + LFO_GRAPH_H / 2; + + const float frames_for_graph = SECS_PER_LFO_OSCILLATION * + Engine::audioEngine()->baseSampleRate() / 10; + + const float gray = 1.0 - fabsf(amount); + const QColor penColor(static_cast(96 * gray), static_cast(255 - 159 * gray), static_cast(128 - 32 * gray)); + p.setPen(QPen(penColor, 1.5)); + + float osc_frames = oscillationFrames; + + if (x100) + { + osc_frames *= 100.0f; + } + + float old_y = 0; + for (int x = 0; x <= LFO_GRAPH_W; ++x) + { + float val = 0.0; + float cur_sample = x * frames_for_graph / LFO_GRAPH_W; + if (static_cast(cur_sample) > predelayFrames) + { + float phase = (cur_sample -= predelayFrames) / osc_frames; + switch (static_cast(waveModel)) + { + case EnvelopeAndLfoParameters::LfoShape::SineWave: + default: + val = Oscillator::sinSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::TriangleWave: + val = Oscillator::triangleSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::SawWave: + val = Oscillator::sawSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::SquareWave: + val = Oscillator::squareSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::RandomWave: + if (x % (int)(900 * lfoSpeed + 1) == 0) + { + m_randomGraph = Oscillator::noiseSample(0.0); + } + val = m_randomGraph; + break; + case EnvelopeAndLfoParameters::LfoShape::UserDefinedWave: + val = Oscillator::userWaveSample(m_params->getLfoUserWave().get(), phase); + break; + } + + if (static_cast(cur_sample) <= attackFrames) + { + val *= cur_sample / attackFrames; + } + } + + float cur_y = -LFO_GRAPH_H / 2.0f * val; + p.drawLine(QLineF(graph_x_base + x - 1, graph_y_base + old_y, graph_x_base + x, graph_y_base + cur_y)); + old_y = cur_y; + } + + // Draw the info text + int ms_per_osc = static_cast(SECS_PER_LFO_OSCILLATION * lfoSpeed * 1000.0); + p.setFont(pointSize(p.font(), 8)); + p.setPen(QColor(201, 201, 225)); + p.drawText(4, m_lfoGraph.height() - 6, tr("ms/LFO:")); + p.drawText(52, m_lfoGraph.height() - 6, QString::number(ms_per_osc)); +} + +void LfoGraph::toggleAmountModel() +{ + auto* params = castModel(); + auto& lfoAmountModel = params->getLfoAmountModel(); + if (lfoAmountModel.value() < 1.0) + { + lfoAmountModel.setValue(1.0); + } + else + { + lfoAmountModel.setValue(0.0); + } +} + +} // namespace gui + +} // namespace lmms From 1f71d65d1e51855dedc87f1ebda06f4364a60f7b Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 4 Apr 2024 15:15:26 +0200 Subject: [PATCH 3/7] EnvelopeAndLfoView with layout Use layouts to align the elements of the `EnvelopeAndLfoView`. This removes lots of hard-coded values. Add helper lambdas for the repeated creation of `Knob` and `PixmapButton` instances. The spacing between the envelope and LFO should be removed once there is a more open layout. --- src/gui/instrument/EnvelopeAndLfoView.cpp | 233 ++++++++++------------ 1 file changed, 105 insertions(+), 128 deletions(-) diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index 6b8dc33c961..c55f75b079e 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -39,159 +39,116 @@ #include "TextFloat.h" #include "Track.h" +#include + + namespace lmms { namespace gui { -const int ENV_GRAPH_X = 6; -const int ENV_GRAPH_Y = 6; - -const int ENV_KNOBS_Y = 43; -const int ENV_KNOBS_LBL_Y = ENV_KNOBS_Y+35; -const int KNOB_X_SPACING = 32; -const int PREDELAY_KNOB_X = 6; -const int ATTACK_KNOB_X = PREDELAY_KNOB_X+KNOB_X_SPACING; -const int HOLD_KNOB_X = ATTACK_KNOB_X+KNOB_X_SPACING; -const int DECAY_KNOB_X = HOLD_KNOB_X+KNOB_X_SPACING; -const int SUSTAIN_KNOB_X = DECAY_KNOB_X+KNOB_X_SPACING; -const int RELEASE_KNOB_X = SUSTAIN_KNOB_X+KNOB_X_SPACING; -const int AMOUNT_KNOB_X = RELEASE_KNOB_X+KNOB_X_SPACING; - -const int LFO_GRAPH_X = 6; -const int LFO_GRAPH_Y = ENV_KNOBS_LBL_Y+14; -const int LFO_KNOB_Y = LFO_GRAPH_Y-2; -const int LFO_PREDELAY_KNOB_X = LFO_GRAPH_X + 100; -const int LFO_ATTACK_KNOB_X = LFO_PREDELAY_KNOB_X+KNOB_X_SPACING; -const int LFO_SPEED_KNOB_X = LFO_ATTACK_KNOB_X+KNOB_X_SPACING; -const int LFO_AMOUNT_KNOB_X = LFO_SPEED_KNOB_X+KNOB_X_SPACING; -const int LFO_SHAPES_X = LFO_GRAPH_X;//PREDELAY_KNOB_X; -const int LFO_SHAPES_Y = LFO_GRAPH_Y + 50; - -EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : - QWidget( _parent ), - ModelView( nullptr, this ), - m_params( nullptr ) +EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : + QWidget(parent), + ModelView(nullptr, this), + m_params(nullptr) { - m_envelopeGraph = new EnvelopeGraph(this); - m_envelopeGraph->move(ENV_GRAPH_X, ENV_GRAPH_Y); + // Helper lambdas for consistent repeated buiding of certain widgets + auto buildKnob = [&](const QString & label, const QString& hintText) + { + auto knob = new Knob(KnobType::Bright26, this); + knob->setLabel(label); + knob->setHintText(hintText, ""); + + return knob; + }; + + auto buildPixmapButton = [&](const QString& activePixmap, const QString& inactivePixmap) + { + auto button = new PixmapButton(this, nullptr); + button->setActiveGraphic(embed::getIconPixmap(activePixmap)); + button->setInactiveGraphic(embed::getIconPixmap(inactivePixmap)); - m_predelayKnob = new Knob( KnobType::Bright26, this ); - m_predelayKnob->setLabel( tr( "DEL" ) ); - m_predelayKnob->move( PREDELAY_KNOB_X, ENV_KNOBS_Y ); - m_predelayKnob->setHintText( tr( "Pre-delay:" ), "" ); + return button; + }; + QVBoxLayout* mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(5, 5, 5, 5); - m_attackKnob = new Knob( KnobType::Bright26, this ); - m_attackKnob->setLabel( tr( "ATT" ) ); - m_attackKnob->move( ATTACK_KNOB_X, ENV_KNOBS_Y ); - m_attackKnob->setHintText( tr( "Attack:" ), "" ); + // Envelope + QVBoxLayout* envelopeLayout = new QVBoxLayout(); + mainLayout->addLayout(envelopeLayout); - m_holdKnob = new Knob( KnobType::Bright26, this ); - m_holdKnob->setLabel( tr( "HOLD" ) ); - m_holdKnob->move( HOLD_KNOB_X, ENV_KNOBS_Y ); - m_holdKnob->setHintText( tr( "Hold:" ), "" ); + QHBoxLayout* graphAndAmountLayout = new QHBoxLayout(); + envelopeLayout->addLayout(graphAndAmountLayout); + m_envelopeGraph = new EnvelopeGraph(this); + graphAndAmountLayout->addWidget(m_envelopeGraph); - m_decayKnob = new Knob( KnobType::Bright26, this ); - m_decayKnob->setLabel( tr( "DEC" ) ); - m_decayKnob->move( DECAY_KNOB_X, ENV_KNOBS_Y ); - m_decayKnob->setHintText( tr( "Decay:" ), "" ); + m_amountKnob = buildKnob(tr("AMT"), tr("Modulation amount:")); + graphAndAmountLayout->addWidget(m_amountKnob, 0, Qt::AlignCenter); + QHBoxLayout* envKnobsLayout = new QHBoxLayout(); + envelopeLayout->addLayout(envKnobsLayout); - m_sustainKnob = new Knob( KnobType::Bright26, this ); - m_sustainKnob->setLabel( tr( "SUST" ) ); - m_sustainKnob->move( SUSTAIN_KNOB_X, ENV_KNOBS_Y ); - m_sustainKnob->setHintText( tr( "Sustain:" ), "" ); + m_predelayKnob = buildKnob(tr("DEL"), tr("Pre-delay:")); + envKnobsLayout->addWidget(m_predelayKnob); + m_attackKnob = buildKnob(tr("ATT"), tr("Attack:")); + envKnobsLayout->addWidget(m_attackKnob); - m_releaseKnob = new Knob( KnobType::Bright26, this ); - m_releaseKnob->setLabel( tr( "REL" ) ); - m_releaseKnob->move( RELEASE_KNOB_X, ENV_KNOBS_Y ); - m_releaseKnob->setHintText( tr( "Release:" ), "" ); + m_holdKnob = buildKnob(tr("HOLD"), tr("Hold:")); + envKnobsLayout->addWidget(m_holdKnob); + m_decayKnob = buildKnob(tr("DEC"), tr("Decay:")); + envKnobsLayout->addWidget(m_decayKnob); - m_amountKnob = new Knob( KnobType::Bright26, this ); - m_amountKnob->setLabel( tr( "AMT" ) ); - m_amountKnob->move( AMOUNT_KNOB_X, ENV_GRAPH_Y ); - m_amountKnob->setHintText( tr( "Modulation amount:" ), "" ); + m_sustainKnob = buildKnob(tr("SUST"), tr("Sustain:")); + envKnobsLayout->addWidget(m_sustainKnob); + m_releaseKnob = buildKnob(tr("REL"), tr("Release:")); + envKnobsLayout->addWidget(m_releaseKnob); - m_lfoGraph = new LfoGraph(this); - m_lfoGraph->move(LFO_GRAPH_X, LFO_GRAPH_Y); + // Add some space between the envelope and LFO section + mainLayout->addSpacing(10); - m_lfoPredelayKnob = new Knob( KnobType::Bright26, this ); - m_lfoPredelayKnob->setLabel( tr( "DEL" ) ); - m_lfoPredelayKnob->move( LFO_PREDELAY_KNOB_X, LFO_KNOB_Y ); - m_lfoPredelayKnob->setHintText( tr( "Pre-delay:" ), "" ); + // LFO - m_lfoAttackKnob = new Knob( KnobType::Bright26, this ); - m_lfoAttackKnob->setLabel( tr( "ATT" ) ); - m_lfoAttackKnob->move( LFO_ATTACK_KNOB_X, LFO_KNOB_Y ); - m_lfoAttackKnob->setHintText( tr( "Attack:" ), "" ); + QHBoxLayout* lfoLayout = new QHBoxLayout(); + mainLayout->addLayout(lfoLayout); + QVBoxLayout* graphAndTypesLayout = new QVBoxLayout(); + lfoLayout->addLayout(graphAndTypesLayout); - m_lfoSpeedKnob = new TempoSyncKnob( KnobType::Bright26, this ); - m_lfoSpeedKnob->setLabel( tr( "SPD" ) ); - m_lfoSpeedKnob->move( LFO_SPEED_KNOB_X, LFO_KNOB_Y ); - m_lfoSpeedKnob->setHintText( tr( "Frequency:" ), "" ); - - - m_lfoAmountKnob = new Knob( KnobType::Bright26, this ); - m_lfoAmountKnob->setLabel( tr( "AMT" ) ); - m_lfoAmountKnob->move( LFO_AMOUNT_KNOB_X, LFO_KNOB_Y ); - m_lfoAmountKnob->setHintText( tr( "Modulation amount:" ), "" ); - - auto sin_lfo_btn = new PixmapButton(this, nullptr); - sin_lfo_btn->move( LFO_SHAPES_X, LFO_SHAPES_Y ); - sin_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "sin_wave_active" ) ); - sin_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "sin_wave_inactive" ) ); - - auto triangle_lfo_btn = new PixmapButton(this, nullptr); - triangle_lfo_btn->move( LFO_SHAPES_X+15, LFO_SHAPES_Y ); - triangle_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "triangle_wave_active" ) ); - triangle_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "triangle_wave_inactive" ) ); - - auto saw_lfo_btn = new PixmapButton(this, nullptr); - saw_lfo_btn->move( LFO_SHAPES_X+30, LFO_SHAPES_Y ); - saw_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "saw_wave_active" ) ); - saw_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "saw_wave_inactive" ) ); - - auto sqr_lfo_btn = new PixmapButton(this, nullptr); - sqr_lfo_btn->move( LFO_SHAPES_X+45, LFO_SHAPES_Y ); - sqr_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "square_wave_active" ) ); - sqr_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "square_wave_inactive" ) ); - - m_userLfoBtn = new PixmapButton( this, nullptr ); - m_userLfoBtn->move( LFO_SHAPES_X+75, LFO_SHAPES_Y ); - m_userLfoBtn->setActiveGraphic( embed::getIconPixmap( - "usr_wave_active" ) ); - m_userLfoBtn->setInactiveGraphic( embed::getIconPixmap( - "usr_wave_inactive" ) ); + m_lfoGraph = new LfoGraph(this); + graphAndTypesLayout->addWidget(m_lfoGraph); + + QHBoxLayout* typesLayout = new QHBoxLayout(); + graphAndTypesLayout->addLayout(typesLayout); + typesLayout->setContentsMargins(0, 0, 0, 0); + typesLayout->setSpacing(0); + + auto sin_lfo_btn = buildPixmapButton("sin_wave_active", "sin_wave_inactive"); + auto triangle_lfo_btn = buildPixmapButton("triangle_wave_active", "triangle_wave_inactive"); + auto saw_lfo_btn = buildPixmapButton("saw_wave_active", "saw_wave_inactive"); + auto sqr_lfo_btn = buildPixmapButton("square_wave_active","square_wave_inactive"); + auto random_lfo_btn = buildPixmapButton("random_wave_active", "random_wave_inactive"); + m_userLfoBtn = buildPixmapButton("usr_wave_active", "usr_wave_inactive"); connect( m_userLfoBtn, SIGNAL(toggled(bool)), this, SLOT(lfoUserWaveChanged())); - auto random_lfo_btn = new PixmapButton(this, nullptr); - random_lfo_btn->move( LFO_SHAPES_X+60, LFO_SHAPES_Y ); - random_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "random_wave_active" ) ); - random_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "random_wave_inactive" ) ); + typesLayout->addWidget(sin_lfo_btn); + typesLayout->addWidget(triangle_lfo_btn); + typesLayout->addWidget(saw_lfo_btn); + typesLayout->addWidget(sqr_lfo_btn); + typesLayout->addWidget(random_lfo_btn); + typesLayout->addWidget(m_userLfoBtn); - m_lfoWaveBtnGrp = new automatableButtonGroup( this ); + m_lfoWaveBtnGrp = new automatableButtonGroup(this); m_lfoWaveBtnGrp->addButton( sin_lfo_btn ); m_lfoWaveBtnGrp->addButton( triangle_lfo_btn ); m_lfoWaveBtnGrp->addButton( saw_lfo_btn ); @@ -199,19 +156,39 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : m_lfoWaveBtnGrp->addButton( m_userLfoBtn ); m_lfoWaveBtnGrp->addButton( random_lfo_btn ); - m_x100Cb = new LedCheckBox( tr( "FREQ x 100" ), this ); + QVBoxLayout* knobsAndCheckBoxesLayout = new QVBoxLayout(); + lfoLayout->addLayout(knobsAndCheckBoxesLayout); + + QHBoxLayout* lfoKnobsLayout = new QHBoxLayout(); + knobsAndCheckBoxesLayout->addLayout(lfoKnobsLayout); + + m_lfoPredelayKnob = buildKnob(tr("DEL"), tr("Pre-delay:")); + lfoKnobsLayout->addWidget(m_lfoPredelayKnob); + + m_lfoAttackKnob = buildKnob(tr("ATT"), tr("Attack:")); + lfoKnobsLayout->addWidget(m_lfoAttackKnob); + + m_lfoSpeedKnob = new TempoSyncKnob( KnobType::Bright26, this ); + m_lfoSpeedKnob->setLabel( tr("SPD") ); + m_lfoSpeedKnob->setHintText( tr("Frequency:"), ""); + lfoKnobsLayout->addWidget(m_lfoSpeedKnob); + + m_lfoAmountKnob = buildKnob(tr("AMT"), tr("Modulation amount:")); + lfoKnobsLayout->addWidget(m_lfoAmountKnob); + + QVBoxLayout* checkBoxesLayout = new QVBoxLayout(); + knobsAndCheckBoxesLayout->addLayout(checkBoxesLayout); + + m_x100Cb = new LedCheckBox( tr("FREQ x 100"), this ); m_x100Cb->setFont(pointSize(m_x100Cb->font(), 6.5)); - m_x100Cb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 36 ); m_x100Cb->setToolTip(tr("Multiply LFO frequency by 100")); + checkBoxesLayout->addWidget(m_x100Cb); - - m_controlEnvAmountCb = new LedCheckBox( tr( "MODULATE ENV AMOUNT" ), + m_controlEnvAmountCb = new LedCheckBox( tr("MODULATE ENV AMOUNT"), this ); - m_controlEnvAmountCb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 54 ); m_controlEnvAmountCb->setFont(pointSize(m_controlEnvAmountCb->font(), 6.5)); - m_controlEnvAmountCb->setToolTip( - tr( "Control envelope amount by this LFO" ) ); - + m_controlEnvAmountCb->setToolTip( tr("Control envelope amount by this LFO") ); + checkBoxesLayout->addWidget(m_controlEnvAmountCb); setAcceptDrops( true ); } From 4373003371dd6d1c496c4932029bb7c1d5927e77 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 4 Apr 2024 15:53:13 +0200 Subject: [PATCH 4/7] Layouts for InstrumentSoundShapingView Use layouts to align the elements of the `InstrumentSoundShapingView`. --- .../instrument/InstrumentSoundShapingView.cpp | 81 ++++++++----------- 1 file changed, 34 insertions(+), 47 deletions(-) diff --git a/src/gui/instrument/InstrumentSoundShapingView.cpp b/src/gui/instrument/InstrumentSoundShapingView.cpp index 59df3097cb2..604e528d217 100644 --- a/src/gui/instrument/InstrumentSoundShapingView.cpp +++ b/src/gui/instrument/InstrumentSoundShapingView.cpp @@ -23,6 +23,7 @@ */ #include +#include #include "InstrumentSoundShapingView.h" #include "EnvelopeAndLfoParameters.h" @@ -37,69 +38,55 @@ namespace lmms::gui { -const int TARGETS_TABWIDGET_X = 4; -const int TARGETS_TABWIDGET_Y = 5; -const int TARGETS_TABWIDGET_WIDTH = 242; -const int TARGETS_TABWIDGET_HEIGTH = 175; - -const int FILTER_GROUPBOX_X = TARGETS_TABWIDGET_X; -const int FILTER_GROUPBOX_Y = TARGETS_TABWIDGET_Y+TARGETS_TABWIDGET_HEIGTH+5; -const int FILTER_GROUPBOX_WIDTH = TARGETS_TABWIDGET_WIDTH; -const int FILTER_GROUPBOX_HEIGHT = 245-FILTER_GROUPBOX_Y; - - - -InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) : - QWidget( _parent ), - ModelView( nullptr, this ), - m_ss( nullptr ) +InstrumentSoundShapingView::InstrumentSoundShapingView(QWidget* parent) : + QWidget(parent), + ModelView(nullptr, this), + m_ss(nullptr) { - m_targetsTabWidget = new TabWidget( tr( "TARGET" ), this ); - m_targetsTabWidget->setGeometry( TARGETS_TABWIDGET_X, - TARGETS_TABWIDGET_Y, - TARGETS_TABWIDGET_WIDTH, - TARGETS_TABWIDGET_HEIGTH ); + QVBoxLayout* mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(5, 5, 5, 5); - for( int i = 0; i < InstrumentSoundShaping::NumTargets; ++i ) + m_targetsTabWidget = new TabWidget(tr("TARGET"), this); + + for (int i = 0; i < InstrumentSoundShaping::NumTargets; ++i) { - m_envLfoViews[i] = new EnvelopeAndLfoView( m_targetsTabWidget ); - m_targetsTabWidget->addTab( m_envLfoViews[i], - tr( InstrumentSoundShaping::targetNames[i][0] ), - nullptr ); + m_envLfoViews[i] = new EnvelopeAndLfoView(m_targetsTabWidget); + m_targetsTabWidget->addTab(m_envLfoViews[i], + tr(InstrumentSoundShaping::targetNames[i][0]), nullptr); } + mainLayout->addWidget(m_targetsTabWidget, 1); - m_filterGroupBox = new GroupBox( tr( "FILTER" ), this ); - m_filterGroupBox->setGeometry( FILTER_GROUPBOX_X, FILTER_GROUPBOX_Y, - FILTER_GROUPBOX_WIDTH, - FILTER_GROUPBOX_HEIGHT ); + m_filterGroupBox = new GroupBox(tr("FILTER"), this); + QHBoxLayout* filterLayout = new QHBoxLayout(m_filterGroupBox); + QMargins filterMargins = filterLayout->contentsMargins(); + filterMargins.setTop(18); + filterLayout->setContentsMargins(filterMargins); - m_filterComboBox = new ComboBox( m_filterGroupBox ); - m_filterComboBox->setGeometry( 14, 22, 120, ComboBox::DEFAULT_HEIGHT ); + m_filterComboBox = new ComboBox(m_filterGroupBox); m_filterComboBox->setFont(pointSize(m_filterComboBox->font(), 8)); + filterLayout->addWidget(m_filterComboBox); + m_filterCutKnob = new Knob(KnobType::Bright26, m_filterGroupBox); + m_filterCutKnob->setLabel(tr("FREQ")); + m_filterCutKnob->setHintText(tr("Cutoff frequency:"), " " + tr("Hz")); + filterLayout->addWidget(m_filterCutKnob); - m_filterCutKnob = new Knob( KnobType::Bright26, m_filterGroupBox ); - m_filterCutKnob->setLabel( tr( "FREQ" ) ); - m_filterCutKnob->move( 140, 18 ); - m_filterCutKnob->setHintText( tr( "Cutoff frequency:" ), " " + tr( "Hz" ) ); - + m_filterResKnob = new Knob(KnobType::Bright26, m_filterGroupBox); + m_filterResKnob->setLabel(tr("Q/RESO")); + m_filterResKnob->setHintText(tr("Q/Resonance:"), ""); + filterLayout->addWidget(m_filterResKnob); - m_filterResKnob = new Knob( KnobType::Bright26, m_filterGroupBox ); - m_filterResKnob->setLabel( tr( "Q/RESO" ) ); - m_filterResKnob->move( 196, 18 ); - m_filterResKnob->setHintText( tr( "Q/Resonance:" ), "" ); + mainLayout->addWidget(m_filterGroupBox); - m_singleStreamInfoLabel = new QLabel( tr( "Envelopes, LFOs and filters are not supported by the current instrument." ), this ); - m_singleStreamInfoLabel->setWordWrap( true ); + m_singleStreamInfoLabel = new QLabel(tr("Envelopes, LFOs and filters are not supported by the current instrument."), this); + m_singleStreamInfoLabel->setWordWrap(true); m_singleStreamInfoLabel->setFont(pointSize(m_singleStreamInfoLabel->font(), 8)); + m_singleStreamInfoLabel->setFixedWidth(242); - m_singleStreamInfoLabel->setGeometry( TARGETS_TABWIDGET_X, - TARGETS_TABWIDGET_Y, - TARGETS_TABWIDGET_WIDTH, - TARGETS_TABWIDGET_HEIGTH ); + mainLayout->addWidget(m_singleStreamInfoLabel, 0, Qt::AlignTop); } From 3de4e19937da14d1193eaef9a5fea98fddf07ed2 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 4 Apr 2024 16:18:02 +0200 Subject: [PATCH 5/7] Info text improvements in LFO graph Draw the info text at around 20% of the LFO graph's height. This prepares the dialog to be scaled later. Write "1000 ms/LFO" instead of "ms/LFO: 1000" with a larger gap. --- src/gui/instrument/LfoGraph.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/instrument/LfoGraph.cpp b/src/gui/instrument/LfoGraph.cpp index 458c335329a..9d208b45b62 100644 --- a/src/gui/instrument/LfoGraph.cpp +++ b/src/gui/instrument/LfoGraph.cpp @@ -151,10 +151,12 @@ void LfoGraph::paintEvent(QPaintEvent*) // Draw the info text int ms_per_osc = static_cast(SECS_PER_LFO_OSCILLATION * lfoSpeed * 1000.0); - p.setFont(pointSize(p.font(), 8)); + + QFont f = p.font(); + f.setPixelSize(height() * 0.2); + p.setFont(f); p.setPen(QColor(201, 201, 225)); - p.drawText(4, m_lfoGraph.height() - 6, tr("ms/LFO:")); - p.drawText(52, m_lfoGraph.height() - 6, QString::number(ms_per_osc)); + p.drawText(4, m_lfoGraph.height() - 6, tr("%1 ms/LFO").arg(ms_per_osc)); } void LfoGraph::toggleAmountModel() From 5007b8ec239f2a90851bcfeb4f27600e57a77adb Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 4 Apr 2024 22:38:26 +0200 Subject: [PATCH 6/7] Code review changes Whitespace and formatting. --- include/EnvelopeGraph.h | 2 +- include/LfoGraph.h | 2 +- src/gui/instrument/EnvelopeAndLfoView.cpp | 29 +++++++++-------- .../instrument/InstrumentSoundShapingView.cpp | 2 +- src/gui/instrument/LfoGraph.cpp | 31 +++++++------------ 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/include/EnvelopeGraph.h b/include/EnvelopeGraph.h index 00a8d4a228b..82d4d00462b 100644 --- a/include/EnvelopeGraph.h +++ b/include/EnvelopeGraph.h @@ -58,7 +58,7 @@ class EnvelopeGraph : public QWidget, public ModelView private: QPixmap m_envGraph = embed::getIconPixmap("envelope_graph"); - EnvelopeAndLfoParameters * m_params; + EnvelopeAndLfoParameters* m_params; }; } // namespace gui diff --git a/include/LfoGraph.h b/include/LfoGraph.h index 486139f8b4d..a64b5fd834c 100644 --- a/include/LfoGraph.h +++ b/include/LfoGraph.h @@ -58,7 +58,7 @@ class LfoGraph : public QWidget, public ModelView private: QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph"); - EnvelopeAndLfoParameters * m_params; + EnvelopeAndLfoParameters* m_params; float m_randomGraph {0.}; }; diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index f4ed554d7ae..c2e642b015e 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -54,7 +54,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : m_params(nullptr) { // Helper lambdas for consistent repeated buiding of certain widgets - auto buildKnob = [&](const QString & label, const QString& hintText) + auto buildKnob = [&](const QString& label, const QString& hintText) { auto knob = new Knob(KnobType::Bright26, this); knob->setLabel(label); @@ -138,8 +138,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : auto random_lfo_btn = buildPixmapButton("random_wave_active", "random_wave_inactive"); m_userLfoBtn = buildPixmapButton("usr_wave_active", "usr_wave_inactive"); - connect( m_userLfoBtn, SIGNAL(toggled(bool)), - this, SLOT(lfoUserWaveChanged())); + connect(m_userLfoBtn, SIGNAL(toggled(bool)), this, SLOT(lfoUserWaveChanged())); typesLayout->addWidget(sin_lfo_btn); typesLayout->addWidget(triangle_lfo_btn); @@ -149,12 +148,12 @@ EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : typesLayout->addWidget(m_userLfoBtn); m_lfoWaveBtnGrp = new automatableButtonGroup(this); - m_lfoWaveBtnGrp->addButton( sin_lfo_btn ); - m_lfoWaveBtnGrp->addButton( triangle_lfo_btn ); - m_lfoWaveBtnGrp->addButton( saw_lfo_btn ); - m_lfoWaveBtnGrp->addButton( sqr_lfo_btn ); - m_lfoWaveBtnGrp->addButton( m_userLfoBtn ); - m_lfoWaveBtnGrp->addButton( random_lfo_btn ); + m_lfoWaveBtnGrp->addButton(sin_lfo_btn); + m_lfoWaveBtnGrp->addButton(triangle_lfo_btn); + m_lfoWaveBtnGrp->addButton(saw_lfo_btn); + m_lfoWaveBtnGrp->addButton(sqr_lfo_btn); + m_lfoWaveBtnGrp->addButton(m_userLfoBtn); + m_lfoWaveBtnGrp->addButton(random_lfo_btn); QVBoxLayout* knobsAndCheckBoxesLayout = new QVBoxLayout(); lfoLayout->addLayout(knobsAndCheckBoxesLayout); @@ -168,9 +167,9 @@ EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : m_lfoAttackKnob = buildKnob(tr("ATT"), tr("Attack:")); lfoKnobsLayout->addWidget(m_lfoAttackKnob); - m_lfoSpeedKnob = new TempoSyncKnob( KnobType::Bright26, this ); - m_lfoSpeedKnob->setLabel( tr("SPD") ); - m_lfoSpeedKnob->setHintText( tr("Frequency:"), ""); + m_lfoSpeedKnob = new TempoSyncKnob(KnobType::Bright26, this); + m_lfoSpeedKnob->setLabel(tr("SPD")); + m_lfoSpeedKnob->setHintText(tr("Frequency:"), ""); lfoKnobsLayout->addWidget(m_lfoSpeedKnob); m_lfoAmountKnob = buildKnob(tr("AMT"), tr("Modulation amount:")); @@ -179,15 +178,15 @@ EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : QVBoxLayout* checkBoxesLayout = new QVBoxLayout(); knobsAndCheckBoxesLayout->addLayout(checkBoxesLayout); - m_x100Cb = new LedCheckBox( tr("FREQ x 100"), this ); + m_x100Cb = new LedCheckBox(tr("FREQ x 100"), this); m_x100Cb->setToolTip(tr("Multiply LFO frequency by 100")); checkBoxesLayout->addWidget(m_x100Cb); m_controlEnvAmountCb = new LedCheckBox(tr("MOD ENV AMOUNT"), this); - m_controlEnvAmountCb->setToolTip( tr("Control envelope amount by this LFO") ); + m_controlEnvAmountCb->setToolTip(tr("Control envelope amount by this LFO")); checkBoxesLayout->addWidget(m_controlEnvAmountCb); - setAcceptDrops( true ); + setAcceptDrops(true); } diff --git a/src/gui/instrument/InstrumentSoundShapingView.cpp b/src/gui/instrument/InstrumentSoundShapingView.cpp index abb3dd92bab..3d91875206f 100644 --- a/src/gui/instrument/InstrumentSoundShapingView.cpp +++ b/src/gui/instrument/InstrumentSoundShapingView.cpp @@ -52,7 +52,7 @@ InstrumentSoundShapingView::InstrumentSoundShapingView(QWidget* parent) : { m_envLfoViews[i] = new EnvelopeAndLfoView(m_targetsTabWidget); m_targetsTabWidget->addTab(m_envLfoViews[i], - tr(InstrumentSoundShaping::targetNames[i][0]), nullptr); + tr(InstrumentSoundShaping::targetNames[i][0]), nullptr); } mainLayout->addWidget(m_targetsTabWidget, 1); diff --git a/src/gui/instrument/LfoGraph.cpp b/src/gui/instrument/LfoGraph.cpp index 9d208b45b62..a2b6eaca851 100644 --- a/src/gui/instrument/LfoGraph.cpp +++ b/src/gui/instrument/LfoGraph.cpp @@ -70,11 +70,8 @@ void LfoGraph::paintEvent(QPaintEvent*) // Draw the graph background p.drawPixmap(rect(), m_lfoGraph); - const auto * params = castModel(); - if (!params) - { - return; - } + const auto* params = castModel(); + if (!params) { return; } const float amount = params->getLfoAmountModel().value(); const float lfoSpeed = params->getLfoSpeedModel().value(); @@ -89,19 +86,19 @@ void LfoGraph::paintEvent(QPaintEvent*) int graph_x_base = 2; int graph_y_base = 3 + LFO_GRAPH_H / 2; - const float frames_for_graph = SECS_PER_LFO_OSCILLATION * - Engine::audioEngine()->baseSampleRate() / 10; + const float frames_for_graph = + SECS_PER_LFO_OSCILLATION * Engine::audioEngine()->baseSampleRate() / 10; const float gray = 1.0 - fabsf(amount); - const QColor penColor(static_cast(96 * gray), static_cast(255 - 159 * gray), static_cast(128 - 32 * gray)); + const auto red = static_cast(96 * gray); + const auto green = static_cast(255 - 159 * gray); + const auto blue = static_cast(128 - 32 * gray); + const QColor penColor(red, green, blue); p.setPen(QPen(penColor, 1.5)); float osc_frames = oscillationFrames; - if (x100) - { - osc_frames *= 100.0f; - } + if (x100) { osc_frames *= 100.0f; } float old_y = 0; for (int x = 0; x <= LFO_GRAPH_W; ++x) @@ -163,14 +160,8 @@ void LfoGraph::toggleAmountModel() { auto* params = castModel(); auto& lfoAmountModel = params->getLfoAmountModel(); - if (lfoAmountModel.value() < 1.0) - { - lfoAmountModel.setValue(1.0); - } - else - { - lfoAmountModel.setValue(0.0); - } + + lfoAmountModel.setValue(lfoAmountModel.value() < 1.0 ? 1.0 : 0.0); } } // namespace gui From 618707fe3047e47daea9234625301de86d8fcda2 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 5 Apr 2024 11:02:04 +0200 Subject: [PATCH 7/7] Code review changes * Remove some "pragma once" for now * Adjust include orders * Variable initialization in headers * Prevention of most vexing parses --- include/EnvelopeGraph.h | 2 -- include/InstrumentSoundShapingView.h | 2 +- include/LfoGraph.h | 6 ++---- src/gui/instrument/InstrumentSoundShapingView.cpp | 6 +++--- src/gui/instrument/LfoGraph.cpp | 11 +++++------ 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/include/EnvelopeGraph.h b/include/EnvelopeGraph.h index 82d4d00462b..8cfeaf11f2d 100644 --- a/include/EnvelopeGraph.h +++ b/include/EnvelopeGraph.h @@ -23,8 +23,6 @@ * */ -#pragma once - #ifndef LMMS_GUI_ENVELOPE_GRAPH_H #define LMMS_GUI_ENVELOPE_GRAPH_H diff --git a/include/InstrumentSoundShapingView.h b/include/InstrumentSoundShapingView.h index 8f671514a89..c9caea28c37 100644 --- a/include/InstrumentSoundShapingView.h +++ b/include/InstrumentSoundShapingView.h @@ -56,7 +56,7 @@ class InstrumentSoundShapingView : public QWidget, public ModelView void modelChanged() override; - InstrumentSoundShaping * m_ss; + InstrumentSoundShaping * m_ss = nullptr; TabWidget * m_targetsTabWidget; EnvelopeAndLfoView * m_envLfoViews[InstrumentSoundShaping::NumTargets]; diff --git a/include/LfoGraph.h b/include/LfoGraph.h index a64b5fd834c..733db3a349c 100644 --- a/include/LfoGraph.h +++ b/include/LfoGraph.h @@ -1,5 +1,5 @@ /* - * EnvelopeGraph.h - Displays LFO graphs + * LfoGraph.h - Displays LFO graphs * * Copyright (c) 2004-2009 Tobias Doerffel * Copyright (c) 2024- Michael Gregorius @@ -23,8 +23,6 @@ * */ -#pragma once - #ifndef LMMS_GUI_LFO_GRAPH_H #define LMMS_GUI_LFO_GRAPH_H @@ -58,7 +56,7 @@ class LfoGraph : public QWidget, public ModelView private: QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph"); - EnvelopeAndLfoParameters* m_params; + EnvelopeAndLfoParameters* m_params = nullptr; float m_randomGraph {0.}; }; diff --git a/src/gui/instrument/InstrumentSoundShapingView.cpp b/src/gui/instrument/InstrumentSoundShapingView.cpp index 3d91875206f..a3a78e25670 100644 --- a/src/gui/instrument/InstrumentSoundShapingView.cpp +++ b/src/gui/instrument/InstrumentSoundShapingView.cpp @@ -22,10 +22,11 @@ * */ +#include "InstrumentSoundShapingView.h" + #include #include -#include "InstrumentSoundShapingView.h" #include "EnvelopeAndLfoParameters.h" #include "EnvelopeAndLfoView.h" #include "ComboBox.h" @@ -40,8 +41,7 @@ namespace lmms::gui InstrumentSoundShapingView::InstrumentSoundShapingView(QWidget* parent) : QWidget(parent), - ModelView(nullptr, this), - m_ss(nullptr) + ModelView(nullptr, this) { QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(5, 5, 5, 5); diff --git a/src/gui/instrument/LfoGraph.cpp b/src/gui/instrument/LfoGraph.cpp index a2b6eaca851..d02f583d0c7 100644 --- a/src/gui/instrument/LfoGraph.cpp +++ b/src/gui/instrument/LfoGraph.cpp @@ -1,5 +1,5 @@ /* - * EnvelopeGraph.cpp - Displays LFO graphs + * LfoGraph.cpp - Displays LFO graphs * * Copyright (c) 2004-2014 Tobias Doerffel * Copyright (c) 2024- Michael Gregorius @@ -23,11 +23,11 @@ * */ +#include "LfoGraph.h" + #include #include -#include "LfoGraph.h" - #include "EnvelopeAndLfoParameters.h" #include "Oscillator.h" @@ -43,8 +43,7 @@ namespace gui LfoGraph::LfoGraph(QWidget* parent) : QWidget(parent), - ModelView(nullptr, this), - m_params(nullptr) + ModelView(nullptr, this) { setFixedSize(m_lfoGraph.size()); } @@ -64,7 +63,7 @@ void LfoGraph::mousePressEvent(QMouseEvent* me) void LfoGraph::paintEvent(QPaintEvent*) { - QPainter p(this); + QPainter p{this}; p.setRenderHint(QPainter::Antialiasing); // Draw the graph background