diff --git a/src/gui/ClickSlider.h b/src/gui/ClickSlider.h index 7e6a461..03346a4 100644 --- a/src/gui/ClickSlider.h +++ b/src/gui/ClickSlider.h @@ -13,6 +13,7 @@ protected: void mousePressEvent(QMouseEvent *event) override { if (event->button() == Qt::LeftButton) { + setProperty("pressValue", value()); const int span = (orientation() == Qt::Horizontal) ? width() : height(); const int pos = (orientation() == Qt::Horizontal) ? static_cast(event->position().x()) diff --git a/src/gui/GraphEditorWidget.cpp b/src/gui/GraphEditorWidget.cpp index 1a714eb..802661e 100644 --- a/src/gui/GraphEditorWidget.cpp +++ b/src/gui/GraphEditorWidget.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -49,10 +48,6 @@ public: { if (m_widget) { m_widget->applyVolumeState(m_nodeId, m_previous, true); - if (m_widget->m_volumeUndoStack) { - m_widget->m_undoVolumeAction->setEnabled(m_widget->m_volumeUndoStack->canUndo()); - m_widget->m_redoVolumeAction->setEnabled(m_widget->m_volumeUndoStack->canRedo()); - } } } @@ -60,10 +55,6 @@ public: { if (m_widget) { m_widget->applyVolumeState(m_nodeId, m_next, true); - if (m_widget->m_volumeUndoStack) { - m_widget->m_undoVolumeAction->setEnabled(m_widget->m_volumeUndoStack->canUndo()); - m_widget->m_redoVolumeAction->setEnabled(m_widget->m_volumeUndoStack->canRedo()); - } } } @@ -270,27 +261,6 @@ GraphEditorWidget::GraphEditorWidget(Potato::PipeWireController *controller, QWi }); m_view->addAction(resetLayoutAction); - m_volumeUndoStack = new QUndoStack(this); - m_undoVolumeAction = new QAction(QString("Undo Volume"), m_view); - m_redoVolumeAction = new QAction(QString("Redo Volume"), m_view); - m_undoVolumeAction->setShortcut(QKeySequence::Undo); - m_redoVolumeAction->setShortcut(QKeySequence::Redo); - m_undoVolumeAction->setEnabled(false); - m_redoVolumeAction->setEnabled(false); - connect(m_undoVolumeAction, &QAction::triggered, m_volumeUndoStack, &QUndoStack::undo); - connect(m_redoVolumeAction, &QAction::triggered, m_volumeUndoStack, &QUndoStack::redo); - m_view->addAction(m_undoVolumeAction); - m_view->addAction(m_redoVolumeAction); - connect(m_volumeUndoStack, &QUndoStack::canUndoChanged, this, [this](bool canUndo) { - if (m_undoVolumeAction) { - m_undoVolumeAction->setEnabled(canUndo); - } - }); - connect(m_volumeUndoStack, &QUndoStack::canRedoChanged, this, [this](bool canRedo) { - if (m_redoVolumeAction) { - m_redoVolumeAction->setEnabled(canRedo); - } - }); auto *savePresetAction = new QAction(QString("Save Preset..."), m_view); connect(savePresetAction, &QAction::triggered, [this]() { @@ -1081,18 +1051,12 @@ void GraphEditorWidget::applyVolumeState(uint32_t nodeId, const NodeVolumeState void GraphEditorWidget::pushVolumeCommand(uint32_t nodeId, const NodeVolumeState &previous, const NodeVolumeState &next) { - if (!m_volumeUndoStack || m_ignoreVolumeUndo) { + if (!m_scene || m_ignoreVolumeUndo) { return; } const bool changedVolume = qAbs(previous.volume - next.volume) > 0.0001f; if (!changedVolume && previous.mute == next.mute) { return; } - m_volumeUndoStack->push(new VolumeChangeCommand(this, nodeId, previous, next)); - if (m_undoVolumeAction) { - m_undoVolumeAction->setEnabled(m_volumeUndoStack->canUndo()); - } - if (m_redoVolumeAction) { - m_redoVolumeAction->setEnabled(m_volumeUndoStack->canRedo()); - } + m_scene->undoStack().push(new VolumeChangeCommand(this, nodeId, previous, next)); } diff --git a/src/gui/GraphEditorWidget.h b/src/gui/GraphEditorWidget.h index 69f4ce5..31977f4 100644 --- a/src/gui/GraphEditorWidget.h +++ b/src/gui/GraphEditorWidget.h @@ -23,9 +23,7 @@ class QToolButton; class QSplitter; class QTabWidget; class PresetManager; -class QUndoStack; class VolumeChangeCommand; -class QAction; class GraphEditorWidget : public QWidget { @@ -109,8 +107,5 @@ private: qint64 m_meterProfileMax = 0; int m_meterProfileFrames = 0; PresetManager *m_presetManager = nullptr; - QUndoStack *m_volumeUndoStack = nullptr; - QAction *m_undoVolumeAction = nullptr; - QAction *m_redoVolumeAction = nullptr; bool m_ignoreVolumeUndo = false; }; diff --git a/src/gui/PipeWireGraphModel.cpp b/src/gui/PipeWireGraphModel.cpp index 6f1ea6d..de76004 100644 --- a/src/gui/PipeWireGraphModel.cpp +++ b/src/gui/PipeWireGraphModel.cpp @@ -157,14 +157,40 @@ QWidget *PipeWireGraphModel::nodeWidget(QtNodes::NodeId nodeId) const return; } const float volume = static_cast(slider->value()) / 100.0f; - const NodeVolumeState state{volume, muteButton->isChecked()}; - m_controller->setNodeVolume(pipewireId, volume, state.mute); + const NodeVolumeState next{volume, muteButton->isChecked()}; + const NodeVolumeState previous = m_nodeVolumeState.value(pipewireId, next); + m_controller->setNodeVolume(pipewireId, volume, next.mute); auto *self = const_cast(this); - self->setNodeVolumeState(pipewireId, state, true); + self->setNodeVolumeState(pipewireId, next, false); + if (!slider->isSliderDown() && !m_inlineStartState.contains(pipewireId)) { + self->emitNodeVolumeChanged(pipewireId, previous, next); + } }; QObject::connect(slider, &QSlider::valueChanged, widget, [applyVolume](int) { applyVolume(); }); QObject::connect(muteButton, &QToolButton::toggled, widget, [applyVolume](bool) { applyVolume(); }); + QObject::connect(slider, &QSlider::sliderPressed, widget, [this, pipewireId, slider, muteButton]() { + if (pipewireId == 0) { + return; + } + bool ok = false; + const int pressValue = slider->property("pressValue").toInt(&ok); + const float volume = ok ? (static_cast(pressValue) / 100.0f) + : static_cast(slider->value()) / 100.0f; + const bool mute = muteButton->isChecked(); + m_inlineStartState.insert(pipewireId, NodeVolumeState{volume, mute}); + }); + QObject::connect(slider, &QSlider::sliderReleased, widget, [this, pipewireId, slider, muteButton]() { + if (pipewireId == 0) { + return; + } + const NodeVolumeState previous = m_inlineStartState.value(pipewireId, m_nodeVolumeState.value(pipewireId)); + m_inlineStartState.remove(pipewireId); + const float volume = static_cast(slider->value()) / 100.0f; + const NodeVolumeState next{volume, muteButton->isChecked()}; + auto *self = const_cast(this); + self->emitNodeVolumeChanged(pipewireId, previous, next); + }); layout->addWidget(muteButton); layout->addWidget(slider); @@ -811,6 +837,15 @@ void PipeWireGraphModel::applyVolumeStates(const QHash } } +void PipeWireGraphModel::emitNodeVolumeChanged(uint32_t nodeId, const NodeVolumeState &previous, const NodeVolumeState ¤t) +{ + const bool changedVolume = qAbs(previous.volume - current.volume) > 0.0001f; + if (!changedVolume && previous.mute == current.mute) { + return; + } + Q_EMIT nodeVolumeChanged(nodeId, previous, current); +} + void PipeWireGraphModel::setNodeVolumeState(uint32_t nodeId, const NodeVolumeState &state, bool notify) { const NodeVolumeState previous = m_nodeVolumeState.value(nodeId, NodeVolumeState{}); diff --git a/src/gui/PipeWireGraphModel.h b/src/gui/PipeWireGraphModel.h index 554fc74..b55e7b7 100644 --- a/src/gui/PipeWireGraphModel.h +++ b/src/gui/PipeWireGraphModel.h @@ -89,6 +89,7 @@ signals: private: QWidget *nodeWidget(QtNodes::NodeId nodeId) const; + void emitNodeVolumeChanged(uint32_t nodeId, const NodeVolumeState &previous, const NodeVolumeState ¤t); QtNodes::ConnectionId connectionFromPipeWire(const Potato::LinkInfo &link, bool *ok) const; bool findPortIndex(const Potato::NodeInfo &node, uint32_t portId, QtNodes::PortType type, QtNodes::PortIndex &index) const; QString portLabel(const Potato::PortInfo &port) const; @@ -115,4 +116,5 @@ private: mutable std::unordered_map m_nodeWidgets; std::unordered_map m_nodeSizes; mutable QHash m_nodeVolumeState; + mutable QHash m_inlineStartState; };