mirror of
https://github.com/LMMS/lmms.git
synced 2026-06-02 03:06:48 -04:00
Bugs fixed: 1. Doubled tooltips on some Knobs (see #8358) 2. No dynamic floating text when dragging a Fader (regression from #8253) 3. Volume knobs displaying their units as "dBFS%" rather than just "dBFS" (regression from #8253) 4. Incorrect dBFS value in the dynamic floating text for volume knobs of the Delay and Flanger plugins 5. Incorrect dBFS values in the "Set value" dialog box for volume knobs of the Delay, Dynamics Processor, Flanger, and Wave Shaper plugins 6. Missing "%" unit in the context menu for Vibed's volume knobs 7. Incorrect handling of volume knobs for models that support negative amplitudes (currently only Flanger's feedback amount knob) For (1), I reworked how static tooltips work in FloatModelEditorBase. Rather than use QWidget's tooltips, it shadows the tooltip methods from QWidget and redirects them to the existing SimpleTextFloat-based system. Supporting both "static" and "dynamic" tooltips required some improvements to keep better track of user interactions with the Knobs. There was an existing m_buttonPressed boolean, but this was insufficient, so I converted it into a new InteractionType enum for keeping track of the user interaction state. See the "Expected Behaviour" section of the bug report (#8358) for an explanation of how it works now from the user's perspective.
233 lines
7.3 KiB
C++
233 lines
7.3 KiB
C++
/*
|
|
* FloatModelEditorBase.h - Base editor for float models
|
|
*
|
|
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
|
* Copyright (c) 2023 Michael Gregorius
|
|
* Copyright (c) 2026 Dalton Messmer <messmer.dalton/at/gmail.com>
|
|
*
|
|
* This file is part of LMMS - https://lmms.io
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this program (see COPYING); if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA.
|
|
*
|
|
*/
|
|
|
|
#ifndef LMMS_GUI_FLOAT_MODEL_EDITOR_BASE_H
|
|
#define LMMS_GUI_FLOAT_MODEL_EDITOR_BASE_H
|
|
|
|
#include <QPoint>
|
|
#include <QWidget>
|
|
#include <optional>
|
|
|
|
#include "AutomatableModelView.h"
|
|
|
|
namespace lmms::gui
|
|
{
|
|
|
|
class SimpleTextFloat;
|
|
|
|
class LMMS_EXPORT FloatModelEditorBase : public QWidget, public FloatModelView
|
|
{
|
|
Q_OBJECT
|
|
|
|
void initUi(const QString & name); //!< to be called by ctors
|
|
|
|
public:
|
|
enum class DirectionOfManipulation : bool
|
|
{
|
|
Vertical,
|
|
Horizontal
|
|
};
|
|
|
|
FloatModelEditorBase(DirectionOfManipulation directionOfManipulation = DirectionOfManipulation::Vertical, QWidget * _parent = nullptr, const QString & _name = QString()); //!< default ctor
|
|
FloatModelEditorBase(const FloatModelEditorBase& other) = delete;
|
|
|
|
// TODO: remove
|
|
inline void setHintText(const QString & txt_before, const QString & txt_after)
|
|
{
|
|
setDescription(txt_before);
|
|
setUnit(txt_after);
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the tooltip displayed when the mouse hovers over the control.
|
|
*
|
|
* Unlike the dynamic floating text from @ref getDynamicFloatingText which represents the
|
|
* current value of the model, this is static text intended to provide a helpful description
|
|
* of the control. That is, it's just a traditional tooltip, though it uses @ref SimpleTextFloat
|
|
* rather than QWidget's own tooltip for consistency with the dynamic floating text.
|
|
*
|
|
* If no static tooltip is set (when this method is not called), dynamic floating text
|
|
* is used in its place. See @ref InteractionType for more information.
|
|
*
|
|
* @param tip The static tooltip. If empty, neither a static nor dynamic tooltip will be
|
|
* displayed when the mouse hovers over the control.
|
|
*/
|
|
void setToolTip(const QString& tip)
|
|
{
|
|
m_staticToolTip.emplace(tip);
|
|
}
|
|
|
|
QString toolTip() const { return m_staticToolTip.value_or(QString{}); }
|
|
|
|
/**
|
|
* Removes the static tooltip set by a previous call to setToolTip().
|
|
* The dynamic floating text will be used in its place.
|
|
* @note This is currently unused.
|
|
*/
|
|
void unsetToolTip() { m_staticToolTip.reset(); }
|
|
|
|
signals:
|
|
void sliderPressed();
|
|
void sliderReleased();
|
|
void sliderMoved(float value);
|
|
|
|
protected:
|
|
void contextMenuEvent(QContextMenuEvent * me) override;
|
|
void dragEnterEvent(QDragEnterEvent * dee) override;
|
|
void dropEvent(QDropEvent * de) override;
|
|
void focusOutEvent(QFocusEvent * fe) override;
|
|
void mousePressEvent(QMouseEvent * me) override;
|
|
void mouseReleaseEvent(QMouseEvent * me) override;
|
|
void mouseMoveEvent(QMouseEvent * me) override;
|
|
void mouseDoubleClickEvent(QMouseEvent * me) override;
|
|
void paintEvent(QPaintEvent * me) override;
|
|
void wheelEvent(QWheelEvent * me) override;
|
|
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
|
void enterEvent(QEnterEvent*) override;
|
|
#else
|
|
void enterEvent(QEvent*) override;
|
|
#endif
|
|
void leaveEvent(QEvent *event) override;
|
|
|
|
virtual float getValue(const QPoint & p);
|
|
|
|
/**
|
|
* @returns the current value of the model as a string
|
|
*
|
|
* @note This method is called just prior to displaying dynamic floating text
|
|
* in order to set its value. If the @ref currentValueToTextUpdate method
|
|
* is not overridden, this method is also called to periodically update
|
|
* the floating text.
|
|
*/
|
|
virtual QString currentValueToText();
|
|
|
|
/**
|
|
* @returns the current value of the model as a string, or std::nullopt to
|
|
* indicate the previous value should continue being used
|
|
*
|
|
* @note This method is called periodically while dynamic floating text is
|
|
* visible and the value of the float model is changing, allowing dynamic updates
|
|
* of the floating text.
|
|
*/
|
|
virtual std::optional<QString> currentValueToTextUpdate()
|
|
{
|
|
return currentValueToText();
|
|
}
|
|
|
|
/**
|
|
* @brief Provides the text to be shown in dynamic floating text.
|
|
*
|
|
* @param currentValue text from @ref currentValueToText or @ref currentValueToTextUpdate
|
|
* @returns formatted text to display in dynamic floating text
|
|
*
|
|
* @note The default format is: "[description] [current value][unit]"
|
|
*/
|
|
virtual QString getDynamicFloatingText(const QString& currentValue) const;
|
|
|
|
void doConnections() override;
|
|
|
|
void showTextFloat(int msecBeforeDisplay, int msecDisplayTime, bool forceTextUpdate = false);
|
|
void showTextFloat(bool forceTextUpdate = false);
|
|
|
|
const SimpleTextFloat& textFloat() const { return *s_textFloat; }
|
|
|
|
void setPosition(const QPoint & p);
|
|
|
|
inline float pageSize() const
|
|
{
|
|
return (model()->maxValue() - model()->minValue()) / 100.0f;
|
|
}
|
|
|
|
DirectionOfManipulation directionOfManipulation() const { return m_directionOfManipulation; }
|
|
|
|
//! Types of user interaction with the control
|
|
enum class InteractionType : std::uint8_t
|
|
{
|
|
//! The user is not interacting with the control.
|
|
//! No floating text is shown.
|
|
None,
|
|
|
|
//! The mouse is hovering over the control without any other interaction.
|
|
//! If a static tooltip is set (see @ref setToolTip), it will be displayed,
|
|
//! otherwise dynamic floating text will be displayed.
|
|
MouseHover,
|
|
|
|
//! The user is dragging the control to adjust the model's value.
|
|
//! This always results in dynamic floating text, not a static tooltip.
|
|
MouseDrag,
|
|
|
|
//! The user is using the mouse wheel on the control to adjust the model's value.
|
|
//! This always results in dynamic floating text, not a static tooltip.
|
|
MouseWheel
|
|
};
|
|
|
|
//! @returns how the user is interacting with the control
|
|
InteractionType currentInteraction() const { return m_interaction; }
|
|
|
|
//! Updates m_interaction based on the event and current state
|
|
void updateInteractionState(QEvent* event);
|
|
|
|
enum class FloatingTextType : std::uint8_t
|
|
{
|
|
//! No floating text
|
|
None,
|
|
|
|
//! Traditional static tooltip
|
|
Static,
|
|
|
|
//! Dynamic floating text
|
|
Dynamic
|
|
};
|
|
|
|
/**
|
|
* @returns which type of floating text is currently being displayed based on how the user
|
|
* is interacting with the control and whether a static tooltip has been set for the control.
|
|
*/
|
|
FloatingTextType floatingTextType() const;
|
|
|
|
QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
|
|
float m_leftOver;
|
|
|
|
private slots:
|
|
virtual void enterValue();
|
|
void friendlyUpdate();
|
|
void toggleScale();
|
|
|
|
private:
|
|
InteractionType m_interaction = InteractionType::None;
|
|
|
|
DirectionOfManipulation m_directionOfManipulation;
|
|
|
|
std::optional<QString> m_staticToolTip;
|
|
|
|
static SimpleTextFloat* s_textFloat;
|
|
};
|
|
|
|
} // namespace lmms::gui
|
|
|
|
#endif // LMMS_GUI_FLOAT_MODEL_EDITOR_BASE_H
|