Undo/redo
This commit is contained in:
parent
adab645c86
commit
f681b69467
5 changed files with 43 additions and 46 deletions
|
|
@ -13,6 +13,7 @@ protected:
|
||||||
void mousePressEvent(QMouseEvent *event) override
|
void mousePressEvent(QMouseEvent *event) override
|
||||||
{
|
{
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
setProperty("pressValue", value());
|
||||||
const int span = (orientation() == Qt::Horizontal) ? width() : height();
|
const int span = (orientation() == Qt::Horizontal) ? width() : height();
|
||||||
const int pos = (orientation() == Qt::Horizontal)
|
const int pos = (orientation() == Qt::Horizontal)
|
||||||
? static_cast<int>(event->position().x())
|
? static_cast<int>(event->position().x())
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
#include <QUndoStack>
|
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
|
@ -49,10 +48,6 @@ public:
|
||||||
{
|
{
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->applyVolumeState(m_nodeId, m_previous, true);
|
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) {
|
if (m_widget) {
|
||||||
m_widget->applyVolumeState(m_nodeId, m_next, true);
|
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_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);
|
auto *savePresetAction = new QAction(QString("Save Preset..."), m_view);
|
||||||
connect(savePresetAction, &QAction::triggered, [this]() {
|
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)
|
void GraphEditorWidget::pushVolumeCommand(uint32_t nodeId, const NodeVolumeState &previous, const NodeVolumeState &next)
|
||||||
{
|
{
|
||||||
if (!m_volumeUndoStack || m_ignoreVolumeUndo) {
|
if (!m_scene || m_ignoreVolumeUndo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bool changedVolume = qAbs(previous.volume - next.volume) > 0.0001f;
|
const bool changedVolume = qAbs(previous.volume - next.volume) > 0.0001f;
|
||||||
if (!changedVolume && previous.mute == next.mute) {
|
if (!changedVolume && previous.mute == next.mute) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_volumeUndoStack->push(new VolumeChangeCommand(this, nodeId, previous, next));
|
m_scene->undoStack().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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,7 @@ class QToolButton;
|
||||||
class QSplitter;
|
class QSplitter;
|
||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
class PresetManager;
|
class PresetManager;
|
||||||
class QUndoStack;
|
|
||||||
class VolumeChangeCommand;
|
class VolumeChangeCommand;
|
||||||
class QAction;
|
|
||||||
|
|
||||||
class GraphEditorWidget : public QWidget
|
class GraphEditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
|
|
@ -109,8 +107,5 @@ private:
|
||||||
qint64 m_meterProfileMax = 0;
|
qint64 m_meterProfileMax = 0;
|
||||||
int m_meterProfileFrames = 0;
|
int m_meterProfileFrames = 0;
|
||||||
PresetManager *m_presetManager = nullptr;
|
PresetManager *m_presetManager = nullptr;
|
||||||
QUndoStack *m_volumeUndoStack = nullptr;
|
|
||||||
QAction *m_undoVolumeAction = nullptr;
|
|
||||||
QAction *m_redoVolumeAction = nullptr;
|
|
||||||
bool m_ignoreVolumeUndo = false;
|
bool m_ignoreVolumeUndo = false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -157,14 +157,40 @@ QWidget *PipeWireGraphModel::nodeWidget(QtNodes::NodeId nodeId) const
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const float volume = static_cast<float>(slider->value()) / 100.0f;
|
const float volume = static_cast<float>(slider->value()) / 100.0f;
|
||||||
const NodeVolumeState state{volume, muteButton->isChecked()};
|
const NodeVolumeState next{volume, muteButton->isChecked()};
|
||||||
m_controller->setNodeVolume(pipewireId, volume, state.mute);
|
const NodeVolumeState previous = m_nodeVolumeState.value(pipewireId, next);
|
||||||
|
m_controller->setNodeVolume(pipewireId, volume, next.mute);
|
||||||
auto *self = const_cast<PipeWireGraphModel*>(this);
|
auto *self = const_cast<PipeWireGraphModel*>(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(slider, &QSlider::valueChanged, widget, [applyVolume](int) { applyVolume(); });
|
||||||
QObject::connect(muteButton, &QToolButton::toggled, widget, [applyVolume](bool) { 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<float>(pressValue) / 100.0f)
|
||||||
|
: static_cast<float>(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<float>(slider->value()) / 100.0f;
|
||||||
|
const NodeVolumeState next{volume, muteButton->isChecked()};
|
||||||
|
auto *self = const_cast<PipeWireGraphModel*>(this);
|
||||||
|
self->emitNodeVolumeChanged(pipewireId, previous, next);
|
||||||
|
});
|
||||||
|
|
||||||
layout->addWidget(muteButton);
|
layout->addWidget(muteButton);
|
||||||
layout->addWidget(slider);
|
layout->addWidget(slider);
|
||||||
|
|
@ -811,6 +837,15 @@ void PipeWireGraphModel::applyVolumeStates(const QHash<QString, NodeVolumeState>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
void PipeWireGraphModel::setNodeVolumeState(uint32_t nodeId, const NodeVolumeState &state, bool notify)
|
||||||
{
|
{
|
||||||
const NodeVolumeState previous = m_nodeVolumeState.value(nodeId, NodeVolumeState{});
|
const NodeVolumeState previous = m_nodeVolumeState.value(nodeId, NodeVolumeState{});
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget *nodeWidget(QtNodes::NodeId nodeId) const;
|
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;
|
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;
|
bool findPortIndex(const Potato::NodeInfo &node, uint32_t portId, QtNodes::PortType type, QtNodes::PortIndex &index) const;
|
||||||
QString portLabel(const Potato::PortInfo &port) const;
|
QString portLabel(const Potato::PortInfo &port) const;
|
||||||
|
|
@ -115,4 +116,5 @@ private:
|
||||||
mutable std::unordered_map<QtNodes::NodeId, QWidget*> m_nodeWidgets;
|
mutable std::unordered_map<QtNodes::NodeId, QWidget*> m_nodeWidgets;
|
||||||
std::unordered_map<QtNodes::NodeId, QSize> m_nodeSizes;
|
std::unordered_map<QtNodes::NodeId, QSize> m_nodeSizes;
|
||||||
mutable QHash<uint32_t, NodeVolumeState> m_nodeVolumeState;
|
mutable QHash<uint32_t, NodeVolumeState> m_nodeVolumeState;
|
||||||
|
mutable QHash<uint32_t, NodeVolumeState> m_inlineStartState;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue