From b6d6509068c97691d7fa7f30d317bb852da35247 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 29 May 2025 19:35:48 +0200 Subject: [PATCH] Individual knob labels rendered using the widget's font size (#7525) Adjust the `Knob` class so that it defaults to taking the font size of the knob's font into account when rendering its label. This allows to use labels of different sizes for different knobs. Previously all knob labels throughout the whole application were rendered with the same fixed font size. Hence it was not possible to adjust the label size for a single knob because this would have affected all other knobs as well. The new implementation also allows the knobs to pick up CSS rules. To be able to control the knob behavior two new constructors have been added to the `Knob` class. Both constructors are concerned with creating knobs with labels and therefore they directly take the label text as a parameter. This removes numerous explicit calls to `setLabel` in the code. There is only one constructor that allows to switch between the new behavior of taking the widget's font size into account and the old legacy behavior of always rendering with the same fixed font size of `SMALL_FONT_SIZE`. The parameter was modelled as an enum to make it easier to find the remaining knob instances that use the legacy behavior. This makes it easier to find them in case they should be removed as well. In that case the string `LegacyFixedFontSize` can be searched. The other new constructor allows to directly set the knob's (and therefore the label's) font size to a pixel value. Corresponding constructors have been added to `TempoSyncKnob`. The constructors of `KnobControl` and `CustomTextKnob` have been adjusted to take advantage of the new constructors. An usused constructor was removed in `CustomTextKnob`. The method `Knob::setLabel` has been made protected because labels should now be set through the new constructors. A new property called `m_fixedFontSizeLabelRendering` was added to the `Knob` class. It controls how the labels are rendered. Fixed font size legacy rendering can be activated by calling the protected method `setFixedFontSizeLabelRendering`. The current setting can be queried via `fixedFontSizeLabelRendering`. ## Changes in the plugins Some plugins have been switched to using layouts to organize their widgets so that they can accommodate for knobs with label sizes set by the application font. The fixed font size (legacy) rendering mode is still used in the following places: * EnvelopeAndLfoView * InstrumentSoundShapingView * InstrumentFunctionViews * EffectView * InstrumentTrackView * SampleTrackView * Delay plugin * Carla plugin # individual commit messages What follows are the individual commit messages of the commits that have been squashed into one commit. They might help in case of more detailed investigations of how things came to be. * Knob with correct label rendering Enable the knob to render the label correctly at arbitrary sizes if it's configured to do so. Otherwise it will render like before. The used mode is determined when a label is set for the knob because as long as the label is not set a knob does not have one anyway. The painting code now always renders the label with the font that's set for the widget. The are now two methods to set the label text. The new method `setLabelLegacy` renders the label as before albeit in a slightly adjusted implementation. It now sets the widget font to a fixed pixel size font and then calculates the new widget size as before, i.e. not really taking the size of the font into account. This might lead to overlaps if the font of the knob is large. The method `setLabel` now has an additional (temporary) parameter called `legacyMode`. It is by default set to `true` so that all knobs still render like they did before. This is implemented by delegating to `setLabelLegacy` if it's set to `true`. Otherwise the method calculates the new size of the widget by taking the pixmap and the label with the current font into account. Please note that as of now you must set the knob font before calling any of the methods that sets the label. This is because the new size is only calculated via these code paths. However, this is already much better than only being able to use one hard-coded label size for all knobs. * Switch from `setLabel` to `setLabelLegacy` Switch all callers of `setLabel` to `setLabelLegacy` so that it becomes obvious in which places the old knob implementation is used. * Remove parameter `legacyMode` from `setLabel` Remove the parameter `legacyMode` from `setLabel`. Add the member `m_legacyMode` as it is needed in `Knob::changeEvent` so that we do not switch the behavior when the knob is enabled/disabled. * Extract methods Extract `setLegacyMode` and `updateFixedSize`. Also add the getter `legacyMode`. * Introduce legacy knob builders Introduce legacy knob builders and apply them to the plugins. There are three new methods which encapsulate how to create a corresponding legacy knob: * `Knob::buildLegacyKnob` * `CustomTextKnob::buildLegacyKnob` * `TempoSyncKnob::buildLegacyKnob` These methods set the knob they build to legacy mode and also set a label in legacy mode. The idea is to concentrate the relevant legacy code in these methods. They will later also be useful to quickly find all the places in the application where legacy knobs are used. The three methods are applied to the plugins directory. Most plugins use the build methods to build their knobs which also enables the removal of the explicit calls to `setLabelLegacy` from their code. For some plugins their implementations were adjusted so that they can deal with showing the labels in the applicaiton font, i.e. in the font size of the widget their are contained in. Most of the times this involved removing the fixed size and putting the elements in a layout (while also removing move calls). The following LMMS plugins use the application font now and are thus better readable: * Amplifier * BassBooster * Dispersion * Flanger * Peak Controller * ReverbSC * StereoEnhancer Effect The Vectorscope now shows the "Persist." label in the same size as the label of the check boxes. Setting an empty label was removed for Lb302. * Legacy knob builders in GUI Apply the legacy knob builders in the GUI components. Most components use the legacy knobs until they can be redesigned: * Effect view ("W/D", "DECAY", "GATE") * LFO Controller * Instrument window Everything related to the instrument window is for now kept to use the legacy knobs and should be adjusted at a later point to be more flexible: * Envelope and LFO * Functions * Sound Shaping The Instrument and sample track both use the legacy knobs for the "VOL" and "PAN" knobs. This might be adjusted later. The following components now render the labels of their knobs with the application font size: * MIDI CC Rack * The class `LadspaControlView`, which is not in used anymore Some vertical spacing was added to the MIDI CC Rack for slightly improved separation of the elements. The knobs are center aligned in the layout so that the transition between element under and over "CC 100" is cleaner. Setting the models in an explicit loop was removed and is now done when the knobs are created. ## Technical details Extend `Knob::buildLegacyKnob` with the option to also set the name of the knob. This is needed for some changes in this PR. The method `KnobControl::setText` now needs to distinguish between legacy mode and non-legacy mode. * Remove `Knob::setLabelLegacy` Remove `Knob::setLabelLegacy`. Instead make sure that the `Knob` updates its size in the following situations: * The label is set. * The font changes. * Legacy mode is set or unset (already implemented). The handling of font changes has been added to `Knob::changeEvent`. The update in case of a changed label is added to `Knob::setLabel`. Every client that called `setLabelLegacy` now also sets the legacy font in size `SMALL_FONT_SIZE` as this was previously done in `setLabelLegacy`. The label is set via `setLabel` now. Both actions should result in an up-to-date size. The method `KnobControl::setText` now only sets the label via `setLabel`, assuming that the wrapped knob was already configured correctly to either be a legacy knob or not. * Use descent to calculate base line Use the descent of the font to calculate the distance of the base line from the bottom of the knob widget if we are not in legacy mode. In legacy mode we still assume the descent to have a value of 2, i.e. the base line will always have a distance of 2 from the bottom of the knob widget regardless of the used font. Also refactor the code a bit to make it more manageable. * Extract `Knob::drawLabel` Extract the method `Knob::drawLabel` which draws the label. It is called from `paintEvent`. * Use non-legacy knobs for instrument and sample track Use non-legacy knobs for the "VOL" and "PAN" knobs of the instrument and sample track. This gives a bit more separation between the knob and the label but to make this work the font size had to be decreased by one pixel. * Introduce `buildKnobWithSmallPixelFont` Introduce the builder method `buildKnobWithSmallPixelFont` in `Knob` and `TempoSyncKnob`. It creates a non-legacy knob with a small pixel sized font, i.e. it still uses the small font but with a corrected size computation and corrected space between the knob and the label. It is mostly used in places with manual layouts where there's enough space to have the bit of extra space between the knob and the label. The following plugins use these knobs: * Bitcrush * Crossover EQ * Dual Filter * Dynamics Processor * Multitap Echo * Spectrum analyzer * Mallets * Waveshaper * ZynAddSubFx The "IN" and "OUT" label of the Bitcrush plugin use the default fixed font size now because the plugin uses a pixel based layout. Using the point based application font looked off. They are also used in the following component: * Effect view, i.e. the "W/D", "DECAY", "GATE" knobs of an effect * LFO Controller * Non-legacy knobs for VSTs Use non-legacy knobs with small pixel fonts for the parameter lists of VST instruments and effects. This is accomplished by renaming `CustomTextKnob::buildLegacyKnob` to `buildKnobWithSmallPixelFont` and removing the call to `setLegacyMode`. * Fix styled knobs Fix the handling of styled knobs which are created in non-legacy mode. Styled knobs do not use pixmaps and have no labels. Their size is set from the outside and they are painted within these limits. Hence we should not compute a new size from a pixmap and/or label in `Knob::updateFixedSize`. This fixes the following plugins: * FreeBoy * Kicker * Monstro * Nescaline * Opulenz * Organic * Sf2 Player * sfxr * SID * SlicerT * Triple * Watsyn * Xpressive The functionality broke with commit defa8c0180e. An alternative would have been to check for a styled knob in the contructor or `initUI` method and to set the legacy flag for these. The best solution would likely be to create an own class for styled knobs and to pull that functionality out of `Knob` because they somewhat clash in their handling. * Code review changes Parameter whitespaces in the builder methods of `Knob`. Use `adjustedToPixelSize` in `InstrumentTrackView` and `SampleTrackView`. * Code review changes Make the code that computes the new fixed size in legacy more readable even if it is just legacy code that's was not touched. Add some code documentation. Other cosmetic changes: * Whitespace adjustments * Remove unused parameter in `paintEvent` * Rename `knob_num` to `knobNum` * Add documentation for legacy mode Add some documentation which explains what the effects of legacy mode are. * Code review Remove unnecessary dereference. Also remove unncessary code repetition by introducing `currentParamModel`. * Decrease the label size of some knobs Decrease the size of the following knob labels to 8 pixels: * "VOL" and "PAN" in the instrument and sample track views * "W/D", "DECAY" and "GATE" in the effect view Technically this is accomplished by introducing `Knob::buildKnobWithFixedPixelFont` and `TempoSyncKnob::buildKnobWithFixedPixelFont`. Both versions of `buildKnobWithSmallPixelFont` now also delegate to the new methods. * Adjustments to CrossoverEQControlDialog Commit the adjustments that were done to `CrossoverEQControlDialog` which I had forgotten to add after fixing the merge. * Fix formatting of CrossoverEQControlDialog Fix the formatting of `CrossoverEQControlDialog` which got messed up after copying the code from the current version on GitHub. * Code review changes Use `std::max` instead of `qMax`. Remove some unnecessary whitespace. * Protected legacy mode methods Make `legacyMode` and `setLegacyMode` protected to ensure that legacy knobs can only be built using the factory method `buildLegacyKnob`. In the long term legacy mode should be removed. * Code review: remove indexed access The original request in the code review was to use `size_t` instead of `uint32_t` in the for-loop. However it is possible to completely remove the indexed access and to turn it into a simple iterated for-loop. Also remove code repetition in the calculation of the maximum knob width of the group. Use std::max instead of manual management. * Fix u_int16_t to uint16_t This should hopefully fix the WIndows builds. * Fix AudioFileProcessor knobs Fix a problem with the `AudioFileProcessorWaveView::knob` which is caused by the fact the this knob uses the pixmap based knob type `Bright26` without a label. Most other knobs that inherit from `Knob` set their knob type to `Styled` which means that no pixmap is used to render the knob. In the specific case the knob instance is created and the contructor runs. In the constructor the AFP knob is set to a fixed size of (37,47). However, at a later point the method `Knob::changeEvent` is triggered by Qt due to a font change. This in turn calls `Knob::updateFixedSize` which then recomputes the fixed size and effectively changes the width of the knob to the width of the pixmap which is 27. Because the knob previously was rendered centered with a width of 37 this means that the knob is now effectively shifted by five pixels to the left. This commit counters this effect by moving the affected AFP knobs five pixels to the right. A visual difference between the fixed version and the current master showed no differences. So this should fix the problem. Because setting the knob to a fixed size of (37,47) does not have any lasting effect anyway the code is removed from the constructor of the AFP knob. * Use legacy knobs in EffectView * Legacy knobs for instrument & sample Use legacy knobs for the instrument and sample track view ("VOL", "PAN"). * Add documentation to Knob builder methods Add some documentation to the `Knob` builder methods. Mark `buildLegacyKnob` as deprecated and note that it should not be used in new code. * Ensure legancy rendering for legacy knobs Ensure that legacy knobs are always rendered at a size of 12 pixels, i.e. `SMALL_FONT_SIZE`. The previous implementation used the font metrics of the knob's current font to compute the new fixed size and to render the label. It assumed that the knob was created using `Knob::buildLegacyKnob` and that therefore the font is set to 12 pixels. However, this meant that legacy knobs can still be affected by style sheet settings. The following CSS rule for example resulted in legacy knobs with a larger font size: ``` * { font-size: 18px; } ``` The fix is to use a font with a size of `SMALL_FONT_SIZE` when calculating the fixed size of the `Knob` widget and when rendering it if we are in legacy mode. This ensures that a legacy knob is unaffected by CSS rules. The non-legacy knob still uses the widget's font size and therefore it is affected by CSS rules. However, this is a feature and not a bug because when for example using a rule like the one above the knob does exactly what it's asked to do. * Remove unused constructor Remove an unused constructor from CustomTextKnob * Remove Knob::buildKnobWithSmallPixelFont Remove the builder method `Knob::buildKnobWithSmallPixelFont` and replace it with an equivalent new contstructor which takes the same arguments as the build method. * Remove Knob::buildKnobWithFixedPixelFont Remove `Knob::buildKnobWithFixedPixelFont` as it is not used anymore. Previously it was delegated to by the now removed method `Knob::buildKnobWithSmallPixelFont`. * Constructor for knobs with pixel size labels Remove `TempoSyncKnob::TempoSyncKnob` and add an equivalent constructor. Make `buildKnobWithSmallPixelFont` use the new constructor. * Remove TempoSyncKnob::buildKnobWithSmallPixelFont Remove `TempoSyncKnob::buildKnobWithSmallPixelFont` and make clients use the new constructor. * Remove CustomTextKnob::buildKnobWithSmallPixelFont Remove `CustomTextKnob::buildKnobWithSmallPixelFont` and extend the constructor so that it also takes a label. Previously all constructions went through the build method and now all constructions use the extended constructor. * Knob constructors whichKnob constructors which take labels Add constructors for `Knob` and `TempoSyncKnob` which also take the label text. Make setLabel protected as most knobs should know their labels at construction time. This prevents "chatty" code like the following example: ``` Knob* knob = new Knob(KnobType::Bright26, this); knob->setLabel("My label"); ``` This now becomes a simple a one-liner: ``` Knob* knob = new Knob(KnobType::Bright26, "My label", this); ``` The constructor of `KnobControl` also had to be extended with the label text because it cannot access the setLabel of the Knob that it manages. However, it can pass the text during construction. Its implementation of the virtual method `Control::setText` becomes empty due to this. The `KnobControl` is currently only used in `Lv2ViewProc::Lv2ViewProc`. Here the `KnobControl` is created by passing the port name into the constructor. However, the virtual method `setText` is still called in line 91 for all other implementations. Add documentation for the constructors. * Remove Knob::buildLegacyKnob Remove `Knob::buildLegacyKnob` by extending the very similar constructor with an enum that indicates whether the constructed `Knob` should be in legacy mode or not. The default is to build a non-legacy `Knob`. Wherever `Knob::buildLegacyKnob` was called the constructor is now called with `Knob::Mode::Legacy` as the parameter. In some places where the onject name is set `Knob::Mode::NonLegacy` has to be added explicitly. * Remove TempoSyncKnob::buildLegacyKnob Remove `TempoSyncKnob::buildLegacyKnob` by extending the very similar constructor with an enum that indicates whether the constructed `TempoSyncKnob` should be in legacy mode or not. The default is to build a non-legacy `TempoSyncKnob`. Wherever `TempoSyncKnob::buildLegacyKnob` was called the constructor is now called with `Knob::Mode::Legacy` as the parameter. * Vertical spacing for Peak Controller Add a vertical spacing of 10 pixel between the knobs of the Peak Controller. * Peak Controller: use default margins Remove the specific call to `setContentsMargins` from the Peak Controller so that the main layout uses Qt's default margins. Also remove the spacing again. * Rename the enum `Knob::Mode` Rename the enum `Knob::Mode` and its values so that they better describe what they influence. `Knob::Mode` is renamed to `Knob::LabelRendering` to indicate that its value affects the label rendering. The value `NonLegacy` is now called `WidgetFont` to indicate that the knob uses the font settings of the widget when rendering the label. The value `Legacy` is now called `LegacyFixedFontSize` to indicate that it's a legacy behavior which uses a fixed font size that does not adhere to the font size that's set for the widget's font. Adjust all callers accordingly. * Add TempoSyncKnob documentation Document the constructor of `TempoSyncKnob` that can be used to set the label rendering to lecacy mode. * Name adjustments and parameter removal Rename `m_legacyMode` to `m_fixedFontSizeLabelRendering`. Rename the method `legacyMode` to `fixedFontSizeLabelRendering`. Rename `setLegacyMode` to `setFixedFontSizeLabelRendering`. Also remove the boolean parameter from the method as it was only called with `true` anyway. --- include/Controls.h | 2 +- include/CustomTextKnob.h | 4 +- include/Knob.h | 90 ++++++++++++++- include/TempoSyncKnob.h | 23 ++++ plugins/Amplifier/AmplifierControlDialog.cpp | 20 ++-- .../AudioFileProcessorView.cpp | 6 +- .../AudioFileProcessorWaveView.h | 1 - .../BassBooster/BassBoosterControlDialog.cpp | 10 +- plugins/Bitcrush/BitcrushControlDialog.cpp | 26 ++--- plugins/CarlaBase/Carla.cpp | 34 +++--- .../CrossoverEQ/CrossoverEQControlDialog.cpp | 4 +- plugins/Delay/DelayControlsDialog.cpp | 12 +- .../Dispersion/DispersionControlDialog.cpp | 25 ++-- .../DualFilter/DualFilterControlDialog.cpp | 4 +- .../DynamicsProcessorControlDialog.cpp | 13 +-- plugins/Flanger/FlangerControlsDialog.cpp | 44 ++++--- plugins/Lb302/Lb302.cpp | 6 - .../MultitapEchoControlDialog.cpp | 10 +- .../PeakControllerEffectControlDialog.cpp | 20 +--- plugins/ReverbSC/ReverbSCControlDialog.cpp | 26 ++--- plugins/SpectrumAnalyzer/SaControlsDialog.cpp | 25 ++-- .../StereoEnhancerControlDialog.cpp | 3 +- plugins/Stk/Mallets/Mallets.cpp | 49 +++----- plugins/Vestige/Vestige.cpp | 8 +- plugins/VstEffect/VstEffectControls.cpp | 8 +- .../WaveShaper/WaveShaperControlDialog.cpp | 7 +- plugins/ZynAddSubFx/ZynAddSubFx.cpp | 21 ++-- src/gui/Controls.cpp | 10 +- src/gui/EffectView.cpp | 10 +- src/gui/LadspaControlView.cpp | 5 +- src/gui/LfoControllerDialog.cpp | 13 +-- src/gui/Lv2ViewBase.cpp | 2 +- src/gui/MidiCCRackView.cpp | 18 ++- src/gui/instrument/EnvelopeAndLfoView.cpp | 6 +- .../instrument/InstrumentFunctionViews.cpp | 36 ++---- .../instrument/InstrumentSoundShapingView.cpp | 6 +- src/gui/tracks/InstrumentTrackView.cpp | 9 +- src/gui/tracks/SampleTrackView.cpp | 10 +- src/gui/widgets/CustomTextKnob.cpp | 13 ++- src/gui/widgets/Knob.cpp | 109 +++++++++++++++--- src/gui/widgets/TempoSyncKnob.cpp | 21 +++- 41 files changed, 437 insertions(+), 332 deletions(-) diff --git a/include/Controls.h b/include/Controls.h index 5ed19027eb..243f77690c 100644 --- a/include/Controls.h +++ b/include/Controls.h @@ -80,7 +80,7 @@ public: FloatModel* model() override; AutomatableModelView* modelView() override; - KnobControl(QWidget* parent = nullptr); + KnobControl(const QString& text, QWidget* parent = nullptr); ~KnobControl() override = default; }; diff --git a/include/CustomTextKnob.h b/include/CustomTextKnob.h index 31a58415e6..34434f3ae8 100644 --- a/include/CustomTextKnob.h +++ b/include/CustomTextKnob.h @@ -36,9 +36,7 @@ class LMMS_EXPORT CustomTextKnob : public Knob protected: inline void setHintText( const QString & _txt_before, const QString & _txt_after ) {} // inaccessible public: - CustomTextKnob( KnobType _knob_num, QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() ); - - CustomTextKnob( QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() ); //!< default ctor + CustomTextKnob( KnobType _knob_num, const QString& label, QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() ); CustomTextKnob( const Knob& other ) = delete; diff --git a/include/Knob.h b/include/Knob.h index 3c3339a6fe..5ec8fd70f9 100644 --- a/include/Knob.h +++ b/include/Knob.h @@ -77,11 +77,65 @@ class LMMS_EXPORT Knob : public FloatModelEditorBase void onKnobNumUpdated(); //!< to be called when you updated @a m_knobNum public: + /** + * @brief Determines how the label of the knob is rendered. + * + * Labels can be rendered using the font that is set for the knob or using a + * font with a fixed size which is determined by SMALL_FONT_SIZE. + */ + enum class LabelRendering + { + /** + * @brief Renders the label using the font that is set for the widget. + * + * The space that's needed for the label is determined using the font metrics of the knob's font. + */ + WidgetFont, + + /** + * @brief Renders the labels in legacy mode. This uses a fixed font size and does not adhere + * to the font size that's set for the widget's font. + * + * @deprecated Do not use this mode in new code as it is considered deprecated and might be removed in the future. + */ + LegacyFixedFontSize + }; + + /** + * @brief Construct a Knob with the given style and no label. + * + * @param _knob_num Style of the knob + * @param _parent Parent widget + * @param _name Object name of the widget + */ Knob( KnobType _knob_num, QWidget * _parent = nullptr, const QString & _name = QString() ); + + /** + * @brief Construct a Knob with the given style and label text. + * + * @param knobNum Style of the knob + * @param labelText Text for the label + * @param parent Parent widget + * @param labelRendering Determines if the label uses the widget font or a font with a fixed size of 12 pixels (LegacyFixedFontSize). The default is to use the widget font. + * @param name Object name of the widget + */ + Knob(KnobType knobNum, const QString& labelText, QWidget* parent = nullptr, LabelRendering labelRendering = LabelRendering::WidgetFont, const QString& name = QString()); + + /** + * @brief Constructs a knob with a label font in the pixel size. + * + * @param knobNum Style of the knob + * @param labelText Text for the label + * @param labelPixelSize Pixel size for the label + * @param parent Parent widget + * @param name Object name of the widget + */ + Knob(KnobType knobNum, const QString& labelText, int labelPixelSize, QWidget* parent, const QString& name = QString()); + Knob( QWidget * _parent = nullptr, const QString & _name = QString() ); //!< default ctor + Knob( const Knob& other ) = delete; - void setLabel( const QString & txt ); void setHtmlLabel( const QString &htmltxt ); void setTotalAngle( float angle ); @@ -113,15 +167,44 @@ public: protected: - void paintEvent( QPaintEvent * _me ) override; + void setLabel(const QString& txt); + + void paintEvent(QPaintEvent*) override; void changeEvent(QEvent * ev) override; + /*! + * Affects how the label of the knob is rendered. + * + * The default mode returns false. The height of the label text is taken into account when a new fixed + * size is computed for the Knob. When the label text is painted the descent of the font is used to + * compute the base line. The default mode returns false. + * + * Enabling fixed font size rendering mode leads to the following behavior: + * * The height of the label is not taken into account when the new fixed height of the Knob is computed. + * Instead a fixed size of 10 is added for the label. + * * When the knob is painted the baseline of the font is always set to 2 pixels away from the lower side + * of the Knob's rectangle. + * * The label is always rendered with a size of SMALL_FONT_SIZE. + */ + bool fixedFontSizeLabelRendering() const { return m_fixedFontSizeLabelRendering; } + + /*! + * Set the button to legacy rendering mode which uses a fixed font size and that does not take the size + * of the widget's font into account. + * + * This can be thought of as a legacy mode which reinstates the old behavior of the knob. + * + * @see fixedFontSizeLabelRendering(). + */ + void setFixedFontSizeLabelRendering(); + private: QLineF calculateLine( const QPointF & _mid, float _radius, float _innerRadius = 1) const; void drawKnob( QPainter * _p ); + void drawLabel(QPainter& p); bool updateAngle(); int angleFromValue( float value, float minValue, float maxValue, float totalAngle ) const @@ -129,7 +212,10 @@ private: return static_cast( ( value - 0.5 * ( minValue + maxValue ) ) / ( maxValue - minValue ) * m_totalAngle ) % 360; } + void updateFixedSize(); + QString m_label; + bool m_fixedFontSizeLabelRendering = false; bool m_isHtmlLabel; QTextDocument* m_tdRenderer; diff --git a/include/TempoSyncKnob.h b/include/TempoSyncKnob.h index b86320d13d..656f145abb 100644 --- a/include/TempoSyncKnob.h +++ b/include/TempoSyncKnob.h @@ -42,6 +42,29 @@ class LMMS_EXPORT TempoSyncKnob : public Knob Q_OBJECT public: TempoSyncKnob( KnobType knobNum, QWidget* parent = nullptr, const QString& name = QString() ); + + /** + * @brief Construct a TempoSyncKnob with the given style and label text. + * + * @param knobNum Style of the knob + * @param labelText Text for the label + * @param parent Parent widget + * @param labelRendering Determines if the label uses the widget font or a font with a fixed size of 12 pixels (LegacyFixedFontSize). The default is to use the widget font. + * @param name Object name of the widget + */ + TempoSyncKnob(KnobType knobNum, const QString& labelText, QWidget* parent = nullptr, LabelRendering labelRendering = LabelRendering::WidgetFont, const QString& name = QString()); + + /** + * @brief Constructs a tempo sync knob with a label font in the pixel size. + * + * @param knobNum Style of the knob + * @param labelText Text for the label + * @param labelPixelSize Pixel size for the label + * @param parent Parent widget + * @param name Object name of the widget + */ + TempoSyncKnob(KnobType knobNum, const QString& labelText, int labelPixelSize, QWidget* parent, const QString& name = QString()); + ~TempoSyncKnob() override; const QString & syncDescription(); diff --git a/plugins/Amplifier/AmplifierControlDialog.cpp b/plugins/Amplifier/AmplifierControlDialog.cpp index 7d303d0d11..9bf0bb649b 100644 --- a/plugins/Amplifier/AmplifierControlDialog.cpp +++ b/plugins/Amplifier/AmplifierControlDialog.cpp @@ -28,6 +28,9 @@ #include "embed.h" #include "Knob.h" +#include + + namespace lmms::gui { @@ -38,23 +41,22 @@ AmplifierControlDialog::AmplifierControlDialog(AmplifierControls* controls) : QPalette pal; pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); setPalette(pal); - setFixedSize(100, 110); + + QGridLayout* gridLayout = new QGridLayout(this); - auto makeKnob = [this](int x, int y, const QString& label, const QString& hintText, const QString& unit, FloatModel* model, bool isVolume) + auto makeKnob = [this](const QString& label, const QString& hintText, const QString& unit, FloatModel* model, bool isVolume) { - Knob* newKnob = new Knob(KnobType::Bright26, this); - newKnob->move(x, y); + Knob* newKnob = new Knob(KnobType::Bright26, label, this); newKnob->setModel(model); - newKnob->setLabel(label); newKnob->setHintText(hintText, unit); newKnob->setVolumeKnob(isVolume); return newKnob; }; - makeKnob(16, 10, tr("VOL"), tr("Volume:"), "%", &controls->m_volumeModel, true); - makeKnob(57, 10, tr("PAN"), tr("Panning:"), "%", &controls->m_panModel, false); - makeKnob(16, 65, tr("LEFT"), tr("Left gain:"), "%", &controls->m_leftModel, true); - makeKnob(57, 65, tr("RIGHT"), tr("Right gain:"), "%", &controls->m_rightModel, true); + gridLayout->addWidget(makeKnob(tr("VOL"), tr("Volume:"), "%", &controls->m_volumeModel, true), 0, 0, Qt::AlignHCenter); + gridLayout->addWidget(makeKnob(tr("PAN"), tr("Panning:"), "%", &controls->m_panModel, false), 0, 1, Qt::AlignHCenter); + gridLayout->addWidget(makeKnob(tr("LEFT"), tr("Left gain:"), "%", &controls->m_leftModel, true), 1, 0, Qt::AlignHCenter); + gridLayout->addWidget(makeKnob(tr("RIGHT"), tr("Right gain:"), "%", &controls->m_rightModel, true), 1, 1, Qt::AlignHCenter); } } // namespace lmms::gui diff --git a/plugins/AudioFileProcessor/AudioFileProcessorView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorView.cpp index 298e79c5ed..02098c540f 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorView.cpp @@ -120,15 +120,15 @@ AudioFileProcessorView::AudioFileProcessorView(Instrument* instrument, m_ampKnob->setHintText(tr("Amplify:"), "%"); m_startKnob = new AudioFileProcessorWaveView::knob(this); - m_startKnob->move(45, 108); + m_startKnob->move(50, 108); m_startKnob->setHintText(tr("Start point:"), ""); m_endKnob = new AudioFileProcessorWaveView::knob(this); - m_endKnob->move(125, 108); + m_endKnob->move(130, 108); m_endKnob->setHintText(tr("End point:"), ""); m_loopKnob = new AudioFileProcessorWaveView::knob(this); - m_loopKnob->move(85, 108); + m_loopKnob->move(90, 108); m_loopKnob->setHintText(tr("Loopback point:"), ""); // interpolation selector diff --git a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h index 6440570e66..69dea0b1b1 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h +++ b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h @@ -73,7 +73,6 @@ public: m_waveView(0), m_relatedKnob(0) { - setFixedSize(37, 47); } void setWaveView(const AudioFileProcessorWaveView* wv) diff --git a/plugins/BassBooster/BassBoosterControlDialog.cpp b/plugins/BassBooster/BassBoosterControlDialog.cpp index 9efa07c0d3..fcdf10cc26 100644 --- a/plugins/BassBooster/BassBoosterControlDialog.cpp +++ b/plugins/BassBooster/BassBoosterControlDialog.cpp @@ -43,26 +43,22 @@ BassBoosterControlDialog::BassBoosterControlDialog( BassBoosterControls* control QPalette pal; pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - setFixedSize( 120, 60 ); auto tl = new QVBoxLayout(this); tl->addSpacing( 4 ); auto l = new QHBoxLayout; - auto freqKnob = new Knob(KnobType::Bright26, this); + auto freqKnob = new Knob(KnobType::Bright26, tr("FREQ"), this); freqKnob->setModel( &controls->m_freqModel ); - freqKnob->setLabel( tr( "FREQ" ) ); freqKnob->setHintText( tr( "Frequency:" ) , "Hz" ); - auto gainKnob = new Knob(KnobType::Bright26, this); + auto gainKnob = new Knob(KnobType::Bright26, tr("GAIN"), this); gainKnob->setModel( &controls->m_gainModel ); - gainKnob->setLabel( tr( "GAIN" ) ); gainKnob->setHintText( tr( "Gain:" ) , "" ); - auto ratioKnob = new Knob(KnobType::Bright26, this); + auto ratioKnob = new Knob(KnobType::Bright26, tr("RATIO"), this); ratioKnob->setModel( &controls->m_ratioModel ); - ratioKnob->setLabel( tr( "RATIO" ) ); ratioKnob->setHintText( tr( "Ratio:" ) , "" ); l->addWidget( freqKnob ); diff --git a/plugins/Bitcrush/BitcrushControlDialog.cpp b/plugins/Bitcrush/BitcrushControlDialog.cpp index 64c9b63616..3036c802a6 100644 --- a/plugins/Bitcrush/BitcrushControlDialog.cpp +++ b/plugins/Bitcrush/BitcrushControlDialog.cpp @@ -29,6 +29,7 @@ #include "embed.h" #include "BitcrushControlDialog.h" #include "BitcrushControls.h" +#include "FontHelper.h" #include "LedCheckBox.h" #include "Knob.h" @@ -46,37 +47,37 @@ BitcrushControlDialog::BitcrushControlDialog( BitcrushControls * controls ) : setFixedSize( 181, 128 ); // labels + const auto labelFont = adjustedToPixelSize(font(), DEFAULT_FONT_SIZE); + auto inLabel = new QLabel(tr("IN"), this); + inLabel->setFont(labelFont); inLabel->move( 24, 15 ); auto outLabel = new QLabel(tr("OUT"), this); + outLabel->setFont(labelFont); outLabel->move( 139, 15 ); // input knobs - auto inGain = new Knob(KnobType::Bright26, this); + auto inGain = new Knob(KnobType::Bright26, tr("GAIN"), SMALL_FONT_SIZE, this); inGain->move( 16, 32 ); inGain->setModel( & controls->m_inGain ); - inGain->setLabel( tr( "GAIN" ) ); inGain->setHintText( tr( "Input gain:" ) , " dBFS" ); - auto inNoise = new Knob(KnobType::Bright26, this); + auto inNoise = new Knob(KnobType::Bright26, tr("NOISE"), SMALL_FONT_SIZE, this); inNoise->move( 14, 76 ); inNoise->setModel( & controls->m_inNoise ); - inNoise->setLabel( tr( "NOISE" ) ); inNoise->setHintText( tr( "Input noise:" ) , "%" ); // output knobs - auto outGain = new Knob(KnobType::Bright26, this); + auto outGain = new Knob(KnobType::Bright26, tr("GAIN"), SMALL_FONT_SIZE, this); outGain->move( 138, 32 ); outGain->setModel( & controls->m_outGain ); - outGain->setLabel( tr( "GAIN" ) ); outGain->setHintText( tr( "Output gain:" ) , " dBFS" ); - auto outClip = new Knob(KnobType::Bright26, this); + auto outClip = new Knob(KnobType::Bright26, tr("CLIP"), SMALL_FONT_SIZE, this); outClip->move( 138, 76 ); outClip->setModel( & controls->m_outClip ); - outClip->setLabel( tr( "CLIP" ) ); outClip->setHintText( tr( "Output clip:" ) , " dBFS"); @@ -94,24 +95,21 @@ BitcrushControlDialog::BitcrushControlDialog( BitcrushControls * controls ) : // rate crushing knobs - auto rate = new Knob(KnobType::Bright26, this); + auto rate = new Knob(KnobType::Bright26, tr("FREQ"), SMALL_FONT_SIZE, this); rate->move( 59, 32 ); rate->setModel( & controls->m_rate ); - rate->setLabel( tr( "FREQ" ) ); rate->setHintText( tr( "Sample rate:" ) , " Hz" ); - auto stereoDiff = new Knob(KnobType::Bright26, this); + auto stereoDiff = new Knob(KnobType::Bright26, tr("STEREO"), SMALL_FONT_SIZE, this); stereoDiff->move( 72, 76 ); stereoDiff->setModel( & controls->m_stereoDiff ); - stereoDiff->setLabel( tr( "STEREO" ) ); stereoDiff->setHintText( tr( "Stereo difference:" ) , "%" ); // depth crushing knob - auto levels = new Knob(KnobType::Bright26, this); + auto levels = new Knob(KnobType::Bright26, tr("QUANT"), SMALL_FONT_SIZE, this); levels->move( 92, 32 ); levels->setModel( & controls->m_levels ); - levels->setLabel( tr( "QUANT" ) ); levels->setHintText( tr( "Levels:" ) , "" ); } diff --git a/plugins/CarlaBase/Carla.cpp b/plugins/CarlaBase/Carla.cpp index 37cba078aa..b572a13d4b 100644 --- a/plugins/CarlaBase/Carla.cpp +++ b/plugins/CarlaBase/Carla.cpp @@ -1004,34 +1004,32 @@ void CarlaParamsView::refreshKnobs() QStringList groupNameList; groupNameList.reserve(m_carlaInstrument->m_paramGroupCount); - for (uint32_t i = 0; i < m_carlaInstrument->m_paramModels.size(); ++i) + for (const auto currentParamModel : m_carlaInstrument->m_paramModels) { - bool enabled = m_carlaInstrument->m_paramModels[i]->enabled(); - m_knobs.push_back(new Knob(KnobType::Dark28, m_inputScrollAreaWidgetContent)); - QString name = (*m_carlaInstrument->m_paramModels[i]).displayName(); - m_knobs[i]->setHintText(name, ""); - m_knobs[i]->setLabel(name); - m_knobs[i]->setObjectName(name); // this is being used for filtering the knobs. + bool enabled = currentParamModel->enabled(); + const QString name = currentParamModel->displayName(); + + auto currentKnob = new Knob(KnobType::Dark28, name, m_inputScrollAreaWidgetContent, Knob::LabelRendering::LegacyFixedFontSize); + currentKnob->setHintText(name, ""); + currentKnob->setObjectName(name); // this is being used for filtering the knobs. // Set the newly created model to the knob. - m_knobs[i]->setModel(m_carlaInstrument->m_paramModels[i]); - m_knobs[i]->setEnabled(enabled); + currentKnob->setModel(currentParamModel); + currentKnob->setEnabled(enabled); + + m_knobs.push_back(currentKnob); if (enabled) { // Collect group names - if (!groupNameList.contains(m_carlaInstrument->m_paramModels[i]->groupName())) + if (!groupNameList.contains(currentParamModel->groupName())) { - groupNameList.append(m_carlaInstrument->m_paramModels[i]->groupName()); + groupNameList.append(currentParamModel->groupName()); } - // Store biggest knob width per group (so we can calc how many - // knobs we can horizontaly fit) - uint8_t groupId = m_carlaInstrument->m_paramModels[i]->groupId(); - if (m_maxKnobWidthPerGroup[groupId] < m_knobs[i]->width()) - { - m_maxKnobWidthPerGroup[groupId] = m_knobs[i]->width(); - } + // Store biggest knob width per group (so we can calc how many knobs we can fit horizontally) + auto & maxGroupWidth = m_maxKnobWidthPerGroup[currentParamModel->groupId()]; + maxGroupWidth = std::max(maxGroupWidth, static_cast(currentKnob->width())); } } diff --git a/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp index c3a61890dd..a046066012 100644 --- a/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp +++ b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp @@ -28,6 +28,7 @@ #include "CrossoverEQControlDialog.h" #include "CrossoverEQControls.h" #include "embed.h" +#include "FontHelper.h" #include "LedCheckBox.h" #include "Knob.h" #include "Fader.h" @@ -60,9 +61,8 @@ CrossoverEQControlDialog::CrossoverEQControlDialog(CrossoverEQControls *controls const QString& label, const QString& txt_before ) { - auto k = new Knob(KnobType::Bright26, this); + auto k = new Knob(KnobType::Bright26, label, SMALL_FONT_SIZE, this); k->setModel(model); - k->setLabel(label); k->setHintText(txt_before, "Hz"); knobsLayout->addWidget(k, 0, Qt::AlignHCenter); }; diff --git a/plugins/Delay/DelayControlsDialog.cpp b/plugins/Delay/DelayControlsDialog.cpp index 065b3d1e4e..6d3e4a3ec1 100644 --- a/plugins/Delay/DelayControlsDialog.cpp +++ b/plugins/Delay/DelayControlsDialog.cpp @@ -44,32 +44,28 @@ DelayControlsDialog::DelayControlsDialog( DelayControls *controls ) : setPalette( pal ); setFixedSize( 300, 208 ); - auto sampleDelayKnob = new TempoSyncKnob(KnobType::Bright26, this); + auto sampleDelayKnob = new TempoSyncKnob(KnobType::Bright26, tr("DELAY"), this, Knob::LabelRendering::LegacyFixedFontSize); sampleDelayKnob->move( 10,14 ); sampleDelayKnob->setVolumeKnob( false ); sampleDelayKnob->setModel( &controls->m_delayTimeModel ); - sampleDelayKnob->setLabel( tr( "DELAY" ) ); sampleDelayKnob->setHintText( tr( "Delay time" ) + " ", " s" ); - auto feedbackKnob = new Knob(KnobType::Bright26, this); + auto feedbackKnob = new Knob(KnobType::Bright26, tr("FDBK"), this, Knob::LabelRendering::LegacyFixedFontSize); feedbackKnob->move( 11, 58 ); feedbackKnob->setVolumeKnob( true) ; feedbackKnob->setModel( &controls->m_feedbackModel); - feedbackKnob->setLabel( tr( "FDBK" ) ); feedbackKnob->setHintText( tr ( "Feedback amount" ) + " " , "" ); - auto lfoFreqKnob = new TempoSyncKnob(KnobType::Bright26, this); + auto lfoFreqKnob = new TempoSyncKnob(KnobType::Bright26, tr("RATE"), this, Knob::LabelRendering::LegacyFixedFontSize); lfoFreqKnob->move( 11, 119 ); lfoFreqKnob->setVolumeKnob( false ); lfoFreqKnob->setModel( &controls->m_lfoTimeModel ); - lfoFreqKnob->setLabel( tr( "RATE" ) ); lfoFreqKnob->setHintText( tr ( "LFO frequency") + " ", " s" ); - auto lfoAmtKnob = new TempoSyncKnob(KnobType::Bright26, this); + auto lfoAmtKnob = new TempoSyncKnob(KnobType::Bright26, tr("AMNT"), this, Knob::LabelRendering::LegacyFixedFontSize); lfoAmtKnob->move( 11, 159 ); lfoAmtKnob->setVolumeKnob( false ); lfoAmtKnob->setModel( &controls->m_lfoAmountModel ); - lfoAmtKnob->setLabel( tr( "AMNT" ) ); lfoAmtKnob->setHintText( tr ( "LFO amount" ) + " " , " s" ); auto outFader diff --git a/plugins/Dispersion/DispersionControlDialog.cpp b/plugins/Dispersion/DispersionControlDialog.cpp index 2879e7613e..3a717d7aa8 100644 --- a/plugins/Dispersion/DispersionControlDialog.cpp +++ b/plugins/Dispersion/DispersionControlDialog.cpp @@ -31,6 +31,8 @@ #include "LcdSpinBox.h" #include "PixmapButton.h" +#include + namespace lmms::gui { @@ -43,39 +45,38 @@ DispersionControlDialog::DispersionControlDialog(DispersionControls* controls) : QPalette pal; pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); setPalette(pal); - setFixedSize(207, 50); + + auto layout = new QHBoxLayout(this); LcdSpinBox * m_amountBox = new LcdSpinBox(3, this, "Amount"); m_amountBox->setModel(&controls->m_amountModel); - m_amountBox->move(5, 10); m_amountBox->setLabel(tr("AMOUNT")); m_amountBox->setToolTip(tr("Number of all-pass filters")); - Knob * freqKnob = new Knob(KnobType::Bright26, this); - freqKnob->move(59, 8); + Knob * freqKnob = new Knob(KnobType::Bright26, tr("FREQ"), this); freqKnob->setModel(&controls->m_freqModel); - freqKnob->setLabel(tr("FREQ")); freqKnob->setHintText(tr("Frequency:") , " Hz"); - Knob * resoKnob = new Knob(KnobType::Bright26, this); - resoKnob->move(99, 8); + Knob * resoKnob = new Knob(KnobType::Bright26, tr("RESO"), this); resoKnob->setModel(&controls->m_resoModel); - resoKnob->setLabel(tr("RESO")); resoKnob->setHintText(tr("Resonance:") , " octaves"); - Knob * feedbackKnob = new Knob(KnobType::Bright26, this); - feedbackKnob->move(139, 8); + Knob * feedbackKnob = new Knob(KnobType::Bright26, tr("FEED"), this); feedbackKnob->setModel(&controls->m_feedbackModel); - feedbackKnob->setLabel(tr("FEED")); feedbackKnob->setHintText(tr("Feedback:") , ""); PixmapButton * dcButton = new PixmapButton(this, tr("DC Offset Removal")); - dcButton->move(176, 16); dcButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("dc_active")); dcButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("dc_inactive")); dcButton->setCheckable(true); dcButton->setModel(&controls->m_dcModel); dcButton->setToolTip(tr("Remove DC Offset")); + + layout->addWidget(m_amountBox); + layout->addWidget(freqKnob); + layout->addWidget(resoKnob); + layout->addWidget(feedbackKnob); + layout->addWidget(dcButton); } diff --git a/plugins/DualFilter/DualFilterControlDialog.cpp b/plugins/DualFilter/DualFilterControlDialog.cpp index a674a4a42c..6d051b2567 100644 --- a/plugins/DualFilter/DualFilterControlDialog.cpp +++ b/plugins/DualFilter/DualFilterControlDialog.cpp @@ -26,6 +26,7 @@ #include "DualFilterControlDialog.h" #include "DualFilterControls.h" +#include "FontHelper.h" #include "Knob.h" #include "LedCheckBox.h" #include "ComboBox.h" @@ -35,10 +36,9 @@ namespace lmms::gui #define makeknob( name, x, y, model, label, hint, unit ) \ - Knob * name = new Knob( KnobType::Bright26, this); \ + Knob * name = new Knob(KnobType::Bright26, label, SMALL_FONT_SIZE, this); \ (name) -> move( x, y ); \ (name) ->setModel( &controls-> model ); \ - (name) ->setLabel( label ); \ (name) ->setHintText( hint, unit ); diff --git a/plugins/DynamicsProcessor/DynamicsProcessorControlDialog.cpp b/plugins/DynamicsProcessor/DynamicsProcessorControlDialog.cpp index bd076b946b..62838d5f46 100644 --- a/plugins/DynamicsProcessor/DynamicsProcessorControlDialog.cpp +++ b/plugins/DynamicsProcessor/DynamicsProcessorControlDialog.cpp @@ -28,6 +28,7 @@ #include "DynamicsProcessorControlDialog.h" #include "DynamicsProcessorControls.h" #include "embed.h" +#include "FontHelper.h" #include "Graph.h" #include "Knob.h" #include "PixmapButton.h" @@ -58,32 +59,28 @@ DynProcControlDialog::DynProcControlDialog( waveGraph->setGraphColor( QColor( 85, 204, 145 ) ); waveGraph -> setMaximumSize( 204, 205 ); - auto inputKnob = new Knob(KnobType::Bright26, this); + auto inputKnob = new Knob(KnobType::Bright26, tr("INPUT"), SMALL_FONT_SIZE, this); inputKnob -> setVolumeKnob( true ); inputKnob -> setVolumeRatio( 1.0 ); inputKnob -> move( 26, 223 ); inputKnob->setModel( &_controls->m_inputModel ); - inputKnob->setLabel( tr( "INPUT" ) ); inputKnob->setHintText( tr( "Input gain:" ) , "" ); - auto outputKnob = new Knob(KnobType::Bright26, this); + auto outputKnob = new Knob(KnobType::Bright26, tr("OUTPUT"), SMALL_FONT_SIZE, this); outputKnob -> setVolumeKnob( true ); outputKnob -> setVolumeRatio( 1.0 ); outputKnob -> move( 76, 223 ); outputKnob->setModel( &_controls->m_outputModel ); - outputKnob->setLabel( tr( "OUTPUT" ) ); outputKnob->setHintText( tr( "Output gain:" ) , "" ); - auto attackKnob = new Knob(KnobType::Bright26, this); + auto attackKnob = new Knob(KnobType::Bright26, tr("ATTACK"), SMALL_FONT_SIZE, this); attackKnob -> move( 24, 268 ); attackKnob->setModel( &_controls->m_attackModel ); - attackKnob->setLabel( tr( "ATTACK" ) ); attackKnob->setHintText( tr( "Peak attack time:" ) , "ms" ); - auto releaseKnob = new Knob(KnobType::Bright26, this); + auto releaseKnob = new Knob(KnobType::Bright26, tr("RELEASE"), SMALL_FONT_SIZE, this); releaseKnob -> move( 74, 268 ); releaseKnob->setModel( &_controls->m_releaseModel ); - releaseKnob->setLabel( tr( "RELEASE" ) ); releaseKnob->setHintText( tr( "Peak release time:" ) , "ms" ); //wavegraph control buttons diff --git a/plugins/Flanger/FlangerControlsDialog.cpp b/plugins/Flanger/FlangerControlsDialog.cpp index 3ac5dc9c63..d30c1fe603 100644 --- a/plugins/Flanger/FlangerControlsDialog.cpp +++ b/plugins/Flanger/FlangerControlsDialog.cpp @@ -29,6 +29,8 @@ #include "LedCheckBox.h" #include "TempoSyncKnob.h" +#include + namespace lmms::gui { @@ -40,55 +42,51 @@ FlangerControlsDialog::FlangerControlsDialog( FlangerControls *controls ) : QPalette pal; pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - setFixedSize( 233, 75 ); - auto delayKnob = new Knob(KnobType::Bright26, this); - delayKnob->move( 10,10 ); + auto mainLayout = new QVBoxLayout(this); + auto knobLayout = new QHBoxLayout(); + mainLayout->addLayout(knobLayout); + + auto delayKnob = new Knob(KnobType::Bright26, tr("DELAY"), this); delayKnob->setVolumeKnob( false ); delayKnob->setModel( &controls->m_delayTimeModel ); - delayKnob->setLabel( tr( "DELAY" ) ); delayKnob->setHintText( tr( "Delay time:" ) + " ", "s" ); - auto lfoFreqKnob = new TempoSyncKnob(KnobType::Bright26, this); - lfoFreqKnob->move( 48,10 ); + auto lfoFreqKnob = new TempoSyncKnob(KnobType::Bright26, tr("RATE"), this); lfoFreqKnob->setVolumeKnob( false ); lfoFreqKnob->setModel( &controls->m_lfoFrequencyModel ); - lfoFreqKnob->setLabel( tr( "RATE" ) ); lfoFreqKnob->setHintText( tr( "Period:" ) , " Sec" ); - auto lfoAmtKnob = new Knob(KnobType::Bright26, this); - lfoAmtKnob->move( 85,10 ); + auto lfoAmtKnob = new Knob(KnobType::Bright26, tr("AMNT"), this); lfoAmtKnob->setVolumeKnob( false ); lfoAmtKnob->setModel( &controls->m_lfoAmountModel ); - lfoAmtKnob->setLabel( tr( "AMNT" ) ); lfoAmtKnob->setHintText( tr( "Amount:" ) , "" ); - auto lfoPhaseKnob = new Knob(KnobType::Bright26, this); - lfoPhaseKnob->move( 123,10 ); + auto lfoPhaseKnob = new Knob(KnobType::Bright26, tr("PHASE"), this); lfoPhaseKnob->setVolumeKnob( false ); lfoPhaseKnob->setModel( &controls->m_lfoPhaseModel ); - lfoPhaseKnob->setLabel( tr( "PHASE" ) ); lfoPhaseKnob->setHintText( tr( "Phase:" ) , " degrees" ); - auto feedbackKnob = new Knob(KnobType::Bright26, this); - feedbackKnob->move( 160,10 ); + auto feedbackKnob = new Knob(KnobType::Bright26, tr("FDBK"), this); feedbackKnob->setVolumeKnob( true) ; feedbackKnob->setModel( &controls->m_feedbackModel ); - feedbackKnob->setLabel( tr( "FDBK" ) ); feedbackKnob->setHintText( tr( "Feedback amount:" ) , "" ); - auto whiteNoiseKnob = new Knob(KnobType::Bright26, this); - whiteNoiseKnob->move( 196,10 ); + auto whiteNoiseKnob = new Knob(KnobType::Bright26, tr("NOISE"), this); whiteNoiseKnob->setVolumeKnob( true) ; whiteNoiseKnob->setModel( &controls->m_whiteNoiseAmountModel ); - whiteNoiseKnob->setLabel( tr( "NOISE" ) ); whiteNoiseKnob->setHintText( tr( "White noise amount:" ) , "" ); + knobLayout->addWidget(delayKnob); + knobLayout->addWidget(lfoFreqKnob); + knobLayout->addWidget(lfoAmtKnob); + knobLayout->addWidget(lfoPhaseKnob); + knobLayout->addWidget(feedbackKnob); + knobLayout->addWidget(whiteNoiseKnob); + auto invertCb = new LedCheckBox(tr("Invert"), this); - invertCb->move( 10,53 ); - - - + + mainLayout->addWidget(invertCb, 0, Qt::AlignLeft); } diff --git a/plugins/Lb302/Lb302.cpp b/plugins/Lb302/Lb302.cpp index 5a085df4df..ab910d134f 100644 --- a/plugins/Lb302/Lb302.cpp +++ b/plugins/Lb302/Lb302.cpp @@ -831,22 +831,18 @@ Lb302SynthView::Lb302SynthView( Instrument * _instrument, QWidget * _parent ) : m_vcfCutKnob = new Knob( KnobType::Bright26, this ); m_vcfCutKnob->move( 75, 130 ); m_vcfCutKnob->setHintText( tr( "Cutoff Freq:" ), "" ); - m_vcfCutKnob->setLabel( "" ); m_vcfResKnob = new Knob( KnobType::Bright26, this ); m_vcfResKnob->move( 120, 130 ); m_vcfResKnob->setHintText( tr( "Resonance:" ), "" ); - m_vcfResKnob->setLabel( "" ); m_vcfModKnob = new Knob( KnobType::Bright26, this ); m_vcfModKnob->move( 165, 130 ); m_vcfModKnob->setHintText( tr( "Env Mod:" ), "" ); - m_vcfModKnob->setLabel( "" ); m_vcfDecKnob = new Knob( KnobType::Bright26, this ); m_vcfDecKnob->move( 210, 130 ); m_vcfDecKnob->setHintText( tr( "Decay:" ), "" ); - m_vcfDecKnob->setLabel( "" ); m_slideToggle = new LedCheckBox( "", this ); m_slideToggle->move( 10, 180 ); @@ -867,12 +863,10 @@ Lb302SynthView::Lb302SynthView( Instrument * _instrument, QWidget * _parent ) : m_slideDecKnob = new Knob( KnobType::Bright26, this ); m_slideDecKnob->move( 210, 75 ); m_slideDecKnob->setHintText( tr( "Slide Decay:" ), "" ); - m_slideDecKnob->setLabel( ""); m_distKnob = new Knob( KnobType::Bright26, this ); m_distKnob->move( 210, 190 ); m_distKnob->setHintText( tr( "DIST:" ), "" ); - m_distKnob->setLabel( tr( "")); // Shapes diff --git a/plugins/MultitapEcho/MultitapEchoControlDialog.cpp b/plugins/MultitapEcho/MultitapEchoControlDialog.cpp index e89137bf0b..8a7c40a374 100644 --- a/plugins/MultitapEcho/MultitapEchoControlDialog.cpp +++ b/plugins/MultitapEcho/MultitapEchoControlDialog.cpp @@ -27,6 +27,7 @@ #include "MultitapEchoControlDialog.h" #include "MultitapEchoControls.h" #include "embed.h" +#include "FontHelper.h" #include "Graph.h" #include "LedCheckBox.h" #include "Knob.h" @@ -78,22 +79,19 @@ MultitapEchoControlDialog::MultitapEchoControlDialog( MultitapEchoControls * con // knobs - auto stepLength = new TempoSyncKnob(KnobType::Bright26, this); + auto stepLength = new TempoSyncKnob(KnobType::Bright26, tr("Length"), SMALL_FONT_SIZE, this); stepLength->move( 100, 245 ); stepLength->setModel( & controls->m_stepLength ); - stepLength->setLabel( tr( "Length" ) ); stepLength->setHintText( tr( "Step length:" ) , " ms" ); - auto dryGain = new Knob(KnobType::Bright26, this); + auto dryGain = new Knob(KnobType::Bright26, tr("Dry"), SMALL_FONT_SIZE, this); dryGain->move( 150, 245 ); dryGain->setModel( & controls->m_dryGain ); - dryGain->setLabel( tr( "Dry" ) ); dryGain->setHintText( tr( "Dry gain:" ) , " dBFS" ); - auto stages = new Knob(KnobType::Bright26, this); + auto stages = new Knob(KnobType::Bright26, tr("Stages"), SMALL_FONT_SIZE, this); stages->move( 200, 245 ); stages->setModel( & controls->m_stages ); - stages->setLabel( tr( "Stages" ) ); stages->setHintText( tr( "Low-pass stages:" ) , "x" ); // switch led diff --git a/plugins/PeakControllerEffect/PeakControllerEffectControlDialog.cpp b/plugins/PeakControllerEffect/PeakControllerEffectControlDialog.cpp index e44d5bcc24..7ce05bc454 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffectControlDialog.cpp +++ b/plugins/PeakControllerEffect/PeakControllerEffectControlDialog.cpp @@ -47,35 +47,28 @@ PeakControllerEffectControlDialog::PeakControllerEffectControlDialog( QPalette pal; pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - setFixedSize( 240, 80 ); - m_baseKnob = new Knob( KnobType::Bright26, this ); - m_baseKnob->setLabel( tr( "BASE" ) ); + m_baseKnob = new Knob(KnobType::Bright26, tr("BASE"), this); m_baseKnob->setModel( &_controls->m_baseModel ); m_baseKnob->setHintText( tr( "Base:" ) , "" ); - m_amountKnob = new Knob( KnobType::Bright26, this ); - m_amountKnob->setLabel( tr( "AMNT" ) ); + m_amountKnob = new Knob(KnobType::Bright26, tr("AMNT"), this); m_amountKnob->setModel( &_controls->m_amountModel ); m_amountKnob->setHintText( tr( "Modulation amount:" ) , "" ); - m_amountMultKnob = new Knob( KnobType::Bright26, this ); - m_amountMultKnob->setLabel( tr( "MULT" ) ); + m_amountMultKnob = new Knob(KnobType::Bright26, tr("MULT"), this); m_amountMultKnob->setModel( &_controls->m_amountMultModel ); m_amountMultKnob->setHintText( tr( "Amount multiplicator:" ) , "" ); - m_attackKnob = new Knob( KnobType::Bright26, this ); - m_attackKnob->setLabel( tr( "ATCK" ) ); + m_attackKnob = new Knob(KnobType::Bright26, tr("ATCK"), this); m_attackKnob->setModel( &_controls->m_attackModel ); m_attackKnob->setHintText( tr( "Attack:" ) , "" ); - m_decayKnob = new Knob( KnobType::Bright26, this ); - m_decayKnob->setLabel( tr( "DCAY" ) ); + m_decayKnob = new Knob(KnobType::Bright26, tr("DCAY"), this); m_decayKnob->setModel( &_controls->m_decayModel ); m_decayKnob->setHintText( tr( "Release:" ) , "" ); - m_tresholdKnob = new Knob( KnobType::Bright26, this ); - m_tresholdKnob->setLabel( tr( "TRSH" ) ); + m_tresholdKnob = new Knob(KnobType::Bright26, tr("TRSH"), this); m_tresholdKnob->setModel( &_controls->m_tresholdModel ); m_tresholdKnob->setHintText( tr( "Treshold:" ) , "" ); @@ -99,7 +92,6 @@ PeakControllerEffectControlDialog::PeakControllerEffectControlDialog( ledLayout->addWidget( m_muteLed ); ledLayout->addWidget( m_absLed ); - mainLayout->setContentsMargins( 3, 10, 0, 0 ); mainLayout->addLayout( knobLayout ); mainLayout->addLayout( ledLayout ); diff --git a/plugins/ReverbSC/ReverbSCControlDialog.cpp b/plugins/ReverbSC/ReverbSCControlDialog.cpp index 615d3823e6..3be156396b 100644 --- a/plugins/ReverbSC/ReverbSCControlDialog.cpp +++ b/plugins/ReverbSC/ReverbSCControlDialog.cpp @@ -29,6 +29,8 @@ #include "Knob.h" #include "ReverbSCControls.h" +#include + namespace lmms::gui { @@ -40,31 +42,29 @@ ReverbSCControlDialog::ReverbSCControlDialog( ReverbSCControls* controls ) : QPalette pal; pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - setFixedSize( 185, 55 ); - auto inputGainKnob = new Knob(KnobType::Bright26, this); - inputGainKnob -> move( 16, 10 ); + auto knobLayout = new QHBoxLayout(this); + + auto inputGainKnob = new Knob(KnobType::Bright26, tr("Input"), this); inputGainKnob->setModel( &controls->m_inputGainModel ); - inputGainKnob->setLabel( tr( "Input" ) ); inputGainKnob->setHintText( tr( "Input gain:" ) , "dB" ); - auto sizeKnob = new Knob(KnobType::Bright26, this); - sizeKnob -> move( 57, 10 ); + auto sizeKnob = new Knob(KnobType::Bright26, tr("Size"), this); sizeKnob->setModel( &controls->m_sizeModel ); - sizeKnob->setLabel( tr( "Size" ) ); sizeKnob->setHintText( tr( "Size:" ) , "" ); - auto colorKnob = new Knob(KnobType::Bright26, this); - colorKnob -> move( 98, 10 ); + auto colorKnob = new Knob(KnobType::Bright26, tr("Color"), this); colorKnob->setModel( &controls->m_colorModel ); - colorKnob->setLabel( tr( "Color" ) ); colorKnob->setHintText( tr( "Color:" ) , "" ); - auto outputGainKnob = new Knob(KnobType::Bright26, this); - outputGainKnob -> move( 139, 10 ); + auto outputGainKnob = new Knob(KnobType::Bright26, tr("Output"), this); outputGainKnob->setModel( &controls->m_outputGainModel ); - outputGainKnob->setLabel( tr( "Output" ) ); outputGainKnob->setHintText( tr( "Output gain:" ) , "dB" ); + + knobLayout->addWidget(inputGainKnob); + knobLayout->addWidget(sizeKnob); + knobLayout->addWidget(colorKnob); + knobLayout->addWidget(outputGainKnob); } diff --git a/plugins/SpectrumAnalyzer/SaControlsDialog.cpp b/plugins/SpectrumAnalyzer/SaControlsDialog.cpp index 8b2c0f35ee..9645f7b838 100644 --- a/plugins/SpectrumAnalyzer/SaControlsDialog.cpp +++ b/plugins/SpectrumAnalyzer/SaControlsDialog.cpp @@ -32,6 +32,7 @@ #include "ComboBox.h" #include "ComboBoxModel.h" +#include "FontHelper.h" #include "Knob.h" #include "LedCheckBox.h" #include "PixmapButton.h" @@ -236,41 +237,36 @@ SaControlsDialog::SaControlsDialog(SaControls *controls, SaProcessor *processor) controls_layout->setStretchFactor(advanced_widget, 10); // Peak envelope resolution - auto envelopeResolutionKnob = new Knob(KnobType::Small17, this); + auto envelopeResolutionKnob = new Knob(KnobType::Small17, tr("Envelope res."), SMALL_FONT_SIZE, this); envelopeResolutionKnob->setModel(&controls->m_envelopeResolutionModel); - envelopeResolutionKnob->setLabel(tr("Envelope res.")); envelopeResolutionKnob->setToolTip(tr("Increase envelope resolution for better details, decrease for better GUI performance.")); envelopeResolutionKnob->setHintText(tr("Maximum number of envelope points drawn per pixel:"), ""); advanced_layout->addWidget(envelopeResolutionKnob, 0, 0, 1, 1, Qt::AlignCenter); // Spectrum graph resolution - auto spectrumResolutionKnob = new Knob(KnobType::Small17, this); + auto spectrumResolutionKnob = new Knob(KnobType::Small17, tr("Spectrum res."), SMALL_FONT_SIZE, this); spectrumResolutionKnob->setModel(&controls->m_spectrumResolutionModel); - spectrumResolutionKnob->setLabel(tr("Spectrum res.")); spectrumResolutionKnob->setToolTip(tr("Increase spectrum resolution for better details, decrease for better GUI performance.")); spectrumResolutionKnob->setHintText(tr("Maximum number of spectrum points drawn per pixel:"), ""); advanced_layout->addWidget(spectrumResolutionKnob, 1, 0, 1, 1, Qt::AlignCenter); // Peak falloff speed - auto peakDecayFactorKnob = new Knob(KnobType::Small17, this); + auto peakDecayFactorKnob = new Knob(KnobType::Small17, tr("Falloff factor"), SMALL_FONT_SIZE, this); peakDecayFactorKnob->setModel(&controls->m_peakDecayFactorModel); - peakDecayFactorKnob->setLabel(tr("Falloff factor")); peakDecayFactorKnob->setToolTip(tr("Decrease to make peaks fall faster.")); peakDecayFactorKnob->setHintText(tr("Multiply buffered value by"), ""); advanced_layout->addWidget(peakDecayFactorKnob, 0, 1, 1, 1, Qt::AlignCenter); // Averaging weight - auto averagingWeightKnob = new Knob(KnobType::Small17, this); + auto averagingWeightKnob = new Knob(KnobType::Small17, tr("Averaging weight"), SMALL_FONT_SIZE, this); averagingWeightKnob->setModel(&controls->m_averagingWeightModel); - averagingWeightKnob->setLabel(tr("Averaging weight")); averagingWeightKnob->setToolTip(tr("Decrease to make averaging slower and smoother.")); averagingWeightKnob->setHintText(tr("New sample contributes"), ""); advanced_layout->addWidget(averagingWeightKnob, 1, 1, 1, 1, Qt::AlignCenter); // Waterfall history size - auto waterfallHeightKnob = new Knob(KnobType::Small17, this); + auto waterfallHeightKnob = new Knob(KnobType::Small17, tr("Waterfall height"), SMALL_FONT_SIZE, this); waterfallHeightKnob->setModel(&controls->m_waterfallHeightModel); - waterfallHeightKnob->setLabel(tr("Waterfall height")); waterfallHeightKnob->setToolTip(tr("Increase to get slower scrolling, decrease to see fast transitions better. Warning: medium CPU usage.")); waterfallHeightKnob->setHintText(tr("Number of lines to keep:"), ""); advanced_layout->addWidget(waterfallHeightKnob, 0, 2, 1, 1, Qt::AlignCenter); @@ -278,25 +274,22 @@ SaControlsDialog::SaControlsDialog(SaControls *controls, SaProcessor *processor) connect(&controls->m_waterfallHeightModel, &FloatModel::dataChanged, [=] {processor->reallocateBuffers();}); // Waterfall gamma correction - auto waterfallGammaKnob = new Knob(KnobType::Small17, this); + auto waterfallGammaKnob = new Knob(KnobType::Small17, tr("Waterfall gamma"), SMALL_FONT_SIZE, this); waterfallGammaKnob->setModel(&controls->m_waterfallGammaModel); - waterfallGammaKnob->setLabel(tr("Waterfall gamma")); waterfallGammaKnob->setToolTip(tr("Decrease to see very weak signals, increase to get better contrast.")); waterfallGammaKnob->setHintText(tr("Gamma value:"), ""); advanced_layout->addWidget(waterfallGammaKnob, 1, 2, 1, 1, Qt::AlignCenter); // FFT window overlap - auto windowOverlapKnob = new Knob(KnobType::Small17, this); + auto windowOverlapKnob = new Knob(KnobType::Small17, tr("Window overlap"), SMALL_FONT_SIZE, this); windowOverlapKnob->setModel(&controls->m_windowOverlapModel); - windowOverlapKnob->setLabel(tr("Window overlap")); windowOverlapKnob->setToolTip(tr("Increase to prevent missing fast transitions arriving near FFT window edges. Warning: high CPU usage.")); windowOverlapKnob->setHintText(tr("Number of times each sample is processed:"), ""); advanced_layout->addWidget(windowOverlapKnob, 0, 3, 1, 1, Qt::AlignCenter); // FFT zero padding - auto zeroPaddingKnob = new Knob(KnobType::Small17, this); + auto zeroPaddingKnob = new Knob(KnobType::Small17, tr("Zero padding"), SMALL_FONT_SIZE, this); zeroPaddingKnob->setModel(&controls->m_zeroPaddingModel); - zeroPaddingKnob->setLabel(tr("Zero padding")); zeroPaddingKnob->setToolTip(tr("Increase to get smoother-looking spectrum. Warning: high CPU usage.")); zeroPaddingKnob->setHintText(tr("Processing buffer is"), tr(" steps larger than input block")); advanced_layout->addWidget(zeroPaddingKnob, 1, 3, 1, 1, Qt::AlignCenter); diff --git a/plugins/StereoEnhancer/StereoEnhancerControlDialog.cpp b/plugins/StereoEnhancer/StereoEnhancerControlDialog.cpp index 05c78616e5..1440a4be51 100644 --- a/plugins/StereoEnhancer/StereoEnhancerControlDialog.cpp +++ b/plugins/StereoEnhancer/StereoEnhancerControlDialog.cpp @@ -40,9 +40,8 @@ StereoEnhancerControlDialog::StereoEnhancerControlDialog( { auto l = new QHBoxLayout(this); - auto widthKnob = new Knob(KnobType::Bright26, this); + auto widthKnob = new Knob(KnobType::Bright26, tr("WIDTH"), this); widthKnob->setModel( &_controls->m_widthModel ); - widthKnob->setLabel( tr( "WIDTH" ) ); widthKnob->setHintText( tr( "Width:" ) , " samples" ); l->addWidget( widthKnob ); diff --git a/plugins/Stk/Mallets/Mallets.cpp b/plugins/Stk/Mallets/Mallets.cpp index fecb15a76a..5c9c11cca8 100644 --- a/plugins/Stk/Mallets/Mallets.cpp +++ b/plugins/Stk/Mallets/Mallets.cpp @@ -37,6 +37,7 @@ #include "AudioEngine.h" #include "ConfigManager.h" #include "Engine.h" +#include "FontHelper.h" #include "GuiApplication.h" #include "InstrumentTrack.h" @@ -454,13 +455,11 @@ MalletsInstrumentView::MalletsInstrumentView( MalletsInstrument * _instrument, connect( &_instrument->m_presetsModel, SIGNAL( dataChanged() ), this, SLOT( changePreset() ) ); - m_spreadKnob = new Knob( KnobType::Vintage32, this ); - m_spreadKnob->setLabel( tr( "Spread" ) ); + m_spreadKnob = new Knob(KnobType::Vintage32, tr("Spread"), SMALL_FONT_SIZE, this); m_spreadKnob->move( 190, 140 ); m_spreadKnob->setHintText( tr( "Spread:" ), "" ); - m_randomKnob = new Knob(KnobType::Vintage32, this); - m_randomKnob->setLabel(tr("Random")); + m_randomKnob = new Knob(KnobType::Vintage32, tr("Random"), SMALL_FONT_SIZE, this); m_randomKnob->move(190, 190); m_randomKnob->setHintText(tr("Random:"), ""); @@ -495,28 +494,23 @@ QWidget * MalletsInstrumentView::setupModalBarControls( QWidget * _parent ) auto widget = new QWidget(_parent); widget->setFixedSize( 250, 250 ); - m_hardnessKnob = new Knob( KnobType::Vintage32, widget ); - m_hardnessKnob->setLabel( tr( "Hardness" ) ); + m_hardnessKnob = new Knob(KnobType::Vintage32, tr("Hardness"), SMALL_FONT_SIZE, widget); m_hardnessKnob->move( 30, 90 ); m_hardnessKnob->setHintText( tr( "Hardness:" ), "" ); - m_positionKnob = new Knob( KnobType::Vintage32, widget ); - m_positionKnob->setLabel( tr( "Position" ) ); + m_positionKnob = new Knob(KnobType::Vintage32, tr("Position"), SMALL_FONT_SIZE, widget); m_positionKnob->move( 110, 90 ); m_positionKnob->setHintText( tr( "Position:" ), "" ); - m_vibratoGainKnob = new Knob( KnobType::Vintage32, widget ); - m_vibratoGainKnob->setLabel( tr( "Vibrato gain" ) ); + m_vibratoGainKnob = new Knob(KnobType::Vintage32, tr("Vibrato gain"), SMALL_FONT_SIZE, widget); m_vibratoGainKnob->move( 30, 140 ); m_vibratoGainKnob->setHintText( tr( "Vibrato gain:" ), "" ); - m_vibratoFreqKnob = new Knob( KnobType::Vintage32, widget ); - m_vibratoFreqKnob->setLabel( tr( "Vibrato frequency" ) ); + m_vibratoFreqKnob = new Knob(KnobType::Vintage32, tr("Vibrato frequency"), SMALL_FONT_SIZE, widget); m_vibratoFreqKnob->move( 110, 140 ); m_vibratoFreqKnob->setHintText( tr( "Vibrato frequency:" ), "" ); - m_stickKnob = new Knob( KnobType::Vintage32, widget ); - m_stickKnob->setLabel( tr( "Stick mix" ) ); + m_stickKnob = new Knob(KnobType::Vintage32, tr("Stick mix"), SMALL_FONT_SIZE, widget); m_stickKnob->move( 190, 90 ); m_stickKnob->setHintText( tr( "Stick mix:" ), "" ); @@ -531,28 +525,23 @@ QWidget * MalletsInstrumentView::setupTubeBellControls( QWidget * _parent ) auto widget = new QWidget(_parent); widget->setFixedSize( 250, 250 ); - m_modulatorKnob = new Knob( KnobType::Vintage32, widget ); - m_modulatorKnob->setLabel( tr( "Modulator" ) ); + m_modulatorKnob = new Knob(KnobType::Vintage32, tr("Modulator"), SMALL_FONT_SIZE, widget); m_modulatorKnob->move( 30, 90 ); m_modulatorKnob->setHintText( tr( "Modulator:" ), "" ); - m_crossfadeKnob = new Knob( KnobType::Vintage32, widget ); - m_crossfadeKnob->setLabel( tr( "Crossfade" ) ); + m_crossfadeKnob = new Knob(KnobType::Vintage32, tr("Crossfade"), SMALL_FONT_SIZE, widget); m_crossfadeKnob->move( 110, 90 ); m_crossfadeKnob->setHintText( tr( "Crossfade:" ), "" ); - m_lfoSpeedKnob = new Knob( KnobType::Vintage32, widget ); - m_lfoSpeedKnob->setLabel( tr( "LFO speed" ) ); + m_lfoSpeedKnob = new Knob(KnobType::Vintage32, tr("LFO speed"), SMALL_FONT_SIZE, widget); m_lfoSpeedKnob->move( 30, 140 ); m_lfoSpeedKnob->setHintText( tr( "LFO speed:" ), "" ); - m_lfoDepthKnob = new Knob( KnobType::Vintage32, widget ); - m_lfoDepthKnob->setLabel( tr( "LFO depth" ) ); + m_lfoDepthKnob = new Knob(KnobType::Vintage32, tr("LFO depth"), SMALL_FONT_SIZE, widget); m_lfoDepthKnob->move( 110, 140 ); m_lfoDepthKnob->setHintText( tr( "LFO depth:" ), "" ); - m_adsrKnob = new Knob( KnobType::Vintage32, widget ); - m_adsrKnob->setLabel( tr( "ADSR" ) ); + m_adsrKnob = new Knob(KnobType::Vintage32, tr("ADSR"), SMALL_FONT_SIZE, widget); m_adsrKnob->move( 190, 90 ); m_adsrKnob->setHintText( tr( "ADSR:" ), "" ); @@ -571,23 +560,19 @@ QWidget * MalletsInstrumentView::setupBandedWGControls( QWidget * _parent ) /* m_strikeLED = new LedCheckBox( tr( "Bowed" ), widget ); m_strikeLED->move( 138, 25 );*/ - m_pressureKnob = new Knob( KnobType::Vintage32, widget ); - m_pressureKnob->setLabel( tr( "Pressure" ) ); + m_pressureKnob = new Knob(KnobType::Vintage32, tr("Pressure"), SMALL_FONT_SIZE, widget); m_pressureKnob->move( 30, 90 ); m_pressureKnob->setHintText( tr( "Pressure:" ), "" ); -/* m_motionKnob = new Knob( KnobType::Vintage32, widget ); - m_motionKnob->setLabel( tr( "Motion" ) ); +/* m_motionKnob = new Knob(KnobType::Vintage32, tr("Motion"), SMALL_FONT_SIZE, widget); m_motionKnob->move( 110, 90 ); m_motionKnob->setHintText( tr( "Motion:" ), "" );*/ - m_velocityKnob = new Knob( KnobType::Vintage32, widget ); - m_velocityKnob->setLabel( tr( "Speed" ) ); + m_velocityKnob = new Knob(KnobType::Vintage32, tr("Speed"), SMALL_FONT_SIZE, widget); m_velocityKnob->move( 30, 140 ); m_velocityKnob->setHintText( tr( "Speed:" ), "" ); -/* m_vibratoKnob = new Knob( KnobType::Vintage32, widget, tr( "Vibrato" ) ); - m_vibratoKnob->setLabel( tr( "Vibrato" ) ); +/* m_vibratoKnob = new Knob(KnobType::Vintage32, tr("Vibrato"), SMALL_FONT_SIZE, widget); m_vibratoKnob->move( 110, 140 ); m_vibratoKnob->setHintText( tr( "Vibrato:" ), "" );*/ diff --git a/plugins/Vestige/Vestige.cpp b/plugins/Vestige/Vestige.cpp index e372924005..1bf9f257cf 100644 --- a/plugins/Vestige/Vestige.cpp +++ b/plugins/Vestige/Vestige.cpp @@ -998,9 +998,11 @@ ManageVestigeInstrumentView::ManageVestigeInstrumentView( Instrument * _instrume std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); - vstKnobs[ i ] = new CustomTextKnob( KnobType::Bright26, this, s_dumpValues.at( 1 ) ); - vstKnobs[ i ]->setDescription( s_dumpValues.at( 1 ) + ":" ); - vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) ); + const auto & description = s_dumpValues.at(1); + + auto knob = new CustomTextKnob(KnobType::Bright26, description.left(15), this, description); + knob->setDescription(description + ":"); + vstKnobs[i] = knob; if( !hasKnobModel ) { diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index ef8bd38d07..c01aef0cef 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -389,9 +389,11 @@ ManageVSTEffectView::ManageVSTEffectView( VstEffect * _eff, VstEffectControls * std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); - vstKnobs[ i ] = new CustomTextKnob( KnobType::Bright26, widget, s_dumpValues.at( 1 ) ); - vstKnobs[ i ]->setDescription( s_dumpValues.at( 1 ) + ":" ); - vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) ); + const auto & description = s_dumpValues.at(1); + + auto knob = new CustomTextKnob(KnobType::Bright26, description.left(15), widget, description); + knob->setDescription(description + ":"); + vstKnobs[i] = knob; if( !hasKnobModel ) { diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 045f84763f..17955fe286 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -28,6 +28,7 @@ #include "WaveShaperControlDialog.h" #include "WaveShaperControls.h" #include "embed.h" +#include "FontHelper.h" #include "Graph.h" #include "Knob.h" #include "PixmapButton.h" @@ -59,20 +60,18 @@ WaveShaperControlDialog::WaveShaperControlDialog( waveGraph->setGraphColor( QColor( 85, 204, 145 ) ); waveGraph -> setMaximumSize( 204, 205 ); - auto inputKnob = new Knob(KnobType::Bright26, this); + auto inputKnob = new Knob(KnobType::Bright26, tr("INPUT"), SMALL_FONT_SIZE, this); inputKnob -> setVolumeKnob( true ); inputKnob -> setVolumeRatio( 1.0 ); inputKnob -> move( 26, 225 ); inputKnob->setModel( &_controls->m_inputModel ); - inputKnob->setLabel( tr( "INPUT" ) ); inputKnob->setHintText( tr( "Input gain:" ) , "" ); - auto outputKnob = new Knob(KnobType::Bright26, this); + auto outputKnob = new Knob(KnobType::Bright26, tr("OUTPUT"), SMALL_FONT_SIZE, this); outputKnob -> setVolumeKnob( true ); outputKnob -> setVolumeRatio( 1.0 ); outputKnob -> move( 76, 225 ); outputKnob->setModel( &_controls->m_outputModel ); - outputKnob->setLabel( tr( "OUTPUT" ) ); outputKnob->setHintText( tr( "Output gain:" ), "" ); auto resetButton = new PixmapButton(this, tr("Reset wavegraph")); diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.cpp b/plugins/ZynAddSubFx/ZynAddSubFx.cpp index ef42259671..27e286b665 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/ZynAddSubFx.cpp @@ -507,33 +507,26 @@ ZynAddSubFxView::ZynAddSubFxView( Instrument * _instrument, QWidget * _parent ) l->setVerticalSpacing( 16 ); l->setHorizontalSpacing( 10 ); - m_portamento = new Knob( KnobType::Bright26, this ); + m_portamento = new Knob(KnobType::Bright26, tr("PORT"), SMALL_FONT_SIZE, this); m_portamento->setHintText( tr( "Portamento:" ), "" ); - m_portamento->setLabel( tr( "PORT" ) ); - m_filterFreq = new Knob( KnobType::Bright26, this ); + m_filterFreq = new Knob(KnobType::Bright26, tr("FREQ"), SMALL_FONT_SIZE, this); m_filterFreq->setHintText( tr( "Filter frequency:" ), "" ); - m_filterFreq->setLabel( tr( "FREQ" ) ); - m_filterQ = new Knob( KnobType::Bright26, this ); + m_filterQ = new Knob(KnobType::Bright26, tr("RES"), SMALL_FONT_SIZE, this); m_filterQ->setHintText( tr( "Filter resonance:" ), "" ); - m_filterQ->setLabel( tr( "RES" ) ); - m_bandwidth = new Knob( KnobType::Bright26, this ); + m_bandwidth = new Knob(KnobType::Bright26, tr("BW"), SMALL_FONT_SIZE, this); m_bandwidth->setHintText( tr( "Bandwidth:" ), "" ); - m_bandwidth->setLabel( tr( "BW" ) ); - m_fmGain = new Knob( KnobType::Bright26, this ); + m_fmGain = new Knob(KnobType::Bright26, tr("FM GAIN"), SMALL_FONT_SIZE, this); m_fmGain->setHintText( tr( "FM gain:" ), "" ); - m_fmGain->setLabel( tr( "FM GAIN" ) ); - m_resCenterFreq = new Knob( KnobType::Bright26, this ); + m_resCenterFreq = new Knob(KnobType::Bright26, tr("RES CF"), SMALL_FONT_SIZE, this); m_resCenterFreq->setHintText( tr( "Resonance center frequency:" ), "" ); - m_resCenterFreq->setLabel( tr( "RES CF" ) ); - m_resBandwidth = new Knob( KnobType::Bright26, this ); + m_resBandwidth = new Knob(KnobType::Bright26, tr("RES BW"), SMALL_FONT_SIZE, this); m_resBandwidth->setHintText( tr( "Resonance bandwidth:" ), "" ); - m_resBandwidth->setLabel( tr( "RES BW" ) ); m_forwardMidiCC = new LedCheckBox( tr( "Forward MIDI control changes" ), this ); diff --git a/src/gui/Controls.cpp b/src/gui/Controls.cpp index 209b0fce1f..d75da6a7df 100644 --- a/src/gui/Controls.cpp +++ b/src/gui/Controls.cpp @@ -38,7 +38,11 @@ namespace lmms::gui { -void KnobControl::setText(const QString &text) { m_knob->setLabel(text); } +void KnobControl::setText(const QString& text) +{ + // For KnobControls the text is set in the constructor + // so we do nothing here +} QWidget *KnobControl::topWidget() { return m_knob; } @@ -51,8 +55,8 @@ FloatModel *KnobControl::model() { return m_knob->model(); } AutomatableModelView* KnobControl::modelView() { return m_knob; } -KnobControl::KnobControl(QWidget *parent) : - m_knob(new Knob(parent)) {} +KnobControl::KnobControl(const QString& text, QWidget *parent) : + m_knob(new Knob(KnobType::Bright26, text, parent)) {} void ComboControl::setText(const QString &text) { m_label->setText(text); } diff --git a/src/gui/EffectView.cpp b/src/gui/EffectView.cpp index dee9eb136e..a77fc1d967 100644 --- a/src/gui/EffectView.cpp +++ b/src/gui/EffectView.cpp @@ -63,23 +63,19 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : m_bypass->setToolTip(tr("On/Off")); - - m_wetDry = new Knob( KnobType::Bright26, this ); - m_wetDry->setLabel( tr( "W/D" ) ); + m_wetDry = new Knob(KnobType::Bright26, tr("W/D"), this, Knob::LabelRendering::LegacyFixedFontSize); m_wetDry->move( 40 - m_wetDry->width() / 2, 5 ); m_wetDry->setEnabled( isEnabled ); m_wetDry->setHintText( tr( "Wet Level:" ), "" ); - m_autoQuit = new TempoSyncKnob( KnobType::Bright26, this ); - m_autoQuit->setLabel( tr( "DECAY" ) ); + m_autoQuit = new TempoSyncKnob(KnobType::Bright26, tr("DECAY"), this, Knob::LabelRendering::LegacyFixedFontSize); m_autoQuit->move( 78 - m_autoQuit->width() / 2, 5 ); m_autoQuit->setEnabled( isEnabled && !effect()->m_autoQuitDisabled ); m_autoQuit->setHintText( tr( "Time:" ), "ms" ); - m_gate = new Knob( KnobType::Bright26, this ); - m_gate->setLabel( tr( "GATE" ) ); + m_gate = new Knob(KnobType::Bright26, tr("GATE"), this, Knob::LabelRendering::LegacyFixedFontSize); m_gate->move( 116 - m_gate->width() / 2, 5 ); m_gate->setEnabled( isEnabled && !effect()->m_autoQuitDisabled ); m_gate->setHintText( tr( "Gate:" ), "" ); diff --git a/src/gui/LadspaControlView.cpp b/src/gui/LadspaControlView.cpp index dbc3b8059b..294500b75c 100644 --- a/src/gui/LadspaControlView.cpp +++ b/src/gui/LadspaControlView.cpp @@ -81,11 +81,11 @@ LadspaControlView::LadspaControlView( QWidget * _parent, case BufferDataType::Integer: case BufferDataType::Enum: case BufferDataType::Floating: - knb = new Knob( KnobType::Bright26, this, m_ctl->port()->name ); + knb = new Knob(KnobType::Bright26, m_ctl->port()->name, this, Knob::LabelRendering::WidgetFont, m_ctl->port()->name); break; case BufferDataType::Time: - knb = new TempoSyncKnob( KnobType::Bright26, this, m_ctl->port()->name ); + knb = new TempoSyncKnob(KnobType::Bright26, m_ctl->port()->name, this, Knob::LabelRendering::WidgetFont, m_ctl->port()->name); break; default: @@ -102,7 +102,6 @@ LadspaControlView::LadspaControlView( QWidget * _parent, { knb->setModel( m_ctl->tempoSyncKnobModel() ); } - knb->setLabel( m_ctl->port()->name ); knb->setHintText( tr( "Value:" ), "" ); layout->addWidget( knb ); if( link != nullptr ) diff --git a/src/gui/LfoControllerDialog.cpp b/src/gui/LfoControllerDialog.cpp index 559ac13360..4a0ff158fe 100644 --- a/src/gui/LfoControllerDialog.cpp +++ b/src/gui/LfoControllerDialog.cpp @@ -27,6 +27,7 @@ #include "embed.h" +#include "FontHelper.h" #include "LfoController.h" #include "Knob.h" #include "TempoSyncKnob.h" @@ -62,23 +63,19 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent setWindowIcon( embed::getIconPixmap( "controller" ) ); setFixedSize( 240, 58 ); - m_baseKnob = new Knob( KnobType::Bright26, this ); - m_baseKnob->setLabel( tr( "BASE" ) ); + m_baseKnob = new Knob(KnobType::Bright26, tr("BASE"), SMALL_FONT_SIZE, this); m_baseKnob->move( CD_LFO_BASE_CD_KNOB_X, CD_LFO_CD_KNOB_Y ); m_baseKnob->setHintText( tr( "Base:" ), "" ); - m_speedKnob = new TempoSyncKnob( KnobType::Bright26, this ); - m_speedKnob->setLabel( tr( "FREQ" ) ); + m_speedKnob = new TempoSyncKnob(KnobType::Bright26, tr("FREQ"), SMALL_FONT_SIZE, this); m_speedKnob->move( CD_LFO_SPEED_CD_KNOB_X, CD_LFO_CD_KNOB_Y ); m_speedKnob->setHintText( tr( "LFO frequency:" ), "" ); - m_amountKnob = new Knob( KnobType::Bright26, this ); - m_amountKnob->setLabel( tr( "AMNT" ) ); + m_amountKnob = new Knob(KnobType::Bright26, tr("AMNT"), SMALL_FONT_SIZE, this); m_amountKnob->move( CD_LFO_AMOUNT_CD_KNOB_X, CD_LFO_CD_KNOB_Y ); m_amountKnob->setHintText( tr( "Modulation amount:" ), "" ); - m_phaseKnob = new Knob( KnobType::Bright26, this ); - m_phaseKnob->setLabel( tr( "PHS" ) ); + m_phaseKnob = new Knob(KnobType::Bright26, tr("PHS"), SMALL_FONT_SIZE, this); m_phaseKnob->move( CD_LFO_PHASE_CD_KNOB_X, CD_LFO_CD_KNOB_Y ); m_phaseKnob->setHintText( tr( "Phase offset:" ) , "" + tr( " degrees" ) ); diff --git a/src/gui/Lv2ViewBase.cpp b/src/gui/Lv2ViewBase.cpp index d6a25af834..0cd6a0ee4b 100644 --- a/src/gui/Lv2ViewBase.cpp +++ b/src/gui/Lv2ViewBase.cpp @@ -70,7 +70,7 @@ Lv2ViewProc::Lv2ViewProc(QWidget* parent, Lv2Proc* proc, int colNum) : switch (port.m_vis) { case PortVis::Generic: - m_control = new KnobControl(m_parent); + m_control = new KnobControl(port.name(), m_parent); break; case PortVis::Integer: { diff --git a/src/gui/MidiCCRackView.cpp b/src/gui/MidiCCRackView.cpp index a0b1496fb5..efeb46d46f 100644 --- a/src/gui/MidiCCRackView.cpp +++ b/src/gui/MidiCCRackView.cpp @@ -79,6 +79,7 @@ MidiCCRackView::MidiCCRackView(InstrumentTrack * track) : auto knobsScrollArea = new QScrollArea(); auto knobsArea = new QWidget(); auto knobsAreaLayout = new QGridLayout(); + knobsAreaLayout->setVerticalSpacing(10); knobsArea->setLayout(knobsAreaLayout); knobsScrollArea->setWidget(knobsArea); @@ -86,24 +87,21 @@ MidiCCRackView::MidiCCRackView(InstrumentTrack * track) : knobsGroupBoxLayout->addWidget(knobsScrollArea); - // Adds the controller knobs + // Adds the controller knobs and sets their models for (int i = 0; i < MidiControllerCount; ++i) { - m_controllerKnob[i] = new Knob(KnobType::Bright26); - m_controllerKnob[i]->setLabel(tr("CC %1").arg(i)); - knobsAreaLayout->addWidget(m_controllerKnob[i], i/4, i%4); + auto knob = new Knob(KnobType::Bright26, tr("CC %1").arg(i), this); + knob->setModel(m_track->m_midiCCModel[i].get()); + knobsAreaLayout->addWidget(knob, i/4, i%4, Qt::AlignHCenter); + + // TODO It seems that this is not really used/needed? + m_controllerKnob[i] = knob; } // Set all the models // Set the LED button to enable/disable the track midi cc m_midiCCGroupBox->setModel(m_track->m_midiCCEnable.get()); - // Set the model for each Knob - for (int i = 0; i < MidiControllerCount; ++i) - { - m_controllerKnob[i]->setModel(m_track->m_midiCCModel[i].get()); - } - // Connection to update the name of the track on the label connect(m_track, SIGNAL(nameChanged()), this, SLOT(renameWindow())); diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index 90e2aa30ec..02dd014f48 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -57,8 +57,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : // 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); + auto knob = new Knob(KnobType::Bright26, label, this, Knob::LabelRendering::LegacyFixedFontSize); knob->setHintText(hintText, ""); return knob; @@ -170,8 +169,7 @@ 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 = new TempoSyncKnob(KnobType::Bright26, tr("SPD"), this, Knob::LabelRendering::LegacyFixedFontSize); m_lfoSpeedKnob->setHintText(tr("Frequency:"), ""); lfoKnobsLayout->addWidget(m_lfoSpeedKnob); diff --git a/src/gui/instrument/InstrumentFunctionViews.cpp b/src/gui/instrument/InstrumentFunctionViews.cpp index a60fa64f92..7c0a624907 100644 --- a/src/gui/instrument/InstrumentFunctionViews.cpp +++ b/src/gui/instrument/InstrumentFunctionViews.cpp @@ -44,7 +44,7 @@ InstrumentFunctionNoteStackingView::InstrumentFunctionNoteStackingView( Instrume m_cc( cc ), m_chordsGroupBox( new GroupBox( tr( "STACKING" ) ) ), m_chordsComboBox( new ComboBox() ), - m_chordRangeKnob( new Knob( KnobType::Bright26 ) ) + m_chordRangeKnob(new Knob(KnobType::Bright26, tr("RANGE"), this, Knob::LabelRendering::LegacyFixedFontSize)) { auto topLayout = new QHBoxLayout(this); topLayout->setContentsMargins(0, 0, 0, 0); @@ -59,7 +59,6 @@ InstrumentFunctionNoteStackingView::InstrumentFunctionNoteStackingView( Instrume auto chordLabel = new QLabel(tr("Chord:")); chordLabel->setFont(adjustedToPixelSize(chordLabel->font(), DEFAULT_FONT_SIZE)); - m_chordRangeKnob->setLabel( tr( "RANGE" ) ); m_chordRangeKnob->setHintText( tr( "Chord range:" ), " " + tr( "octave(s)" ) ); mainLayout->addWidget( chordLabel, 0, 0 ); @@ -98,13 +97,13 @@ InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFuncti m_a( arp ), m_arpGroupBox( new GroupBox( tr( "ARPEGGIO" ) ) ), m_arpComboBox( new ComboBox() ), - m_arpRangeKnob( new Knob( KnobType::Bright26 ) ), - m_arpRepeatsKnob( new Knob( KnobType::Bright26 ) ), - m_arpCycleKnob( new Knob( KnobType::Bright26 ) ), - m_arpSkipKnob( new Knob( KnobType::Bright26 ) ), - m_arpMissKnob( new Knob( KnobType::Bright26 ) ), - m_arpTimeKnob( new TempoSyncKnob( KnobType::Bright26 ) ), - m_arpGateKnob( new Knob( KnobType::Bright26 ) ), + m_arpRangeKnob(new Knob(KnobType::Bright26, tr("RANGE"), this, Knob::LabelRendering::LegacyFixedFontSize)), + m_arpRepeatsKnob(new Knob(KnobType::Bright26, tr("REP"), this, Knob::LabelRendering::LegacyFixedFontSize)), + m_arpCycleKnob(new Knob(KnobType::Bright26, tr("CYCLE"), this, Knob::LabelRendering::LegacyFixedFontSize)), + m_arpSkipKnob(new Knob(KnobType::Bright26, tr("SKIP"), this, Knob::LabelRendering::LegacyFixedFontSize)), + m_arpMissKnob(new Knob(KnobType::Bright26, tr("MISS"), this, Knob::LabelRendering::LegacyFixedFontSize)), + m_arpTimeKnob(new TempoSyncKnob(KnobType::Bright26, tr("TIME"), this, Knob::LabelRendering::LegacyFixedFontSize)), + m_arpGateKnob(new Knob(KnobType::Bright26, tr("GATE"), this, Knob::LabelRendering::LegacyFixedFontSize)), m_arpDirectionComboBox( new ComboBox() ), m_arpModeComboBox( new ComboBox() ) { @@ -118,31 +117,12 @@ InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFuncti mainLayout->setHorizontalSpacing( 20 ); mainLayout->setVerticalSpacing( 1 ); - m_arpRangeKnob->setLabel( tr( "RANGE" ) ); m_arpRangeKnob->setHintText( tr( "Arpeggio range:" ), " " + tr( "octave(s)" ) ); - - - m_arpRepeatsKnob->setLabel( tr( "REP" ) ); m_arpRepeatsKnob->setHintText( tr( "Note repeats:" ) + " ", " " + tr( "time(s)" ) ); - - - m_arpCycleKnob->setLabel( tr( "CYCLE" ) ); m_arpCycleKnob->setHintText( tr( "Cycle notes:" ) + " ", " " + tr( "note(s)" ) ); - - - m_arpSkipKnob->setLabel( tr( "SKIP" ) ); m_arpSkipKnob->setHintText( tr( "Skip rate:" ), tr( "%" ) ); - - - m_arpMissKnob->setLabel( tr( "MISS" ) ); m_arpMissKnob->setHintText( tr( "Miss rate:" ), tr( "%" ) ); - - - m_arpTimeKnob->setLabel( tr( "TIME" ) ); m_arpTimeKnob->setHintText( tr( "Arpeggio time:" ), " " + tr( "ms" ) ); - - - m_arpGateKnob->setLabel( tr( "GATE" ) ); m_arpGateKnob->setHintText( tr( "Arpeggio gate:" ), tr( "%" ) ); auto arpChordLabel = new QLabel(tr("Chord:")); diff --git a/src/gui/instrument/InstrumentSoundShapingView.cpp b/src/gui/instrument/InstrumentSoundShapingView.cpp index e0d6a6e98d..7f786867d1 100644 --- a/src/gui/instrument/InstrumentSoundShapingView.cpp +++ b/src/gui/instrument/InstrumentSoundShapingView.cpp @@ -68,13 +68,11 @@ InstrumentSoundShapingView::InstrumentSoundShapingView(QWidget* parent) : m_filterComboBox = new ComboBox(m_filterGroupBox); filterLayout->addWidget(m_filterComboBox); - m_filterCutKnob = new Knob(KnobType::Bright26, m_filterGroupBox); - m_filterCutKnob->setLabel(tr("FREQ")); + m_filterCutKnob = new Knob(KnobType::Bright26, tr("FREQ"), m_filterGroupBox, Knob::LabelRendering::LegacyFixedFontSize); m_filterCutKnob->setHintText(tr("Cutoff frequency:"), " " + tr("Hz")); filterLayout->addWidget(m_filterCutKnob); - m_filterResKnob = new Knob(KnobType::Bright26, m_filterGroupBox); - m_filterResKnob->setLabel(tr("Q/RESO")); + m_filterResKnob = new Knob(KnobType::Bright26, tr("Q/RESO"), m_filterGroupBox, Knob::LabelRendering::LegacyFixedFontSize); m_filterResKnob->setHintText(tr("Q/Resonance:"), ""); filterLayout->addWidget(m_filterResKnob); diff --git a/src/gui/tracks/InstrumentTrackView.cpp b/src/gui/tracks/InstrumentTrackView.cpp index b8ca43bcdd..b6681beeb8 100644 --- a/src/gui/tracks/InstrumentTrackView.cpp +++ b/src/gui/tracks/InstrumentTrackView.cpp @@ -35,6 +35,7 @@ #include "ConfigManager.h" #include "Engine.h" #include "FadeButton.h" +#include "FontHelper.h" #include "Knob.h" #include "MidiCCRackView.h" #include "Mixer.h" @@ -77,19 +78,15 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV m_mixerChannelNumber = new MixerChannelLcdSpinBox(2, getTrackSettingsWidget(), tr("Mixer channel"), this); m_mixerChannelNumber->show(); - m_volumeKnob = new Knob( KnobType::Small17, getTrackSettingsWidget(), - tr( "Volume" ) ); + m_volumeKnob = new Knob(KnobType::Small17, tr("VOL"), getTrackSettingsWidget(), Knob::LabelRendering::LegacyFixedFontSize, tr("VOL")); m_volumeKnob->setVolumeKnob( true ); m_volumeKnob->setModel( &_it->m_volumeModel ); m_volumeKnob->setHintText( tr( "Volume:" ), "%" ); - m_volumeKnob->setLabel( tr( "VOL" ) ); m_volumeKnob->show(); - m_panningKnob = new Knob( KnobType::Small17, getTrackSettingsWidget(), - tr( "Panning" ) ); + m_panningKnob = new Knob(KnobType::Small17, tr("PAN"), getTrackSettingsWidget(), Knob::LabelRendering::LegacyFixedFontSize, tr("Panning")); m_panningKnob->setModel( &_it->m_panningModel ); m_panningKnob->setHintText(tr("Panning:"), "%"); - m_panningKnob->setLabel( tr( "PAN" ) ); m_panningKnob->show(); m_midiMenu = new QMenu( tr( "MIDI" ), this ); diff --git a/src/gui/tracks/SampleTrackView.cpp b/src/gui/tracks/SampleTrackView.cpp index 2c7fde8c67..34495e7358 100644 --- a/src/gui/tracks/SampleTrackView.cpp +++ b/src/gui/tracks/SampleTrackView.cpp @@ -31,6 +31,7 @@ #include "embed.h" #include "Engine.h" #include "FadeButton.h" +#include "FontHelper.h" #include "Mixer.h" #include "MixerView.h" #include "GuiApplication.h" @@ -62,20 +63,15 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : m_mixerChannelNumber = new MixerChannelLcdSpinBox(2, getTrackSettingsWidget(), tr("Mixer channel"), this); m_mixerChannelNumber->show(); - m_volumeKnob = new Knob( KnobType::Small17, getTrackSettingsWidget(), - tr( "Track volume" ) ); + m_volumeKnob = new Knob(KnobType::Small17, tr("VOL"), getTrackSettingsWidget(), Knob::LabelRendering::LegacyFixedFontSize, tr("Track volume")); m_volumeKnob->setVolumeKnob( true ); m_volumeKnob->setModel( &_t->m_volumeModel ); m_volumeKnob->setHintText( tr( "Channel volume:" ), "%" ); - - m_volumeKnob->setLabel( tr( "VOL" ) ); m_volumeKnob->show(); - m_panningKnob = new Knob( KnobType::Small17, getTrackSettingsWidget(), - tr( "Panning" ) ); + m_panningKnob = new Knob(KnobType::Small17, tr("PAN"), getTrackSettingsWidget(), Knob::LabelRendering::LegacyFixedFontSize, tr("Panning")); m_panningKnob->setModel( &_t->m_panningModel ); m_panningKnob->setHintText( tr( "Panning:" ), "%" ); - m_panningKnob->setLabel( tr( "PAN" ) ); m_panningKnob->show(); m_activityIndicator = new FadeButton( diff --git a/src/gui/widgets/CustomTextKnob.cpp b/src/gui/widgets/CustomTextKnob.cpp index a4edde47cc..0623591571 100644 --- a/src/gui/widgets/CustomTextKnob.cpp +++ b/src/gui/widgets/CustomTextKnob.cpp @@ -23,18 +23,19 @@ */ #include "CustomTextKnob.h" +#include "FontHelper.h" namespace lmms::gui { -CustomTextKnob::CustomTextKnob( KnobType _knob_num, QWidget * _parent, const QString & _name, const QString & _value_text ) : +CustomTextKnob::CustomTextKnob( KnobType _knob_num, const QString& label, QWidget * _parent, const QString & _name, const QString & _value_text ) : Knob( _knob_num, _parent, _name ), - m_value_text( _value_text ) {} - -CustomTextKnob::CustomTextKnob( QWidget * _parent, const QString & _name, const QString & _value_text ) : //!< default ctor - Knob( _parent, _name ), - m_value_text( _value_text ) {} + m_value_text( _value_text ) +{ + setFont(adjustedToPixelSize(font(), SMALL_FONT_SIZE)); + setLabel(label); +} QString CustomTextKnob::displayValue() const { diff --git a/src/gui/widgets/Knob.cpp b/src/gui/widgets/Knob.cpp index 25d2e3e3f7..624ea287da 100644 --- a/src/gui/widgets/Knob.cpp +++ b/src/gui/widgets/Knob.cpp @@ -32,6 +32,8 @@ #include "embed.h" #include "FontHelper.h" +#include + namespace lmms::gui { @@ -49,6 +51,24 @@ Knob::Knob( KnobType _knob_num, QWidget * _parent, const QString & _name ) : initUi( _name ); } +Knob::Knob(KnobType knobNum, const QString& labelText, QWidget* parent, LabelRendering labelRendering, const QString& name) : + Knob(knobNum, parent, name) +{ + setLabel(labelText); + + if (labelRendering == LabelRendering::LegacyFixedFontSize) + { + setFixedFontSizeLabelRendering(); + } +} + +Knob::Knob(KnobType knobNum, const QString& labelText, int labelPixelSize, QWidget* parent, const QString& name) : + Knob(knobNum, parent, name) +{ + setFont(adjustedToPixelSize(font(), labelPixelSize)); + setLabel(labelText); +} + Knob::Knob( QWidget * _parent, const QString & _name ) : Knob( KnobType::Bright26, _parent, _name ) { @@ -56,7 +76,6 @@ Knob::Knob( QWidget * _parent, const QString & _name ) : - void Knob::initUi( const QString & _name ) { onKnobNumUpdated(); @@ -129,16 +148,12 @@ void Knob::onKnobNumUpdated() -void Knob::setLabel( const QString & txt ) +void Knob::setLabel(const QString& txt) { m_label = txt; m_isHtmlLabel = false; - if( m_knobPixmap ) - { - setFixedSize(qMax( m_knobPixmap->width(), - horizontalAdvance(QFontMetrics(adjustedToPixelSize(font(), SMALL_FONT_SIZE)), m_label)), - m_knobPixmap->height() + 10); - } + + updateFixedSize(); update(); } @@ -165,8 +180,49 @@ void Knob::setHtmlLabel(const QString &htmltxt) update(); } +void Knob::setFixedFontSizeLabelRendering() +{ + m_fixedFontSizeLabelRendering = true; + updateFixedSize(); + update(); +} + +void Knob::updateFixedSize() +{ + if (fixedFontSizeLabelRendering()) + { + if (m_knobPixmap) + { + // In legacy mode only the width of the label is taken into account while the height is not + const int labelWidth = horizontalAdvance(QFontMetrics(adjustedToPixelSize(font(), SMALL_FONT_SIZE)), m_label); + const int width = std::max(m_knobPixmap->width(), labelWidth); + + // Legacy mode assumes that the label will fit into 10 pixels plus some of the pixmap area + setFixedSize(width, m_knobPixmap->height() + 10); + } + } + else + { + // Styled knobs do not use pixmaps and have no labels. Their size is set from the outside and + // they are painted within these limits. Hence we should not compute a new size from a pixmap + // and/or label the case of styled knobs. + if (knobNum() == KnobType::Styled) + { + return; + } + + QSize pixmapSize = m_knobPixmap ? m_knobPixmap->size() : QSize(0, 0); + + auto fm = QFontMetrics(font()); + + const int width = std::max(pixmapSize.width(), horizontalAdvance(fm, m_label)); + const int height = pixmapSize.height() + fm.height(); + + setFixedSize(width, height); + } +} void Knob::setTotalAngle( float angle ) { @@ -447,31 +503,42 @@ void Knob::drawKnob( QPainter * _p ) _p->drawImage( 0, 0, m_cache ); } -void Knob::paintEvent( QPaintEvent * _me ) +void Knob::drawLabel(QPainter& p) { - QPainter p( this ); - - drawKnob( &p ); if( !m_label.isEmpty() ) { if (!m_isHtmlLabel) { - p.setFont(adjustedToPixelSize(p.font(), SMALL_FONT_SIZE)); + if (fixedFontSizeLabelRendering()) + { + p.setFont(adjustedToPixelSize(p.font(), SMALL_FONT_SIZE)); + } + auto fm = p.fontMetrics(); + const auto x = (width() - horizontalAdvance(fm, m_label)) / 2; + const auto descent = fixedFontSizeLabelRendering() ? 2 : fm.descent(); + const auto y = height() - descent; + p.setPen(textColor()); - p.drawText(width() / 2 - - horizontalAdvance(p.fontMetrics(), m_label) / 2, - height() - 2, m_label); + p.drawText(x, y, m_label); } else { // TODO setHtmlLabel is never called so this will never be executed. Remove functionality? - m_tdRenderer->setDefaultFont(adjustedToPixelSize(p.font(), SMALL_FONT_SIZE)); + m_tdRenderer->setDefaultFont(font()); p.translate((width() - m_tdRenderer->idealWidth()) / 2, (height() - m_tdRenderer->pageSize().height()) / 2); m_tdRenderer->drawContents(&p); } } } +void Knob::paintEvent(QPaintEvent*) +{ + QPainter p(this); + + drawKnob(&p); + drawLabel(p); +} + void Knob::changeEvent(QEvent * ev) { if (ev->type() == QEvent::EnabledChange) @@ -484,6 +551,14 @@ void Knob::changeEvent(QEvent * ev) m_cache = QImage(); update(); } + else if (ev->type() == QEvent::FontChange) + { + // The size of the label might have changed so update + // the size of this widget. + updateFixedSize(); + + update(); + } } diff --git a/src/gui/widgets/TempoSyncKnob.cpp b/src/gui/widgets/TempoSyncKnob.cpp index 473cee28ca..eedefd4ad2 100644 --- a/src/gui/widgets/TempoSyncKnob.cpp +++ b/src/gui/widgets/TempoSyncKnob.cpp @@ -30,6 +30,7 @@ #include "Engine.h" #include "CaptionMenu.h" #include "embed.h" +#include "FontHelper.h" #include "GuiApplication.h" #include "MainWindow.h" #include "MeterDialog.h" @@ -51,6 +52,24 @@ TempoSyncKnob::TempoSyncKnob( KnobType _knob_num, QWidget * _parent, { } +TempoSyncKnob::TempoSyncKnob(KnobType knobNum, const QString& labelText, QWidget* parent, LabelRendering labelRendering, const QString& name) : + TempoSyncKnob(knobNum, parent, name) +{ + setLabel(labelText); + + if (labelRendering == Knob::LabelRendering::LegacyFixedFontSize) + { + setFixedFontSizeLabelRendering(); + } +} + + +TempoSyncKnob::TempoSyncKnob(KnobType knobNum, const QString& labelText, int labelPixelSize, QWidget* parent, const QString& name) : + TempoSyncKnob(knobNum, parent, name) +{ + setFont(adjustedToPixelSize(font(), labelPixelSize)); + setLabel(labelText); +} @@ -63,8 +82,6 @@ TempoSyncKnob::~TempoSyncKnob() } - - void TempoSyncKnob::modelChanged() { if( model() == nullptr )