Area editor + sound player + various DBC pickers/editors
This commit is contained in:
@@ -108,7 +108,7 @@ set(FASTNOISE2_NOISETOOL OFF CACHE BOOL "")
|
|||||||
FIND_PACKAGE(FastNoise2 REQUIRED)
|
FIND_PACKAGE(FastNoise2 REQUIRED)
|
||||||
|
|
||||||
FIND_PACKAGE(Sol2 REQUIRED)
|
FIND_PACKAGE(Sol2 REQUIRED)
|
||||||
FIND_PACKAGE(Qt5 COMPONENTS Widgets OpenGL OpenGLExtensions Network Xml REQUIRED)
|
FIND_PACKAGE(Qt5 COMPONENTS Widgets OpenGL OpenGLExtensions Network Xml Multimedia REQUIRED)
|
||||||
|
|
||||||
IF(USE_SQL)
|
IF(USE_SQL)
|
||||||
FIND_LIBRARY(MYSQL_LIBRARY NAMES libmysql
|
FIND_LIBRARY(MYSQL_LIBRARY NAMES libmysql
|
||||||
@@ -342,6 +342,7 @@ TARGET_LINK_LIBRARIES (noggit
|
|||||||
Qt5::OpenGLExtensions
|
Qt5::OpenGLExtensions
|
||||||
Qt5::Xml
|
Qt5::Xml
|
||||||
Qt5::Network
|
Qt5::Network
|
||||||
|
Qt5::Multimedia
|
||||||
ColorWidgets-qt5
|
ColorWidgets-qt5
|
||||||
FramelessHelper
|
FramelessHelper
|
||||||
qt_imgui_widgets
|
qt_imgui_widgets
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ LightFloatBandDB gLightFloatBandDB;
|
|||||||
GroundEffectDoodadDB gGroundEffectDoodadDB;
|
GroundEffectDoodadDB gGroundEffectDoodadDB;
|
||||||
GroundEffectTextureDB gGroundEffectTextureDB;
|
GroundEffectTextureDB gGroundEffectTextureDB;
|
||||||
LiquidTypeDB gLiquidTypeDB;
|
LiquidTypeDB gLiquidTypeDB;
|
||||||
|
SoundProviderPreferencesDB gSoundProviderPreferencesDB;
|
||||||
|
SoundAmbienceDB gSoundAmbienceDB;
|
||||||
|
ZoneMusicDB gZoneMusicDB;
|
||||||
|
ZoneIntroMusicTableDB gZoneIntroMusicTableDB;
|
||||||
|
SoundEntriesDB gSoundEntriesDB;
|
||||||
|
|
||||||
void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData)
|
void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData)
|
||||||
{
|
{
|
||||||
@@ -31,6 +36,11 @@ void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData)
|
|||||||
gGroundEffectDoodadDB.open(clientData);
|
gGroundEffectDoodadDB.open(clientData);
|
||||||
gGroundEffectTextureDB.open(clientData);
|
gGroundEffectTextureDB.open(clientData);
|
||||||
gLiquidTypeDB.open(clientData);
|
gLiquidTypeDB.open(clientData);
|
||||||
|
gSoundProviderPreferencesDB.open(clientData);
|
||||||
|
gSoundAmbienceDB.open(clientData);
|
||||||
|
gZoneMusicDB.open(clientData);
|
||||||
|
gZoneIntroMusicTableDB.open(clientData);
|
||||||
|
gSoundEntriesDB.open(clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -89,6 +99,18 @@ std::uint32_t AreaDB::get_area_parent(int area_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::uint32_t AreaDB::get_new_areabit()
|
||||||
|
{
|
||||||
|
unsigned int areabit = 0;
|
||||||
|
|
||||||
|
for (Iterator i = gAreaDB.begin(); i != gAreaDB.end(); ++i)
|
||||||
|
{
|
||||||
|
areabit = std::max(i->getUInt(AreaDB::AreaBit), areabit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<int>(++areabit);
|
||||||
|
}
|
||||||
|
|
||||||
std::string MapDB::getMapName(int pMapID)
|
std::string MapDB::getMapName(int pMapID)
|
||||||
{
|
{
|
||||||
if (pMapID<0) return "Unknown map";
|
if (pMapID<0) return "Unknown map";
|
||||||
|
|||||||
@@ -17,11 +17,24 @@ public:
|
|||||||
static const size_t AreaID = 0; // uint
|
static const size_t AreaID = 0; // uint
|
||||||
static const size_t Continent = 1; // uint
|
static const size_t Continent = 1; // uint
|
||||||
static const size_t Region = 2; // uint [AreaID]
|
static const size_t Region = 2; // uint [AreaID]
|
||||||
|
static const size_t AreaBit = 3; // uint
|
||||||
static const size_t Flags = 4; // bit field
|
static const size_t Flags = 4; // bit field
|
||||||
|
static const size_t SoundProviderPreferences = 5; // uint
|
||||||
|
static const size_t UnderwaterSoundProviderPreferences = 6; // uint
|
||||||
|
static const size_t SoundAmbience = 7; // uint
|
||||||
|
static const size_t ZoneMusic = 8; // uint
|
||||||
|
static const size_t ZoneIntroMusicTable = 9; // uint
|
||||||
|
static const size_t ExplorationLevel = 10; // int
|
||||||
static const size_t Name = 11; // localisation string
|
static const size_t Name = 11; // localisation string
|
||||||
|
static const size_t FactionGroup = 28; // uint
|
||||||
|
static const size_t LiquidType = 29; // uint[4]
|
||||||
|
static const size_t MinElevation = 33; // float
|
||||||
|
static const size_t AmbientMultiplier = 34; // float
|
||||||
|
static const size_t LightId = 35; // int
|
||||||
|
|
||||||
static std::string getAreaName(int pAreaID);
|
static std::string getAreaName(int pAreaID);
|
||||||
static std::uint32_t get_area_parent(int area_id);
|
static std::uint32_t get_area_parent(int area_id);
|
||||||
|
static std::uint32_t get_new_areabit();
|
||||||
};
|
};
|
||||||
|
|
||||||
class MapDB : public DBCFile
|
class MapDB : public DBCFile
|
||||||
@@ -184,6 +197,87 @@ public:
|
|||||||
static std::string getLiquidName(int pID);
|
static std::string getLiquidName(int pID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SoundProviderPreferencesDB : public DBCFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoundProviderPreferencesDB() :
|
||||||
|
DBCFile("DBFilesClient\\SoundProviderPreferences.dbc")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// Fields
|
||||||
|
static const size_t ID = 0; // uint
|
||||||
|
static const size_t Description = 1; // string
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundAmbienceDB : public DBCFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoundAmbienceDB() :
|
||||||
|
DBCFile("DBFilesClient\\SoundAmbience.dbc")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// Fields
|
||||||
|
static const size_t ID = 0; // uint
|
||||||
|
static const size_t SoundEntry_day = 1; // uint
|
||||||
|
static const size_t SoundEntry_night = 2; // uint
|
||||||
|
};
|
||||||
|
|
||||||
|
class ZoneMusicDB : public DBCFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZoneMusicDB() :
|
||||||
|
DBCFile("DBFilesClient\\ZoneMusic.dbc")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// Fields
|
||||||
|
static const size_t ID = 0; // uint
|
||||||
|
static const size_t Name = 1; // string
|
||||||
|
static const size_t SilenceIntervalMinDay = 2; // uint
|
||||||
|
static const size_t SilenceIntervalMinNight = 3; // uint
|
||||||
|
static const size_t SilenceIntervalMaxDay = 4; // uint
|
||||||
|
static const size_t SilenceIntervalMaxNight = 5; // uint
|
||||||
|
static const size_t DayMusic = 6; // uint [soundEntries]
|
||||||
|
static const size_t NightMusic = 7; // uint [soundEntries]
|
||||||
|
};
|
||||||
|
|
||||||
|
class ZoneIntroMusicTableDB : public DBCFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZoneIntroMusicTableDB() :
|
||||||
|
DBCFile("DBFilesClient\\ZoneIntroMusicTable.dbc")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// Fields
|
||||||
|
static const size_t ID = 0; // uint
|
||||||
|
static const size_t Name = 1; // string
|
||||||
|
static const size_t SoundId = 2; // uint
|
||||||
|
static const size_t Priority = 3; // uint
|
||||||
|
static const size_t MinDelayMinutes = 4; // uint
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundEntriesDB : public DBCFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoundEntriesDB() :
|
||||||
|
DBCFile("DBFilesClient\\SoundEntries.dbc")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// Fields
|
||||||
|
static const size_t ID = 0; // uint
|
||||||
|
static const size_t SoundType = 1; // uint
|
||||||
|
static const size_t Name = 2; // string
|
||||||
|
static const size_t Filenames = 3; // string[10]
|
||||||
|
static const size_t Freq = 13; // uint[10)
|
||||||
|
static const size_t FilePath = 23; // string[10)
|
||||||
|
static const size_t Volume = 24; // float
|
||||||
|
static const size_t Flags = 25; // int
|
||||||
|
static const size_t minDistance = 26; // float
|
||||||
|
static const size_t distanceCutoff = 27; // float
|
||||||
|
static const size_t EAXDef = 28; // int
|
||||||
|
static const size_t soundEntriesAdvancedID = 29; // int
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData);
|
void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData);
|
||||||
|
|
||||||
const char * getGroundEffectDoodad(unsigned int effectID, int DoodadNum);
|
const char * getGroundEffectDoodad(unsigned int effectID, int DoodadNum);
|
||||||
@@ -199,3 +293,8 @@ extern LightFloatBandDB gLightFloatBandDB;
|
|||||||
extern GroundEffectDoodadDB gGroundEffectDoodadDB;
|
extern GroundEffectDoodadDB gGroundEffectDoodadDB;
|
||||||
extern GroundEffectTextureDB gGroundEffectTextureDB;
|
extern GroundEffectTextureDB gGroundEffectTextureDB;
|
||||||
extern LiquidTypeDB gLiquidTypeDB;
|
extern LiquidTypeDB gLiquidTypeDB;
|
||||||
|
extern SoundProviderPreferencesDB gSoundProviderPreferencesDB;
|
||||||
|
extern SoundAmbienceDB gSoundAmbienceDB;
|
||||||
|
extern ZoneMusicDB gZoneMusicDB;
|
||||||
|
extern ZoneIntroMusicTableDB gZoneIntroMusicTableDB;
|
||||||
|
extern SoundEntriesDB gSoundEntriesDB;
|
||||||
|
|||||||
@@ -181,6 +181,27 @@ public:
|
|||||||
}
|
}
|
||||||
throw NotFound();
|
throw NotFound();
|
||||||
}
|
}
|
||||||
|
inline bool CheckIfIdExists(unsigned int id, size_t field = 0)
|
||||||
|
{
|
||||||
|
for (Iterator i = begin(); i != end(); ++i)
|
||||||
|
{
|
||||||
|
if (i->getUInt(field) == id)
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
inline int getRecordRowId(unsigned int id, size_t field = 0)
|
||||||
|
{
|
||||||
|
int row_id = 0;
|
||||||
|
for (Iterator i = begin(); i != end(); ++i)
|
||||||
|
{
|
||||||
|
if (i->getUInt(field) == id)
|
||||||
|
return row_id;
|
||||||
|
|
||||||
|
row_id++;
|
||||||
|
}
|
||||||
|
throw NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
Record addRecord(size_t id, size_t id_field = 0);
|
Record addRecord(size_t id, size_t id_field = 0);
|
||||||
Record addRecordCopy(size_t id, size_t id_from, size_t id_field = 0);
|
Record addRecordCopy(size_t id, size_t id_from, size_t id_field = 0);
|
||||||
|
|||||||
@@ -1,17 +1,39 @@
|
|||||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||||
|
|
||||||
#include <noggit/ui/ZoneIDBrowser.h>
|
#include <noggit/ui/ZoneIDBrowser.h>
|
||||||
|
#include <noggit/ui/windows/SoundPlayer/SoundEntryPlayer.h>
|
||||||
|
#include <noggit/ui/windows/EditorWindows/ZoneIntroMusicPickerWindow.h>
|
||||||
|
#include <noggit/ui/windows/EditorWindows/SoundEntryPickerWindow.h>
|
||||||
|
#include <noggit/ui/windows/EditorWindows/ZoneMusicPickerWindow.h>
|
||||||
|
#include <noggit/ui/tools/MapCreationWizard/Ui/MapCreationWizard.hpp>
|
||||||
|
|
||||||
#include <noggit/DBC.h>
|
#include <noggit/DBC.h>
|
||||||
#include <noggit/Log.h>
|
#include <noggit/Log.h>
|
||||||
#include <noggit/Misc.h>
|
#include <noggit/Misc.h>
|
||||||
|
#include <ClientFile.hpp>
|
||||||
|
#include <noggit/application/NoggitApplication.hpp>
|
||||||
|
|
||||||
#include <QtWidgets/QVBoxLayout>
|
#include <QtWidgets/QVBoxLayout>
|
||||||
#include <QtWidgets/QFormLayout>
|
#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 <noggit/ui/tools/UiCommon/expanderwidget.h>
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
namespace Noggit
|
namespace Noggit
|
||||||
{
|
{
|
||||||
@@ -22,52 +44,84 @@ namespace Noggit
|
|||||||
, _area_tree(new QTreeWidget())
|
, _area_tree(new QTreeWidget())
|
||||||
, mapID(-1)
|
, mapID(-1)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto layout = new QFormLayout(this);
|
auto layout = new QFormLayout(this);
|
||||||
|
|
||||||
_radius_spin = new QDoubleSpinBox (this);
|
_radius_spin = new QDoubleSpinBox(this);
|
||||||
_radius_spin->setRange (0.0f, 1000.0f);
|
_radius_spin->setRange(0.0f, 1000.0f);
|
||||||
_radius_spin->setDecimals (2);
|
_radius_spin->setDecimals(2);
|
||||||
_radius_spin->setValue (_radius);
|
_radius_spin->setValue(_radius);
|
||||||
|
|
||||||
layout->addRow ("Radius:", _radius_spin);
|
layout->addRow("Radius:", _radius_spin);
|
||||||
|
|
||||||
_radius_slider = new QSlider (Qt::Orientation::Horizontal, this);
|
_radius_slider = new QSlider(Qt::Orientation::Horizontal, this);
|
||||||
_radius_slider->setRange (0, 250);
|
_radius_slider->setRange(0, 250);
|
||||||
_radius_slider->setSliderPosition (_radius);
|
_radius_slider->setSliderPosition(_radius);
|
||||||
|
|
||||||
layout->addRow (_radius_slider);
|
QPushButton* edit_area_button = new QPushButton("Edit selected Area", this);
|
||||||
layout->addRow (_area_tree);
|
edit_area_button->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::cog));
|
||||||
|
QPushButton* add_zone_button = new QPushButton("Add a new Zone(parent Area)", this);
|
||||||
|
add_zone_button->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::plus));
|
||||||
|
QPushButton* add_subzone_button = new QPushButton("Add a new Subzone(selected as Parent)", this);
|
||||||
|
add_subzone_button->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::plus));
|
||||||
|
|
||||||
|
|
||||||
|
_area_editor = new AreaEditor(this);
|
||||||
|
|
||||||
|
layout->addRow(_radius_slider);
|
||||||
|
layout->addRow(_area_tree);
|
||||||
|
layout->addRow(edit_area_button);
|
||||||
|
layout->addRow(add_zone_button);
|
||||||
|
layout->addRow(add_subzone_button);
|
||||||
|
|
||||||
setMinimumWidth(250);
|
setMinimumWidth(250);
|
||||||
|
|
||||||
connect ( _area_tree, &QTreeWidget::itemSelectionChanged
|
connect(_area_tree, &QTreeWidget::itemSelectionChanged
|
||||||
, [this]
|
, [this]
|
||||||
{
|
{
|
||||||
auto const& selected_items = _area_tree->selectedItems();
|
auto const& selected_items = _area_tree->selectedItems();
|
||||||
if (selected_items.size())
|
if (selected_items.size())
|
||||||
{
|
{
|
||||||
emit selected (selected_items.back()->data(0, 1).toInt());
|
emit selected(selected_items.back()->data(0, 1).toInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
connect ( _radius_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
connect(_area_tree, &QTreeWidget::itemDoubleClicked
|
||||||
, [&] (double v)
|
, [this]
|
||||||
|
{
|
||||||
|
open_area_editor();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(_radius_spin, qOverload<double>(&QDoubleSpinBox::valueChanged)
|
||||||
|
, [&](double v)
|
||||||
{
|
{
|
||||||
_radius = v;
|
_radius = v;
|
||||||
QSignalBlocker const blocker(_radius_slider);
|
QSignalBlocker const blocker(_radius_slider);
|
||||||
_radius_slider->setSliderPosition ((int)std::round (v));
|
_radius_slider->setSliderPosition((int)std::round(v));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
connect ( _radius_slider, &QSlider::valueChanged
|
connect(_radius_slider, &QSlider::valueChanged
|
||||||
, [&] (int v)
|
, [&](int v)
|
||||||
{
|
{
|
||||||
_radius = v;
|
_radius = v;
|
||||||
QSignalBlocker const blocker(_radius_spin);
|
QSignalBlocker const blocker(_radius_spin);
|
||||||
_radius_spin->setValue(v);
|
_radius_spin->setValue(v);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
connect(edit_area_button, &QPushButton::clicked, [=]() {
|
||||||
|
open_area_editor();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(add_zone_button, &QPushButton::clicked, [=]() {
|
||||||
|
add_new_zone();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(add_subzone_button, &QPushButton::clicked, [=]() {
|
||||||
|
add_new_subzone();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void zone_id_browser::setMapID(int id)
|
void zone_id_browser::setMapID(int id)
|
||||||
@@ -124,7 +178,7 @@ namespace Noggit
|
|||||||
|
|
||||||
void zone_id_browser::changeRadius(float change)
|
void zone_id_browser::changeRadius(float change)
|
||||||
{
|
{
|
||||||
_radius_spin->setValue (_radius + change);
|
_radius_spin->setValue(_radius + change);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zone_id_browser::setRadius(float radius)
|
void zone_id_browser::setRadius(float radius)
|
||||||
@@ -132,6 +186,17 @@ namespace Noggit
|
|||||||
_radius_spin->setValue(radius);
|
_radius_spin->setValue(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int zone_id_browser::GetSelectedAreaId()
|
||||||
|
{
|
||||||
|
auto const& selected_items = _area_tree->selectedItems();
|
||||||
|
if (selected_items.size())
|
||||||
|
{
|
||||||
|
int selected_area_id = selected_items.back()->data(0, 1).toInt();
|
||||||
|
return selected_area_id;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QTreeWidgetItem* zone_id_browser::create_or_get_tree_widget_item(int area_id)
|
QTreeWidgetItem* zone_id_browser::create_or_get_tree_widget_item(int area_id)
|
||||||
{
|
{
|
||||||
auto it = _items.find(area_id);
|
auto it = _items.find(area_id);
|
||||||
@@ -145,7 +210,18 @@ namespace Noggit
|
|||||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << area_id << "-" << gAreaDB.getAreaName(area_id);
|
// ss << area_id << "-" << gAreaDB.getAreaName(area_id);
|
||||||
|
std::string areaName = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AreaDB::Record rec = gAreaDB.getByID(area_id);
|
||||||
|
areaName = rec.getLocalizedString(AreaDB::Name);
|
||||||
|
}
|
||||||
|
catch (AreaDB::NotFound)
|
||||||
|
{
|
||||||
|
areaName = "Unknown location";
|
||||||
|
}
|
||||||
|
ss << area_id << "-" << areaName;
|
||||||
item->setData(0, 1, QVariant(area_id));
|
item->setData(0, 1, QVariant(area_id));
|
||||||
item->setText(0, QString(ss.str().c_str()));
|
item->setText(0, QString(ss.str().c_str()));
|
||||||
_items.emplace(area_id, item);
|
_items.emplace(area_id, item);
|
||||||
@@ -172,5 +248,553 @@ namespace Noggit
|
|||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zone_id_browser::open_area_editor()
|
||||||
|
{
|
||||||
|
// opens and loads the area editor with the currently selected item in the tree.
|
||||||
|
int selected_area_id = GetSelectedAreaId();
|
||||||
|
if (selected_area_id != 0)
|
||||||
|
{
|
||||||
|
_area_editor->load_area(selected_area_id);
|
||||||
|
_area_editor->show();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No selected area popup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void zone_id_browser::add_new_zone()
|
||||||
|
{
|
||||||
|
// create new zone area id
|
||||||
|
auto new_id = gAreaDB.getEmptyRecordID();
|
||||||
|
auto new_record = gAreaDB.addRecord(new_id);
|
||||||
|
// init some defaults
|
||||||
|
new_record.write(AreaDB::Continent, mapID);
|
||||||
|
// get new areabit
|
||||||
|
new_record.write(AreaDB::AreaBit, gAreaDB.get_new_areabit());
|
||||||
|
new_record.write(AreaDB::Flags, 64); // allow dueling, seems to the be the common default for regions
|
||||||
|
new_record.write(AreaDB::UnderwaterSoundProviderPreferences, 11); // underwater sound pref, usually set
|
||||||
|
|
||||||
|
// locale stuff
|
||||||
|
new_record.writeString(AreaDB::Name, "Unnamed Noggit Zone"); // only write default name for enUS and enGB ? maybe get the client's locale somehow
|
||||||
|
new_record.writeString(AreaDB::Name + 1, "Unnamed Noggit Zone"); // enGB
|
||||||
|
new_record.write(AreaDB::Name + 16, 16712190); // loc mask, only verified for enUS
|
||||||
|
|
||||||
|
new_record.write(AreaDB::MinElevation, -500.0f); // loc mask, only verified for enUS
|
||||||
|
// save dbc instantly ?
|
||||||
|
gAreaDB.save();
|
||||||
|
// add to tree
|
||||||
|
auto areawidgetitem = add_area(new_id);
|
||||||
|
// select the new item
|
||||||
|
_area_tree->clearSelection();
|
||||||
|
areawidgetitem->setSelected(true);
|
||||||
|
open_area_editor();// open the editor
|
||||||
|
}
|
||||||
|
|
||||||
|
void zone_id_browser::add_new_subzone()
|
||||||
|
{
|
||||||
|
// create new subzone area id
|
||||||
|
// set selected as parent
|
||||||
|
int selected_areaid = GetSelectedAreaId();
|
||||||
|
if (!selected_areaid) // no valid item selected
|
||||||
|
return;
|
||||||
|
// check if it's a valid parent : it shouldn't have a parent
|
||||||
|
std::uint32_t selected_parent_area_id = gAreaDB.get_area_parent(selected_areaid); // the selected area's parentid
|
||||||
|
if (selected_parent_area_id)
|
||||||
|
{
|
||||||
|
// error, parent must not have a parent
|
||||||
|
QMessageBox messagebox;
|
||||||
|
messagebox.setIcon(QMessageBox::Information);
|
||||||
|
messagebox.setWindowIcon(QIcon(":/icon"));
|
||||||
|
messagebox.setWindowTitle("Wrong Parent type");
|
||||||
|
messagebox.setText("The parent must be a Zone, not a Subzone.");
|
||||||
|
messagebox.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto new_id = gAreaDB.getEmptyRecordID();
|
||||||
|
auto new_record = gAreaDB.addRecord(new_id);
|
||||||
|
// init some defaults
|
||||||
|
new_record.write(AreaDB::Continent, mapID);
|
||||||
|
|
||||||
|
new_record.write(AreaDB::Region, selected_areaid); // set selecetd area as parent.
|
||||||
|
// get new areabit
|
||||||
|
new_record.write(AreaDB::AreaBit, gAreaDB.get_new_areabit());
|
||||||
|
new_record.write(AreaDB::Flags, 1073759296); // allow dueling + force area on dynamic transport + enable flight bounds+ subzone flags
|
||||||
|
new_record.write(AreaDB::UnderwaterSoundProviderPreferences, 11); // underwater sound pref, usually set
|
||||||
|
// lcoale stuff
|
||||||
|
new_record.writeString(AreaDB::Name, "Unnamed Noggit Subzone"); // only write default name for enUS and enGB ? maybe get the client's locale somehow
|
||||||
|
new_record.writeString(AreaDB::Name + 1, "Unnamed Noggit Subzone"); // enGB
|
||||||
|
new_record.write(AreaDB::Name + 16, 16712190); // loc mask, only verified for enUS
|
||||||
|
|
||||||
|
new_record.write(AreaDB::MinElevation, -500.0f); // loc mask, only verified for enUS
|
||||||
|
// save dbc instantly ?
|
||||||
|
gAreaDB.save();
|
||||||
|
// add to tree
|
||||||
|
auto areawidgetitem = add_area(new_id);
|
||||||
|
// select the new item
|
||||||
|
_area_tree->clearSelection();
|
||||||
|
areawidgetitem->setSelected(true);
|
||||||
|
open_area_editor();// open the editor
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AreaEditor::AreaEditor(QWidget* parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle("Area Editor");
|
||||||
|
setWindowFlags(Qt::Dialog);
|
||||||
|
// setWindowFlags(Qt::Widget);
|
||||||
|
|
||||||
|
auto main_layout = new QHBoxLayout(this);
|
||||||
|
|
||||||
|
QGroupBox* area_settings_group = new QGroupBox("Area Settings", this);
|
||||||
|
main_layout->addWidget(area_settings_group);
|
||||||
|
auto layout = new QFormLayout(area_settings_group);
|
||||||
|
// main_layout->addLayout(layout);
|
||||||
|
|
||||||
|
_area_id_label = new QLabel("0", this);
|
||||||
|
_area_id_label->setEnabled(false);
|
||||||
|
|
||||||
|
_parent_area_label = new QLabel("-NONE-", area_settings_group);
|
||||||
|
_parent_area_label->setEnabled(false);
|
||||||
|
|
||||||
|
// auto parent_set_layout = new QHBoxLayout(this);
|
||||||
|
_set_parent_button = new QPushButton("Set Selected Zone as Parent", area_settings_group);
|
||||||
|
// QPushButton* unset_parent_button = new QPushButton("Unset Parent", this);
|
||||||
|
// parent_set_layout->addWidget(set_parent_button);
|
||||||
|
// parent_set_layout->addWidget(unset_parent_button);
|
||||||
|
|
||||||
|
_area_name = new Tools::MapCreationWizard::Ui::LocaleDBCEntry(area_settings_group);
|
||||||
|
|
||||||
|
_exploration_level_spinbox = new QSpinBox(this);
|
||||||
|
_exploration_level_spinbox->setRange(-1, 255);
|
||||||
|
|
||||||
|
_ambiant_multiplier = new QSlider(Qt::Horizontal, this);
|
||||||
|
_ambiant_multiplier->setRange(0, 100); // 0.0 - 1.0, decimal not supported so *100
|
||||||
|
_ambiant_multiplier->setTickInterval(5);
|
||||||
|
_ambiant_multiplier->setSingleStep(5);
|
||||||
|
|
||||||
|
// faction group
|
||||||
|
// read FactionGroup.dbc or just hardcode?
|
||||||
|
_faction_group_combobox = new QComboBox(this);
|
||||||
|
_faction_group_combobox->addItem("Contested"); // 0
|
||||||
|
_faction_group_combobox->addItem("Alliance"); // 2
|
||||||
|
_faction_group_combobox->addItem("Horde"); // 4
|
||||||
|
_faction_group_combobox->addItem("Horde & Alliance"); // mask : 2 + 4
|
||||||
|
|
||||||
|
// _liquid_type_water_combobox = new QComboBox(this);
|
||||||
|
// _liquid_type_water_combobox->addItem("None");
|
||||||
|
// _liquid_type_ocean_combobox = new QComboBox(this);
|
||||||
|
// _liquid_type_ocean_combobox->addItem("None");
|
||||||
|
// _liquid_type_magma_combobox = new QComboBox(this);
|
||||||
|
// _liquid_type_magma_combobox->addItem("None");
|
||||||
|
// _liquid_type_slime_combobox = new QComboBox(this);
|
||||||
|
// _liquid_type_slime_combobox->addItem("None");
|
||||||
|
// for (DBCFile::Iterator i = gLiquidTypeDB.begin(); i != gLiquidTypeDB.end(); ++i)
|
||||||
|
// {
|
||||||
|
// std::stringstream ss;
|
||||||
|
// int liquid_type = i->getInt(LiquidTypeDB::Type);
|
||||||
|
// ss << i->getInt(LiquidTypeDB::ID) << "-" << i->getString(LiquidTypeDB::Name);
|
||||||
|
// switch (liquid_type)
|
||||||
|
// {
|
||||||
|
// case 0:
|
||||||
|
// _liquid_type_water_combobox->addItem(i->getString(LiquidTypeDB::Name));
|
||||||
|
// break;
|
||||||
|
// case 1:
|
||||||
|
// _liquid_type_ocean_combobox->addItem(i->getString(LiquidTypeDB::Name));
|
||||||
|
// break;
|
||||||
|
// case 2:
|
||||||
|
// _liquid_type_magma_combobox->addItem(i->getString(LiquidTypeDB::Name));
|
||||||
|
// break;
|
||||||
|
// case 3:
|
||||||
|
// _liquid_type_slime_combobox->addItem(i->getString(LiquidTypeDB::Name));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
_sound_provider_preferences_cbbox = new QComboBox(this);
|
||||||
|
_sound_provider_preferences_cbbox->addItem("None");
|
||||||
|
|
||||||
|
_underwater_sound_provider_preferences_cbbox = new QComboBox(this);
|
||||||
|
_underwater_sound_provider_preferences_cbbox->addItem("None");
|
||||||
|
for (DBCFile::Iterator i = gSoundProviderPreferencesDB.begin(); i != gSoundProviderPreferencesDB.end(); ++i)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << i->getInt(SoundProviderPreferencesDB::ID) << "-" << i->getString(SoundProviderPreferencesDB::Description);
|
||||||
|
|
||||||
|
_sound_provider_preferences_cbbox->addItem(ss.str().c_str());
|
||||||
|
_underwater_sound_provider_preferences_cbbox->addItem(ss.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
_sound_ambiance_day_button = new QPushButton("-None-", this);
|
||||||
|
_sound_ambiance_day_button->setProperty("id", 0);
|
||||||
|
connect(_sound_ambiance_day_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto window = new SoundEntryPickerWindow(_sound_ambiance_day_button, SoundEntryTypes::ZONE_AMBIENCE, false, this);
|
||||||
|
window->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
_sound_ambiance_night_button = new QPushButton("-None-", this);
|
||||||
|
_sound_ambiance_night_button->setProperty("id", 0);
|
||||||
|
connect(_sound_ambiance_night_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto window = new SoundEntryPickerWindow(_sound_ambiance_night_button, SoundEntryTypes::ZONE_AMBIENCE, false, this);
|
||||||
|
window->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
_zone_music_button = new QPushButton("-None-", this);
|
||||||
|
_zone_music_button->setProperty("id", 0);
|
||||||
|
connect(_zone_music_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto window = new ZoneMusicPickerWindow(_zone_music_button, this);
|
||||||
|
window->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
_zone_intro_music_button = new QPushButton("-None-", this);
|
||||||
|
_zone_intro_music_button->setProperty("id", 0);
|
||||||
|
connect(_zone_intro_music_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto window = new ZoneIntroMusicPickerWindow(_zone_intro_music_button, this);
|
||||||
|
window->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
// advanced settings group
|
||||||
|
auto* AdvancedOptionsBox = new ExpanderWidget(this);
|
||||||
|
AdvancedOptionsBox->setExpanderTitle("Advanced Options");
|
||||||
|
// selectionOptionsBox->setExpanded(_settings->value("object_editor/movement_options", false).toBool());
|
||||||
|
|
||||||
|
auto advancedOptionsBox_content = new QWidget(this);
|
||||||
|
auto advancedOptions_layout = new QFormLayout(advancedOptionsBox_content);
|
||||||
|
// advancedOptions_layout->setAlignment(Qt::AlignTop);
|
||||||
|
AdvancedOptionsBox->addPage(advancedOptionsBox_content);
|
||||||
|
AdvancedOptionsBox->setExpanded(false);
|
||||||
|
|
||||||
|
_min_elevation_spinbox = new QDoubleSpinBox(this);
|
||||||
|
_min_elevation_spinbox->setRange(-5000, 5000); // only 3 known values : -5000, -500, 1000
|
||||||
|
_min_elevation_spinbox->setSingleStep(100);
|
||||||
|
|
||||||
|
advancedOptions_layout->addRow("Min Elevation:", _min_elevation_spinbox);
|
||||||
|
advancedOptions_layout->addRow("Ambiant Multiplier:", _ambiant_multiplier);
|
||||||
|
// advancedOptions_layout->addRow("Water Liquid Type override:", _liquid_type_water_combobox);
|
||||||
|
// advancedOptions_layout->addRow("Ocean Liquid Type override:", _liquid_type_ocean_combobox);
|
||||||
|
// advancedOptions_layout->addRow("Magma Liquid Type override:", _liquid_type_magma_combobox);
|
||||||
|
// advancedOptions_layout->addRow("Slime Liquid Type override:", _liquid_type_slime_combobox);
|
||||||
|
advancedOptions_layout->addRow("Sound Provider Preference:", _sound_provider_preferences_cbbox);
|
||||||
|
advancedOptions_layout->addRow("Underwater Sound Provider Preference:", _underwater_sound_provider_preferences_cbbox);
|
||||||
|
|
||||||
|
|
||||||
|
QPushButton* save_area_button = new QPushButton("Save changes (write DBC)", this);
|
||||||
|
// TODO : unset parent button?
|
||||||
|
|
||||||
|
// flags tab **************************//
|
||||||
|
|
||||||
|
QGroupBox* area_flags_group = new QGroupBox("Flags", this);
|
||||||
|
main_layout->addWidget(area_flags_group);
|
||||||
|
auto flags_layout = new QVBoxLayout(area_flags_group);
|
||||||
|
|
||||||
|
_flags_value_spinbox = new QSpinBox(this);
|
||||||
|
_flags_value_spinbox->setRange(0, INT_MAX); // uint?
|
||||||
|
flags_layout->addWidget(_flags_value_spinbox);
|
||||||
|
|
||||||
|
// TODO : update checkboxes when value is changed, temporarly disable it from edit
|
||||||
|
_flags_value_spinbox->setEnabled(false);
|
||||||
|
|
||||||
|
for (int i = 0; i < 31; ++i)
|
||||||
|
{
|
||||||
|
QCheckBox* flag_checkbox = new QCheckBox(QString::fromStdString(area_flags_names.at(i)), this);
|
||||||
|
flags_checkboxes[i] = flag_checkbox;
|
||||||
|
|
||||||
|
flags_layout->addWidget(flag_checkbox);
|
||||||
|
|
||||||
|
connect(flag_checkbox, &QCheckBox::stateChanged, [&, i](bool state) {
|
||||||
|
// connect(flag_checkbox, &QCheckBox::clicked, [=]() {
|
||||||
|
// int old_value = _flags_value_spinbox->value();
|
||||||
|
int new_value = _flags_value_spinbox->value();
|
||||||
|
if (state) // set bit
|
||||||
|
new_value |= (1ULL << (i));
|
||||||
|
else // remove bit
|
||||||
|
new_value &= ~(1ULL << (i));
|
||||||
|
|
||||||
|
_flags_value_spinbox->setValue(new_value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// hide some useless flags to gain space
|
||||||
|
flags_checkboxes[30]->setEnabled(false); // user can't set subzone flag.
|
||||||
|
flags_checkboxes[30]->setHidden(true); // subzone flag
|
||||||
|
flags_checkboxes[20]->setHidden(true); // tournement realm thingy, useless for pservers
|
||||||
|
flags_checkboxes[17]->setHidden(true); // "Area not in use", prob some blizz dev stuff
|
||||||
|
//************************************//
|
||||||
|
layout->addRow("Area ID:", _area_id_label);
|
||||||
|
layout->addRow("Area Name:", _area_name);
|
||||||
|
layout->addWidget(_set_parent_button);
|
||||||
|
layout->addRow("Parent Area ID:", _parent_area_label);
|
||||||
|
layout->addRow("Faction Group:", _faction_group_combobox);
|
||||||
|
layout->addRow("Exploration Level:", _exploration_level_spinbox);
|
||||||
|
layout->addRow("Zone Music:", _zone_music_button);
|
||||||
|
layout->addRow("Zone Intro Music:", _zone_intro_music_button);
|
||||||
|
layout->addRow("Sound Ambience Day:", _sound_ambiance_day_button);
|
||||||
|
layout->addRow("Sound Ambience Night:", _sound_ambiance_night_button);
|
||||||
|
|
||||||
|
layout->addRow(AdvancedOptionsBox);
|
||||||
|
layout->addRow(save_area_button);
|
||||||
|
|
||||||
|
layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||||
|
|
||||||
|
// main_layout->addStretch();
|
||||||
|
|
||||||
|
connect(_set_parent_button, &QPushButton::clicked, [=]() {
|
||||||
|
|
||||||
|
// Current design choice : Cannot change a zone to be a subzone or the opposite, only current subzones can have a parent set.
|
||||||
|
auto parent = static_cast<zone_id_browser*>(this->parentWidget());
|
||||||
|
auto tree_selected_id = parent->GetSelectedAreaId();
|
||||||
|
if (!tree_selected_id)
|
||||||
|
return;
|
||||||
|
// can only set a zone as parent, not a subzone.
|
||||||
|
// a zone must be a top level item, and not have a parent or the subzone flag.
|
||||||
|
|
||||||
|
// checks :
|
||||||
|
// 1 : current area must be a subzone
|
||||||
|
if (!_parent_area_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::uint32_t selected_parent_area_id = gAreaDB.get_area_parent(tree_selected_id); // the selected area's parentid
|
||||||
|
if (selected_parent_area_id)
|
||||||
|
{
|
||||||
|
// error, parent must not have a parent
|
||||||
|
QMessageBox messagebox;
|
||||||
|
messagebox.setIcon(QMessageBox::Information);
|
||||||
|
messagebox.setWindowIcon(QIcon(":/icon"));
|
||||||
|
messagebox.setWindowTitle("Wrong Parent type");
|
||||||
|
messagebox.setText("The parent must be a Zone, not a Subzone.");
|
||||||
|
messagebox.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// can't be self
|
||||||
|
if (tree_selected_id == _parent_area_id)
|
||||||
|
return;// same parent, ignore
|
||||||
|
if (tree_selected_id == _area_id_label->text().toInt())
|
||||||
|
return; // error, can't select self
|
||||||
|
|
||||||
|
// save the change for the session (don't write dbc yet)
|
||||||
|
_parent_area_id = tree_selected_id;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << _parent_area_id << "-" << gAreaDB.getAreaName(_parent_area_id);
|
||||||
|
_parent_area_label->setText(ss.str().c_str());
|
||||||
|
|
||||||
|
// _parent_area_label->setText(std::to_string( tree_selected_id).c_str());
|
||||||
|
auto curr_record = gAreaDB.getByID(_area_id_label->text().toInt());
|
||||||
|
curr_record.write(AreaDB::Region, tree_selected_id);
|
||||||
|
// update the tree
|
||||||
|
parent->buildAreaList();
|
||||||
|
// select the item ?
|
||||||
|
auto item = parent->create_or_get_tree_widget_item(_area_id_label->text().toInt());
|
||||||
|
// parent->selected(_area_id_label->text().toInt());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(save_area_button, &QPushButton::clicked, [=]() {
|
||||||
|
save_area();// save and write DBC
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(_flags_value_spinbox, qOverload<int>(&QSpinBox::valueChanged), [&](int v) {
|
||||||
|
|
||||||
|
// std::bitset<32> IntBits(_flags_value_spinbox->value());
|
||||||
|
//
|
||||||
|
// for (int i = 0; i < 31; i++)
|
||||||
|
// flags_checkboxes[i]->setChecked(IntBits[i]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AreaEditor::load_area(int area_id)
|
||||||
|
{
|
||||||
|
DBCFile::Record record = gAreaDB.getByID(area_id);
|
||||||
|
// record.getString(AreaDB::Name)
|
||||||
|
|
||||||
|
_area_id_label->setText(QString(std::to_string(area_id).c_str()));
|
||||||
|
|
||||||
|
_areabit = record.getInt(AreaDB::AreaBit);
|
||||||
|
|
||||||
|
_parent_area_id = record.getInt(AreaDB::Region);
|
||||||
|
|
||||||
|
if (_parent_area_id)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << _parent_area_id << "-" << gAreaDB.getAreaName(_parent_area_id);
|
||||||
|
_parent_area_label->setText(ss.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_parent_area_label->setText("-NONE-");
|
||||||
|
|
||||||
|
// hide some UI if not subzone
|
||||||
|
_set_parent_button->setHidden(_parent_area_id ? false : true);
|
||||||
|
|
||||||
|
// _area_name_ledit->setText(record.getString(AreaDB::Name));
|
||||||
|
_area_name->fill(record, AreaDB::Name);
|
||||||
|
|
||||||
|
_flags_value_spinbox->setValue(record.getInt(AreaDB::Flags));
|
||||||
|
|
||||||
|
std::bitset<32> IntBits(_flags_value_spinbox->value());
|
||||||
|
for (int i = 0; i < 31; i++)
|
||||||
|
flags_checkboxes[i]->setChecked(IntBits[i]);
|
||||||
|
|
||||||
|
_exploration_level_spinbox->setValue(record.getInt(AreaDB::ExplorationLevel));
|
||||||
|
|
||||||
|
int faction_group_mask = record.getInt(AreaDB::FactionGroup);
|
||||||
|
switch (faction_group_mask) // hardcoded but can be read from factiongroup.dbc
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
_faction_group_combobox->setCurrentIndex(1);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
_faction_group_combobox->setCurrentIndex(2);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
_faction_group_combobox->setCurrentIndex(3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_faction_group_combobox->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_min_elevation_spinbox->setValue(record.getFloat(AreaDB::MinElevation)); // only 3 known values : -5000, -500, 1000
|
||||||
|
|
||||||
|
_ambiant_multiplier->setValue(record.getFloat(AreaDB::AmbientMultiplier) * 100);
|
||||||
|
|
||||||
|
int sound_provider_id = record.getInt(AreaDB::SoundProviderPreferences);
|
||||||
|
if (sound_provider_id != 0)
|
||||||
|
{
|
||||||
|
int row_id = gSoundProviderPreferencesDB.getRecordRowId(sound_provider_id);
|
||||||
|
_sound_provider_preferences_cbbox->setCurrentIndex(row_id + 1); // index 0 = "None"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_sound_provider_preferences_cbbox->setCurrentIndex(0);
|
||||||
|
|
||||||
|
int underwater_sound_provider_id = record.getInt(AreaDB::UnderwaterSoundProviderPreferences);
|
||||||
|
if (underwater_sound_provider_id != 0)
|
||||||
|
{
|
||||||
|
int row_id = gSoundProviderPreferencesDB.getRecordRowId(underwater_sound_provider_id);
|
||||||
|
_underwater_sound_provider_preferences_cbbox->setCurrentIndex(row_id + 1); // index 0 = "None"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_underwater_sound_provider_preferences_cbbox->setCurrentIndex(0);
|
||||||
|
|
||||||
|
int zone_music_id = record.getInt(AreaDB::ZoneMusic);
|
||||||
|
_zone_music_button->setProperty("id", zone_music_id);
|
||||||
|
if (zone_music_id != 0)
|
||||||
|
{
|
||||||
|
auto zone_music_record = gZoneMusicDB.getByID(zone_music_id);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << zone_music_id << "-" << zone_music_record.getString(ZoneMusicDB::Name);
|
||||||
|
_zone_music_button->setText(ss.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_zone_music_button->setText("-NONE-");
|
||||||
|
|
||||||
|
|
||||||
|
int zone_intro_music_id = record.getInt(AreaDB::ZoneIntroMusicTable);
|
||||||
|
_zone_intro_music_button->setProperty("id", zone_intro_music_id);
|
||||||
|
if (zone_intro_music_id != 0)
|
||||||
|
{
|
||||||
|
auto zone_intro_music_record = gZoneIntroMusicTableDB.getByID(zone_intro_music_id);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << zone_intro_music_id << "-" << zone_intro_music_record.getString(ZoneIntroMusicTableDB::Name);
|
||||||
|
_zone_intro_music_button->setText(ss.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_zone_intro_music_button->setText("-NONE-");
|
||||||
|
|
||||||
|
int sound_ambiance_id = record.getInt(AreaDB::SoundAmbience);
|
||||||
|
if (sound_ambiance_id != 0)
|
||||||
|
{
|
||||||
|
auto sound_ambiance_record = gSoundAmbienceDB.getByID(sound_ambiance_id);
|
||||||
|
|
||||||
|
int day_sound_id = sound_ambiance_record.getInt(SoundAmbienceDB::SoundEntry_day);
|
||||||
|
auto sound_entry_day_record = gSoundEntriesDB.getByID(day_sound_id);
|
||||||
|
int night_sound_id = sound_ambiance_record.getInt(SoundAmbienceDB::SoundEntry_night);
|
||||||
|
auto sound_entry_night_record = gSoundEntriesDB.getByID(night_sound_id);
|
||||||
|
|
||||||
|
std::stringstream ss_day;
|
||||||
|
ss_day << day_sound_id << "-" << sound_entry_day_record.getString(SoundEntriesDB::Name);
|
||||||
|
_sound_ambiance_day_button->setText(ss_day.str().c_str());
|
||||||
|
_sound_ambiance_day_button->setProperty("id", day_sound_id);
|
||||||
|
|
||||||
|
std::stringstream ss_night;
|
||||||
|
ss_night << night_sound_id << "-" << sound_entry_night_record.getString(SoundEntriesDB::Name);
|
||||||
|
_sound_ambiance_night_button->setText(ss_night.str().c_str());
|
||||||
|
_sound_ambiance_night_button->setProperty("id", night_sound_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_sound_ambiance_day_button->setProperty("id", 0);
|
||||||
|
_sound_ambiance_day_button->setText("-NONE-");
|
||||||
|
_sound_ambiance_night_button->setProperty("id", 0);
|
||||||
|
_sound_ambiance_night_button->setText("-NONE-");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AreaEditor::save_area()
|
||||||
|
{
|
||||||
|
DBCFile::Record record = gAreaDB.getByID(_area_id_label->text().toInt()); // is_new_record ? gLightDB.addRecord(Id) : gLightDB.getByID(Id);
|
||||||
|
// record.write(AreaDB::ID, entry_id);
|
||||||
|
// rewrite mapid ?
|
||||||
|
record.write(AreaDB::Region, _parent_area_id);
|
||||||
|
record.write(AreaDB::AreaBit, _areabit);
|
||||||
|
record.write(AreaDB::Flags, _flags_value_spinbox->value());
|
||||||
|
|
||||||
|
int SoundProviderPreferences_id = 0;
|
||||||
|
if (_sound_provider_preferences_cbbox->currentIndex() != 0)
|
||||||
|
{
|
||||||
|
auto rec = gSoundProviderPreferencesDB.getRecord(_sound_provider_preferences_cbbox->currentIndex() - 1);
|
||||||
|
SoundProviderPreferences_id = rec.getInt(SoundProviderPreferencesDB::ID);
|
||||||
|
}
|
||||||
|
record.write(AreaDB::SoundProviderPreferences, SoundProviderPreferences_id);
|
||||||
|
|
||||||
|
int underwaterSoundProviderPreferences_id = 0;
|
||||||
|
if (_underwater_sound_provider_preferences_cbbox->currentIndex() != 0)
|
||||||
|
{
|
||||||
|
auto rec = gSoundProviderPreferencesDB.getRecord(_underwater_sound_provider_preferences_cbbox->currentIndex() - 1);
|
||||||
|
underwaterSoundProviderPreferences_id = rec.getInt(SoundProviderPreferencesDB::ID);
|
||||||
|
}
|
||||||
|
record.write(AreaDB::UnderwaterSoundProviderPreferences, underwaterSoundProviderPreferences_id);
|
||||||
|
|
||||||
|
// Ambiance ID. Blizzard stores those as unamed pair
|
||||||
|
// Just iterate the DBC to see if an entry with our settings already exists, if not create it.
|
||||||
|
// The reasoning for not having a selector/picker with the existing pairs is that it has less freedom, is harder to use and it's ugly if they don't have a name.
|
||||||
|
// This doesn't have the option to edit that entry for all its users though.
|
||||||
|
bool sound_ambiance_exists {false};
|
||||||
|
for (DBCFile::Iterator i = gSoundAmbienceDB.begin(); i != gSoundAmbienceDB.end(); ++i)
|
||||||
|
{
|
||||||
|
int day_id = i->getInt(SoundAmbienceDB::SoundEntry_day);
|
||||||
|
int night_id = i->getInt(SoundAmbienceDB::SoundEntry_night);
|
||||||
|
if (day_id == _sound_ambiance_day_button->property("id").toInt() && night_id == _sound_ambiance_night_button->property("id").toInt())
|
||||||
|
{
|
||||||
|
record.write(AreaDB::SoundAmbience, i->getInt(SoundAmbienceDB::ID));
|
||||||
|
sound_ambiance_exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sound_ambiance_exists)
|
||||||
|
{
|
||||||
|
// create new sond entry record
|
||||||
|
auto new_id = gSoundAmbienceDB.getEmptyRecordID();
|
||||||
|
auto new_record = gSoundAmbienceDB.addRecord(new_id);
|
||||||
|
|
||||||
|
new_record.write(SoundAmbienceDB::SoundEntry_day, _sound_ambiance_day_button->property("id").toInt());
|
||||||
|
new_record.write(SoundAmbienceDB::SoundEntry_night, _sound_ambiance_night_button->property("id").toInt());
|
||||||
|
gSoundAmbienceDB.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
record.write(AreaDB::ZoneMusic, _zone_music_button->property("id").toInt());
|
||||||
|
record.write(AreaDB::ZoneIntroMusicTable, _zone_intro_music_button->property("id").toInt());
|
||||||
|
|
||||||
|
record.write(AreaDB::ExplorationLevel, _exploration_level_spinbox->value());
|
||||||
|
|
||||||
|
_area_name->toRecord(record, AreaDB::Name);
|
||||||
|
|
||||||
|
record.write(AreaDB::FactionGroup, _faction_group_combobox->currentIndex() * 2);
|
||||||
|
record.write(AreaDB::MinElevation, static_cast<float>(_min_elevation_spinbox->value()));
|
||||||
|
record.write(AreaDB::AmbientMultiplier, _ambiant_multiplier->value() / 100.0f);
|
||||||
|
record.write(AreaDB::LightId, 0); // never used
|
||||||
|
|
||||||
|
gAreaDB.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,21 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <noggit/DBC.h>
|
||||||
|
#include <noggit/ui/tools/MapCreationWizard/Ui/MapCreationWizard.hpp>
|
||||||
|
|
||||||
#include <QtWidgets/QWidget>
|
#include <QtWidgets/QWidget>
|
||||||
#include <QtWidgets/QTreeWidget>
|
#include <QtWidgets/QTreeWidget>
|
||||||
#include <QtWidgets/QDoubleSpinBox>
|
#include <QtWidgets/QDoubleSpinBox>
|
||||||
#include <QtWidgets/QSlider>
|
#include <QtWidgets/QSlider>
|
||||||
|
#include <QtWidgets/QCheckBox.h>
|
||||||
|
#include <QtWidgets/QComboBox.h>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <QtWidgets/QListWidget>
|
||||||
|
#include <QtWidgets/QListView>
|
||||||
|
#include <QtWidgets/QTableView>
|
||||||
|
#include <QtWidgets/QPushButton>
|
||||||
|
#include <QMediaPlayer>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -14,6 +25,78 @@ namespace Noggit
|
|||||||
{
|
{
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static std::map <int, std::string> area_flags_names = {
|
||||||
|
{0 , "Emit Breath Particles"},
|
||||||
|
{1 , "Breath Particles Override Parent"},
|
||||||
|
{2 , "On Map Dungeon"},
|
||||||
|
{3 , "Allow Trade Channel"},
|
||||||
|
{4 , "Enemies PvP Flagged"},
|
||||||
|
{5 , "Allow Resting"},
|
||||||
|
{6 , "Allow Dueling"},
|
||||||
|
{7 , "Free For All PvP"},
|
||||||
|
{8 , "Linked Chat (Set in cities)"},
|
||||||
|
{9 , "Linked Chat Special Area"},
|
||||||
|
{10, "Force this area when on a Dynamic Transport"},
|
||||||
|
{11, "No PvP"},
|
||||||
|
{12, "No Ghost on Release"},
|
||||||
|
{13, "Sub-zone Ambient Multiplier"},
|
||||||
|
{14, "Enable Flight Bounds on Map"},
|
||||||
|
{15, "PVP POI"},
|
||||||
|
{16, "No chat channels"},
|
||||||
|
{17, "Area not in use"},
|
||||||
|
{18, "Contested"},
|
||||||
|
{19, "No Player Summoning"},
|
||||||
|
{20, "No Dueling if Tournament Realm"},
|
||||||
|
{21, "Players Call Guards"},
|
||||||
|
{22, "Horde Resting"},
|
||||||
|
{23, "Alliance Resting"},
|
||||||
|
{24, "Combat Zone"},
|
||||||
|
{25, "Force Indoors"},
|
||||||
|
{26, "Force Outdoors"},
|
||||||
|
{27, "Allow Hearth-and-Resurrect from Area"},
|
||||||
|
{28, "No Local Defense Channel"},
|
||||||
|
{29, "Only Evaluate Ghost Bind Once"},
|
||||||
|
{30, "Is Subzone"},
|
||||||
|
// {31, "Don't Evaluate Graveyard From Client"}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AreaEditor : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AreaEditor(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
void load_area(int area_id);
|
||||||
|
private:
|
||||||
|
QLabel* _area_id_label;
|
||||||
|
QLabel* _parent_area_label;
|
||||||
|
int _parent_area_id = 0;
|
||||||
|
QPushButton* _set_parent_button;
|
||||||
|
QSpinBox* _flags_value_spinbox;
|
||||||
|
Tools::MapCreationWizard::Ui::LocaleDBCEntry* _area_name;
|
||||||
|
QCheckBox* flags_checkboxes[31]{ 0 };
|
||||||
|
QSpinBox* _exploration_level_spinbox;
|
||||||
|
QDoubleSpinBox* _min_elevation_spinbox;
|
||||||
|
QSlider* _ambiant_multiplier;
|
||||||
|
QComboBox* _faction_group_combobox;
|
||||||
|
QComboBox* _sound_provider_preferences_cbbox;
|
||||||
|
QComboBox* _underwater_sound_provider_preferences_cbbox;
|
||||||
|
// QComboBox* _liquid_type_water_combobox;
|
||||||
|
// QComboBox* _liquid_type_ocean_combobox;
|
||||||
|
// QComboBox* _liquid_type_magma_combobox;
|
||||||
|
// QComboBox* _liquid_type_slime_combobox;
|
||||||
|
|
||||||
|
QPushButton* _zone_music_button;
|
||||||
|
QPushButton* _zone_intro_music_button;
|
||||||
|
QPushButton* _sound_ambiance_day_button;
|
||||||
|
QPushButton* _sound_ambiance_night_button;
|
||||||
|
|
||||||
|
void save_area();
|
||||||
|
|
||||||
|
int _areabit = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class zone_id_browser : public QWidget
|
class zone_id_browser : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -27,6 +110,10 @@ namespace Noggit
|
|||||||
|
|
||||||
float brushRadius() const { return _radius; }
|
float brushRadius() const { return _radius; }
|
||||||
|
|
||||||
|
int GetSelectedAreaId();
|
||||||
|
void buildAreaList();
|
||||||
|
QTreeWidgetItem* create_or_get_tree_widget_item(int area_id);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void selected (int area_id);
|
void selected (int area_id);
|
||||||
|
|
||||||
@@ -36,13 +123,18 @@ namespace Noggit
|
|||||||
QSlider* _radius_slider;
|
QSlider* _radius_slider;
|
||||||
QDoubleSpinBox* _radius_spin;
|
QDoubleSpinBox* _radius_spin;
|
||||||
|
|
||||||
|
AreaEditor* _area_editor;
|
||||||
|
|
||||||
std::map<int, QTreeWidgetItem*> _items;
|
std::map<int, QTreeWidgetItem*> _items;
|
||||||
int mapID;
|
int mapID;
|
||||||
float _radius = 15.0f;
|
float _radius = 15.0f;
|
||||||
|
|
||||||
void buildAreaList();
|
|
||||||
QTreeWidgetItem* create_or_get_tree_widget_item(int area_id);
|
|
||||||
QTreeWidgetItem* add_area(int area_id);
|
QTreeWidgetItem* add_area(int area_id);
|
||||||
|
void open_area_editor();
|
||||||
|
void add_new_zone();
|
||||||
|
void add_new_subzone();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
479
src/noggit/ui/windows/EditorWindows/SoundEntryPickerWindow.cpp
Normal file
479
src/noggit/ui/windows/EditorWindows/SoundEntryPickerWindow.cpp
Normal file
@@ -0,0 +1,479 @@
|
|||||||
|
#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)
|
||||||
|
{
|
||||||
|
_entry_id = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
_entry_id_lbl->setText(QString(std::to_string(id).c_str()));
|
||||||
|
|
||||||
|
DBCFile::Record record = gSoundEntriesDB.getByID(id);
|
||||||
|
|
||||||
|
_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEntryPickerWindow::save_entry(int entry_id)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
156
src/noggit/ui/windows/EditorWindows/SoundEntryPickerWindow.h
Normal file
156
src/noggit/ui/windows/EditorWindows/SoundEntryPickerWindow.h
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <noggit/DBC.h>
|
||||||
|
|
||||||
|
#include <QtWidgets/QWidget>
|
||||||
|
#include <QtWidgets/QTreeWidget>
|
||||||
|
#include <QtWidgets/QDoubleSpinBox>
|
||||||
|
#include <QtWidgets/QSlider>
|
||||||
|
#include <QtWidgets/QCheckBox.h>
|
||||||
|
#include <QtWidgets/QComboBox.h>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <QtWidgets/QListWidget>
|
||||||
|
#include <QtWidgets/QListView>
|
||||||
|
#include <QtWidgets/QPushButton>
|
||||||
|
#include <QMediaPlayer>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Noggit
|
||||||
|
{
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
// struct SoundEntryFilename
|
||||||
|
// {
|
||||||
|
// SoundEntryFilename(std::string f, int freq);
|
||||||
|
//
|
||||||
|
// std::string filename;
|
||||||
|
// int freq;
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
|
||||||
|
class SoundFileWListWidgetItem : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SoundFileWListWidgetItem(QLineEdit* filename_ledit, std::string dirpath, QWidget* parent = nullptr);
|
||||||
|
// QLineEdit* _filename_ledit;
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundEntryPickerWindow : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SoundEntryPickerWindow(QPushButton* button, int sound_type_filter = -1, bool allow_none = true, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QComboBox* _tree_filter_cbbox;
|
||||||
|
QLineEdit* _tree_searchbar;
|
||||||
|
QListWidget* _picker_listview;
|
||||||
|
|
||||||
|
int _entry_id = 0;
|
||||||
|
QLabel* _entry_id_lbl;
|
||||||
|
QLineEdit* _name_ledit;
|
||||||
|
|
||||||
|
QComboBox* _sound_type_cbbox;
|
||||||
|
QComboBox* _eax_type_cbbox;
|
||||||
|
QSpinBox* _min_distance_spinbox;
|
||||||
|
QSpinBox* _max_distance_spinbox;
|
||||||
|
QSlider* _volume_slider;
|
||||||
|
|
||||||
|
QCheckBox* _flag6_checkbox;
|
||||||
|
QCheckBox* _flag10_checkbox;
|
||||||
|
QCheckBox* _flag11_checkbox;
|
||||||
|
|
||||||
|
QLineEdit* _directory_ledit;
|
||||||
|
QLabel* _filescount_lbl;
|
||||||
|
QListWidget* _files_listview;
|
||||||
|
QLineEdit* _filenames_ledits[10]{ 0 };
|
||||||
|
QSpinBox* _freqs_spinboxes[10]{ 0 };
|
||||||
|
|
||||||
|
bool _flag12; // 7 users and unknown definition, not adding it to the UI.
|
||||||
|
|
||||||
|
// TODO sound advanced. shouldn't use a picker as it is unique for each sound, just add an optional advanced layout without maybe a checkbox. maybe it is in a separate tab ?
|
||||||
|
int _sound_advanced_id = 0;
|
||||||
|
|
||||||
|
void filter_sound_type(int sound_type, bool load_all = false);
|
||||||
|
void select_entry(int id);
|
||||||
|
void save_entry(int entry_id);
|
||||||
|
void update_files_count();
|
||||||
|
// void duplicate_entry();
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SoundEntryTypes
|
||||||
|
{
|
||||||
|
SPELLS = 1,
|
||||||
|
UI,
|
||||||
|
FOOTSTEPS,
|
||||||
|
COMBAT_IMPACTS,
|
||||||
|
COMBAT_SWINGS = 6,
|
||||||
|
GREETINGS,
|
||||||
|
CASTING,
|
||||||
|
ITEM_USE_SOUNDS,
|
||||||
|
MONSTER_SOUNDS,
|
||||||
|
VOCAL_UI_SOUNDS = 12,
|
||||||
|
POINT_SOUND_EMITTERS,
|
||||||
|
DOODAD_SOUNDS,
|
||||||
|
DEATH = 16,
|
||||||
|
NPC_SOUNDS,
|
||||||
|
FOLEY_SOUNDS = 19,
|
||||||
|
FOOTSTEPS_SPLASHES,
|
||||||
|
CHARACTER_SPLASH_SOUNDS,
|
||||||
|
WATERVOLUME_SOUNDS,
|
||||||
|
TRADESKILL,
|
||||||
|
TERRAIN_EMITER,
|
||||||
|
GAME_OBJECTS,
|
||||||
|
SPELL_FIZZLES,
|
||||||
|
CREATURE_LOOPS,
|
||||||
|
ZONE_MUSIC_FILES,
|
||||||
|
EMOTES,
|
||||||
|
CINEMATIC_MUSIC,
|
||||||
|
CINEMATIC_VOICE,
|
||||||
|
ZONE_AMBIENCE = 50,
|
||||||
|
SOUND_EMITTERS = 52,
|
||||||
|
VEHICLE_STATES
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map <int, std::string> sound_types_names = {
|
||||||
|
{SPELLS , "Spells"},
|
||||||
|
{UI , "UI"},
|
||||||
|
{FOOTSTEPS , "Footsteps"},
|
||||||
|
{COMBAT_IMPACTS , "Combat Impacts"},
|
||||||
|
{COMBAT_SWINGS , "Combat Swings"},
|
||||||
|
{GREETINGS, "Greetings"},
|
||||||
|
{CASTING, "Casting"},
|
||||||
|
{ITEM_USE_SOUNDS, "Item Use Sound"},
|
||||||
|
{MONSTER_SOUNDS, "Monster Sound"},
|
||||||
|
{VOCAL_UI_SOUNDS, "VocalUISound"},
|
||||||
|
{POINT_SOUND_EMITTERS, "Point Sound Emitter"},
|
||||||
|
{DOODAD_SOUNDS, "Doodad Sounds"},
|
||||||
|
{DEATH, "Death Thud Sounds"},
|
||||||
|
{NPC_SOUNDS, "NPC Sounds"},
|
||||||
|
{FOLEY_SOUNDS, "Foley Sound"},
|
||||||
|
{FOOTSTEPS_SPLASHES, "Footsteps(Splashes)"},
|
||||||
|
{CHARACTER_SPLASH_SOUNDS, "CharacterSplashSounds"},
|
||||||
|
{WATERVOLUME_SOUNDS, "WaterVolume Sounds"},
|
||||||
|
{TRADESKILL, "Tradeskill Sounds"},
|
||||||
|
{TERRAIN_EMITER, "Terrain Emitter Sounds"},
|
||||||
|
{GAME_OBJECTS, "Game Object Sounds"},
|
||||||
|
{SPELL_FIZZLES, "SpellFizzles"},
|
||||||
|
{CREATURE_LOOPS, "CreatureLoops"},
|
||||||
|
{ZONE_MUSIC_FILES, "Zone Music Files"},
|
||||||
|
{EMOTES, "Character Macro Line"},
|
||||||
|
{CINEMATIC_MUSIC, "Cinematic Music"},
|
||||||
|
{CINEMATIC_VOICE, "Cinematic Voice"},
|
||||||
|
{ZONE_AMBIENCE, "Zone Ambience"},
|
||||||
|
{SOUND_EMITTERS, "Sound Emitters"},
|
||||||
|
{VEHICLE_STATES, "Vehicle States"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
#include <noggit/ui/windows/SoundPlayer/SoundEntryPlayer.h>
|
||||||
|
#include "ZoneIntroMusicPickerWindow.h"
|
||||||
|
// #include <noggit/ui/ZoneIDBrowser.h>
|
||||||
|
#include "SoundEntryPickerWindow.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
|
||||||
|
{
|
||||||
|
ZoneIntroMusicPickerWindow::ZoneIntroMusicPickerWindow(QPushButton* button, QWidget* parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle("Zone Intro Music 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);
|
||||||
|
|
||||||
|
_picker_listview = new QListWidget(this);
|
||||||
|
_picker_listview->setFixedSize(280, 460);
|
||||||
|
_picker_listview->setSelectionMode(QListWidget::SingleSelection);
|
||||||
|
list_layout->addWidget(_picker_listview);
|
||||||
|
|
||||||
|
for (DBCFile::Iterator i = gZoneIntroMusicTableDB.begin(); i != gZoneIntroMusicTableDB.end(); ++i)
|
||||||
|
{
|
||||||
|
auto item = new QListWidgetItem();
|
||||||
|
item->setData(1, i->getInt(ZoneIntroMusicTableDB::ID));
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << i->getInt(ZoneIntroMusicTableDB::ID) << "-" << i->getString(ZoneIntroMusicTableDB::Name);
|
||||||
|
item->setText(ss.str().c_str());
|
||||||
|
|
||||||
|
_picker_listview->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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("Intro Music Name:", _name_ledit);
|
||||||
|
|
||||||
|
|
||||||
|
_sound_button = new QPushButton("-NONE-", this);
|
||||||
|
_sound_button->setProperty("id", 0);
|
||||||
|
connect(_sound_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto window = new SoundEntryPickerWindow(_sound_button, SoundEntryTypes::ZONE_MUSIC_FILES, false, this);
|
||||||
|
window->show();
|
||||||
|
});
|
||||||
|
auto music_layout = new QHBoxLayout(this);
|
||||||
|
auto play_music_button = new QToolButton(this);
|
||||||
|
play_music_button->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::play));
|
||||||
|
music_layout->addWidget(new QLabel("Music sound entry:"));
|
||||||
|
music_layout->addWidget(_sound_button);
|
||||||
|
music_layout->addWidget(play_music_button);
|
||||||
|
editor_form_layout->addRow(music_layout);
|
||||||
|
|
||||||
|
_min_delay_spinbox = new QSpinBox(this);
|
||||||
|
_min_delay_spinbox->setMaximum(300);
|
||||||
|
editor_form_layout->addRow("Min Delay (minutes):", _min_delay_spinbox);
|
||||||
|
|
||||||
|
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_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(play_music_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto sound_entry = _sound_button->property("id").toInt();
|
||||||
|
if (sound_entry)
|
||||||
|
{
|
||||||
|
auto sound_player = new SoundEntryPlayer(this);
|
||||||
|
sound_player->LoadSoundsFromSoundEntry(sound_entry);
|
||||||
|
sound_player->show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(save_music_entry_btn, &QPushButton::clicked, [=]() {
|
||||||
|
save_entry(_entry_id);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(duplicate_entry_btn, &QPushButton::clicked, [=]() {
|
||||||
|
auto new_id = gZoneIntroMusicTableDB.getEmptyRecordID(ZoneIntroMusicTableDB::ID);
|
||||||
|
|
||||||
|
auto new_record = gZoneIntroMusicTableDB.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 ZoneIntroMusicPickerWindow::select_entry(int id)
|
||||||
|
{
|
||||||
|
_entry_id = id;
|
||||||
|
|
||||||
|
if (id != 0)
|
||||||
|
_picker_listview->setCurrentRow(gZoneIntroMusicTableDB.getRecordRowId(id));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_picker_listview->setCurrentRow(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_entry_id_lbl->setText(QString(std::to_string(id).c_str()));
|
||||||
|
|
||||||
|
DBCFile::Record record = gZoneIntroMusicTableDB.getByID(id);
|
||||||
|
|
||||||
|
_name_ledit->setText(record.getString(ZoneIntroMusicTableDB::Name));
|
||||||
|
|
||||||
|
int sound_entry = record.getInt(ZoneIntroMusicTableDB::SoundId);
|
||||||
|
|
||||||
|
if (sound_entry != 0 && gSoundEntriesDB.CheckIfIdExists(sound_entry))
|
||||||
|
{
|
||||||
|
DBCFile::Record sound_record = gSoundEntriesDB.getByID(sound_entry);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << sound_entry << "-" << sound_record.getString(SoundEntriesDB::Name);
|
||||||
|
_sound_button->setText(ss.str().c_str());
|
||||||
|
_sound_button->setProperty("id", sound_entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_sound_button->setText("-NONE-");
|
||||||
|
_sound_button->setProperty("id", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_priority = record.getInt(ZoneIntroMusicTableDB::Priority); // always 1 except for 1 test entry
|
||||||
|
|
||||||
|
_min_delay_spinbox->setValue(record.getInt(ZoneIntroMusicTableDB::MinDelayMinutes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneIntroMusicPickerWindow::save_entry(int entry_id)
|
||||||
|
{
|
||||||
|
DBCFile::Record record = gZoneIntroMusicTableDB.getByID(entry_id); // is_new_record ? gLightDB.addRecord(Id) : gLightDB.getByID(Id);
|
||||||
|
|
||||||
|
|
||||||
|
record.write(ZoneIntroMusicTableDB::ID, entry_id);
|
||||||
|
record.writeString(ZoneIntroMusicTableDB::Name, _name_ledit->text().toStdString());
|
||||||
|
record.write(ZoneIntroMusicTableDB::SoundId, _sound_button->property("id").toInt());
|
||||||
|
record.write(ZoneIntroMusicTableDB::Priority, _priority);
|
||||||
|
record.write(ZoneIntroMusicTableDB::MinDelayMinutes, _min_delay_spinbox->value());
|
||||||
|
|
||||||
|
gZoneIntroMusicTableDB.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <noggit/DBC.h>
|
||||||
|
|
||||||
|
#include <QtWidgets/QWidget>
|
||||||
|
#include <QtWidgets/QTreeWidget>
|
||||||
|
#include <QtWidgets/QDoubleSpinBox>
|
||||||
|
#include <QtWidgets/QSlider>
|
||||||
|
#include <QtWidgets/QCheckBox.h>
|
||||||
|
#include <QtWidgets/QComboBox.h>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <QtWidgets/QListWidget>
|
||||||
|
#include <QtWidgets/QListView>
|
||||||
|
#include <QtWidgets/QPushButton>
|
||||||
|
#include <QMediaPlayer>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Noggit
|
||||||
|
{
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class ZoneIntroMusicPickerWindow : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ZoneIntroMusicPickerWindow(QPushButton* button, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineEdit* _tree_searchbar;
|
||||||
|
QListWidget* _picker_listview;
|
||||||
|
|
||||||
|
int _entry_id = 0;
|
||||||
|
int _priority = 1;
|
||||||
|
QLabel* _entry_id_lbl;
|
||||||
|
QLineEdit* _name_ledit;
|
||||||
|
QSpinBox* _min_delay_spinbox;
|
||||||
|
|
||||||
|
QPushButton* _sound_button;
|
||||||
|
|
||||||
|
void select_entry(int id);
|
||||||
|
void save_entry(int entry_id);
|
||||||
|
// void duplicate_entry();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
326
src/noggit/ui/windows/EditorWindows/ZoneMusicPickerWindow.cpp
Normal file
326
src/noggit/ui/windows/EditorWindows/ZoneMusicPickerWindow.cpp
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
#include "ZoneMusicPickerWindow.h"
|
||||||
|
#include <noggit/ui/windows/SoundPlayer/SoundEntryPlayer.h>
|
||||||
|
#include "SoundEntryPickerWindow.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
|
||||||
|
{
|
||||||
|
ZoneMusicPickerWindow::ZoneMusicPickerWindow(QPushButton* button, QWidget* parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle("Zone Music 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);
|
||||||
|
|
||||||
|
_picker_listview = new QListWidget(this);
|
||||||
|
_picker_listview->setFixedSize(280, 460);
|
||||||
|
_picker_listview->setSelectionMode(QListWidget::SingleSelection);
|
||||||
|
list_layout->addWidget(_picker_listview);
|
||||||
|
|
||||||
|
for (DBCFile::Iterator i = gZoneMusicDB.begin(); i != gZoneMusicDB.end(); ++i)
|
||||||
|
{
|
||||||
|
auto item = new QListWidgetItem();
|
||||||
|
item->setData(1, i->getInt(ZoneMusicDB::ID));
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << i->getInt(ZoneMusicDB::ID) << "-" << i->getString(ZoneMusicDB::Name);
|
||||||
|
item->setText(ss.str().c_str());
|
||||||
|
|
||||||
|
// _picker_listview->addItem(ss.str().c_str());
|
||||||
|
_picker_listview->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto select_entry_btn = new QPushButton("Select Entry", this);
|
||||||
|
select_entry_btn->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::check));
|
||||||
|
auto select_entry_none_btn = new QPushButton("Select -NONE-", this);
|
||||||
|
select_entry_none_btn->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::check));
|
||||||
|
auto duplicate_entry_btn = new QPushButton("Duplicate selected Entry (create new)", this);
|
||||||
|
duplicate_entry_btn->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::plus));
|
||||||
|
list_layout->addWidget(duplicate_entry_btn);
|
||||||
|
list_layout->addWidget(select_entry_btn);
|
||||||
|
list_layout->addWidget(select_entry_none_btn);
|
||||||
|
|
||||||
|
// 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("Music Set Name:", _name_ledit);
|
||||||
|
|
||||||
|
|
||||||
|
_day_music_button = new QPushButton("-NONE-", this);
|
||||||
|
_day_music_button->setProperty("id", 0);
|
||||||
|
connect(_day_music_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto window = new SoundEntryPickerWindow(_day_music_button, SoundEntryTypes::ZONE_MUSIC_FILES, true, this);
|
||||||
|
window->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto day_music_layout = new QHBoxLayout(this);
|
||||||
|
auto play_day_music_button = new QToolButton(this);
|
||||||
|
play_day_music_button->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::play));
|
||||||
|
day_music_layout->addWidget(new QLabel("Day Music:"));
|
||||||
|
day_music_layout->addWidget(_day_music_button);
|
||||||
|
day_music_layout->addWidget(play_day_music_button);
|
||||||
|
editor_form_layout->addRow(day_music_layout);
|
||||||
|
|
||||||
|
_night_music_button = new QPushButton("-NONE-", this);
|
||||||
|
_night_music_button->setProperty("id", 0);
|
||||||
|
connect(_night_music_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto window = new SoundEntryPickerWindow(_night_music_button, SoundEntryTypes::ZONE_MUSIC_FILES, true, this);
|
||||||
|
window->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto night_music_layout = new QHBoxLayout(this);
|
||||||
|
auto play_night_music_button = new QToolButton(this);
|
||||||
|
play_night_music_button->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::play));
|
||||||
|
night_music_layout->addWidget(new QLabel("Night Music:"));
|
||||||
|
night_music_layout->addWidget(_night_music_button);
|
||||||
|
night_music_layout->addWidget(play_night_music_button);
|
||||||
|
editor_form_layout->addRow(night_music_layout);
|
||||||
|
// editor_form_layout->addRow("Night Music:", _night_music_button);
|
||||||
|
|
||||||
|
QGroupBox* silence_intervals_group = new QGroupBox("Silence Intervals", this);
|
||||||
|
Editor_layout->addWidget(silence_intervals_group);
|
||||||
|
auto silence_interval_layout = new QVBoxLayout(silence_intervals_group);
|
||||||
|
|
||||||
|
silence_interval_layout->addWidget(new QLabel("Day:"));
|
||||||
|
auto day_silence_intervals_layout = new QHBoxLayout(this);
|
||||||
|
silence_interval_layout->addLayout(day_silence_intervals_layout);
|
||||||
|
day_silence_intervals_layout->addWidget(new QLabel("Min:"));
|
||||||
|
_day_min_interval_spinbox = new QSpinBox(this);
|
||||||
|
_day_min_interval_spinbox->setMaximum(600000);
|
||||||
|
day_silence_intervals_layout->addWidget(_day_min_interval_spinbox);
|
||||||
|
day_silence_intervals_layout->addWidget(new QLabel("Max:"));
|
||||||
|
_day_max_interval_spinbox = new QSpinBox(this);
|
||||||
|
_day_max_interval_spinbox->setMaximum(600000);
|
||||||
|
day_silence_intervals_layout->addWidget(_day_max_interval_spinbox);
|
||||||
|
|
||||||
|
silence_interval_layout->addWidget(new QLabel("Night:"));
|
||||||
|
auto night_silence_intervals_layout = new QHBoxLayout(this);
|
||||||
|
silence_interval_layout->addLayout(night_silence_intervals_layout);
|
||||||
|
night_silence_intervals_layout->addWidget(new QLabel("Min:"));
|
||||||
|
_night_min_interval_spinbox = new QSpinBox(this);
|
||||||
|
_night_min_interval_spinbox->setMaximum(600000);
|
||||||
|
night_silence_intervals_layout->addWidget(_night_min_interval_spinbox);
|
||||||
|
night_silence_intervals_layout->addWidget(new QLabel("Max:"));
|
||||||
|
_night_max_interval_spinbox = new QSpinBox(this);
|
||||||
|
_night_max_interval_spinbox->setMaximum(600000);
|
||||||
|
night_silence_intervals_layout->addWidget(_night_max_interval_spinbox);
|
||||||
|
|
||||||
|
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_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(play_day_music_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto sound_entry = _day_music_button->property("id").toInt();
|
||||||
|
if (sound_entry)
|
||||||
|
{
|
||||||
|
auto sound_player = new SoundEntryPlayer(this);
|
||||||
|
sound_player->LoadSoundsFromSoundEntry(sound_entry);
|
||||||
|
sound_player->show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(play_night_music_button, &QPushButton::clicked, [=]() {
|
||||||
|
auto sound_entry = _night_music_button->property("id").toInt();
|
||||||
|
if (sound_entry)
|
||||||
|
{
|
||||||
|
auto sound_player = new SoundEntryPlayer(this);
|
||||||
|
sound_player->LoadSoundsFromSoundEntry(sound_entry);
|
||||||
|
sound_player->show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(save_music_entry_btn, &QPushButton::clicked, [=]() {
|
||||||
|
save_entry(_entry_id);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(duplicate_entry_btn, &QPushButton::clicked, [=]() {
|
||||||
|
auto new_id = gZoneMusicDB.getEmptyRecordID(ZoneMusicDB::ID);
|
||||||
|
|
||||||
|
auto new_record = gZoneMusicDB.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 ZoneMusicPickerWindow::select_entry(int id)
|
||||||
|
{
|
||||||
|
_entry_id = id;
|
||||||
|
|
||||||
|
if (id != 0)
|
||||||
|
_picker_listview->setCurrentRow(gZoneMusicDB.getRecordRowId(id));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_picker_listview->setCurrentRow(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_entry_id_lbl->setText(QString(std::to_string(id).c_str()));
|
||||||
|
|
||||||
|
DBCFile::Record record = gZoneMusicDB.getByID(id);
|
||||||
|
|
||||||
|
_name_ledit->setText(record.getString(ZoneMusicDB::Name));
|
||||||
|
|
||||||
|
int day_sound_entry = record.getInt(ZoneMusicDB::DayMusic);
|
||||||
|
int night_sound_entry = record.getInt(ZoneMusicDB::NightMusic);
|
||||||
|
|
||||||
|
if (day_sound_entry != 0 && gSoundEntriesDB.CheckIfIdExists(day_sound_entry)) // some entries reference sound entries that don't exist
|
||||||
|
{
|
||||||
|
DBCFile::Record day_sound_record = gSoundEntriesDB.getByID(day_sound_entry);
|
||||||
|
std::stringstream ss_day;
|
||||||
|
ss_day << day_sound_entry << "-" << day_sound_record.getString(SoundEntriesDB::Name);
|
||||||
|
_day_music_button->setText(ss_day.str().c_str());
|
||||||
|
_day_music_button->setProperty("id", day_sound_entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_day_music_button->setText("-NONE-");
|
||||||
|
_day_music_button->setProperty("id", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (night_sound_entry != 0 && gSoundEntriesDB.CheckIfIdExists(night_sound_entry))
|
||||||
|
{
|
||||||
|
DBCFile::Record night_sound_record = gSoundEntriesDB.getByID(night_sound_entry);
|
||||||
|
std::stringstream ss_night;
|
||||||
|
ss_night << night_sound_entry << "-" << night_sound_record.getString(SoundEntriesDB::Name);
|
||||||
|
_night_music_button->setText(ss_night.str().c_str());
|
||||||
|
_night_music_button->setProperty("id", night_sound_entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_night_music_button->setText("-NONE-");
|
||||||
|
_night_music_button->setProperty("id", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_day_min_interval_spinbox->setValue(record.getInt(ZoneMusicDB::SilenceIntervalMinDay));
|
||||||
|
_day_max_interval_spinbox->setValue(record.getInt(ZoneMusicDB::SilenceIntervalMaxDay));
|
||||||
|
_night_min_interval_spinbox->setValue(record.getInt(ZoneMusicDB::SilenceIntervalMinNight));
|
||||||
|
_night_max_interval_spinbox->setValue(record.getInt(ZoneMusicDB::SilenceIntervalMaxNight));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneMusicPickerWindow::save_entry(int entry_id)
|
||||||
|
{
|
||||||
|
DBCFile::Record record = gZoneMusicDB.getByID(entry_id); // is_new_record ? gLightDB.addRecord(Id) : gLightDB.getByID(Id);
|
||||||
|
|
||||||
|
|
||||||
|
record.write(ZoneMusicDB::ID, entry_id);
|
||||||
|
record.writeString(ZoneMusicDB::Name, _name_ledit->text().toStdString());
|
||||||
|
record.write(ZoneMusicDB::SilenceIntervalMinDay, _day_min_interval_spinbox->value());
|
||||||
|
record.write(ZoneMusicDB::SilenceIntervalMaxDay, _day_max_interval_spinbox->value());
|
||||||
|
record.write(ZoneMusicDB::SilenceIntervalMinNight, _night_min_interval_spinbox->value());
|
||||||
|
record.write(ZoneMusicDB::SilenceIntervalMaxNight, _night_max_interval_spinbox->value());
|
||||||
|
record.write(ZoneMusicDB::DayMusic, _day_music_button->property("id").toInt());
|
||||||
|
record.write(ZoneMusicDB::NightMusic, _night_music_button->property("id").toInt());
|
||||||
|
|
||||||
|
gZoneMusicDB.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/noggit/ui/windows/EditorWindows/ZoneMusicPickerWindow.h
Normal file
53
src/noggit/ui/windows/EditorWindows/ZoneMusicPickerWindow.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <noggit/DBC.h>
|
||||||
|
|
||||||
|
#include <QtWidgets/QWidget>
|
||||||
|
#include <QtWidgets/QTreeWidget>
|
||||||
|
#include <QtWidgets/QDoubleSpinBox>
|
||||||
|
#include <QtWidgets/QSlider>
|
||||||
|
#include <QtWidgets/QCheckBox.h>
|
||||||
|
#include <QtWidgets/QComboBox.h>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <QtWidgets/QListWidget>
|
||||||
|
#include <QtWidgets/QListView>
|
||||||
|
#include <QtWidgets/QPushButton>
|
||||||
|
#include <QMediaPlayer>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Noggit
|
||||||
|
{
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class ZoneMusicPickerWindow : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ZoneMusicPickerWindow(QPushButton* button, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineEdit* _tree_searchbar;
|
||||||
|
QListWidget* _picker_listview;
|
||||||
|
|
||||||
|
int _entry_id = 0;
|
||||||
|
QLabel* _entry_id_lbl;
|
||||||
|
QLineEdit* _name_ledit;
|
||||||
|
QSpinBox* _day_min_interval_spinbox;
|
||||||
|
QSpinBox* _day_max_interval_spinbox;
|
||||||
|
QSpinBox* _night_min_interval_spinbox;
|
||||||
|
QSpinBox* _night_max_interval_spinbox;
|
||||||
|
|
||||||
|
QPushButton* _day_music_button;
|
||||||
|
QPushButton* _night_music_button;
|
||||||
|
|
||||||
|
void select_entry(int id);
|
||||||
|
void save_entry(int entry_id);
|
||||||
|
// void duplicate_entry();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
213
src/noggit/ui/windows/SoundPlayer/SoundEntryPlayer.cpp
Normal file
213
src/noggit/ui/windows/SoundPlayer/SoundEntryPlayer.cpp
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
#include "SoundEntryPlayer.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
|
||||||
|
{
|
||||||
|
SoundEntryPlayer::SoundEntryPlayer(QWidget* parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle("Sound entry player");
|
||||||
|
setWindowFlags(Qt::Tool);
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
// auto sound_id_lbl = new QLabel(this);
|
||||||
|
// sound_id_lbl->setText("Sound Entry : " + sound_entry_id);
|
||||||
|
// layout->addWidget(sound_id_lbl);
|
||||||
|
|
||||||
|
auto dir_layout = new QHBoxLayout(this);
|
||||||
|
layout->addLayout(dir_layout);
|
||||||
|
|
||||||
|
dir_layout->addWidget(new QLabel("Directory:"));
|
||||||
|
_directory_lbl = new QLabel(this);
|
||||||
|
dir_layout->addWidget(_directory_lbl);
|
||||||
|
|
||||||
|
auto controls_layout = new QHBoxLayout(this);
|
||||||
|
layout->addLayout(controls_layout);
|
||||||
|
|
||||||
|
_media_player = new QMediaPlayer(this);
|
||||||
|
|
||||||
|
auto btn_play = new QToolButton(this);
|
||||||
|
controls_layout->addWidget(btn_play);
|
||||||
|
connect(btn_play, &QToolButton::clicked, _media_player, &QMediaPlayer::play);
|
||||||
|
btn_play->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::play));
|
||||||
|
|
||||||
|
auto btn_pause = new QToolButton(this);
|
||||||
|
controls_layout->addWidget(btn_pause);
|
||||||
|
connect(btn_pause, &QToolButton::clicked, _media_player, &QMediaPlayer::pause);
|
||||||
|
btn_pause->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::pause));
|
||||||
|
|
||||||
|
auto btn_stop = new QToolButton(this);
|
||||||
|
controls_layout->addWidget(btn_stop);
|
||||||
|
connect(btn_stop, &QToolButton::clicked, _media_player, &QMediaPlayer::stop);
|
||||||
|
btn_stop->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::stop));
|
||||||
|
|
||||||
|
_position_slider = new QSlider(Qt::Horizontal, this);
|
||||||
|
_position_slider->setTickInterval(100);
|
||||||
|
_position_slider->setSingleStep(100);
|
||||||
|
controls_layout->addWidget(_position_slider);
|
||||||
|
|
||||||
|
_volume_slider = new QSlider(Qt::Horizontal, this);
|
||||||
|
_volume_slider->setRange(0, 100);
|
||||||
|
_volume_slider->setValue(80);
|
||||||
|
_media_player->setVolume(80);
|
||||||
|
|
||||||
|
|
||||||
|
// controls_layout->addWidget(new QLabel("Volume:"));
|
||||||
|
auto btn_volume = new QToolButton(this);
|
||||||
|
controls_layout->addWidget(btn_volume);
|
||||||
|
// connect(btn_volume, &QToolButton::clicked, _media_player, &QMediaPlayer::stop);
|
||||||
|
btn_volume->setIcon(Noggit::Ui::FontAwesomeIcon(FontAwesome::volumeup));
|
||||||
|
controls_layout->addWidget(btn_volume);
|
||||||
|
controls_layout->addWidget(_volume_slider);
|
||||||
|
|
||||||
|
_files_listview = new QListWidget();
|
||||||
|
_files_listview->setSelectionMode(QListWidget::SingleSelection);
|
||||||
|
layout->addWidget(_files_listview);
|
||||||
|
|
||||||
|
connect(_files_listview, &QListWidget::itemClicked, this, [=](QListWidgetItem* item) {
|
||||||
|
play_selected_sound();
|
||||||
|
});
|
||||||
|
|
||||||
|
// connect volume
|
||||||
|
connect(_volume_slider, &QSlider::valueChanged, [&](int v) {
|
||||||
|
_media_player->setVolume(v);
|
||||||
|
});
|
||||||
|
|
||||||
|
// media doesn't start playnig imemdiatly when called, need to use this signal
|
||||||
|
connect(_media_player, &QMediaPlayer::durationChanged, this, [&](qint64 dur) {
|
||||||
|
_position_slider->setMaximum(dur);
|
||||||
|
});
|
||||||
|
|
||||||
|
// connect(_media_player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
|
||||||
|
connect(_media_player, &QMediaPlayer::positionChanged, [&](qint64 v) {
|
||||||
|
auto testmax = _position_slider->maximum();
|
||||||
|
QSignalBlocker const blocker(_position_slider);
|
||||||
|
_position_slider->setSliderPosition(v);
|
||||||
|
});
|
||||||
|
// position bar
|
||||||
|
connect(_position_slider, &QSlider::valueChanged, [&](int v) {
|
||||||
|
// _media_player->currentMedia().canonicalResource().dataSize();
|
||||||
|
_media_player->setPosition(v);
|
||||||
|
});
|
||||||
|
// _media_player->setPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEntryPlayer::LoadSoundsFromSoundEntry(int sound_entry_id)
|
||||||
|
{
|
||||||
|
if (sound_entry_id == 0)
|
||||||
|
{
|
||||||
|
this->close();
|
||||||
|
this->destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get files list
|
||||||
|
DBCFile::Record sound_entry_record = gSoundEntriesDB.getByID(sound_entry_id);
|
||||||
|
|
||||||
|
_directory_lbl->setText(sound_entry_record.getString(SoundEntriesDB::FilePath));
|
||||||
|
|
||||||
|
_volume_slider->setValue(sound_entry_record.getFloat(SoundEntriesDB::Volume) * 100);
|
||||||
|
_media_player->setVolume(sound_entry_record.getFloat(SoundEntriesDB::Volume) * 100);
|
||||||
|
|
||||||
|
for (int fileid = 0; fileid < 10; fileid++)
|
||||||
|
{
|
||||||
|
std::string filename = sound_entry_record.getString(SoundEntriesDB::Filenames + fileid);
|
||||||
|
if (!filename.empty())
|
||||||
|
{
|
||||||
|
// std::stringstream ss_filepah;
|
||||||
|
// ss_filepath << directory << "\\" << filename;
|
||||||
|
// music_files.push_back(ss_filepah.str());
|
||||||
|
// music_files.push_back(filename);
|
||||||
|
_files_listview->addItem(filename.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_files_listview->setCurrentRow(0);
|
||||||
|
play_selected_sound();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEntryPlayer::PlaySingleSoundFile(std::string filepath, std::string dir_path)
|
||||||
|
{
|
||||||
|
_directory_lbl->setText(dir_path.c_str());
|
||||||
|
|
||||||
|
_files_listview->clear();
|
||||||
|
_files_listview->addItem(filepath.c_str());
|
||||||
|
|
||||||
|
_files_listview->setCurrentRow(0);
|
||||||
|
play_selected_sound();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEntryPlayer::play_selected_sound()
|
||||||
|
{
|
||||||
|
std::stringstream filename;
|
||||||
|
auto item = _files_listview->selectedItems().back();
|
||||||
|
filename << _directory_lbl->text().toStdString() << "\\" << item->text().toStdString();
|
||||||
|
|
||||||
|
if (!Noggit::Application::NoggitApplication::instance()->clientData()->exists(filename.str()))
|
||||||
|
{
|
||||||
|
LogError << "The requested sound file \"" << filename.str() << "\" does not exist! Oo" << std::endl;
|
||||||
|
QMessageBox not_found_messagebox;
|
||||||
|
not_found_messagebox.setIcon(QMessageBox::Warning);
|
||||||
|
not_found_messagebox.setWindowIcon(QIcon(":/icon"));
|
||||||
|
not_found_messagebox.setWindowTitle("File not found");
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "The requested sound file \"" << filename.str() << "\" was not found in the client." << std::endl;
|
||||||
|
not_found_messagebox.setText(ss.str().c_str());
|
||||||
|
not_found_messagebox.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlizzardArchive::ClientFile file(filename.str(), Noggit::Application::NoggitApplication::instance()->clientData());
|
||||||
|
|
||||||
|
auto temp_file = new QTemporaryFile(this); // must parent for the object to be destroyed properly(and file deleted)
|
||||||
|
|
||||||
|
temp_file->open();
|
||||||
|
temp_file->write(file.getBuffer(), file.getSize());
|
||||||
|
temp_file->close();
|
||||||
|
// default tempname is like User\AppData\Local\Temp\Noggit.qrRfsy ...We need to add back the file extension or it won't be read by the player!
|
||||||
|
// must rename after closing or it doesn't write correctly
|
||||||
|
temp_file->rename(temp_file->fileName() + item->text());
|
||||||
|
// file.save(); // saves file to project folder
|
||||||
|
// auto save_path = file.getPath().string();
|
||||||
|
|
||||||
|
auto testlol = temp_file->fileName().toStdString();
|
||||||
|
|
||||||
|
_media_player->setMedia(QUrl::fromLocalFile(temp_file->fileName())); // QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3")
|
||||||
|
_media_player->play();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEntryPlayer::closeEvent(QCloseEvent* event)
|
||||||
|
{
|
||||||
|
// makes the music stop when closing
|
||||||
|
_media_player->stop();
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/noggit/ui/windows/SoundPlayer/SoundEntryPlayer.h
Normal file
49
src/noggit/ui/windows/SoundPlayer/SoundEntryPlayer.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <noggit/DBC.h>
|
||||||
|
|
||||||
|
#include <QtWidgets/QWidget>
|
||||||
|
#include <QtWidgets/QTreeWidget>
|
||||||
|
#include <QtWidgets/QDoubleSpinBox>
|
||||||
|
#include <QtWidgets/QSlider>
|
||||||
|
#include <QtWidgets/QCheckBox.h>
|
||||||
|
#include <QtWidgets/QComboBox.h>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <QtWidgets/QListWidget>
|
||||||
|
#include <QtWidgets/QListView>
|
||||||
|
#include <QtWidgets/QPushButton>
|
||||||
|
#include <QMediaPlayer>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Noggit
|
||||||
|
{
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class SoundEntryPlayer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SoundEntryPlayer(QWidget* parent = nullptr);
|
||||||
|
void LoadSoundsFromSoundEntry(int sound_entry_id);
|
||||||
|
void PlaySingleSoundFile(std::string filepath, std::string dir_path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMediaPlayer* _media_player;
|
||||||
|
|
||||||
|
// QLabel* sound_id_lbl;
|
||||||
|
QLabel* _directory_lbl;
|
||||||
|
QListWidget* _files_listview;
|
||||||
|
QSlider* _volume_slider;
|
||||||
|
QSlider* _position_slider;
|
||||||
|
|
||||||
|
void play_selected_sound();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user