Skip to content

Commit 68aad50

Browse files
authored
QtFred Combined spooled music selector/player widget (#7377)
* combined spooled music selector/player widget * clang * private members * case insensitive compare
1 parent 3d18cf4 commit 68aad50

12 files changed

Lines changed: 285 additions & 99 deletions

qtfred/source_groups.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ add_file_folder("Source/UI/Widgets"
321321
src/ui/widgets/SimpleListSelectDialog.h
322322
src/ui/widgets/weaponList.cpp
323323
src/ui/widgets/weaponList.h
324+
src/ui/widgets/MusicComboWidget.cpp
325+
src/ui/widgets/MusicComboWidget.h
324326
)
325327

326328
add_file_folder("UI"

qtfred/src/ui/dialogs/BriefingEditorDialog.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "mission/util.h"
55
#include "ui/Theme.h"
6+
#include <gamesnd/eventmusic.h>
67
#include "ui/widgets/BriefingMapWidget.h"
78
#include "BriefingEditor/CameraCoordinatesDialog.h"
89
#include "BriefingEditor/IconFromShipDialog.h"
@@ -111,6 +112,8 @@ void BriefingEditorDialog::accept()
111112
// If apply() returns true, close the dialog
112113
if (_model->apply()) {
113114
_viewport->editor->autosave("briefing editor");
115+
ui->defaultMusicWidget->stopPlayback();
116+
ui->musicPackWidget->stopPlayback();
114117
QDialog::accept();
115118
create_default_grid(); // restore the grid back to the normal version
116119
}
@@ -123,6 +126,8 @@ void BriefingEditorDialog::reject()
123126
// If they do, it runs _model->apply() and returns the success value
124127
// If they don't, it runs _model->reject() and returns true
125128
if (rejectOrCloseHandler(this, _model.get(), _viewport)) {
129+
ui->defaultMusicWidget->stopPlayback();
130+
ui->musicPackWidget->stopPlayback();
126131
QDialog::reject(); // actually close
127132
create_default_grid(); // restore the grid back to the normal version
128133
}
@@ -218,6 +223,7 @@ void BriefingEditorDialog::applyMapWidgetAspectRatio()
218223
void BriefingEditorDialog::initializeUi()
219224
{
220225
fso::fred::bindStandardIcon(ui->voiceFilePlayButton, QStyle::SP_MediaPlay);
226+
221227
util::SignalBlockers blockers(this);
222228
ui->drawLinesCheckBox->setTristate(true);
223229
ui->highlightCheckBox->setTristate(true);
@@ -248,12 +254,6 @@ void BriefingEditorDialog::initializeUi()
248254
ui->iconTeamComboBox->addItem(iff.second.c_str(), iff.first);
249255
}
250256

251-
auto musicList = _model->getMusicList();
252-
for (const auto& m : musicList) {
253-
ui->defaultMusicComboBox->addItem(m.c_str());
254-
ui->musicPackComboBox->addItem(m.c_str());
255-
}
256-
257257
// Initialize the formula tree editor
258258
ui->formulaTreeView->initializeEditor(_viewport->editor, this);
259259

@@ -276,8 +276,18 @@ void BriefingEditorDialog::updateUi()
276276

277277
ui->stageTextPlainTextEdit->setPlainText(QString::fromStdString(_model->getStageText()));
278278
ui->voiceFileLineEdit->setText(QString::fromStdString(_model->getSpeechFilename()));
279-
ui->defaultMusicComboBox->setCurrentIndex(_model->getBriefingMusicIndex());
280-
ui->musicPackComboBox->setCurrentIndex(ui->musicPackComboBox->findText(_model->getSubstituteBriefingMusicName().c_str()));
279+
// getBriefingMusicIndex() is 1-based (0 = None); widget uses Spooled_music index (-1 = None)
280+
ui->defaultMusicWidget->setCurrentMusicIndex(_model->getBriefingMusicIndex() - 1);
281+
282+
// Substitute music is stored by name; find the corresponding Spooled_music index
283+
{
284+
const SCP_string& subName = _model->getSubstituteBriefingMusicName();
285+
int smIdx = -1;
286+
for (int i = 0; i < static_cast<int>(Spooled_music.size()); ++i) {
287+
if (stricmp(Spooled_music[i].name, subName.c_str()) == 0) { smIdx = i; break; }
288+
}
289+
ui->musicPackWidget->setCurrentMusicIndex(smIdx);
290+
}
281291

282292
SCP_string stages = "No Stages";
283293
int total = _model->getTotalStages();
@@ -705,14 +715,28 @@ void BriefingEditorDialog::on_formulaTreeView_nodeChanged(int newTree)
705715
_model->setFormula(newTree);
706716
}
707717

708-
void BriefingEditorDialog::on_defaultMusicComboBox_currentIndexChanged(int index)
718+
void BriefingEditorDialog::on_defaultMusicWidget_currentIndexChanged(int spooledMusicIdx)
719+
{
720+
// Model uses 1-based index (0 = None); widget uses Spooled_music index (-1 = None)
721+
_model->setBriefingMusicIndex(spooledMusicIdx + 1);
722+
}
723+
724+
void BriefingEditorDialog::on_musicPackWidget_currentIndexChanged(int spooledMusicIdx)
725+
{
726+
SCP_string name = (spooledMusicIdx >= 0 && spooledMusicIdx < static_cast<int>(Spooled_music.size()))
727+
? Spooled_music[spooledMusicIdx].name
728+
: "";
729+
_model->setSubstituteBriefingMusicName(name);
730+
}
731+
732+
void BriefingEditorDialog::on_defaultMusicWidget_playbackStarted()
709733
{
710-
_model->setBriefingMusicIndex(index);
734+
ui->musicPackWidget->stopPlayback();
711735
}
712736

713-
void BriefingEditorDialog::on_musicPackComboBox_currentIndexChanged(int /*index*/)
737+
void BriefingEditorDialog::on_musicPackWidget_playbackStarted()
714738
{
715-
_model->setSubstituteBriefingMusicName(ui->musicPackComboBox->currentText().toUtf8().constData());
739+
ui->defaultMusicWidget->stopPlayback();
716740
}
717741

718742
} // namespace fso::fred::dialogs

qtfred/src/ui/dialogs/BriefingEditorDialog.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ class BriefingEditorDialog : public QDialog, public SexpTreeEditorInterface {
8585
void on_voiceFilePlayButton_clicked();
8686
void on_formulaTreeView_nodeChanged(int newTree);
8787

88-
void on_defaultMusicComboBox_currentIndexChanged(int index);
89-
void on_musicPackComboBox_currentIndexChanged(int /*index*/);
88+
void on_defaultMusicWidget_currentIndexChanged(int spooledMusicIdx);
89+
void on_musicPackWidget_currentIndexChanged(int spooledMusicIdx);
90+
void on_defaultMusicWidget_playbackStarted();
91+
void on_musicPackWidget_playbackStarted();
9092

9193
private: // NOLINT(readability-redundant-access-specifiers)
9294
std::unique_ptr<Ui::BriefingEditorDialog> ui;

qtfred/src/ui/dialogs/DebriefingDialog.cpp

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "ui_DebriefingDialog.h"
33
#include "ui/Theme.h"
44
#include "mission/util.h"
5+
#include <gamesnd/eventmusic.h>
56
#include <globalincs/globals.h>
67
#include <globalincs/linklist.h>
78
#include <ui/util/default_dir.h>
@@ -35,6 +36,9 @@ void DebriefingDialog::accept()
3536
// If apply() returns true, close the dialog
3637
if (_model->apply()) {
3738
_viewport->editor->autosave("debriefing editor");
39+
ui->successMusicWidget->stopPlayback();
40+
ui->averageMusicWidget->stopPlayback();
41+
ui->failureMusicWidget->stopPlayback();
3842
QDialog::accept();
3943
}
4044
// else: validation failed, don't close
@@ -46,6 +50,9 @@ void DebriefingDialog::reject()
4650
// If they do, it runs _model->apply() and returns the success value
4751
// If they don't, it runs _model->reject() and returns true
4852
if (rejectOrCloseHandler(this, _model.get(), _viewport)) {
53+
ui->successMusicWidget->stopPlayback();
54+
ui->averageMusicWidget->stopPlayback();
55+
ui->failureMusicWidget->stopPlayback();
4956
QDialog::reject(); // actually close
5057
}
5158
// else: do nothing, don't close
@@ -60,8 +67,9 @@ void DebriefingDialog::closeEvent(QCloseEvent* e)
6067
void DebriefingDialog::initializeUi()
6168
{
6269
fso::fred::bindStandardIcon(ui->voiceFilePlayButton, QStyle::SP_MediaPlay);
70+
6371
util::SignalBlockers blockers(this);
64-
72+
6573
auto list = _model->getTeamList();
6674

6775
ui->actionChangeTeams->clear();
@@ -70,18 +78,6 @@ void DebriefingDialog::initializeUi()
7078
ui->actionChangeTeams->addItem(QString::fromStdString(team.first), team.second);
7179
}
7280

73-
auto musicList = _model->getMusicList();
74-
QStringList qMusicList;
75-
for (const auto& track : musicList) {
76-
qMusicList << QString::fromStdString(track);
77-
}
78-
ui->successMusicComboBox->clear();
79-
ui->successMusicComboBox->addItems(qMusicList);
80-
ui->averageMusicComboBox->clear();
81-
ui->averageMusicComboBox->addItems(qMusicList);
82-
ui->failureMusicComboBox->clear();
83-
ui->failureMusicComboBox->addItems(qMusicList);
84-
8581
// Initialize the formula tree editor
8682
ui->formulaTreeView->initializeEditor(_viewport->editor, this);
8783
}
@@ -114,10 +110,10 @@ void DebriefingDialog::updateUi()
114110
ui->formulaTreeView->hilite_item(ui->formulaTreeView->select_sexp_node);
115111
}
116112

117-
// Music tracks (data is index, UI is index + 1 to account for "None")
118-
ui->successMusicComboBox->setCurrentIndex(_model->getSuccessMusicTrack() + 1);
119-
ui->averageMusicComboBox->setCurrentIndex(_model->getAverageMusicTrack() + 1);
120-
ui->failureMusicComboBox->setCurrentIndex(_model->getFailureMusicTrack() + 1);
113+
// Music tracks: model uses Spooled_music index (-1 = None), widget uses the same convention
114+
ui->successMusicWidget->setCurrentMusicIndex(_model->getSuccessMusicTrack());
115+
ui->averageMusicWidget->setCurrentMusicIndex(_model->getAverageMusicTrack());
116+
ui->failureMusicWidget->setCurrentMusicIndex(_model->getFailureMusicTrack());
121117

122118
enableDisableControls();
123119
}
@@ -240,19 +236,37 @@ void DebriefingDialog::on_formulaTreeView_nodeChanged(int newTree)
240236
_model->setFormula(newTree);
241237
}
242238

243-
void DebriefingDialog::on_successMusicComboBox_currentIndexChanged(int index)
239+
void DebriefingDialog::on_successMusicWidget_currentIndexChanged(int spooledMusicIdx)
240+
{
241+
_model->setSuccessMusicTrack(spooledMusicIdx);
242+
}
243+
244+
void DebriefingDialog::on_averageMusicWidget_currentIndexChanged(int spooledMusicIdx)
245+
{
246+
_model->setAverageMusicTrack(spooledMusicIdx);
247+
}
248+
249+
void DebriefingDialog::on_failureMusicWidget_currentIndexChanged(int spooledMusicIdx)
250+
{
251+
_model->setFailureMusicTrack(spooledMusicIdx);
252+
}
253+
254+
void DebriefingDialog::on_successMusicWidget_playbackStarted()
244255
{
245-
_model->setSuccessMusicTrack(index - 1); // -1 to account for "None"
256+
ui->averageMusicWidget->stopPlayback();
257+
ui->failureMusicWidget->stopPlayback();
246258
}
247259

248-
void DebriefingDialog::on_averageMusicComboBox_currentIndexChanged(int index)
260+
void DebriefingDialog::on_averageMusicWidget_playbackStarted()
249261
{
250-
_model->setAverageMusicTrack(index - 1); // -1 to account for "None"
262+
ui->successMusicWidget->stopPlayback();
263+
ui->failureMusicWidget->stopPlayback();
251264
}
252265

253-
void DebriefingDialog::on_failureMusicComboBox_currentIndexChanged(int index)
266+
void DebriefingDialog::on_failureMusicWidget_playbackStarted()
254267
{
255-
_model->setFailureMusicTrack(index - 1); // -1 to account for "None"
268+
ui->successMusicWidget->stopPlayback();
269+
ui->averageMusicWidget->stopPlayback();
256270
}
257271

258272
} // namespace fso::fred::dialogs

qtfred/src/ui/dialogs/DebriefingDialog.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ private slots:
4949
void on_voiceFilePlayButton_clicked();
5050
void on_formulaTreeView_nodeChanged(int newTree);
5151

52-
void on_successMusicComboBox_currentIndexChanged(int index);
53-
void on_averageMusicComboBox_currentIndexChanged(int index);
54-
void on_failureMusicComboBox_currentIndexChanged(int index);
52+
void on_successMusicWidget_currentIndexChanged(int spooledMusicIdx);
53+
void on_averageMusicWidget_currentIndexChanged(int spooledMusicIdx);
54+
void on_failureMusicWidget_currentIndexChanged(int spooledMusicIdx);
55+
void on_successMusicWidget_playbackStarted();
56+
void on_averageMusicWidget_playbackStarted();
57+
void on_failureMusicWidget_playbackStarted();
5558

5659
private: // NOLINT(readability-redundant-access-specifiers)
5760
std::unique_ptr<Ui::DebriefingDialog> ui;
@@ -61,6 +64,5 @@ private slots:
6164
void initializeUi();
6265
void updateUi();
6366
void enableDisableControls();
64-
6567
};
6668
} // namespace fso::fred::dialogs

qtfred/src/ui/dialogs/FictionViewerDialog.cpp

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void FictionViewerDialog::accept()
3737
{
3838
// If apply() returns true, close the dialog
3939
if (_model->apply()) {
40+
ui->musicWidget->stopPlayback();
4041
QDialog::accept();
4142
}
4243
// else: validation failed, don't close
@@ -48,6 +49,7 @@ void FictionViewerDialog::reject()
4849
// If they do, it runs _model->apply() and returns the success value
4950
// If they don't, it runs _model->reject() and returns true
5051
if (rejectOrCloseHandler(this, _model.get(), _viewport)) {
52+
ui->musicWidget->stopPlayback();
5153
QDialog::reject(); // actually close
5254
}
5355
// else: do nothing, don't close
@@ -65,35 +67,16 @@ void FictionViewerDialog::initializeUi()
6567
ui->fontFileEdit->setMaxLength(_model->getMaxFontFileLength());
6668
ui->voiceFileEdit->setMaxLength(_model->getMaxVoiceFileLength());
6769

68-
updateMusicComboBox();
6970
}
7071

71-
void FictionViewerDialog::updateUi() {
72+
void FictionViewerDialog::updateUi()
73+
{
7274
util::SignalBlockers blockers(this);
7375

7476
ui->storyFileEdit->setText(QString::fromStdString(_model->getStoryFile()));
7577
ui->fontFileEdit->setText(QString::fromStdString(_model->getFontFile()));
7678
ui->voiceFileEdit->setText(QString::fromStdString(_model->getVoiceFile()));
77-
ui->musicComboBox->setCurrentIndex(ui->musicComboBox->findData(_model->getFictionMusic()));
78-
}
79-
80-
void FictionViewerDialog::updateMusicComboBox()
81-
{
82-
util::SignalBlockers blockers(this);
83-
84-
ui->musicComboBox->clear();
85-
86-
const auto& musicOptions = _model->getMusicOptions();
87-
88-
if (musicOptions.empty()) {
89-
ui->musicComboBox->setEnabled(false);
90-
return;
91-
}
92-
93-
ui->musicComboBox->setEnabled(true);
94-
for (const auto& option : musicOptions) {
95-
ui->musicComboBox->addItem(QString::fromStdString(option.first), option.second);
96-
}
79+
ui->musicWidget->setCurrentMusicIndex(_model->getFictionMusic());
9780
}
9881

9982
void FictionViewerDialog::on_okAndCancelButtons_accepted()
@@ -121,9 +104,9 @@ void FictionViewerDialog::on_voiceFileEdit_textChanged(const QString& text)
121104
_model->setVoiceFile(text.toUtf8().constData());
122105
}
123106

124-
void FictionViewerDialog::on_musicComboBox_currentIndexChanged(int index)
107+
void FictionViewerDialog::on_musicWidget_currentIndexChanged(int spooledMusicIdx)
125108
{
126-
_model->setFictionMusic(ui->musicComboBox->itemData(index).value<int>());
109+
_model->setFictionMusic(spooledMusicIdx);
127110
}
128111

129112
} // namespace fso::fred::dialogs

qtfred/src/ui/dialogs/FictionViewerDialog.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,14 @@ private slots:
3131
void on_storyFileEdit_textChanged(const QString& text);
3232
void on_fontFileEdit_textChanged(const QString& text);
3333
void on_voiceFileEdit_textChanged(const QString& text);
34-
void on_musicComboBox_currentIndexChanged(int index);
34+
35+
void on_musicWidget_currentIndexChanged(int spooledMusicIdx);
3536

3637
private: // NOLINT(readability-redundant-access-specifiers)
3738

3839
void initializeUi();
3940
void updateUi();
4041

41-
void updateMusicComboBox();
42-
43-
44-
4542
EditorViewport* _viewport = nullptr;
4643
std::unique_ptr<Ui::FictionViewerDialog> ui;
4744
std::unique_ptr<FictionViewerDialogModel> _model;

0 commit comments

Comments
 (0)