493 lines
19 KiB
C++
493 lines
19 KiB
C++
#include "SoundEntryPickerWindow.h"
|
|
#include <noggit/ui/windows/SoundPlayer/SoundEntryPlayer.h>
|
|
// #include <noggit/ui/ZoneIDBrowser.h>
|
|
|
|
#include <noggit/DBC.h>
|
|
#include <noggit/Log.h>
|
|
#include <noggit/Misc.h>
|
|
#include <ClientFile.hpp>
|
|
#include <noggit/application/NoggitApplication.hpp>
|
|
|
|
#include <QtWidgets/QVBoxLayout>
|
|
#include <QtWidgets/QFormLayout>
|
|
#include <QtWidgets/qpushbutton.h>
|
|
#include <QtWidgets/qgroupbox.h>
|
|
#include <QtWidgets/qcheckbox.h>
|
|
#include <QtWidgets/qlineedit.h>
|
|
#include <QtWidgets/QTableView>
|
|
#include <QStandardItemModel>
|
|
#include <QTableWidgetItem>
|
|
#include <QSound>
|
|
#include <qtemporaryfile>
|
|
#include <QMediaPlayer>
|
|
#include <QListWidget>
|
|
#include <QToolButton>
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
|
|
namespace Noggit
|
|
{
|
|
namespace Ui
|
|
{
|
|
SoundEntryPickerWindow::SoundEntryPickerWindow(QPushButton* button, int sound_type_filter, bool allow_none, QWidget* parent)
|
|
: QWidget(parent)
|
|
{
|
|
setWindowTitle("Sound Entry Picker");
|
|
setWindowFlags(Qt::Dialog);
|
|
|
|
auto layout = new QHBoxLayout(this);
|
|
|
|
auto list_layout = new QVBoxLayout(this);
|
|
|
|
auto Editor_layout = new QVBoxLayout(this);
|
|
|
|
layout->addLayout(list_layout);
|
|
layout->addLayout(Editor_layout);
|
|
|
|
_tree_searchbar = new QLineEdit(this);
|
|
list_layout->addWidget(_tree_searchbar);
|
|
|
|
|
|
_tree_filter_cbbox = new QComboBox(this);
|
|
_tree_filter_cbbox->addItem("Show All");
|
|
for (auto sound_types : sound_types_names)
|
|
{
|
|
_tree_filter_cbbox->addItem(sound_types.second.c_str());
|
|
}
|
|
list_layout->addWidget(_tree_filter_cbbox);
|
|
|
|
_picker_listview = new QListWidget(this);
|
|
_picker_listview->setFixedSize(280, 460);
|
|
_picker_listview->setSelectionMode(QListWidget::SingleSelection);
|
|
// _picker_listview->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
|
|
list_layout->addWidget(_picker_listview);
|
|
|
|
if (sound_type_filter == -1)
|
|
{
|
|
_tree_filter_cbbox->setCurrentIndex(0);
|
|
filter_sound_type(sound_type_filter, true);
|
|
}
|
|
else
|
|
{
|
|
int row_id = 0;
|
|
for (auto sound_type_pair : sound_types_names)
|
|
{
|
|
if (sound_type_pair.first == sound_type_filter)
|
|
{
|
|
_tree_filter_cbbox->setCurrentIndex(row_id + 1);
|
|
filter_sound_type(sound_type_filter);
|
|
break;
|
|
}
|
|
row_id++;
|
|
}
|
|
}
|
|
|
|
auto select_entry_btn = new QPushButton("Select Entry", this);
|
|
auto select_entry_none_btn = new QPushButton("Select -NONE-", this);
|
|
auto duplicate_entry_btn = new QPushButton("Duplicate selected Entry (create new)", this);
|
|
list_layout->addWidget(duplicate_entry_btn);
|
|
list_layout->addWidget(select_entry_btn);
|
|
list_layout->addWidget(select_entry_none_btn);
|
|
|
|
list_layout->addStretch();
|
|
|
|
// Editor frame
|
|
QGroupBox* editor_group = new QGroupBox("Edit Selected Entry", this);
|
|
Editor_layout->addWidget(editor_group);
|
|
|
|
auto editor_form_layout = new QFormLayout(editor_group);
|
|
|
|
_entry_id_lbl = new QLabel(this);
|
|
editor_form_layout->addRow("Id:", _entry_id_lbl);
|
|
_entry_id_lbl->setEnabled(false);
|
|
|
|
_name_ledit = new QLineEdit(this);
|
|
editor_form_layout->addRow("Sound Entry Name:", _name_ledit);
|
|
|
|
_sound_type_cbbox = new QComboBox(this);
|
|
for (auto sound_type : sound_types_names)
|
|
{
|
|
_sound_type_cbbox->addItem(sound_type.second.c_str(), sound_type.first);
|
|
}
|
|
editor_form_layout->addRow("Sound Type:", _sound_type_cbbox);
|
|
|
|
_volume_slider = new QSlider(Qt::Horizontal, this);
|
|
_volume_slider->setMaximum(100);
|
|
// ticks should be 1, should bt QT's default ?
|
|
editor_form_layout->addRow("Volume:", _volume_slider);
|
|
|
|
_min_distance_spinbox = new QSpinBox(this);
|
|
_min_distance_spinbox->setMaximum(1000);
|
|
editor_form_layout->addRow("Min Distance:", _min_distance_spinbox);
|
|
|
|
_max_distance_spinbox = new QSpinBox(this);
|
|
_max_distance_spinbox->setMaximum(1000);
|
|
editor_form_layout->addRow("Distance Cut off:", _max_distance_spinbox);
|
|
|
|
_eax_type_cbbox = new QComboBox(this);
|
|
_eax_type_cbbox->addItem("None");
|
|
_eax_type_cbbox->addItem("Effect 1");
|
|
_eax_type_cbbox->addItem("Effect 2");
|
|
editor_form_layout->addRow("EAX definition:", _eax_type_cbbox);
|
|
|
|
_flag6_checkbox = new QCheckBox("Use OS sound settings", this);
|
|
editor_form_layout->addRow(_flag6_checkbox);
|
|
_flag10_checkbox = new QCheckBox("PlaySpellLoopedSound", this);
|
|
editor_form_layout->addRow(_flag10_checkbox);
|
|
_flag11_checkbox = new QCheckBox("SetFrequencyAndVolume", this);
|
|
editor_form_layout->addRow(_flag11_checkbox);
|
|
|
|
_directory_ledit = new QLineEdit(this);
|
|
editor_form_layout->addRow("Directory Path", _directory_ledit);
|
|
|
|
auto filecount_layout = new QHBoxLayout(this);
|
|
Editor_layout->addLayout(filecount_layout);
|
|
|
|
_filescount_lbl = new QLabel(this);
|
|
filecount_layout->addWidget(_filescount_lbl);
|
|
auto add_file_button = new QPushButton("Add sound file");
|
|
filecount_layout->addWidget(add_file_button);
|
|
|
|
_files_listview = new QListWidget(this);
|
|
_files_listview->setFixedHeight(400);
|
|
// _files_listview->setFixedSize(280, 460);
|
|
_files_listview->setSelectionMode(QListWidget::SingleSelection);
|
|
Editor_layout->addWidget(_files_listview);
|
|
|
|
|
|
auto save_music_entry_btn = new QPushButton("Save changes", this);
|
|
Editor_layout->addWidget(save_music_entry_btn, 0, Qt::AlignRight);
|
|
|
|
Editor_layout->addStretch();
|
|
|
|
/// check if needed
|
|
select_entry(button->property("id").toInt());
|
|
|
|
connect(_tree_filter_cbbox, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
|
|
|
if (index == 0) // load all
|
|
filter_sound_type(0, true);
|
|
else
|
|
{
|
|
int sound_type_id = 0;
|
|
int row_id = 0;
|
|
for (auto sound_type : sound_types_names)
|
|
{
|
|
if (row_id == index - 1)
|
|
{
|
|
sound_type_id = sound_type.first;
|
|
break;
|
|
}
|
|
row_id++;
|
|
}
|
|
filter_sound_type(sound_type_id);
|
|
}
|
|
|
|
});
|
|
|
|
connect(_tree_searchbar, &QLineEdit::textChanged, [=](QString obj) {
|
|
if (obj.isEmpty())
|
|
{
|
|
// unhide all
|
|
}
|
|
|
|
// hide all items
|
|
for (int i = 0; i < _picker_listview->count(); i++)
|
|
{
|
|
auto item = _picker_listview->item(i);
|
|
item->setHidden(true);
|
|
}
|
|
// unhide matching items
|
|
auto matching_items = _picker_listview->findItems(obj, Qt::MatchContains);
|
|
|
|
for (auto item : matching_items)
|
|
{
|
|
item->setHidden(false);
|
|
}
|
|
});
|
|
|
|
connect(_picker_listview, &QListWidget::itemClicked, this, [=](QListWidgetItem* item) {
|
|
select_entry(item->data(1).toInt());
|
|
});
|
|
|
|
connect(select_entry_btn, &QPushButton::clicked, [=]() {
|
|
// auto selection = _picker_listview->selectedItems();
|
|
auto selected_item = _picker_listview->currentItem();
|
|
if (selected_item == nullptr)
|
|
return;
|
|
|
|
button->setProperty("id", selected_item->data(1).toInt());
|
|
button->setText(selected_item->text());
|
|
this->close();
|
|
});
|
|
|
|
connect(select_entry_none_btn, &QPushButton::clicked, [=]() {
|
|
button->setText("-NONE-");
|
|
button->setProperty("id", 0);
|
|
this->close();
|
|
});
|
|
|
|
connect(save_music_entry_btn, &QPushButton::clicked, [=]() {
|
|
save_entry(_entry_id);
|
|
});
|
|
|
|
connect(add_file_button, &QPushButton::clicked, [=]() {
|
|
|
|
int new_row_id = _files_listview->count();
|
|
if (new_row_id > 9)
|
|
return; // can't have more than 10
|
|
|
|
_filenames_ledits[new_row_id] = new QLineEdit(); // set parent in the widget class
|
|
_filenames_ledits[new_row_id]->setText("your_sound_file.mp3");
|
|
auto file_widget = new SoundFileWListWidgetItem(_filenames_ledits[new_row_id], _directory_ledit->text().toStdString());
|
|
|
|
auto item = new QListWidgetItem(_files_listview);
|
|
_files_listview->setItemWidget(item, file_widget);
|
|
item->setSizeHint(QSize(_files_listview->width(), _files_listview->height() / 10));
|
|
|
|
_files_listview->addItem(item);
|
|
|
|
update_files_count();
|
|
|
|
});
|
|
|
|
connect(duplicate_entry_btn, &QPushButton::clicked, [=]() {
|
|
auto new_id = gSoundEntriesDB.getEmptyRecordID(SoundEntriesDB::ID);
|
|
|
|
auto new_record = gSoundEntriesDB.addRecord(new_id);
|
|
|
|
_name_ledit->setText("Noggit Unnamed entry");
|
|
|
|
save_entry(new_id);
|
|
|
|
// add new tree item
|
|
auto item = new QListWidgetItem();
|
|
item->setData(1, new_id);
|
|
std::stringstream ss;
|
|
|
|
_picker_listview->addItem(item);
|
|
|
|
select_entry(new_id);
|
|
|
|
ss << new_id << "-" << _name_ledit->text().toStdString();
|
|
item->setText(ss.str().c_str());
|
|
});
|
|
}
|
|
|
|
void SoundEntryPickerWindow::filter_sound_type(int sound_type, bool load_all)
|
|
{
|
|
_picker_listview->clear();
|
|
for (DBCFile::Iterator i = gSoundEntriesDB.begin(); i != gSoundEntriesDB.end(); ++i)
|
|
{
|
|
if (!(i->getInt(SoundEntriesDB::SoundType) == sound_type) && !load_all) // it freezes for 2sec if we try to add directly all 13k items
|
|
continue;
|
|
|
|
auto item = new QListWidgetItem();
|
|
item->setData(1, i->getInt(SoundEntriesDB::ID));
|
|
|
|
std::stringstream ss;
|
|
ss << i->getInt(SoundEntriesDB::ID) << "-" << i->getString(SoundEntriesDB::Name);
|
|
|
|
if (load_all)
|
|
ss << "(" << sound_types_names.at(i->getInt(SoundEntriesDB::SoundType)) << ')';
|
|
item->setText(ss.str().c_str());
|
|
|
|
_picker_listview->addItem(item);
|
|
}
|
|
}
|
|
|
|
void SoundEntryPickerWindow::select_entry(int id)
|
|
{
|
|
if (id != 0)
|
|
{
|
|
// _picker_listview->setCurrentRow(0);
|
|
// doesn't work because of the type filter ! :(
|
|
// _picker_listview->setCurrentRow(gSoundEntriesDB.getRecordRowId(id));
|
|
}
|
|
else
|
|
{
|
|
_picker_listview->setCurrentRow(0);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
DBCFile::Record record = gSoundEntriesDB.getByID(id);
|
|
|
|
_entry_id = id;
|
|
_entry_id_lbl->setText(QString(std::to_string(id).c_str()));
|
|
|
|
_name_ledit->setText(record.getString(SoundEntriesDB::Name));
|
|
|
|
int sound_type_id = record.getInt(SoundEntriesDB::SoundType);
|
|
|
|
int row_id = 0;
|
|
for (auto sound_type : sound_types_names)
|
|
{
|
|
if (sound_type.first == sound_type_id)
|
|
{
|
|
_sound_type_cbbox->setCurrentIndex(row_id);
|
|
break;
|
|
}
|
|
|
|
row_id++;
|
|
}
|
|
|
|
_eax_type_cbbox->setCurrentIndex(record.getInt(SoundEntriesDB::EAXDef));
|
|
_min_distance_spinbox->setValue(record.getFloat(SoundEntriesDB::minDistance));
|
|
_max_distance_spinbox->setValue(record.getFloat(SoundEntriesDB::distanceCutoff));
|
|
_volume_slider->setValue(record.getFloat(SoundEntriesDB::Volume) * 100);
|
|
|
|
int flags = record.getInt(SoundEntriesDB::Flags);
|
|
|
|
_flag6_checkbox->setChecked((flags & (1 << (6 - 1))) ? true : false);
|
|
_flag10_checkbox->setChecked((flags & (1 << (10 - 1))) ? true : false);
|
|
_flag11_checkbox->setChecked((flags & (1 << (11 - 1))) ? true : false);
|
|
_flag12 = (flags & (1 << (12 - 1))) ? true : false;
|
|
|
|
_directory_ledit->setText(record.getString(SoundEntriesDB::FilePath));
|
|
|
|
_files_listview->clear();
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
std::string filename = record.getString(SoundEntriesDB::Filenames + i);
|
|
// auto freq = record.getInt(SoundEntriesDB::Freq + i);
|
|
|
|
if (filename.empty())
|
|
continue;
|
|
|
|
_filenames_ledits[i] = new QLineEdit(); // set parent in the widget class
|
|
_filenames_ledits[i]->setText(filename.c_str());
|
|
auto file_widget = new SoundFileWListWidgetItem(_filenames_ledits[i], _directory_ledit->text().toStdString());
|
|
|
|
auto item = new QListWidgetItem(_files_listview);
|
|
_files_listview->setItemWidget(item, file_widget);
|
|
item->setSizeHint(QSize(_files_listview->width(), _files_listview->height() / 10) );
|
|
|
|
_files_listview->addItem(item);
|
|
}
|
|
update_files_count();
|
|
|
|
_sound_advanced_id = record.getInt(SoundEntriesDB::soundEntriesAdvancedID);
|
|
}
|
|
catch (SoundEntriesDB::NotFound)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void SoundEntryPickerWindow::save_entry(int entry_id)
|
|
{
|
|
try
|
|
{
|
|
DBCFile::Record record = gSoundEntriesDB.getByID(entry_id);
|
|
|
|
record.write(SoundEntriesDB::ID, entry_id);
|
|
|
|
int sound_type_id = 0;
|
|
int row_id = 0;
|
|
for (auto sound_type : sound_types_names)
|
|
{
|
|
if (row_id == _sound_type_cbbox->currentIndex())
|
|
{
|
|
sound_type_id = sound_type.first;
|
|
break;
|
|
}
|
|
row_id++;
|
|
}
|
|
record.write(SoundEntriesDB::SoundType, sound_type_id);
|
|
|
|
record.writeString(SoundEntriesDB::Name, _name_ledit->text().toStdString());
|
|
|
|
// _files_listview->count()
|
|
int i = 0;
|
|
for (;i < _files_listview->count(); i++)
|
|
{
|
|
record.writeString(SoundEntriesDB::Filenames + i, _filenames_ledits[i]->text().toStdString());
|
|
record.write(SoundEntriesDB::Freq + i, 1); // TODO. but in 99.9% 1 is fine
|
|
}
|
|
for (;i < 10; i++) // clean up unset entries
|
|
{
|
|
record.writeString(SoundEntriesDB::Filenames + i, "");
|
|
record.write(SoundEntriesDB::Freq + i, 0);
|
|
}
|
|
|
|
record.writeString(SoundEntriesDB::FilePath, _directory_ledit->text().toStdString());
|
|
record.write(SoundEntriesDB::Volume, _volume_slider->value() / 100.0f); // should be a float
|
|
|
|
int flags = 0;
|
|
if (_flag6_checkbox->isChecked())
|
|
flags |= (1ULL << (5));
|
|
if (_flag10_checkbox->isChecked())
|
|
flags |= (1ULL << (9));
|
|
if (_flag11_checkbox->isChecked())
|
|
flags |= (1ULL << (10));
|
|
if (_flag12)
|
|
flags |= (1ULL << (11));
|
|
record.write(SoundEntriesDB::Flags, flags);
|
|
|
|
record.write(SoundEntriesDB::minDistance, static_cast<float>(_min_distance_spinbox->value()));
|
|
record.write(SoundEntriesDB::distanceCutoff, static_cast<float>(_max_distance_spinbox->value()));
|
|
record.write(SoundEntriesDB::EAXDef, _eax_type_cbbox->currentIndex());
|
|
record.write(SoundEntriesDB::soundEntriesAdvancedID, _sound_advanced_id);
|
|
|
|
gSoundEntriesDB.save();
|
|
}
|
|
catch (SoundEntriesDB::NotFound)
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void SoundEntryPickerWindow::update_files_count()
|
|
{
|
|
int file_count = _files_listview->count();
|
|
std::stringstream ss;
|
|
ss << "Files: " << std::to_string(file_count) << "/10";
|
|
|
|
_filescount_lbl->setText(ss.str().c_str());
|
|
}
|
|
|
|
SoundFileWListWidgetItem::SoundFileWListWidgetItem(QLineEdit* filename_ledit, std::string dirpath, QWidget* parent) // std::string filename
|
|
: QWidget(parent)
|
|
{
|
|
auto layout = new QHBoxLayout(this);
|
|
layout->addWidget(new QLabel("File:", this));
|
|
|
|
// auto lol = _filenames_ledits[i];
|
|
// auto _filename_ledit = new QLineEdit(filename.c_str(), this);
|
|
filename_ledit->setParent(this);
|
|
filename_ledit->setFixedHeight(30);
|
|
layout->addWidget(filename_ledit);
|
|
|
|
auto play_sound_button = new QToolButton(this);
|
|
play_sound_button->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::play));
|
|
//play_sound_button->setFixedSize(play_sound_button->size() * 0.5);
|
|
play_sound_button->setFixedSize(20, 20);
|
|
layout->addWidget(play_sound_button);
|
|
|
|
// auto removefile_button = new QToolButton(this);
|
|
// removefile_button->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::windowclose));
|
|
//removefile_button->setFixedSize(removefile_button->size() * 0.5);
|
|
// removefile_button->setFixedSize(20, 20);
|
|
// layout->addWidget(removefile_button);
|
|
|
|
|
|
connect(play_sound_button, &QPushButton::clicked, [=]() {
|
|
|
|
if (!filename_ledit->text().toStdString().empty() && !dirpath.empty())
|
|
{
|
|
auto sound_player = new SoundEntryPlayer(this);
|
|
sound_player->PlaySingleSoundFile(filename_ledit->text().toStdString(), dirpath);
|
|
sound_player->show();
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
}
|