Save presets
This commit is contained in:
parent
ecfb59501a
commit
b3a1d2b7f3
9 changed files with 542 additions and 4 deletions
|
|
@ -144,12 +144,19 @@ QWidget *PipeWireGraphModel::nodeWidget(QtNodes::NodeId nodeId) const
|
|||
slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
slider->setToolTip(QString("Volume"));
|
||||
|
||||
if (pipewireId != 0 && m_nodeVolumeState.contains(pipewireId)) {
|
||||
const NodeVolumeState state = m_nodeVolumeState.value(pipewireId);
|
||||
slider->setValue(static_cast<int>(state.volume * 100.0f));
|
||||
muteButton->setChecked(state.mute);
|
||||
}
|
||||
|
||||
const auto applyVolume = [this, pipewireId, slider, muteButton]() {
|
||||
if (!m_controller || pipewireId == 0) {
|
||||
return;
|
||||
}
|
||||
const float volume = static_cast<float>(slider->value()) / 100.0f;
|
||||
m_controller->setNodeVolume(pipewireId, volume, muteButton->isChecked());
|
||||
m_nodeVolumeState.insert(pipewireId, NodeVolumeState{volume, muteButton->isChecked()});
|
||||
};
|
||||
|
||||
QObject::connect(slider, &QSlider::valueChanged, widget, [applyVolume](int) { applyVolume(); });
|
||||
|
|
@ -694,6 +701,135 @@ void PipeWireGraphModel::loadLayout()
|
|||
}
|
||||
}
|
||||
|
||||
QJsonObject PipeWireGraphModel::layoutJson() const
|
||||
{
|
||||
QJsonObject root;
|
||||
QJsonArray nodes;
|
||||
for (auto it = m_layoutByStableId.cbegin(); it != m_layoutByStableId.cend(); ++it) {
|
||||
QJsonObject item;
|
||||
item["id"] = it.key();
|
||||
item["x"] = it.value().x();
|
||||
item["y"] = it.value().y();
|
||||
nodes.append(item);
|
||||
}
|
||||
root["nodes"] = nodes;
|
||||
|
||||
QJsonObject view;
|
||||
view["scale"] = m_viewScale;
|
||||
view["center_x"] = m_viewCenter.x();
|
||||
view["center_y"] = m_viewCenter.y();
|
||||
root["view"] = view;
|
||||
|
||||
if (m_hasSplitterSizes && !m_splitterSizes.isEmpty()) {
|
||||
QJsonArray splitter;
|
||||
for (const auto size : m_splitterSizes) {
|
||||
splitter.append(size);
|
||||
}
|
||||
root["splitter"] = splitter;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
void PipeWireGraphModel::applyLayoutJson(const QJsonObject &root)
|
||||
{
|
||||
m_layoutByStableId.clear();
|
||||
m_hasViewState = false;
|
||||
m_hasSplitterSizes = false;
|
||||
m_splitterSizes.clear();
|
||||
|
||||
const QJsonArray nodes = root.value("nodes").toArray();
|
||||
applyLayoutData(nodes);
|
||||
|
||||
const QJsonObject view = root.value("view").toObject();
|
||||
if (!view.isEmpty()) {
|
||||
m_viewScale = view.value("scale").toDouble(1.0);
|
||||
const double x = view.value("center_x").toDouble(0.0);
|
||||
const double y = view.value("center_y").toDouble(0.0);
|
||||
m_viewCenter = QPointF(x, y);
|
||||
m_hasViewState = true;
|
||||
}
|
||||
|
||||
const QJsonArray splitter = root.value("splitter").toArray();
|
||||
if (!splitter.isEmpty()) {
|
||||
QList<int> sizes;
|
||||
sizes.reserve(splitter.size());
|
||||
for (const auto &value : splitter) {
|
||||
sizes.append(value.toInt());
|
||||
}
|
||||
if (!sizes.isEmpty()) {
|
||||
m_splitterSizes = sizes;
|
||||
m_hasSplitterSizes = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &entry : m_nodes) {
|
||||
const QtNodes::NodeId nodeId = entry.first;
|
||||
const Potato::NodeInfo &info = entry.second;
|
||||
if (!info.stableId.isEmpty() && m_layoutByStableId.contains(info.stableId)) {
|
||||
const QPointF position = m_layoutByStableId.value(info.stableId);
|
||||
m_positions[nodeId] = position;
|
||||
Q_EMIT nodePositionUpdated(nodeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, NodeVolumeState> PipeWireGraphModel::volumeStates() const
|
||||
{
|
||||
QHash<QString, NodeVolumeState> result;
|
||||
for (const auto &entry : m_nodes) {
|
||||
const Potato::NodeInfo &info = entry.second;
|
||||
if (info.stableId.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (!m_nodeVolumeState.contains(info.id)) {
|
||||
continue;
|
||||
}
|
||||
result.insert(info.stableId, m_nodeVolumeState.value(info.id));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PipeWireGraphModel::applyVolumeStates(const QHash<QString, NodeVolumeState> &states)
|
||||
{
|
||||
if (!m_controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector<Potato::NodeInfo> nodes = m_controller->nodes();
|
||||
for (const auto &node : nodes) {
|
||||
if (node.stableId.isEmpty() || !states.contains(node.stableId)) {
|
||||
continue;
|
||||
}
|
||||
const NodeVolumeState state = states.value(node.stableId);
|
||||
m_nodeVolumeState.insert(node.id, state);
|
||||
m_controller->setNodeVolume(node.id, state.volume, state.mute);
|
||||
|
||||
auto nodeIt = m_pwToNode.find(node.id);
|
||||
if (nodeIt == m_pwToNode.end()) {
|
||||
continue;
|
||||
}
|
||||
auto widgetIt = m_nodeWidgets.find(nodeIt->second);
|
||||
if (widgetIt == m_nodeWidgets.end()) {
|
||||
continue;
|
||||
}
|
||||
QWidget *widget = widgetIt->second;
|
||||
if (!widget) {
|
||||
continue;
|
||||
}
|
||||
if (auto *slider = widget->findChild<QSlider*>()) {
|
||||
slider->blockSignals(true);
|
||||
slider->setValue(static_cast<int>(state.volume * 100.0f));
|
||||
slider->blockSignals(false);
|
||||
}
|
||||
if (auto *button = widget->findChild<QToolButton*>()) {
|
||||
button->blockSignals(true);
|
||||
button->setChecked(state.mute);
|
||||
button->blockSignals(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PipeWireGraphModel::saveLayout() const
|
||||
{
|
||||
const QString path = layoutFilePath();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue