mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
[UI] Implement achievement notification sound using Qt media player
This commit is contained in:
@@ -85,7 +85,7 @@ jobs:
|
||||
pip install aqtinstall
|
||||
echo "Available architectures for Qt 6.9.2:"
|
||||
aqt list-qt linux desktop --arch 6.9.2 || true
|
||||
aqt install-qt linux desktop 6.9.2 linux_gcc_64 -O /opt/Qt
|
||||
aqt install-qt linux desktop 6.9.2 linux_gcc_64 -m qtmultimedia -O /opt/Qt
|
||||
fi
|
||||
export PATH="/opt/Qt/6.9.2/gcc_64/bin:$PATH"
|
||||
export CMAKE_PREFIX_PATH="/opt/Qt/6.9.2/gcc_64"
|
||||
@@ -257,7 +257,7 @@ jobs:
|
||||
$qtCacheHit = '${{ steps.cache-qt.outputs.cache-hit }}'
|
||||
if ($qtCacheHit -ne 'true') {
|
||||
pip install aqtinstall
|
||||
aqt install-qt windows desktop 6.9.2 win64_msvc2022_64 -O C:\Qt
|
||||
aqt install-qt windows desktop 6.9.2 win64_msvc2022_64 -m qtmultimedia -O C:\Qt
|
||||
}
|
||||
|
||||
$cacheHit = '${{ steps.cache-submodules.outputs.cache-hit }}'
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ drivers.
|
||||
* Install using aqtinstall:
|
||||
```
|
||||
pip install aqtinstall
|
||||
python -m aqt install-qt windows desktop 6.9.2 win64_msvc2022_64 -O C:\Qt
|
||||
python -m aqt install-qt windows desktop 6.9.2 win64_msvc2022_64 -m qtmultimedia -O C:\Qt
|
||||
# Note: msvc2022_64 is compatible with with VS2026
|
||||
```
|
||||
* The build script will automatically detect it if installed in `C:\Qt`
|
||||
@@ -127,7 +127,7 @@ You can install Qt from your distribution's package manager, or use aqtinstall:
|
||||
|
||||
```sh
|
||||
pip install aqtinstall
|
||||
aqt install-qt linux desktop 6.9.2 linux_gcc_64 -O /opt/Qt
|
||||
aqt install-qt linux desktop 6.9.2 linux_gcc_64 -m qtmultimedia -O /opt/Qt
|
||||
```
|
||||
|
||||
If using aqtinstall, add Qt to your environment:
|
||||
|
||||
@@ -176,6 +176,7 @@ filter("platforms:Linux")
|
||||
path.join(qt_dir, "include/QtCore"),
|
||||
path.join(qt_dir, "include/QtGui"),
|
||||
path.join(qt_dir, "include/QtWidgets"),
|
||||
path.join(qt_dir, "include/QtMultimedia"),
|
||||
})
|
||||
libdirs({
|
||||
path.join(qt_dir, "lib"),
|
||||
@@ -191,6 +192,7 @@ filter("platforms:Linux")
|
||||
"Qt6Core",
|
||||
"Qt6Gui",
|
||||
"Qt6Widgets",
|
||||
"Qt6Multimedia",
|
||||
})
|
||||
end
|
||||
|
||||
@@ -332,6 +334,7 @@ filter("platforms:Windows")
|
||||
path.join(qt_dir, "include/QtCore"),
|
||||
path.join(qt_dir, "include/QtGui"),
|
||||
path.join(qt_dir, "include/QtWidgets"),
|
||||
path.join(qt_dir, "include/QtMultimedia"),
|
||||
})
|
||||
libdirs({
|
||||
path.join(qt_dir, "lib"),
|
||||
@@ -344,6 +347,7 @@ filter({"platforms:Windows", "configurations:Release"})
|
||||
"Qt6Core",
|
||||
"Qt6Gui",
|
||||
"Qt6Widgets",
|
||||
"Qt6Multimedia",
|
||||
})
|
||||
end
|
||||
|
||||
@@ -353,6 +357,7 @@ filter({"platforms:Windows", "configurations:Debug or Checked"})
|
||||
"Qt6Cored",
|
||||
"Qt6Guid",
|
||||
"Qt6Widgetsd",
|
||||
"Qt6Multimediad",
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
@@ -312,8 +312,9 @@ QWidget* ConfigDialogQt::CreateEditorWidget(ConfigVarInfo* var_info) {
|
||||
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&ConfigDialogQt::OnValueChanged);
|
||||
return combo;
|
||||
} else if (dynamic_cast<cvar::ConfigVar<std::filesystem::path>*>(
|
||||
var_info->var)) {
|
||||
} else if (auto* path_var =
|
||||
dynamic_cast<cvar::ConfigVar<std::filesystem::path>*>(
|
||||
var_info->var)) {
|
||||
// Path input with browse button
|
||||
auto* container = new QWidget();
|
||||
auto* layout = new QHBoxLayout(container);
|
||||
@@ -328,9 +329,20 @@ QWidget* ConfigDialogQt::CreateEditorWidget(ConfigVarInfo* var_info) {
|
||||
auto* browse_button = new QPushButton("Browse...");
|
||||
connect(browse_button, &QPushButton::clicked,
|
||||
[this, line_edit, var_info]() {
|
||||
QString path = QFileDialog::getExistingDirectory(
|
||||
this, SafeQString("Select Directory for " + var_info->name),
|
||||
line_edit->text());
|
||||
QString path;
|
||||
// Special case for notification_sound_path - file picker with
|
||||
// audio filters
|
||||
if (var_info->name == "notification_sound_path") {
|
||||
path = QFileDialog::getOpenFileName(
|
||||
this, "Select Notification Sound", line_edit->text(),
|
||||
"Audio Files (*.wav *.mp3 *.ogg *.flac *.m4a *.aac *.wma "
|
||||
"*.opus);;All Files (*)");
|
||||
} else {
|
||||
// Default: directory picker
|
||||
path = QFileDialog::getExistingDirectory(
|
||||
this, SafeQString("Select Directory for " + var_info->name),
|
||||
line_edit->text());
|
||||
}
|
||||
if (!path.isEmpty()) {
|
||||
line_edit->setText(path);
|
||||
}
|
||||
|
||||
@@ -14,15 +14,6 @@
|
||||
#include "xenia/ui/imgui_guest_notification.h"
|
||||
#include "xenia/ui/imgui_notification.h"
|
||||
|
||||
#if XE_PLATFORM_WIN32
|
||||
#include <playsoundapi.h>
|
||||
#endif
|
||||
|
||||
DEFINE_string(notification_sound_path, "",
|
||||
"Path (including filename) to selected notification sound. Sound "
|
||||
"MUST be in wav format!",
|
||||
"General");
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
|
||||
@@ -46,19 +37,6 @@ void ImGuiGuestNotification::UpdateNotificationState() {
|
||||
// TODO(Gliniak): Implement delayed notifications.
|
||||
current_stage_ = NotificationStage::FazeIn;
|
||||
notification_draw_progress_ = 0.2f;
|
||||
#if XE_PLATFORM_WIN32
|
||||
if (!cvars::notification_sound_path.empty()) {
|
||||
auto notification_sound_path = cvars::notification_sound_path;
|
||||
if (std::filesystem::exists(notification_sound_path)) {
|
||||
PlaySound(std::wstring(notification_sound_path.begin(),
|
||||
notification_sound_path.end())
|
||||
.c_str(),
|
||||
NULL,
|
||||
SND_FILENAME | SND_NODEFAULT | SND_NOSTOP | SND_ASYNC);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case NotificationStage::FazeIn: {
|
||||
SetCreationTime(Clock::QueryHostUptimeMillis());
|
||||
|
||||
@@ -9,16 +9,29 @@
|
||||
|
||||
#include "xenia/ui/notification_widget_qt.h"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QVBoxLayout>
|
||||
#include <filesystem>
|
||||
|
||||
#include "xenia/base/cvar.h"
|
||||
#include "xenia/base/string.h"
|
||||
#include "xenia/ui/qt_util.h"
|
||||
|
||||
DEFINE_path(notification_sound_path, "",
|
||||
"Path (including filename) to selected notification sound. "
|
||||
"Supports WAV, MP3, OGG, FLAC, and other common formats.",
|
||||
"UI");
|
||||
|
||||
namespace xe {
|
||||
namespace app {
|
||||
|
||||
using xe::ui::SafeQString;
|
||||
|
||||
NotificationWidgetQt::NotificationWidgetQt(QWidget* parent,
|
||||
const QString& title,
|
||||
const QString& message,
|
||||
int duration_ms)
|
||||
: QWidget(parent) {
|
||||
: QWidget(parent), media_player_(nullptr), audio_output_(nullptr) {
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
setAutoFillBackground(true);
|
||||
@@ -57,6 +70,19 @@ NotificationWidgetQt::NotificationWidgetQt(QWidget* parent,
|
||||
deleteLater(); // Ensure widget is actually destroyed
|
||||
});
|
||||
auto_close_timer_->setInterval(duration_ms);
|
||||
|
||||
// Setup media player for notification sound
|
||||
if (!cvars::notification_sound_path.empty()) {
|
||||
std::filesystem::path sound_path = cvars::notification_sound_path;
|
||||
if (std::filesystem::exists(sound_path)) {
|
||||
media_player_ = new QMediaPlayer(this);
|
||||
audio_output_ = new QAudioOutput(this);
|
||||
media_player_->setAudioOutput(audio_output_);
|
||||
media_player_->setSource(
|
||||
QUrl::fromLocalFile(SafeQString(xe::path_to_utf8(sound_path))));
|
||||
audio_output_->setVolume(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationWidgetQt::Show() {
|
||||
@@ -74,6 +100,11 @@ void NotificationWidgetQt::Show() {
|
||||
show();
|
||||
raise();
|
||||
auto_close_timer_->start();
|
||||
|
||||
// Play sound if configured
|
||||
if (media_player_) {
|
||||
media_player_->play();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#ifndef XENIA_UI_NOTIFICATION_WIDGET_QT_H_
|
||||
#define XENIA_UI_NOTIFICATION_WIDGET_QT_H_
|
||||
|
||||
#include <QAudioOutput>
|
||||
#include <QLabel>
|
||||
#include <QMediaPlayer>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
@@ -29,6 +31,8 @@ class NotificationWidgetQt : public QWidget {
|
||||
|
||||
private:
|
||||
QTimer* auto_close_timer_;
|
||||
QMediaPlayer* media_player_;
|
||||
QAudioOutput* audio_output_;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
Reference in New Issue
Block a user