Compare commits
3 commits
82170b3078
...
350ad59f8e
Author | SHA1 | Date | |
---|---|---|---|
350ad59f8e | |||
883d5d3f41 | |||
77d7eaefad |
7 changed files with 200 additions and 170 deletions
|
@ -35,8 +35,6 @@
|
||||||
|
|
||||||
#include "Mass.h"
|
#include "Mass.h"
|
||||||
|
|
||||||
std::string Mass::_lastError;
|
|
||||||
|
|
||||||
Mass::Mass(const std::string& path) {
|
Mass::Mass(const std::string& path) {
|
||||||
_folder = Utility::Directory::path(path);
|
_folder = Utility::Directory::path(path);
|
||||||
_filename = Utility::Directory::filename(path);
|
_filename = Utility::Directory::filename(path);
|
||||||
|
@ -50,28 +48,28 @@ auto Mass::lastError() -> std::string const& {
|
||||||
|
|
||||||
auto Mass::getNameFromFile(const std::string& path) -> Containers::Optional<std::string> {
|
auto Mass::getNameFromFile(const std::string& path) -> Containers::Optional<std::string> {
|
||||||
if(!Utility::Directory::exists(path)) {
|
if(!Utility::Directory::exists(path)) {
|
||||||
_lastError = path + " couldn't be found.";
|
Utility::Error{} << path.c_str() << "couldn't be found.";
|
||||||
return Containers::NullOpt;
|
return Containers::NullOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
UESaveFile mass{path};
|
UESaveFile mass{path};
|
||||||
|
|
||||||
if(!mass.valid()) {
|
if(!mass.valid()) {
|
||||||
_lastError = "The unit file seems to be corrupt.";
|
Utility::Error{} << "The unit file seems to be corrupt.";
|
||||||
return Containers::NullOpt;
|
return Containers::NullOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto unit_data = mass.at<GenericStructProperty>("UnitData");
|
auto unit_data = mass.at<GenericStructProperty>("UnitData");
|
||||||
|
|
||||||
if(!unit_data) {
|
if(!unit_data) {
|
||||||
_lastError = "Couldn't find unit data in the file.";
|
Utility::Error{} << "Couldn't find unit data in the file.";
|
||||||
return Containers::NullOpt;
|
return Containers::NullOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name_prop = unit_data->at<StringProperty>("Name_45_A037C5D54E53456407BDF091344529BB");
|
auto name_prop = unit_data->at<StringProperty>("Name_45_A037C5D54E53456407BDF091344529BB");
|
||||||
|
|
||||||
if(!name_prop) {
|
if(!name_prop) {
|
||||||
_lastError = "Couldn't find the name in the file.";
|
Utility::Error{} << "Couldn't find the name in the file.";
|
||||||
return Containers::NullOpt;
|
return Containers::NullOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +376,7 @@ auto Mass::writeJointSliders() -> bool {
|
||||||
frame_prop->properties = std::move(temp);
|
frame_prop->properties = std::move(temp);
|
||||||
|
|
||||||
if(!_mass->saveToFile()) {
|
if(!_mass->saveToFile()) {
|
||||||
_lastError = "Couldn't write data to " + _filename;
|
_lastError = _mass->lastError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +443,7 @@ auto Mass::writeFrameStyles() -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_mass->saveToFile()) {
|
if(!_mass->saveToFile()) {
|
||||||
_lastError = "Couldn't write data to " + _filename;
|
_lastError = _mass->lastError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,18 +480,21 @@ auto Mass::writeEyeFlareColour() -> bool {
|
||||||
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
||||||
if(!unit_data) {
|
if(!unit_data) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No unit data in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frame = unit_data->at<GenericStructProperty>("Frame_3_F92B0F6A44A15088AF7F41B9FF290653");
|
auto frame = unit_data->at<GenericStructProperty>("Frame_3_F92B0F6A44A15088AF7F41B9FF290653");
|
||||||
if(!frame) {
|
if(!frame) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No frame data in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto eye_flare_prop = frame->at<ColourStructProperty>("EyeFlareColor_36_AF79999C40FCA0E88A2F9A84488A38CA");
|
auto eye_flare_prop = frame->at<ColourStructProperty>("EyeFlareColor_36_AF79999C40FCA0E88A2F9A84488A38CA");
|
||||||
if(!eye_flare_prop) {
|
if(!eye_flare_prop) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No eye flare property in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +503,12 @@ auto Mass::writeEyeFlareColour() -> bool {
|
||||||
eye_flare_prop->b = _frame.eyeFlare.b();
|
eye_flare_prop->b = _frame.eyeFlare.b();
|
||||||
eye_flare_prop->a = _frame.eyeFlare.a();
|
eye_flare_prop->a = _frame.eyeFlare.a();
|
||||||
|
|
||||||
return _mass->saveToFile();
|
if(!_mass->saveToFile()) {
|
||||||
|
_lastError = _mass->lastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Mass::frameCustomStyles() -> Containers::ArrayView<CustomStyle> {
|
auto Mass::frameCustomStyles() -> Containers::ArrayView<CustomStyle> {
|
||||||
|
@ -532,18 +538,21 @@ void Mass::getFrameCustomStyles() {
|
||||||
|
|
||||||
auto Mass::writeFrameCustomStyle(UnsignedLong index) -> bool {
|
auto Mass::writeFrameCustomStyle(UnsignedLong index) -> bool {
|
||||||
if(index > _frame.customStyles.size()) {
|
if(index > _frame.customStyles.size()) {
|
||||||
|
_lastError = "Style index out of range.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
||||||
if(!unit_data) {
|
if(!unit_data) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No unit data in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frame_styles = unit_data->at<ArrayProperty>("FrameStyle_44_04A44C9440363CCEC5443D98BFAF22AA");
|
auto frame_styles = unit_data->at<ArrayProperty>("FrameStyle_44_04A44C9440363CCEC5443D98BFAF22AA");
|
||||||
if(!frame_styles) {
|
if(!frame_styles) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No frame styles in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,6 +661,14 @@ auto Mass::writeArmourPart(ArmourSlot slot) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!part_prop) {
|
if(!part_prop) {
|
||||||
|
_lastError = "Couldn't find the armour part for slot ";
|
||||||
|
switch(slot) {
|
||||||
|
#define c(enumerator, strenum, name) case ArmourSlot::enumerator: \
|
||||||
|
_lastError += "ArmourSlot::" #enumerator "."; \
|
||||||
|
break;
|
||||||
|
#include "../Maps/ArmourSlots.hpp"
|
||||||
|
#undef c
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,7 +687,12 @@ auto Mass::writeArmourPart(ArmourSlot slot) -> bool {
|
||||||
writeAccessories(part.accessories, accs_array);
|
writeAccessories(part.accessories, accs_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _mass->saveToFile();
|
if(!_mass->saveToFile()) {
|
||||||
|
_lastError = _mass->lastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Mass::armourCustomStyles() -> Containers::ArrayView<CustomStyle> {
|
auto Mass::armourCustomStyles() -> Containers::ArrayView<CustomStyle> {
|
||||||
|
@ -700,17 +722,20 @@ void Mass::getArmourCustomStyles() {
|
||||||
|
|
||||||
auto Mass::writeArmourCustomStyle(UnsignedLong index) -> bool {
|
auto Mass::writeArmourCustomStyle(UnsignedLong index) -> bool {
|
||||||
if(index > _armour.customStyles.size()) {
|
if(index > _armour.customStyles.size()) {
|
||||||
|
_lastError = "Style index out of range.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
||||||
if(!unit_data) {
|
if(!unit_data) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "Couldn't find unit data in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto armour_styles = unit_data->at<ArrayProperty>("ArmorStyle_42_E2F6AC3647788CB366BD469B3B7E899E");
|
auto armour_styles = unit_data->at<ArrayProperty>("ArmorStyle_42_E2F6AC3647788CB366BD469B3B7E899E");
|
||||||
if(!armour_styles) {
|
if(!armour_styles) {
|
||||||
|
_lastError = "Couldn't find armour custom styles in " + _filename;
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -817,18 +842,21 @@ void Mass::getGlobalStyles() {
|
||||||
|
|
||||||
auto Mass::writeGlobalStyle(UnsignedLong index) -> bool {
|
auto Mass::writeGlobalStyle(UnsignedLong index) -> bool {
|
||||||
if(index > _globalStyles.size()) {
|
if(index > _globalStyles.size()) {
|
||||||
|
_lastError = "Global style index out of range";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
||||||
if(!unit_data) {
|
if(!unit_data) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No unit data found in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto global_styles = unit_data->at<ArrayProperty>("GlobalStyles_57_6A681C114035241F7BDAAE9B43A8BF1B");
|
auto global_styles = unit_data->at<ArrayProperty>("GlobalStyles_57_6A681C114035241F7BDAAE9B43A8BF1B");
|
||||||
if(!global_styles) {
|
if(!global_styles) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No global styles found in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,11 +947,17 @@ void Mass::getCustomStyles(Containers::ArrayView<CustomStyle> styles, ArrayPrope
|
||||||
|
|
||||||
auto Mass::setCustomStyle(const CustomStyle& style, UnsignedLong index, ArrayProperty* style_array) -> bool {
|
auto Mass::setCustomStyle(const CustomStyle& style, UnsignedLong index, ArrayProperty* style_array) -> bool {
|
||||||
if(!style_array) {
|
if(!style_array) {
|
||||||
|
_lastError = "Mass::setCustomStyle(): style_array is null.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto style_prop = style_array->at<GenericStructProperty>(index);
|
auto style_prop = style_array->at<GenericStructProperty>(index);
|
||||||
|
|
||||||
|
if(!style_prop) {
|
||||||
|
_lastError = "Style index is out of range in " + _filename;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
style_prop->at<StringProperty>("Name_27_1532115A46EF2B2FA283908DF561A86B")->value = style.name;
|
style_prop->at<StringProperty>("Name_27_1532115A46EF2B2FA283908DF561A86B")->value = style.name;
|
||||||
auto colour_prop = style_prop->at<ColourStructProperty>("Color_5_F0D383DF40474C9464AE48A0984A212E");
|
auto colour_prop = style_prop->at<ColourStructProperty>("Color_5_F0D383DF40474C9464AE48A0984A212E");
|
||||||
colour_prop->r = style.colour.r();
|
colour_prop->r = style.colour.r();
|
||||||
|
@ -940,7 +974,12 @@ auto Mass::setCustomStyle(const CustomStyle& style, UnsignedLong index, ArrayPro
|
||||||
style_prop->at<FloatProperty>("Rotation_25_EC2DFAD84AD0A6BD3FA841ACD52EDD6D")->value = style.rotation;
|
style_prop->at<FloatProperty>("Rotation_25_EC2DFAD84AD0A6BD3FA841ACD52EDD6D")->value = style.rotation;
|
||||||
style_prop->at<FloatProperty>("Scale_26_19DF0708409262183E1247B317137671")->value = style.scale;
|
style_prop->at<FloatProperty>("Scale_26_19DF0708409262183E1247B317137671")->value = style.scale;
|
||||||
|
|
||||||
return _mass->saveToFile();
|
if(!_mass->saveToFile()) {
|
||||||
|
_lastError = _mass->lastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mass::getDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array) {
|
void Mass::getDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array) {
|
||||||
|
@ -1162,17 +1201,20 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView<Weapon>
|
||||||
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
auto unit_data = _mass->at<GenericStructProperty>("UnitData");
|
||||||
if(!unit_data) {
|
if(!unit_data) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No unit data in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto prop = unit_data->at<ArrayProperty>(prop_name);
|
auto prop = unit_data->at<ArrayProperty>(prop_name);
|
||||||
if(!prop) {
|
if(!prop) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = std::string{prop_name} + " not found in " + _filename;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prop->items.size() != weapon_array.size()) {
|
if(prop->items.size() != weapon_array.size()) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "Weapon type array size mismatch.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1192,6 +1234,7 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView<Weapon>
|
||||||
auto parts_prop = weapon_prop->at<ArrayProperty>("Element_6_8E4617CC4B2C1F1490435599784EC6E0");
|
auto parts_prop = weapon_prop->at<ArrayProperty>("Element_6_8E4617CC4B2C1F1490435599784EC6E0");
|
||||||
if(parts_prop->items.size() != weapon.parts.size()) {
|
if(parts_prop->items.size() != weapon.parts.size()) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "Weapon parts array size mismatch.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,6 +1259,7 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView<Weapon>
|
||||||
|
|
||||||
if(part_accs->items.size() != part.accessories.size()) {
|
if(part_accs->items.size() != part.accessories.size()) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "Accessories array size mismatch.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1225,11 +1269,13 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView<Weapon>
|
||||||
auto custom_styles = weapon_prop->at<ArrayProperty>("Styles_10_8C3C82444B986AD7A99595AD4985912D");
|
auto custom_styles = weapon_prop->at<ArrayProperty>("Styles_10_8C3C82444B986AD7A99595AD4985912D");
|
||||||
if(!custom_styles) {
|
if(!custom_styles) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "No custom styles found for weapon.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(custom_styles->items.size() != weapon.customStyles.size()) {
|
if(custom_styles->items.size() != weapon.customStyles.size()) {
|
||||||
_state = State::Invalid;
|
_state = State::Invalid;
|
||||||
|
_lastError = "Custom styles array size mismatch.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,7 +1289,7 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView<Weapon>
|
||||||
#include "../Maps/DamageTypes.hpp"
|
#include "../Maps/DamageTypes.hpp"
|
||||||
#undef c
|
#undef c
|
||||||
default:
|
default:
|
||||||
Utility::Warning{} << "Invalid damage type enum value in writeWeaponType().";
|
Utility::Warning{} << "Unknown damage type enum value in writeWeaponType().";
|
||||||
}
|
}
|
||||||
weapon_prop->at<BoolProperty>("DualWield_20_B2EB2CEA4A6A233DC7575996B6DD1222")->value = weapon.dualWield;
|
weapon_prop->at<BoolProperty>("DualWield_20_B2EB2CEA4A6A233DC7575996B6DD1222")->value = weapon.dualWield;
|
||||||
switch(weapon.effectColourMode) {
|
switch(weapon.effectColourMode) {
|
||||||
|
@ -1252,6 +1298,8 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView<Weapon>
|
||||||
break;
|
break;
|
||||||
#include "../Maps/EffectColourModes.hpp"
|
#include "../Maps/EffectColourModes.hpp"
|
||||||
#undef c
|
#undef c
|
||||||
|
default:
|
||||||
|
Utility::Warning{} << "Unknown effect colour mode in writeWeaponType().";
|
||||||
}
|
}
|
||||||
auto effect_colour = weapon_prop->at<ColourStructProperty>("ColorEfx_26_D921B62946C493E487455A831F4520AC");
|
auto effect_colour = weapon_prop->at<ColourStructProperty>("ColorEfx_26_D921B62946C493E487455A831F4520AC");
|
||||||
effect_colour->r = weapon.effectColour.r();
|
effect_colour->r = weapon.effectColour.r();
|
||||||
|
@ -1260,7 +1308,12 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView<Weapon>
|
||||||
effect_colour->a = weapon.effectColour.a();
|
effect_colour->a = weapon.effectColour.a();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _mass->saveToFile();
|
if(!_mass->saveToFile()) {
|
||||||
|
_lastError = _mass->lastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mass::getTuningCategory(const char* big_node_prop_name, Int& big_node_id,
|
void Mass::getTuningCategory(const char* big_node_prop_name, Int& big_node_id,
|
||||||
|
|
|
@ -56,7 +56,7 @@ class Mass {
|
||||||
Mass(Mass&&) = default;
|
Mass(Mass&&) = default;
|
||||||
Mass& operator=(Mass&&) = default;
|
Mass& operator=(Mass&&) = default;
|
||||||
|
|
||||||
static auto lastError() -> std::string const&;
|
auto lastError() -> std::string const&;
|
||||||
|
|
||||||
static auto getNameFromFile(const std::string& path) -> Containers::Optional<std::string>;
|
static auto getNameFromFile(const std::string& path) -> Containers::Optional<std::string>;
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ class Mass {
|
||||||
|
|
||||||
Containers::Optional<UESaveFile> _mass;
|
Containers::Optional<UESaveFile> _mass;
|
||||||
|
|
||||||
static std::string _lastError;
|
std::string _lastError;
|
||||||
|
|
||||||
std::string _folder;
|
std::string _folder;
|
||||||
std::string _filename;
|
std::string _filename;
|
||||||
|
|
|
@ -168,6 +168,12 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void drawAlignedText(const char* text, Args... args) {
|
||||||
|
ImGui::AlignTextToFramePadding();
|
||||||
|
ImGui::Text(text, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
void openUri(const std::string& uri);
|
void openUri(const std::string& uri);
|
||||||
|
|
||||||
void checkGameState();
|
void checkGameState();
|
||||||
|
|
|
@ -42,10 +42,9 @@ void SaveTool::drawManager() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Current profile: %s (%s)",
|
||||||
ImGui::Text("Current profile: %s (%s)",
|
_currentProfile->companyName().c_str(),
|
||||||
_currentProfile->companyName().c_str(),
|
_currentProfile->type() == ProfileType::Demo ? "demo" : "full game");
|
||||||
_currentProfile->type() == ProfileType::Demo ? "demo" : "full game");
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button(ICON_FA_ARROW_LEFT " Back to profile manager")) {
|
if(ImGui::Button(ICON_FA_ARROW_LEFT " Back to profile manager")) {
|
||||||
_currentProfile = nullptr;
|
_currentProfile = nullptr;
|
||||||
|
|
|
@ -133,7 +133,7 @@ void SaveTool::drawMassViewer() {
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_currentMass->globalStyles().size() != 0 && ImGui::BeginTabItem("Global styles")) {
|
if(_currentMass->globalStyles().size() != 0 && ImGui::BeginTabItem("Global styles")) {
|
||||||
drawGlobalStyles();
|
drawGlobalStyles();
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
|
@ -218,8 +218,7 @@ void SaveTool::drawJointSliders() {
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Neck");
|
||||||
ImGui::TextUnformatted("Neck");
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
ImGui::SetNextItemWidth(-1.0f);
|
ImGui::SetNextItemWidth(-1.0f);
|
||||||
if(ImGui::SliderFloat("##NeckSlider", &_currentMass->jointSliders().neck, 0.0f, 1.0f)) {
|
if(ImGui::SliderFloat("##NeckSlider", &_currentMass->jointSliders().neck, 0.0f, 1.0f)) {
|
||||||
|
@ -228,8 +227,7 @@ void SaveTool::drawJointSliders() {
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Body");
|
||||||
ImGui::TextUnformatted("Body");
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
ImGui::SetNextItemWidth(-1.0f);
|
ImGui::SetNextItemWidth(-1.0f);
|
||||||
if(ImGui::SliderFloat("##BodySlider", &_currentMass->jointSliders().body, 0.0f, 1.0f)) {
|
if(ImGui::SliderFloat("##BodySlider", &_currentMass->jointSliders().body, 0.0f, 1.0f)) {
|
||||||
|
@ -238,8 +236,7 @@ void SaveTool::drawJointSliders() {
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Shoulders");
|
||||||
ImGui::TextUnformatted("Shoulders");
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
ImGui::SetNextItemWidth(-1.0f);
|
ImGui::SetNextItemWidth(-1.0f);
|
||||||
if(ImGui::SliderFloat("##ShouldersSlider", &_currentMass->jointSliders().shoulders, 0.0f, 1.0f)) {
|
if(ImGui::SliderFloat("##ShouldersSlider", &_currentMass->jointSliders().shoulders, 0.0f, 1.0f)) {
|
||||||
|
@ -248,8 +245,7 @@ void SaveTool::drawJointSliders() {
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Hips");
|
||||||
ImGui::TextUnformatted("Hips");
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
ImGui::SetNextItemWidth(-1.0f);
|
ImGui::SetNextItemWidth(-1.0f);
|
||||||
if(ImGui::SliderFloat("##HipsSlider", &_currentMass->jointSliders().hips, 0.0f, 1.0f)) {
|
if(ImGui::SliderFloat("##HipsSlider", &_currentMass->jointSliders().hips, 0.0f, 1.0f)) {
|
||||||
|
@ -258,8 +254,7 @@ void SaveTool::drawJointSliders() {
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Arms");
|
||||||
ImGui::TextUnformatted("Arms");
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
||||||
if(ImGui::BeginTable("##UpperLowerArmsLayoutTable", 2)) {
|
if(ImGui::BeginTable("##UpperLowerArmsLayoutTable", 2)) {
|
||||||
|
@ -283,8 +278,7 @@ void SaveTool::drawJointSliders() {
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Legs");
|
||||||
ImGui::TextUnformatted("Legs");
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
||||||
if(ImGui::BeginTable("##UpperLowerLegsLayoutTable", 2)) {
|
if(ImGui::BeginTable("##UpperLowerLegsLayoutTable", 2)) {
|
||||||
|
@ -319,7 +313,7 @@ void SaveTool::drawJointSliders() {
|
||||||
else {
|
else {
|
||||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||||
if(!_currentMass->writeJointSliders()) {
|
if(!_currentMass->writeJointSliders()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Error: " + Mass::lastError());
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
_jointsDirty = false;
|
_jointsDirty = false;
|
||||||
}
|
}
|
||||||
|
@ -337,8 +331,7 @@ void SaveTool::drawFrameStyles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Int i = 0; i < 4; i++) {
|
for(Int i = 0; i < 4; i++) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Slot %d:", i + 1);
|
||||||
ImGui::Text("Slot %d:", i + 1);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
@ -368,7 +361,7 @@ void SaveTool::drawFrameStyles() {
|
||||||
else {
|
else {
|
||||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||||
if(!_currentMass->writeFrameStyles()) {
|
if(!_currentMass->writeFrameStyles()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Error: " + Mass::lastError());
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
_stylesDirty = false;
|
_stylesDirty = false;
|
||||||
}
|
}
|
||||||
|
@ -399,7 +392,7 @@ void SaveTool::drawEyeColourPicker() {
|
||||||
else {
|
else {
|
||||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||||
if(!_currentMass->writeEyeFlareColour()) {
|
if(!_currentMass->writeEyeFlareColour()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Error writing the eye flare colour.");
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
_eyeFlareDirty = false;
|
_eyeFlareDirty = false;
|
||||||
}
|
}
|
||||||
|
@ -432,7 +425,9 @@ void SaveTool::drawCustomFrameStyles() {
|
||||||
_currentMass->getFrameCustomStyles();
|
_currentMass->getFrameCustomStyles();
|
||||||
break;
|
break;
|
||||||
case DCS_Save:
|
case DCS_Save:
|
||||||
_currentMass->writeFrameCustomStyle(i);
|
if(!_currentMass->writeFrameCustomStyle(i)) {
|
||||||
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -518,8 +513,7 @@ void SaveTool::drawArmour() {
|
||||||
ImGui::TextUnformatted("Styles:");
|
ImGui::TextUnformatted("Styles:");
|
||||||
|
|
||||||
for(Int j = 0; j < 4; j++) {
|
for(Int j = 0; j < 4; j++) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Slot %d:", j + 1);
|
||||||
ImGui::Text("Slot %d:", j + 1);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
@ -545,8 +539,7 @@ void SaveTool::drawArmour() {
|
||||||
|
|
||||||
ImGui::PushID("Decal");
|
ImGui::PushID("Decal");
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Showing/editing decal");
|
||||||
ImGui::TextUnformatted("Showing/editing decal");
|
|
||||||
for(UnsignedLong j = 0; j < part.decals.size(); j++) {
|
for(UnsignedLong j = 0; j < part.decals.size(); j++) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton(std::to_string(j + 1).c_str(), &_selectedArmourDecals[i], j);
|
ImGui::RadioButton(std::to_string(j + 1).c_str(), &_selectedArmourDecals[i], j);
|
||||||
|
@ -561,8 +554,7 @@ void SaveTool::drawArmour() {
|
||||||
|
|
||||||
ImGui::PushID("Accessory");
|
ImGui::PushID("Accessory");
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Showing/editing accessory");
|
||||||
ImGui::TextUnformatted("Showing/editing accessory");
|
|
||||||
for(UnsignedInt j = 0; j < part.accessories.size(); j++) {
|
for(UnsignedInt j = 0; j < part.accessories.size(); j++) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton(std::string{char(65 + j)}.c_str(), &_selectedArmourAccessories[i], j);
|
ImGui::RadioButton(std::string{char(65 + j)}.c_str(), &_selectedArmourAccessories[i], j);
|
||||||
|
@ -576,7 +568,9 @@ void SaveTool::drawArmour() {
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||||
_currentMass->writeArmourPart(part.slot);
|
if(!_currentMass->writeArmourPart(part.slot)) {
|
||||||
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,7 +601,9 @@ void SaveTool::drawCustomArmourStyles() {
|
||||||
_currentMass->getArmourCustomStyles();
|
_currentMass->getArmourCustomStyles();
|
||||||
break;
|
break;
|
||||||
case DCS_Save:
|
case DCS_Save:
|
||||||
_currentMass->writeArmourCustomStyle(i);
|
if(_currentMass->writeArmourCustomStyle(i)) {
|
||||||
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -713,28 +709,57 @@ void SaveTool::drawWeapons() {
|
||||||
|
|
||||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||||
if(_meleeDirty) {
|
if(_meleeDirty) {
|
||||||
_currentMass->writeMeleeWeapons();
|
if(!_currentMass->writeMeleeWeapons()) {
|
||||||
_meleeDirty = false;
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_meleeDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_shieldsDirty) {
|
if(_shieldsDirty) {
|
||||||
_currentMass->writeShields();
|
if(!_currentMass->writeShields()) {
|
||||||
_shieldsDirty = false;
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_shieldsDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_bShootersDirty) {
|
if(_bShootersDirty) {
|
||||||
_currentMass->writeBulletShooters();
|
if(!_currentMass->writeBulletShooters()) {
|
||||||
_bShootersDirty = false;
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_bShootersDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_eShootersDirty) {
|
if(_eShootersDirty) {
|
||||||
_currentMass->writeEnergyShooters();
|
if(_currentMass->writeEnergyShooters()) {
|
||||||
_eShootersDirty = false;
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_eShootersDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_bLaunchersDirty) {
|
if(_bLaunchersDirty) {
|
||||||
_currentMass->writeBulletLaunchers();
|
if(_currentMass->writeBulletLaunchers()) {
|
||||||
_bLaunchersDirty = false;
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_bLaunchersDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_eLaunchersDirty) {
|
if(_eLaunchersDirty) {
|
||||||
_currentMass->writeEnergyLaunchers();
|
if(_currentMass->writeEnergyLaunchers()) {
|
||||||
_eLaunchersDirty = false;
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_eLaunchersDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,32 +822,32 @@ void SaveTool::drawWeapons() {
|
||||||
switch(current_weapon->type) {
|
switch(current_weapon->type) {
|
||||||
case WeaponType::Melee:
|
case WeaponType::Melee:
|
||||||
if(!_currentMass->writeMeleeWeapons()) {
|
if(!_currentMass->writeMeleeWeapons()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Couldn't save melee weapons");
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WeaponType::Shield:
|
case WeaponType::Shield:
|
||||||
if(!_currentMass->writeShields()) {
|
if(!_currentMass->writeShields()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Couldn't save shields");
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WeaponType::BulletShooter:
|
case WeaponType::BulletShooter:
|
||||||
if(!_currentMass->writeBulletShooters()) {
|
if(!_currentMass->writeBulletShooters()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Couldn't save bullet shooters");
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WeaponType::EnergyShooter:
|
case WeaponType::EnergyShooter:
|
||||||
if(!_currentMass->writeEnergyShooters()) {
|
if(!_currentMass->writeEnergyShooters()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Couldn't save energy shooters");
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WeaponType::BulletLauncher:
|
case WeaponType::BulletLauncher:
|
||||||
if(!_currentMass->writeBulletLaunchers()) {
|
if(!_currentMass->writeBulletLaunchers()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Couldn't save bullet launchers");
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WeaponType::EnergyLauncher:
|
case WeaponType::EnergyLauncher:
|
||||||
if(!_currentMass->writeEnergyLaunchers()) {
|
if(!_currentMass->writeEnergyLaunchers()) {
|
||||||
_queue.addToast(Toast::Type::Error, "Couldn't save energy launchers");
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -866,13 +891,13 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
static const char* labels[] {
|
static const char* labels[] {
|
||||||
#define c(enumerator, strenum, name) name,
|
#define c(enumerator, strenum, name) name,
|
||||||
#include "../Maps/WeaponTypes.hpp"
|
#include "../Maps/WeaponTypes.hpp"
|
||||||
#undef c
|
#undef c
|
||||||
};
|
};
|
||||||
ImGui::Text("%s: %s", labels[UnsignedInt(weapon.type)], weapon.name.c_str());
|
|
||||||
|
drawAlignedText("%s: %s", labels[UnsignedInt(weapon.type)], weapon.name.c_str());
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
@ -889,23 +914,18 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Equipped:");
|
||||||
ImGui::TextUnformatted("Equipped:");
|
|
||||||
|
|
||||||
if(weapon.type != WeaponType::Shield) {
|
if(weapon.type != WeaponType::Shield) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Damage type:");
|
||||||
ImGui::TextUnformatted("Damage type:");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(weapon.type == WeaponType::Melee) {
|
if(weapon.type == WeaponType::Melee) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Dual-wield:");
|
||||||
ImGui::TextUnformatted("Dual-wield:");
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Custom effect mode:");
|
||||||
ImGui::TextUnformatted("Custom effect mode:");
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Custom effect colour:");
|
||||||
ImGui::TextUnformatted("Custom effect colour:");
|
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
@ -971,8 +991,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if(ImGui::CollapsingHeader("Weapon parts")) {
|
if(ImGui::CollapsingHeader("Weapon parts")) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Viewing/editing part:");
|
||||||
ImGui::TextUnformatted("Viewing/editing part:");
|
|
||||||
for(Int i = 0; UnsignedLong(i) < weapon.parts.size(); i++) {
|
for(Int i = 0; UnsignedLong(i) < weapon.parts.size(); i++) {
|
||||||
if(UnsignedLong(_selectedWeaponPart) >= weapon.parts.size()) {
|
if(UnsignedLong(_selectedWeaponPart) >= weapon.parts.size()) {
|
||||||
_selectedWeaponPart = 0;
|
_selectedWeaponPart = 0;
|
||||||
|
@ -989,8 +1008,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||||
ImGui::TextUnformatted("Styles:");
|
ImGui::TextUnformatted("Styles:");
|
||||||
|
|
||||||
for(Int i = 0; i < 4; i++) {
|
for(Int i = 0; i < 4; i++) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Slot %d:", i + 1);
|
||||||
ImGui::Text("Slot %d:", i + 1);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
@ -1014,8 +1032,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||||
|
|
||||||
ImGui::PushID("Decal");
|
ImGui::PushID("Decal");
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Showing/editing decal");
|
||||||
ImGui::TextUnformatted("Showing/editing decal");
|
|
||||||
for(UnsignedLong i = 0; i < part.decals.size(); i++) {
|
for(UnsignedLong i = 0; i < part.decals.size(); i++) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponDecal, i);
|
ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponDecal, i);
|
||||||
|
@ -1030,8 +1047,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||||
|
|
||||||
ImGui::PushID("Accessory");
|
ImGui::PushID("Accessory");
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Showing/editing accessory");
|
||||||
ImGui::TextUnformatted("Showing/editing accessory");
|
|
||||||
for(UnsignedLong i = 0; i < part.accessories.size(); i++) {
|
for(UnsignedLong i = 0; i < part.accessories.size(); i++) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton(std::string{char(65 + i)}.c_str(), &_selectedWeaponAccessory, i);
|
ImGui::RadioButton(std::string{char(65 + i)}.c_str(), &_selectedWeaponAccessory, i);
|
||||||
|
@ -1068,7 +1084,9 @@ void SaveTool::drawGlobalStyles() {
|
||||||
_currentMass->getGlobalStyles();
|
_currentMass->getGlobalStyles();
|
||||||
break;
|
break;
|
||||||
case DCS_Save:
|
case DCS_Save:
|
||||||
_currentMass->writeGlobalStyle(i);
|
if(!_currentMass->writeGlobalStyle(i)) {
|
||||||
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1218,14 +1236,10 @@ auto SaveTool::drawCustomStyle(CustomStyle& style) -> DCSResult {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Colour:");
|
||||||
ImGui::TextUnformatted("Colour:");
|
drawAlignedText("Metallic:");
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Gloss:");
|
||||||
ImGui::TextUnformatted("Metallic:");
|
drawAlignedText("Glow:");
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Gloss:");
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Glow:");
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -1247,25 +1261,18 @@ auto SaveTool::drawCustomStyle(CustomStyle& style) -> DCSResult {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Pattern:");
|
||||||
ImGui::TextUnformatted("Pattern:");
|
drawAlignedText("Opacity:");
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("X offset:");
|
||||||
ImGui::TextUnformatted("Opacity:");
|
drawAlignedText("Y offset:");
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Rotation:");
|
||||||
ImGui::TextUnformatted("X offset:");
|
drawAlignedText("Scale:");
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Y offset:");
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Rotation:");
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Scale:");
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("%i", style.patternId);
|
||||||
ImGui::Text("%i", style.patternId);
|
|
||||||
ImGui::PushItemWidth(-FLT_MIN);
|
ImGui::PushItemWidth(-FLT_MIN);
|
||||||
ImGui::SliderFloat("##SliderOpacity", &style.opacity, 0.0f, 1.0f);
|
ImGui::SliderFloat("##SliderOpacity", &style.opacity, 0.0f, 1.0f);
|
||||||
ImGui::SliderFloat("##SliderOffsetX", &style.offset.x(), 0.0f, 1.0f);
|
ImGui::SliderFloat("##SliderOffsetX", &style.offset.x(), 0.0f, 1.0f);
|
||||||
|
@ -1303,23 +1310,12 @@ void SaveTool::drawDecalEditor(Decal& decal) {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Colour:");
|
||||||
ImGui::TextUnformatted("Colour:");
|
drawAlignedText("Offset:");
|
||||||
|
drawAlignedText("Rotation:");
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Scale:");
|
||||||
ImGui::TextUnformatted("Offset:");
|
drawAlignedText("Flip X:");
|
||||||
|
drawAlignedText("Surface wrap:");
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Rotation:");
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Scale:");
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Flip X:");
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Surface wrap:");
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -1359,14 +1355,9 @@ void SaveTool::drawDecalEditor(Decal& decal) {
|
||||||
ImGui::TextUnformatted("Advanced settings. Touch these at your own risk.");
|
ImGui::TextUnformatted("Advanced settings. Touch these at your own risk.");
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Position:");
|
||||||
ImGui::TextUnformatted("Position:");
|
drawAlignedText("U axis:");
|
||||||
|
drawAlignedText("V axis:");
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("U axis:");
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("V axis:");
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -1425,18 +1416,12 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Styles:");
|
||||||
ImGui::TextUnformatted("Styles:");
|
drawAlignedText("Base position:");
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Position offset:");
|
||||||
ImGui::TextUnformatted("Base position:");
|
drawAlignedText("Base rotation:");
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Rotation offset:");
|
||||||
ImGui::TextUnformatted("Position offset:");
|
drawAlignedText("Scale:");
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Base rotation:");
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Rotation offset:");
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::TextUnformatted("Scale:");
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
|
@ -57,9 +57,8 @@ void SaveTool::drawAbout() {
|
||||||
ImGui::TextWrapped("This application, made for the M.A.S.S. Builder community by Guillaume Jacquemin (aka William JCM), "
|
ImGui::TextWrapped("This application, made for the M.A.S.S. Builder community by Guillaume Jacquemin (aka William JCM), "
|
||||||
"is a rewrite of the wxWidgets-powered M.A.S.S. Builder Save Tool (formerly known as wxMASSManager).");
|
"is a rewrite of the wxWidgets-powered M.A.S.S. Builder Save Tool (formerly known as wxMASSManager).");
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* repo = "https://williamjcm.ovh/git/williamjcm/MassBuilderSaveTool";
|
const char* repo = "https://williamjcm.ovh/git/williamjcm/MassBuilderSaveTool";
|
||||||
ImGui::Text(ICON_FA_GIT_ALT " %s", repo);
|
drawAlignedText(ICON_FA_GIT_ALT " %s", repo);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(repo);
|
ImGui::SetClipboardText(repo);
|
||||||
|
@ -90,9 +89,8 @@ void SaveTool::drawAbout() {
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("Corrade", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("Corrade", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::Text("Version used: %s", CORRADE_VERSION_STRING);
|
ImGui::Text("Version used: %s", CORRADE_VERSION_STRING);
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* corrade_website = "https://magnum.graphics/corrade";
|
const char* corrade_website = "https://magnum.graphics/corrade";
|
||||||
ImGui::Text(ICON_FA_GLOBE " %s", corrade_website);
|
drawAlignedText(ICON_FA_GLOBE " %s", corrade_website);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(corrade_website);
|
ImGui::SetClipboardText(corrade_website);
|
||||||
|
@ -119,9 +117,8 @@ void SaveTool::drawAbout() {
|
||||||
ImGui::TextUnformatted("Versions used:");
|
ImGui::TextUnformatted("Versions used:");
|
||||||
ImGui::BulletText("Magnum: %s", MAGNUM_VERSION_STRING);
|
ImGui::BulletText("Magnum: %s", MAGNUM_VERSION_STRING);
|
||||||
ImGui::BulletText("Integration: %s", MAGNUMINTEGRATION_VERSION_STRING);
|
ImGui::BulletText("Integration: %s", MAGNUMINTEGRATION_VERSION_STRING);
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* magnum_website = "https://magnum.graphics";
|
const char* magnum_website = "https://magnum.graphics";
|
||||||
ImGui::Text(ICON_FA_GLOBE " %s", magnum_website);
|
drawAlignedText(ICON_FA_GLOBE " %s", magnum_website);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(magnum_website);
|
ImGui::SetClipboardText(magnum_website);
|
||||||
|
@ -146,9 +143,8 @@ void SaveTool::drawAbout() {
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("Dear ImGui", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("Dear ImGui", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::Text("Version used: %s", IMGUI_VERSION);
|
ImGui::Text("Version used: %s", IMGUI_VERSION);
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* imgui_repo = "https://github.com/ocornut/imgui";
|
const char* imgui_repo = "https://github.com/ocornut/imgui";
|
||||||
ImGui::Text(ICON_FA_GITHUB " %s", imgui_repo);
|
drawAlignedText(ICON_FA_GITHUB " %s", imgui_repo);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(imgui_repo);
|
ImGui::SetClipboardText(imgui_repo);
|
||||||
|
@ -173,9 +169,8 @@ void SaveTool::drawAbout() {
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("Simple DirectMedia Layer (SDL) 2", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("Simple DirectMedia Layer (SDL) 2", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::Text("Version used: %i.%i.%i", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL);
|
ImGui::Text("Version used: %i.%i.%i", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL);
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* sdl_website = "https://www.libsdl.org/";
|
const char* sdl_website = "https://www.libsdl.org/";
|
||||||
ImGui::Text(ICON_FA_GLOBE " %s", sdl_website);
|
drawAlignedText(ICON_FA_GLOBE " %s", sdl_website);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(sdl_website);
|
ImGui::SetClipboardText(sdl_website);
|
||||||
|
@ -200,9 +195,8 @@ void SaveTool::drawAbout() {
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("libzip", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("libzip", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::Text("Version used: %s", LIBZIP_VERSION);
|
ImGui::Text("Version used: %s", LIBZIP_VERSION);
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* libzip_website = "https://libzip.org/";
|
const char* libzip_website = "https://libzip.org/";
|
||||||
ImGui::Text(ICON_FA_GLOBE " %s", libzip_website);
|
drawAlignedText(ICON_FA_GLOBE " %s", libzip_website);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(libzip_website);
|
ImGui::SetClipboardText(libzip_website);
|
||||||
|
@ -226,9 +220,8 @@ void SaveTool::drawAbout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("Entropia File System Watcher (efsw)", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("Entropia File System Watcher (efsw)", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* efsw_repo = "https://github.com/SpartanJ/efsw";
|
const char* efsw_repo = "https://github.com/SpartanJ/efsw";
|
||||||
ImGui::Text(ICON_FA_GITHUB " %s", efsw_repo);
|
drawAlignedText(ICON_FA_GITHUB " %s", efsw_repo);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(efsw_repo);
|
ImGui::SetClipboardText(efsw_repo);
|
||||||
|
@ -252,9 +245,8 @@ void SaveTool::drawAbout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("C++ Requests (cpr)", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("C++ Requests (cpr)", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* cpr_website = "https://whoshuu.github.io/cpr/";
|
const char* cpr_website = "https://whoshuu.github.io/cpr/";
|
||||||
ImGui::Text(ICON_FA_GLOBE " %s", cpr_website);
|
drawAlignedText(ICON_FA_GLOBE " %s", cpr_website);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(cpr_website);
|
ImGui::SetClipboardText(cpr_website);
|
||||||
|
@ -278,9 +270,8 @@ void SaveTool::drawAbout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("JSON for Modern C++ (aka json.hpp)", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("JSON for Modern C++ (aka json.hpp)", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* json_website = "https://json.nlohmann.me/";
|
const char* json_website = "https://json.nlohmann.me/";
|
||||||
ImGui::Text(ICON_FA_GLOBE " %s", json_website);
|
drawAlignedText(ICON_FA_GLOBE " %s", json_website);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(json_website);
|
ImGui::SetClipboardText(json_website);
|
||||||
|
@ -305,9 +296,8 @@ void SaveTool::drawAbout() {
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("Font Awesome", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("Font Awesome", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::TextUnformatted("Version used: 5.15.3");
|
ImGui::TextUnformatted("Version used: 5.15.3");
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* fa_website = "https://fontawesome.com/";
|
const char* fa_website = "https://fontawesome.com/";
|
||||||
ImGui::Text(ICON_FA_GLOBE " %s", fa_website);
|
drawAlignedText(ICON_FA_GLOBE " %s", fa_website);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(fa_website);
|
ImGui::SetClipboardText(fa_website);
|
||||||
|
@ -323,9 +313,8 @@ void SaveTool::drawAbout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::TreeNodeEx("IconFontCppHeaders", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
if(ImGui::TreeNodeEx("IconFontCppHeaders", ImGuiTreeNodeFlags_SpanAvailWidth)) {
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
const char* icon_repo = "https://github.com/juliettef/IconFontCppHeaders";
|
const char* icon_repo = "https://github.com/juliettef/IconFontCppHeaders";
|
||||||
ImGui::Text(ICON_FA_GITHUB " %s", icon_repo);
|
drawAlignedText(ICON_FA_GITHUB " %s", icon_repo);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Copy to clipboard")) {
|
if(ImGui::Button("Copy to clipboard")) {
|
||||||
ImGui::SetClipboardText(icon_repo);
|
ImGui::SetClipboardText(icon_repo);
|
||||||
|
|
|
@ -55,8 +55,7 @@ void SaveTool::drawMainMenu() {
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if(ImGui::BeginMenu(ICON_FA_COG " Settings")) {
|
if(ImGui::BeginMenu(ICON_FA_COG " Settings")) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Frame limiter:");
|
||||||
ImGui::TextUnformatted("Frame limiter:");
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
static UnsignedByte selection = static_cast<UnsignedByte>(_framelimit);
|
static UnsignedByte selection = static_cast<UnsignedByte>(_framelimit);
|
||||||
|
@ -118,8 +117,7 @@ void SaveTool::drawMainMenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_updateAvailable) {
|
if(_updateAvailable) {
|
||||||
ImGui::AlignTextToFramePadding();
|
drawAlignedText("Version %s is available.", _latestVersion.c_str());
|
||||||
ImGui::Text("Version %s is available.", _latestVersion.c_str());
|
|
||||||
if(ImGui::Button(ICON_FA_FILE_SIGNATURE " Release notes")) {
|
if(ImGui::Button(ICON_FA_FILE_SIGNATURE " Release notes")) {
|
||||||
openUri(_releaseLink);
|
openUri(_releaseLink);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue