chatgui: add sound playback via miniaudio (MP3 notification sounds)
- SoundManager singleton wraps ma_engine + ma_sound (non-blocking, background thread) - MP3 files embedded in QRC, decoded to PCM at startup with MA_SOUND_FLAG_DECODE - miniaudio.h (MIT) in lib/, IMPLEMENTATION in separate miniaudio_impl.c - Sound settings page in SettingsDialog: enable/disable, volume slider (0-100%) - Config keys [gui] sound_enabled, sound_volume - Incoming messages trigger msg_incoming.mp3 sound
This commit is contained in:
1 parent
f6f7e12192
commit
c2ad2e78c3
25 files changed
+101647
-2
No files matched your search
@@ -0,0 +1,120 @@
|
||||
#include "soundsettingspage.h"
|
||||
#include "sound_manager.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QSlider>
|
||||
#include <QLabel>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
|
||||
SoundSettingsPage::SoundSettingsPage(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 12, 0, 0);
|
||||
layout->setSpacing(14);
|
||||
|
||||
m_enabledCheck = new QCheckBox("Enable sounds", this);
|
||||
m_enabledCheck->setStyleSheet("font-size: 13px;");
|
||||
layout->addWidget(m_enabledCheck);
|
||||
|
||||
auto* volLayout = new QHBoxLayout();
|
||||
auto* volLabel = new QLabel("Volume:", this);
|
||||
volLabel->setStyleSheet("font-size: 13px;");
|
||||
volLayout->addWidget(volLabel);
|
||||
|
||||
m_volumeSlider = new QSlider(Qt::Horizontal, this);
|
||||
m_volumeSlider->setRange(0, 100);
|
||||
m_volumeSlider->setFixedWidth(200);
|
||||
m_volumeSlider->setStyleSheet("QSlider::groove:horizontal { height: 6px; border-radius: 3px; background: palette(mid); }"
|
||||
"QSlider::handle:horizontal { width: 14px; height: 14px; margin: -4px 0; border-radius: 7px; background: #3390EC; }");
|
||||
volLayout->addWidget(m_volumeSlider);
|
||||
|
||||
m_volumeLabel = new QLabel("80%", this);
|
||||
m_volumeLabel->setFixedWidth(36);
|
||||
m_volumeLabel->setStyleSheet("font-size: 13px;");
|
||||
volLayout->addWidget(m_volumeLabel);
|
||||
volLayout->addStretch();
|
||||
layout->addLayout(volLayout);
|
||||
|
||||
layout->addStretch();
|
||||
|
||||
connect(m_enabledCheck, &QCheckBox::stateChanged, this, &SoundSettingsPage::onEnabledChanged);
|
||||
connect(m_volumeSlider, &QSlider::valueChanged, this, [this](int val) {
|
||||
m_volumeLabel->setText(QString::number(val) + "%");
|
||||
});
|
||||
}
|
||||
|
||||
void SoundSettingsPage::onEnabledChanged(int state) {
|
||||
m_volumeSlider->setEnabled(state == Qt::Checked);
|
||||
m_volumeLabel->setEnabled(state == Qt::Checked);
|
||||
}
|
||||
|
||||
void SoundSettingsPage::loadFromConfig(const QString& path) {
|
||||
QFile f(path);
|
||||
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
||||
|
||||
bool enabled = true;
|
||||
int volume = 80;
|
||||
bool inGui = false;
|
||||
QTextStream in(&f);
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().trimmed();
|
||||
if (line == "[gui]") { inGui = true; continue; }
|
||||
if (line.startsWith("[") && line.endsWith("]")) inGui = false;
|
||||
if (!inGui) continue;
|
||||
if (line.startsWith("sound_enabled="))
|
||||
enabled = line.mid(QString("sound_enabled=").size()).trimmed() != "0";
|
||||
else if (line.startsWith("sound_volume="))
|
||||
volume = line.mid(QString("sound_volume=").size()).trimmed().toInt();
|
||||
}
|
||||
f.close();
|
||||
|
||||
m_enabledCheck->setChecked(enabled);
|
||||
m_volumeSlider->setValue(volume);
|
||||
m_volumeSlider->setEnabled(enabled);
|
||||
m_volumeLabel->setEnabled(enabled);
|
||||
m_volumeLabel->setText(QString::number(volume) + "%");
|
||||
}
|
||||
|
||||
void SoundSettingsPage::saveToConfig(const QString& path) const {
|
||||
QFile f(path);
|
||||
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
||||
QString content = f.readAll();
|
||||
f.close();
|
||||
|
||||
QStringList lines = content.split('\n');
|
||||
|
||||
bool inGui = false;
|
||||
bool foundEnabled = false, foundVolume = false;
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
QString line = lines[i].trimmed();
|
||||
if (line == "[gui]") { inGui = true; continue; }
|
||||
if (line.startsWith("[") && line.endsWith("]")) inGui = false;
|
||||
if (!inGui) continue;
|
||||
|
||||
if (line.startsWith("sound_enabled=")) {
|
||||
lines[i] = QString("sound_enabled=%1").arg(m_enabledCheck->isChecked() ? 1 : 0);
|
||||
foundEnabled = true;
|
||||
} else if (line.startsWith("sound_volume=")) {
|
||||
lines[i] = QString("sound_volume=%1").arg(m_volumeSlider->value());
|
||||
foundVolume = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundEnabled || !foundVolume) {
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
if (lines[i].trimmed() == "[gui]") {
|
||||
if (!foundEnabled) lines.insert(i + 1, QString("sound_enabled=%1").arg(m_enabledCheck->isChecked() ? 1 : 0));
|
||||
if (!foundVolume) lines.insert(i + 1, QString("sound_volume=%1").arg(m_volumeSlider->value()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
|
||||
f.write(lines.join('\n').toUtf8());
|
||||
f.close();
|
||||
}
|
||||
Reference in new issue
Block a user