Split up the GUI a little

Panels now have their own files for hopefully better readability.
This commit is contained in:
prisixia 2023-04-27 21:20:23 +02:00
parent b139b9e37a
commit 3bf7f58e4e
Signed by: prisixia
GPG Key ID: CB939A148C9B4125
7 changed files with 1085 additions and 937 deletions

View File

@ -12,6 +12,8 @@ endif()
set(SOURCE_LIST
"src/speciesgen.cpp"
"src/error.cpp"
"src/gui/main_panel.cpp"
"src/gui/stages_panel.cpp"
"src/starbound/metadata.cpp"
"src/starbound/item.cpp"
"src/starbound/patch.cpp"

92
include/gui/main_panel.h Normal file
View File

@ -0,0 +1,92 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
speciesgen is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
/////////////////////////////////////////////////////////////////////////////
// Name: main_panel.cpp
// Purpose: Main panel, part of the GUI
// Author: prisixia
// Created: 2023-04-27
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_PANEL_MAIN_H
#define SPECIESGEN_PANEL_MAIN_H
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif // WX_PRECOMP
#if wxUSE_CLIPBOARD
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#endif // wxUSE_CLIPBOARD
#include <wx/dir.h>
#include <wx/stdpaths.h>
#include "error.h"
namespace SpeciesGen {
enum {
MOD_GENERATE,
DIR_CHOOSE
};
class MainPanel : public wxPanel, public ErrorHandler {
public:
MainPanel(wxWindow *, int, int, int, int, const std::string);
#if wxUSE_CLIPBOARD
// bool HasSelection() const;
// void DoPasteFromClipboard();
// void DoCopyToClipboard();
#endif // wxUSE_CLIPBOARD
#if wxUSE_DIRDLG
void DoChooseDir(wxCommandEvent &WXUNUSED(event));
#endif // wxUSE_DIRDLG
virtual size_t CheckForErrors();
wxTextCtrl *m_author;
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_modDestination;
wxButton *m_generate;
private:
#if wxUSE_CLIPBOARD
// wxTextCtrl *GetFocusedText() const;
#endif // wxUSE_CLIPBOARD
wxButton *m_browse;
wxStaticText *m_modDestinationText;
wxStaticText *m_authorText;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxDECLARE_EVENT_TABLE();
};
} // namespace SpeciesGen
#endif // SPECIESGEN_PANEL_MAIN_H

142
include/gui/stages_panel.h Normal file
View File

@ -0,0 +1,142 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
speciesgen is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
/////////////////////////////////////////////////////////////////////////////
// Name: stages_panel.cpp
// Purpose: Stages panel, part of the GUI
// Author: prisixia
// Created: 2023-04-27
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_PANEL_STAGES_H
#define SPECIESGEN_PANEL_STAGES_H
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif // WX_PRECOMP
#if wxUSE_CLIPBOARD
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#endif // wxUSE_CLIPBOARD
#include "error.h"
#include "starpounds/types.h"
#include "starpounds/weightstage.h"
namespace SpeciesGen {
enum {
STAGES_ADD,
STAGES_REMOVE,
STAGES_SUB_ADD,
STAGES_SUB_REMOVE,
STAGES_SET_DEFAULT,
STAGES_ID,
STAGES_LIST,
STAGES_SUB_LIST,
STAGES_FRAMES,
STAGES_TYPE_CHEST,
STAGES_TYPE_LEG,
STAGES_TEXT_NAME,
STAGES_TEXT_FRIENDLYNAME,
STAGES_TEXT_DESCRIPTION_CHEST,
STAGES_TEXT_DESCRIPTION_LEG
};
class StagesPanel : public wxPanel, public ErrorHandler {
public:
StagesPanel(wxWindow *, int, int, int, int, const std::string);
void DoAddWeightStage(Starpounds::WeightStage = Starpounds::WeightStage(
"new", "New", "Chest description.",
Starpounds::Types::Chests::Belly,
"Leg description.", Starpounds::Types::Legs::Legs,
false, true, {}));
void DoRemoveWeightStage();
void DoAddWeightStageSub(
Starpounds::WeightStageSub =
Starpounds::WeightStageSub("new", "New", "Chest description.",
Starpounds::Types::Chests::Belly));
void DoRemoveWeightStageSub();
void DoClickCheckboxID(const bool);
std::vector<Starpounds::WeightStage> GetWeightStages() const;
virtual size_t CheckForErrors();
void ClearForm();
wxButton *m_add;
wxButton *m_remove;
wxButton *m_subAdd;
wxButton *m_subRemove;
wxCheckBox *m_id;
private:
void EnableForm(const bool, const bool = true, const bool = false);
void PopulateForm(const Starpounds::WeightStage &);
void PopulateForm(const Starpounds::WeightStageSub &);
void DoResetWeightStages();
std::string GetInternalNameReplacement(const Starpounds::WeightStage &);
std::string GetInternalNameReplacement(const Starpounds::WeightStageSub &);
bool HasDuplicateInternalName(const std::string &, const bool);
bool HasDuplicateNoID();
void OnClickWeightStage(wxCommandEvent &);
void OnClickWeightStageSub(wxCommandEvent &);
void OnClickCheckboxFrames(wxCommandEvent &);
void OnSelectComboBoxChest(wxCommandEvent &);
void OnSelectComboBoxLeg(wxCommandEvent &);
void OnInternalNameEdit(wxCommandEvent &WXUNUSED(event));
void OnFriendlyNameEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionChestEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionLegEdit(wxCommandEvent &WXUNUSED(event));
void OnResetWeightStages(wxCommandEvent &WXUNUSED(event));
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_descriptionChest;
wxTextCtrl *m_descriptionLeg;
wxChoice *m_typeChest;
wxChoice *m_typeLeg;
wxCheckBox *m_frames;
wxListBox *m_stagesList;
wxListBox *m_subStagesList;
wxButton *m_default;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxStaticText *m_descriptionChestText;
wxStaticText *m_descriptionLegText;
wxStaticText *m_typeChestText;
wxStaticText *m_typeLegText;
wxStaticText *m_stagesListText;
wxStaticText *m_subStagesListText;
std::vector<Starpounds::WeightStage> m_stages;
wxDECLARE_EVENT_TABLE();
};
} // namespace SpeciesGen
#endif // SPECIESGEN_PANEL_STAGES_H

View File

@ -49,15 +49,15 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
#define wxUSE_CLIPBOARD 0
#endif // wxUSE_DRAG_AND_DROP
#include <wx/dir.h>
#include <wx/notebook.h>
#include <wx/propgrid/propgrid.h>
#include <wx/stdpaths.h>
#include <filesystem>
#include <optional>
#include "error.h"
#include "gui/main_panel.h"
#include "gui/stages_panel.h"
#include "starbound/frames.h"
#include "starbound/item.h"
#include "starbound/metadata.h"
@ -116,26 +116,6 @@ enum {
// TEXT_CLIPBOARD_PASTE,
// TEXT_CLIPBOARD_VETO,
MOD_GENERATE,
DIR_CHOOSE,
STAGES_ADD,
STAGES_REMOVE,
STAGES_SUB_ADD,
STAGES_SUB_REMOVE,
STAGES_SET_DEFAULT,
STAGES_ID,
STAGES_LIST,
STAGES_SUB_LIST,
STAGES_FRAMES,
STAGES_TYPE_CHEST,
STAGES_TYPE_LEG,
STAGES_TEXT_NAME,
STAGES_TEXT_FRIENDLYNAME,
STAGES_TEXT_DESCRIPTION_CHEST,
STAGES_TEXT_DESCRIPTION_LEG,
CONFIG_IMPORT = (1 << 0),
CONFIG_IMPORT_APPEND = (1 << 1),
CONFIG_EXPORT = (1 << 2)
@ -146,115 +126,6 @@ public:
bool OnInit() wxOVERRIDE;
};
class MainPanel : public wxPanel, public ErrorHandler {
public:
MainPanel(wxWindow *, int, int, int, int, const std::string);
#if wxUSE_CLIPBOARD
// bool HasSelection() const;
// void DoPasteFromClipboard();
// void DoCopyToClipboard();
#endif // wxUSE_CLIPBOARD
#if wxUSE_DIRDLG
void DoChooseDir(wxCommandEvent &WXUNUSED(event));
#endif // wxUSE_DIRDLG
virtual size_t CheckForErrors();
wxTextCtrl *m_author;
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_modDestination;
wxButton *m_generate;
private:
#if wxUSE_CLIPBOARD
// wxTextCtrl *GetFocusedText() const;
#endif // wxUSE_CLIPBOARD
wxButton *m_browse;
wxStaticText *m_modDestinationText;
wxStaticText *m_authorText;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxDECLARE_EVENT_TABLE();
};
class StagesPanel : public wxPanel, public ErrorHandler {
public:
StagesPanel(wxWindow *, int, int, int, int, const std::string);
void DoAddWeightStage(Starpounds::WeightStage = Starpounds::WeightStage(
"new", "New", "Chest description.",
Starpounds::Types::Chests::Belly,
"Leg description.", Starpounds::Types::Legs::Legs,
false, true, {}));
void DoRemoveWeightStage();
void DoAddWeightStageSub(
Starpounds::WeightStageSub =
Starpounds::WeightStageSub("new", "New", "Chest description.",
Starpounds::Types::Chests::Belly));
void DoRemoveWeightStageSub();
void DoClickCheckboxID(const bool);
std::vector<Starpounds::WeightStage> GetWeightStages() const;
virtual size_t CheckForErrors();
void ClearForm();
wxButton *m_add;
wxButton *m_remove;
wxButton *m_subAdd;
wxButton *m_subRemove;
wxCheckBox *m_id;
private:
void EnableForm(const bool, const bool = true, const bool = false);
void PopulateForm(const Starpounds::WeightStage &);
void PopulateForm(const Starpounds::WeightStageSub &);
void DoResetWeightStages();
std::string GetInternalNameReplacement(const Starpounds::WeightStage &);
std::string GetInternalNameReplacement(const Starpounds::WeightStageSub &);
bool HasDuplicateInternalName(const std::string &, const bool);
bool HasDuplicateNoID();
void OnClickWeightStage(wxCommandEvent &);
void OnClickWeightStageSub(wxCommandEvent &);
void OnClickCheckboxFrames(wxCommandEvent &);
void OnSelectComboBoxChest(wxCommandEvent &);
void OnSelectComboBoxLeg(wxCommandEvent &);
void OnInternalNameEdit(wxCommandEvent &WXUNUSED(event));
void OnFriendlyNameEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionChestEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionLegEdit(wxCommandEvent &WXUNUSED(event));
void OnResetWeightStages(wxCommandEvent &WXUNUSED(event));
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_descriptionChest;
wxTextCtrl *m_descriptionLeg;
wxChoice *m_typeChest;
wxChoice *m_typeLeg;
wxCheckBox *m_frames;
wxListBox *m_stagesList;
wxListBox *m_subStagesList;
wxButton *m_default;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxStaticText *m_descriptionChestText;
wxStaticText *m_descriptionLegText;
wxStaticText *m_typeChestText;
wxStaticText *m_typeLegText;
wxStaticText *m_stagesListText;
wxStaticText *m_subStagesListText;
std::vector<Starpounds::WeightStage> m_stages;
wxDECLARE_EVENT_TABLE();
};
/*
class SpritesPanel: public wxPanel, public ErrorHandler
{
@ -307,7 +178,6 @@ private:
wxDECLARE_EVENT_TABLE();
};
} // namespace SpeciesGen
#endif // SPECIESGEN_H

203
src/gui/main_panel.cpp Normal file
View File

@ -0,0 +1,203 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
speciesgen is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
#include "gui/main_panel.h"
namespace SpeciesGen {
wxBEGIN_EVENT_TABLE(MainPanel, wxPanel)
#if wxUSE_DIRDLG
EVT_BUTTON(DIR_CHOOSE, MainPanel::DoChooseDir)
#endif // wxUSE_DIRDLG
wxEND_EVENT_TABLE()
MainPanel::MainPanel(wxWindow *window, int x, int y, int w, int h,
const std::string handlerName)
: wxPanel(window, wxID_ANY, wxPoint(x, y), wxSize(w, h)),
ErrorHandler(handlerName) {
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *row = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
m_authorText = new wxStaticText(this, wxID_ANY, "Author");
m_nameText = new wxStaticText(this, wxID_ANY, "Species (Internal)");
m_friendlyNameText = new wxStaticText(this, wxID_ANY, "Species (In-Game)");
m_modDestinationText = new wxStaticText(this, wxID_ANY, "Output directory");
m_author = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_author->SetHint("Author's name");
m_author->SetMaxLength(128);
#ifdef _WIN32
m_author->SetValue(wxGetUserName());
#else
m_author->SetValue(getenv("USER"));
#endif // _WIN32
m_name = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_name->SetHint("Internal species name");
m_name->SetMaxLength(128);
m_friendlyName =
new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_friendlyName->SetHint("In-Game species name");
m_friendlyName->SetMaxLength(128);
#ifdef _WIN32
m_modDestination = new wxTextCtrl(
this, wxID_ANY,
"C:\\Program Files (x86)\\Steam\\steamapps\\common\\Starbound\\mods",
wxDefaultPosition, wxSize(400, wxDefaultSize.GetHeight()));
#else
m_modDestination = new wxTextCtrl(
this, wxID_ANY,
wxString::Format("%s/.steam/steam/steamapps/common/Starbound/mods",
wxGetUserHome(wxGetUserName())));
#endif // _WIN32
m_generate = new wxButton(this, MOD_GENERATE, "Generate mod",
wxDefaultPosition, wxSize(280, 80));
column1->Add(m_authorText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_author, 0, wxEXPAND | wxALL, 10);
column1->Add(m_nameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_name, 0, wxEXPAND | wxALL, 10);
column1->Add(m_friendlyNameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_friendlyName, 0, wxEXPAND | wxALL, 10);
column2->Add(m_modDestinationText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column2->Add(m_modDestination, 0, wxEXPAND | wxLEFT | wxUP, 10);
#if wxUSE_DIRDLG
m_browse = new wxButton(this, DIR_CHOOSE, "Browse...");
column2->Add(m_browse, 0, wxALL, 10);
#endif // wxUSE_DIRDLG
column2->AddSpacer(20);
column2->Add(m_generate, 0, wxALIGN_CENTER, 0);
row->Add(column1, 0, wxALL | wxALIGN_CENTER, 10);
row->Add(column2, 0, wxALL | wxALIGN_CENTER, 10);
topSizer->Add(row, 0, wxALL | wxALIGN_CENTER, 10);
SetSizer(topSizer);
}
#if wxUSE_CLIPBOARD
/*
wxTextCtrl *MainPanel::GetFocusedText() const
{
wxWindow *win = FindFocus();
wxTextCtrl *text = win ? wxDynamicCast(win, wxTextCtrl) : NULL;
return text;
}
bool MainPanel::HasSelection() const
{
long from;
long to;
GetFocusedText()->GetSelection(&from, &to);
return from != to;
}
void MainPanel::DoPasteFromClipboard()
{
// On X11, we want to get the data from the primary selection instead
// of the normal clipboard (which isn't normal under X11 at all). This
// call has no effect under MSW.
wxTheClipboard->UsePrimarySelection();
if (!wxTheClipboard->Open())
return;
wxTextDataObject data;
if (wxTheClipboard->IsSupported(data.GetFormat())) {
if (wxTheClipboard->GetData(data))
GetFocusedText()->AppendText(data.GetText());
}
wxTheClipboard->Close();
}
void MainPanel::DoCopyToClipboard()
{
// On X11, we want to get the data from the primary selection instead
// of the normal clipboard (which isn't normal under X11 at all). This
// call has no effect under MSW.
wxTheClipboard->UsePrimarySelection();
wxString text(GetFocusedText()->GetStringSelection());
if (text.IsEmpty())
return;
if (!wxTheClipboard->Open())
return;
wxTextDataObject *data = new wxTextDataObject(text);
wxTheClipboard->SetData(data);
wxTheClipboard->Close();
}
*/
#endif // wxUSE_CLIPBOARD
#if wxUSE_DIRDLG
void MainPanel::DoChooseDir(wxCommandEvent &WXUNUSED(event)) {
wxString dirHome =
wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Desktop);
wxDirDialog dialog(this, "Select a directory", dirHome,
wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
if (dialog.ShowModal() == wxID_OK)
m_modDestination->SetValue(dialog.GetPath());
}
#endif // wxUSE_DIRDLG
size_t MainPanel::CheckForErrors() {
size_t errorCount = 0;
if (m_author->IsEmpty()) {
m_errorLog.push_back("Empty author field, please fill it out.");
errorCount++;
}
if (m_name->IsEmpty()) {
m_errorLog.push_back("Empty internal name field, please fill it out.");
errorCount++;
}
if (m_friendlyName->IsEmpty()) {
m_errorLog.push_back("Empty in-game name field, please fill it out.");
errorCount++;
}
if (m_modDestination->IsEmpty()) {
m_errorLog.push_back("Empty path field, please fill it out.");
errorCount++;
}
if (!wxDir::Exists(m_modDestination->GetValue())) {
m_errorLog.push_back(
"Invalid directory, please check your entered path.");
errorCount++;
}
return errorCount;
}
} // namespace SpeciesGen

644
src/gui/stages_panel.cpp Normal file
View File

@ -0,0 +1,644 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
speciesgen is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
#include "gui/stages_panel.h"
namespace SpeciesGen {
wxBEGIN_EVENT_TABLE(StagesPanel, wxPanel)
EVT_LISTBOX(STAGES_LIST, StagesPanel::OnClickWeightStage)
EVT_LISTBOX(STAGES_SUB_LIST, StagesPanel::OnClickWeightStageSub)
EVT_CHECKBOX(STAGES_FRAMES, StagesPanel::OnClickCheckboxFrames)
EVT_COMBOBOX(STAGES_TYPE_CHEST, StagesPanel::OnSelectComboBoxChest)
EVT_COMBOBOX(STAGES_TYPE_LEG, StagesPanel::OnSelectComboBoxLeg)
EVT_TEXT(STAGES_TEXT_NAME, StagesPanel::OnInternalNameEdit)
EVT_TEXT(STAGES_TEXT_FRIENDLYNAME, StagesPanel::OnFriendlyNameEdit)
EVT_TEXT(STAGES_TEXT_DESCRIPTION_CHEST, StagesPanel::OnDescriptionChestEdit)
EVT_TEXT(STAGES_TEXT_DESCRIPTION_LEG, StagesPanel::OnDescriptionLegEdit)
EVT_BUTTON(STAGES_SET_DEFAULT, StagesPanel::OnResetWeightStages)
wxEND_EVENT_TABLE()
StagesPanel::StagesPanel(wxWindow *window, int x, int y, int w, int h,
const std::string handlerName)
: wxPanel(window, wxID_ANY, wxPoint(x, y), wxSize(w, h)),
ErrorHandler(handlerName) {
wxBoxSizer *row1 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *row2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column3 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column4 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
wxArrayString choicesChest;
wxArrayString choicesLeg;
constexpr auto enumsChest =
magic_enum::enum_values<Starpounds::Types::Chests>();
constexpr auto enumsLeg =
magic_enum::enum_values<Starpounds::Types::Legs>();
for (auto enumChest : enumsChest)
choicesChest.Add(
static_cast<std::string>(magic_enum::enum_name(enumChest)));
for (auto enumLeg : enumsLeg)
choicesLeg.Add(
static_cast<std::string>(magic_enum::enum_name(enumLeg)));
m_add = new wxButton(this, STAGES_ADD, "Add");
m_remove = new wxButton(this, STAGES_REMOVE, "Remove");
m_default = new wxButton(this, STAGES_SET_DEFAULT, "Restore default");
m_subAdd = new wxButton(this, STAGES_SUB_ADD, "Add sub-stage");
m_subRemove = new wxButton(this, STAGES_SUB_ADD, "Remove sub-stage");
m_subAdd->Disable();
m_subRemove->Disable();
m_nameText = new wxStaticText(this, wxID_ANY, "Internal name");
m_friendlyNameText = new wxStaticText(this, wxID_ANY, "In-Game name");
m_descriptionChestText =
new wxStaticText(this, wxID_ANY, "Chest description");
m_descriptionLegText = new wxStaticText(this, wxID_ANY, "Leg description");
m_typeChestText = new wxStaticText(this, wxID_ANY, "Chest type");
m_typeLegText = new wxStaticText(this, wxID_ANY, "Leg type");
m_stagesListText = new wxStaticText(this, wxID_ANY, "Stages");
m_subStagesListText = new wxStaticText(this, wxID_ANY, "Sub-Stages");
m_frames = new wxCheckBox(this, STAGES_FRAMES, "Has frames");
m_id = new wxCheckBox(this, STAGES_ID, "Has ID");
m_name = new wxTextCtrl(this, STAGES_TEXT_NAME);
m_friendlyName = new wxTextCtrl(this, STAGES_TEXT_FRIENDLYNAME);
m_descriptionChest = new wxTextCtrl(this, STAGES_TEXT_DESCRIPTION_CHEST,
wxEmptyString, wxDefaultPosition,
wxSize(240, wxDefaultSize.GetHeight()));
m_descriptionLeg = new wxTextCtrl(this, STAGES_TEXT_DESCRIPTION_LEG,
wxEmptyString, wxDefaultPosition,
wxSize(240, wxDefaultSize.GetHeight()));
m_stagesList =
new wxListBox(this, STAGES_LIST, wxDefaultPosition, wxSize(105, 220));
m_subStagesList = new wxListBox(this, STAGES_SUB_LIST, wxDefaultPosition,
wxSize(105, 220));
m_typeChest = new wxComboBox(
this, STAGES_TYPE_CHEST, choicesChest.Item(2), wxDefaultPosition,
wxSize(74, wxDefaultSize.GetHeight()), choicesChest, wxCB_READONLY);
m_typeLeg = new wxComboBox(
this, STAGES_TYPE_LEG, choicesLeg.Item(0), wxDefaultPosition,
wxSize(74, wxDefaultSize.GetHeight()), choicesLeg, wxCB_READONLY);
row1->Add(m_add, 0, wxALL, 10);
row1->Add(m_remove, 0, wxALL, 10);
row1->Add(m_default, 0, wxALL, 10);
row1->Add(m_subAdd, 0, wxALL, 10);
row1->Add(m_subRemove, 0, wxALL, 10);
column1->Add(m_stagesListText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_stagesList, 0, wxALL, 10);
column2->Add(m_subStagesListText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column2->Add(m_subStagesList, 0, wxALL, 10);
column3->Add(m_nameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_name, 0, wxEXPAND | wxALL, 10);
column3->Add(m_friendlyNameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_friendlyName, 0, wxEXPAND | wxALL, 10);
column3->Add(m_typeChestText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_typeChest, 0, wxALL, 10);
column4->Add(m_descriptionChestText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_descriptionChest, 0, wxEXPAND | wxALL, 10);
column4->Add(m_descriptionLegText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_descriptionLeg, 0, wxEXPAND | wxALL, 10);
column4->Add(m_typeLegText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_typeLeg, 0, wxALL, 10);
column3->Add(m_frames, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_id, 0, wxEXPAND | wxLEFT | wxUP, 10);
row2->Add(column1, 0, 0, 0);
row2->Add(column2, 0, 0, 0);
row2->Add(column3, 0, 0, 0);
row2->Add(column4, 0, 0, 0);
topSizer->Add(row1, 0, wxLEFT | wxUP, 10);
topSizer->Add(row2, 0, wxALL | wxEXPAND, 10);
EnableForm(false);
DoResetWeightStages();
SetSizer(topSizer);
}
void StagesPanel::DoAddWeightStage(Starpounds::WeightStage stage) {
stage.SetName(GetInternalNameReplacement(stage));
m_stages.push_back(stage);
wxArrayString name;
name.Add(stage.GetName());
m_stagesList->InsertItems(name, m_stagesList->GetCount());
}
void StagesPanel::DoRemoveWeightStage() {
if (m_stagesList->GetCount() == 0)
return;
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
m_stagesList->Delete(selection);
m_subStagesList->Clear();
m_subAdd->Disable();
m_subRemove->Disable();
m_stages.erase(m_stages.begin() + selection);
EnableForm(false);
ClearForm();
}
void StagesPanel::DoAddWeightStageSub(Starpounds::WeightStageSub sub) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
sub.SetName(GetInternalNameReplacement(sub));
subs.push_back(sub);
stage.SetSubs(subs);
wxArrayString name;
name.Add(sub.GetName());
m_subStagesList->InsertItems(name, m_subStagesList->GetCount());
}
void StagesPanel::DoRemoveWeightStageSub() {
if (m_subStagesList->GetCount() == 0)
return;
int selection = m_subStagesList->GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
if (stageSelection == wxNOT_FOUND)
stageSelection = 0;
Starpounds::WeightStage &stage = m_stages.at(stageSelection);
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
m_subStagesList->Delete(selection);
subs.erase(subs.begin() + selection);
stage.SetSubs(subs);
EnableForm(false);
ClearForm();
}
void StagesPanel::DoClickCheckboxID(const bool isChecked) {
Starpounds::WeightStage &stage = m_stages.at(m_stagesList->GetSelection());
stage.SetID(isChecked);
EnableForm(true, isChecked);
}
std::vector<Starpounds::WeightStage> StagesPanel::GetWeightStages() const {
return m_stages;
}
size_t StagesPanel::CheckForErrors() {
size_t errorCount = 0;
if (m_stagesList->GetCount() == 0) {
m_errorLog.push_back("No available weightstages, please fill it or"
" restore the defaults.");
errorCount++;
}
if (HasDuplicateNoID()) {
m_errorLog.push_back("More than one weightstages have \"Has ID\""
" unchecked.");
errorCount++;
}
return errorCount;
}
void StagesPanel::EnableForm(const bool enable, const bool id, const bool sub) {
m_name->Enable(enable);
m_friendlyName->Enable(enable && id);
m_descriptionChest->Enable(enable && id);
m_descriptionLeg->Enable(enable && id && !sub);
m_typeChest->Enable(enable && id);
m_typeLeg->Enable(enable && id && !sub);
m_frames->Enable(enable && !sub);
m_id->Enable(enable && !sub);
m_nameText->Enable(enable);
m_friendlyNameText->Enable(enable && id);
m_descriptionChestText->Enable(enable && id);
m_descriptionLegText->Enable(enable && id && !sub);
m_typeChestText->Enable(enable && id);
m_typeLegText->Enable(enable && id && !sub);
}
void StagesPanel::ClearForm() {
m_name->ChangeValue(wxEmptyString);
m_friendlyName->ChangeValue(wxEmptyString);
m_descriptionChest->ChangeValue(wxEmptyString);
m_descriptionLeg->ChangeValue(wxEmptyString);
m_typeChest->SetSelection(2);
m_typeLeg->SetSelection(0);
m_frames->SetValue(false);
m_id->SetValue(false);
}
void StagesPanel::PopulateForm(const Starpounds::WeightStage &stage) {
m_name->ChangeValue(stage.GetName());
m_friendlyName->ChangeValue(stage.GetFriendlyName());
m_descriptionChest->ChangeValue(stage.GetChestDescription());
m_descriptionLeg->ChangeValue(stage.GetLegDescription());
m_typeChest->SetSelection(magic_enum::enum_integer(stage.GetChestType()));
m_typeLeg->SetSelection(magic_enum::enum_integer(stage.GetLegType()));
m_frames->SetValue(stage.HasFrames());
m_id->SetValue(stage.HasID());
EnableForm(true, stage.HasID());
}
void StagesPanel::PopulateForm(const Starpounds::WeightStageSub &sub) {
m_name->ChangeValue(sub.GetName());
m_friendlyName->ChangeValue(sub.GetFriendlyName());
m_descriptionChest->ChangeValue(sub.GetChestDescription());
m_typeChest->SetSelection(magic_enum::enum_integer(sub.GetChestType()));
EnableForm(true, true, true);
}
void StagesPanel::DoResetWeightStages() {
m_stages.clear();
m_stagesList->Clear();
m_subStagesList->Clear();
DoAddWeightStage(Starpounds::WeightStage(
"skinny", false, false,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"Someone is a bit well developed."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"You can hear the sloshing with every bounce."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Someone is a bit well developed."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Saturated,
"Got a nice small gut from that meal you just had."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"Quite a large meal you had with that big gut."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Packed,
"You've since past the point you could "
"try sucking in this gut."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Glutted,
"Either you're just that gluttonous or "
"your stomach is quite elastic."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"You can start visualizing how much "
"padding you're gonna get from all this food."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Every pound in your stomach you can feel "
"turning into fat right now.")}));
DoAddWeightStage(Starpounds::WeightStage(
"soft", "Soft", "Your stomach is looking a little less flat nowadays.",
Starpounds::Types::Chests::Belly,
"Your hips are a bit flared. No stick legs for you.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"You might be a bit out of shape but at "
"least you got some boob to balance it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"It's okay that you got a bit of a belly. "
"Those sloshing milkers are hiding it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Got some real nice melons there."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"A bit out of shape and having a big meal, huh?"),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Packed,
"You certainly ain't gonna lose that "
"chub with a meal like this."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Glutted,
"Either you're just that gluttonous or "
"your stomach is quite elastic."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"No wonder you've packed on weight with meals like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"You won't be just thick with meals like this.")}));
DoAddWeightStage(Starpounds::WeightStage(
"thick", "Thick",
"First sign of being out of shape is a soft gut that can't be sucked "
"in.",
Starpounds::Types::Chests::Belly,
"Thighs touching one another? Seems like someone is a bit thicker than "
"the most.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"You might be a bit out of shape but at "
"least you got some boob to balance it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"It's okay that you got a bit of a belly. "
"Those sloshing milkers are hiding it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Got some real nice melons there."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"A bit out of shape and having a big meal, huh?"),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Packed,
"You certainly ain't gonna lose that "
"chub with a meal like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"No wonder you've packed on weight with meals like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"You won't be just thick with meals like this.")}));
DoAddWeightStage(Starpounds::WeightStage(
"chubster", "Chubby",
"So wide, so chubby. Someone's been eating too many sweets.",
Starpounds::Types::Chests::Belly,
"Log sized legs, door jamming hips, ultra soft rear. You've been "
"snacking heavily.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"It's hard to tell your boobs are that big "
"with a gut that still dwarfs them."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"Those sloshing milk tanks help to obscure "
"that chubby belly of yours."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Hyper,
"My, my. Your breasts are bigger than your own head."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Stuffed,
"It's okay. It's hard to tell you've eaten "
"with that much padding."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Filled,
"No wonder you've been packing on the "
"pounds with that much food eaten."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Is this a sign you've given up on losing "
"weight? Or can you not stop yourself?")}));
DoAddWeightStage(Starpounds::WeightStage(
"plump", "Plump",
"When your gut is resting on a table, it's pretty fat porky.",
Starpounds::Types::Chests::Belly,
"A rear the size of a couch? You're really out of shape.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(
Starpounds::Types::Subs::Busty,
"When your gut is resting on a table, it's pretty fat porky."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"When your gut is resting on a table, it's pretty fat porky."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Tables must fear a rack of that size."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"It's hard to even tell you've just eaten."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"A meal like this must just be an appetizer for you."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"The food in your stomach weighs more than a person, tubs.")}));
DoAddWeightStage(Starpounds::WeightStage(
"fatty", "Fatty",
"Your gut is the size of a person, you're just a hopeless, fat "
"glutton.",
Starpounds::Types::Chests::Belly,
"That butt is an absolute dumptruck. Only good for sitting down every "
"single day.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"Such impressive boobs you have. If they "
"weren't dwarfed by a big fat gut."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"From a certain angle. Your chest can give "
"the illusion your stomach isn't as big as it is."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Those boobs are as wide as you are tall."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Stuffed,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Filled,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton.")}));
DoAddWeightStage(Starpounds::WeightStage(
"blob", "Blobby", "A bit of arm fat that can't be missed.",
Starpounds::Types::Chests::Arms,
"It'd be amazing if you can fit into a house since you're now a whale.",
Starpounds::Types::Legs::Body, true, true));
DoAddWeightStage(Starpounds::WeightStage(
"immobile", "Blobby", "A bit of arm fat that can't be missed.",
Starpounds::Types::Chests::Arms,
"Now you can't even move fatty. Your gluttony knows no bounds.",
Starpounds::Types::Legs::Body, true, true));
}
std::string
StagesPanel::GetInternalNameReplacement(const Starpounds::WeightStage &stage) {
size_t i = 0;
const std::string name = stage.GetName();
std::string newName = name;
while (HasDuplicateInternalName(newName, false))
newName = wxString::Format("%s%d", name, ++i);
return newName;
}
std::string
StagesPanel::GetInternalNameReplacement(const Starpounds::WeightStageSub &sub) {
size_t i = 0;
const std::string name = sub.GetName();
std::string newName = name;
while (HasDuplicateInternalName(newName, true))
newName = wxString::Format("%s%d", name, ++i);
return newName;
}
bool StagesPanel::HasDuplicateInternalName(const std::string &name,
const bool subs) {
if (subs) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
const Starpounds::WeightStage &stage = m_stages.at(selection);
for (const Starpounds::WeightStageSub sub : stage.GetSubs()) {
if (sub.GetName() == name)
return true;
}
} else {
for (const Starpounds::WeightStage &stage : m_stages) {
if (stage.GetName() == name)
return true;
}
}
return false;
}
bool StagesPanel::HasDuplicateNoID() {
bool hasNoID = false;
for (const Starpounds::WeightStage &stage : m_stages) {
if (!stage.HasID()) {
if (hasNoID)
return true;
else
hasNoID = true;
}
}
return false;
}
void StagesPanel::OnClickWeightStage(wxCommandEvent &event) {
if (event.IsSelection()) {
ClearForm();
const int selection = event.GetSelection();
const Starpounds::WeightStage &stage = m_stages.at(selection);
wxArrayString names;
for (const Starpounds::WeightStageSub &sub : stage.GetSubs())
names.Add(sub.GetName());
m_subStagesList->Clear();
m_subStagesList->InsertItems(names, 0);
m_subAdd->Enable();
m_subRemove->Enable();
PopulateForm(stage);
} else {
m_subAdd->Disable();
m_subRemove->Disable();
EnableForm(false);
ClearForm();
}
}
void StagesPanel::OnClickWeightStageSub(wxCommandEvent &event) {
if (event.IsSelection()) {
ClearForm();
const int selection = event.GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (stageSelection == wxNOT_FOUND)
stageSelection = 0;
const Starpounds::WeightStage &stage = m_stages.at(stageSelection);
const Starpounds::WeightStageSub sub = stage.GetSubs().at(selection);
PopulateForm(sub);
} else {
EnableForm(false);
ClearForm();
}
}
void StagesPanel::OnClickCheckboxFrames(wxCommandEvent &event) {
const bool isChecked = event.IsChecked();
Starpounds::WeightStage &stage = m_stages.at(m_stagesList->GetSelection());
stage.SetFrames(isChecked);
}
void StagesPanel::OnSelectComboBoxChest(wxCommandEvent &event) {
const int selection = event.GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (stageSelection == wxNOT_FOUND)
stageSelection = 0;
Starpounds::WeightStage &stage = m_stages.at(stageSelection);
stage.SetChestType(
magic_enum::enum_value<Starpounds::Types::Chests>(selection));
}
void StagesPanel::OnSelectComboBoxLeg(wxCommandEvent &event) {
const int selection = event.GetSelection();
int parentSelection = m_stagesList->GetSelection();
if (parentSelection == wxNOT_FOUND)
parentSelection = 0;
Starpounds::WeightStage &stage = m_stages.at(parentSelection);
stage.SetLegType(
magic_enum::enum_value<Starpounds::Types::Legs>(selection));
}
void StagesPanel::OnInternalNameEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
int subSelection = m_subStagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
if (subSelection != wxNOT_FOUND) {
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
Starpounds::WeightStageSub &sub = subs.at(subSelection);
sub.SetName(m_name->GetValue().ToStdString());
stage.SetSubs(subs);
m_subStagesList->SetString(subSelection, m_name->GetValue());
} else {
stage.SetName(m_name->GetValue().ToStdString());
m_stagesList->SetString(selection, m_name->GetValue());
}
}
void StagesPanel::OnFriendlyNameEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
int subSelection = m_subStagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
if (subSelection != wxNOT_FOUND) {
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
Starpounds::WeightStageSub &sub = subs.at(subSelection);
sub.SetFriendlyName(m_friendlyName->GetValue().ToStdString());
stage.SetSubs(subs);
} else {
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetFriendlyName(m_friendlyName->GetValue().ToStdString());
}
}
void StagesPanel::OnDescriptionChestEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetChestDescription(m_descriptionChest->GetValue().ToStdString());
}
void StagesPanel::OnDescriptionLegEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetLegDescription(m_descriptionLeg->GetValue().ToStdString());
}
void StagesPanel::OnResetWeightStages(wxCommandEvent &WXUNUSED(event)) {
DoResetWeightStages();
}
} // namespace SpeciesGen

View File

@ -64,811 +64,6 @@ bool App::OnInit() {
return true;
}
//----------------------------------------------------------------------
// MainPanel
//----------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(MainPanel, wxPanel)
#if wxUSE_DIRDLG
EVT_BUTTON(DIR_CHOOSE, MainPanel::DoChooseDir)
#endif // wxUSE_DIRDLG
wxEND_EVENT_TABLE()
MainPanel::MainPanel(wxWindow *window, int x, int y, int w, int h,
const std::string handlerName)
: wxPanel(window, wxID_ANY, wxPoint(x, y), wxSize(w, h)),
ErrorHandler(handlerName) {
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *row = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
m_authorText = new wxStaticText(this, wxID_ANY, "Author");
m_nameText = new wxStaticText(this, wxID_ANY, "Species (Internal)");
m_friendlyNameText = new wxStaticText(this, wxID_ANY, "Species (In-Game)");
m_modDestinationText = new wxStaticText(this, wxID_ANY, "Output directory");
m_author = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_author->SetHint("Author's name");
m_author->SetMaxLength(128);
#ifdef _WIN32
m_author->SetValue(wxGetUserName());
#else
m_author->SetValue(getenv("USER"));
#endif // _WIN32
m_name = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_name->SetHint("Internal species name");
m_name->SetMaxLength(128);
m_friendlyName =
new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_friendlyName->SetHint("In-Game species name");
m_friendlyName->SetMaxLength(128);
#ifdef _WIN32
m_modDestination = new wxTextCtrl(
this, wxID_ANY,
"C:\\Program Files (x86)\\Steam\\steamapps\\common\\Starbound\\mods",
wxDefaultPosition, wxSize(400, wxDefaultSize.GetHeight()));
#else
m_modDestination = new wxTextCtrl(
this, wxID_ANY,
wxString::Format("%s/.steam/steam/steamapps/common/Starbound/mods",
wxGetUserHome(wxGetUserName())));
#endif // _WIN32
m_generate = new wxButton(this, MOD_GENERATE, "Generate mod",
wxDefaultPosition, wxSize(280, 80));
column1->Add(m_authorText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_author, 0, wxEXPAND | wxALL, 10);
column1->Add(m_nameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_name, 0, wxEXPAND | wxALL, 10);
column1->Add(m_friendlyNameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_friendlyName, 0, wxEXPAND | wxALL, 10);
column2->Add(m_modDestinationText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column2->Add(m_modDestination, 0, wxEXPAND | wxLEFT | wxUP, 10);
#if wxUSE_DIRDLG
m_browse = new wxButton(this, DIR_CHOOSE, "Browse...");
column2->Add(m_browse, 0, wxALL, 10);
#endif // wxUSE_DIRDLG
column2->AddSpacer(20);
column2->Add(m_generate, 0, wxALIGN_CENTER, 0);
row->Add(column1, 0, wxALL | wxALIGN_CENTER, 10);
row->Add(column2, 0, wxALL | wxALIGN_CENTER, 10);
topSizer->Add(row, 0, wxALL | wxALIGN_CENTER, 10);
SetSizer(topSizer);
}
#if wxUSE_CLIPBOARD
/*
wxTextCtrl *MainPanel::GetFocusedText() const
{
wxWindow *win = FindFocus();
wxTextCtrl *text = win ? wxDynamicCast(win, wxTextCtrl) : NULL;
return text;
}
bool MainPanel::HasSelection() const
{
long from;
long to;
GetFocusedText()->GetSelection(&from, &to);
return from != to;
}
void MainPanel::DoPasteFromClipboard()
{
// On X11, we want to get the data from the primary selection instead
// of the normal clipboard (which isn't normal under X11 at all). This
// call has no effect under MSW.
wxTheClipboard->UsePrimarySelection();
if (!wxTheClipboard->Open())
return;
wxTextDataObject data;
if (wxTheClipboard->IsSupported(data.GetFormat())) {
if (wxTheClipboard->GetData(data))
GetFocusedText()->AppendText(data.GetText());
}
wxTheClipboard->Close();
}
void MainPanel::DoCopyToClipboard()
{
// On X11, we want to get the data from the primary selection instead
// of the normal clipboard (which isn't normal under X11 at all). This
// call has no effect under MSW.
wxTheClipboard->UsePrimarySelection();
wxString text(GetFocusedText()->GetStringSelection());
if (text.IsEmpty())
return;
if (!wxTheClipboard->Open())
return;
wxTextDataObject *data = new wxTextDataObject(text);
wxTheClipboard->SetData(data);
wxTheClipboard->Close();
}
*/
#endif // wxUSE_CLIPBOARD
#if wxUSE_DIRDLG
void MainPanel::DoChooseDir(wxCommandEvent &WXUNUSED(event)) {
wxString dirHome =
wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Desktop);
wxDirDialog dialog(this, "Select a directory", dirHome,
wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
if (dialog.ShowModal() == wxID_OK)
m_modDestination->SetValue(dialog.GetPath());
}
#endif // wxUSE_DIRDLG
size_t MainPanel::CheckForErrors() {
size_t errorCount = 0;
if (m_author->IsEmpty()) {
m_errorLog.push_back("Empty author field, please fill it out.");
errorCount++;
}
if (m_name->IsEmpty()) {
m_errorLog.push_back("Empty internal name field, please fill it out.");
errorCount++;
}
if (m_friendlyName->IsEmpty()) {
m_errorLog.push_back("Empty in-game name field, please fill it out.");
errorCount++;
}
if (m_modDestination->IsEmpty()) {
m_errorLog.push_back("Empty path field, please fill it out.");
errorCount++;
}
if (!wxDir::Exists(m_modDestination->GetValue())) {
m_errorLog.push_back(
"Invalid directory, please check your entered path.");
errorCount++;
}
return errorCount;
}
//----------------------------------------------------------------------
// StagesPanel
//----------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(StagesPanel, wxPanel)
EVT_LISTBOX(STAGES_LIST, StagesPanel::OnClickWeightStage)
EVT_LISTBOX(STAGES_SUB_LIST, StagesPanel::OnClickWeightStageSub)
EVT_CHECKBOX(STAGES_FRAMES, StagesPanel::OnClickCheckboxFrames)
EVT_COMBOBOX(STAGES_TYPE_CHEST, StagesPanel::OnSelectComboBoxChest)
EVT_COMBOBOX(STAGES_TYPE_LEG, StagesPanel::OnSelectComboBoxLeg)
EVT_TEXT(STAGES_TEXT_NAME, StagesPanel::OnInternalNameEdit)
EVT_TEXT(STAGES_TEXT_FRIENDLYNAME, StagesPanel::OnFriendlyNameEdit)
EVT_TEXT(STAGES_TEXT_DESCRIPTION_CHEST, StagesPanel::OnDescriptionChestEdit)
EVT_TEXT(STAGES_TEXT_DESCRIPTION_LEG, StagesPanel::OnDescriptionLegEdit)
EVT_BUTTON(STAGES_SET_DEFAULT, StagesPanel::OnResetWeightStages)
wxEND_EVENT_TABLE()
StagesPanel::StagesPanel(wxWindow *window, int x, int y, int w, int h,
const std::string handlerName)
: wxPanel(window, wxID_ANY, wxPoint(x, y), wxSize(w, h)),
ErrorHandler(handlerName) {
wxBoxSizer *row1 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *row2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column3 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column4 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
wxArrayString choicesChest;
wxArrayString choicesLeg;
constexpr auto enumsChest =
magic_enum::enum_values<Starpounds::Types::Chests>();
constexpr auto enumsLeg =
magic_enum::enum_values<Starpounds::Types::Legs>();
for (auto enumChest : enumsChest)
choicesChest.Add(
static_cast<std::string>(magic_enum::enum_name(enumChest)));
for (auto enumLeg : enumsLeg)
choicesLeg.Add(
static_cast<std::string>(magic_enum::enum_name(enumLeg)));
m_add = new wxButton(this, STAGES_ADD, "Add");
m_remove = new wxButton(this, STAGES_REMOVE, "Remove");
m_default = new wxButton(this, STAGES_SET_DEFAULT, "Restore default");
m_subAdd = new wxButton(this, STAGES_SUB_ADD, "Add sub-stage");
m_subRemove = new wxButton(this, STAGES_SUB_ADD, "Remove sub-stage");
m_subAdd->Disable();
m_subRemove->Disable();
m_nameText = new wxStaticText(this, wxID_ANY, "Internal name");
m_friendlyNameText = new wxStaticText(this, wxID_ANY, "In-Game name");
m_descriptionChestText =
new wxStaticText(this, wxID_ANY, "Chest description");
m_descriptionLegText = new wxStaticText(this, wxID_ANY, "Leg description");
m_typeChestText = new wxStaticText(this, wxID_ANY, "Chest type");
m_typeLegText = new wxStaticText(this, wxID_ANY, "Leg type");
m_stagesListText = new wxStaticText(this, wxID_ANY, "Stages");
m_subStagesListText = new wxStaticText(this, wxID_ANY, "Sub-Stages");
m_frames = new wxCheckBox(this, STAGES_FRAMES, "Has frames");
m_id = new wxCheckBox(this, STAGES_ID, "Has ID");
m_name = new wxTextCtrl(this, STAGES_TEXT_NAME);
m_friendlyName = new wxTextCtrl(this, STAGES_TEXT_FRIENDLYNAME);
m_descriptionChest = new wxTextCtrl(this, STAGES_TEXT_DESCRIPTION_CHEST,
wxEmptyString, wxDefaultPosition,
wxSize(240, wxDefaultSize.GetHeight()));
m_descriptionLeg = new wxTextCtrl(this, STAGES_TEXT_DESCRIPTION_LEG,
wxEmptyString, wxDefaultPosition,
wxSize(240, wxDefaultSize.GetHeight()));
m_stagesList =
new wxListBox(this, STAGES_LIST, wxDefaultPosition, wxSize(105, 220));
m_subStagesList = new wxListBox(this, STAGES_SUB_LIST, wxDefaultPosition,
wxSize(105, 220));
m_typeChest = new wxComboBox(
this, STAGES_TYPE_CHEST, choicesChest.Item(2), wxDefaultPosition,
wxSize(74, wxDefaultSize.GetHeight()), choicesChest, wxCB_READONLY);
m_typeLeg = new wxComboBox(
this, STAGES_TYPE_LEG, choicesLeg.Item(0), wxDefaultPosition,
wxSize(74, wxDefaultSize.GetHeight()), choicesLeg, wxCB_READONLY);
row1->Add(m_add, 0, wxALL, 10);
row1->Add(m_remove, 0, wxALL, 10);
row1->Add(m_default, 0, wxALL, 10);
row1->Add(m_subAdd, 0, wxALL, 10);
row1->Add(m_subRemove, 0, wxALL, 10);
column1->Add(m_stagesListText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_stagesList, 0, wxALL, 10);
column2->Add(m_subStagesListText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column2->Add(m_subStagesList, 0, wxALL, 10);
column3->Add(m_nameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_name, 0, wxEXPAND | wxALL, 10);
column3->Add(m_friendlyNameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_friendlyName, 0, wxEXPAND | wxALL, 10);
column3->Add(m_typeChestText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_typeChest, 0, wxALL, 10);
column4->Add(m_descriptionChestText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_descriptionChest, 0, wxEXPAND | wxALL, 10);
column4->Add(m_descriptionLegText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_descriptionLeg, 0, wxEXPAND | wxALL, 10);
column4->Add(m_typeLegText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_typeLeg, 0, wxALL, 10);
column3->Add(m_frames, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_id, 0, wxEXPAND | wxLEFT | wxUP, 10);
row2->Add(column1, 0, 0, 0);
row2->Add(column2, 0, 0, 0);
row2->Add(column3, 0, 0, 0);
row2->Add(column4, 0, 0, 0);
topSizer->Add(row1, 0, wxLEFT | wxUP, 10);
topSizer->Add(row2, 0, wxALL | wxEXPAND, 10);
EnableForm(false);
DoResetWeightStages();
SetSizer(topSizer);
}
void StagesPanel::DoAddWeightStage(Starpounds::WeightStage stage) {
stage.SetName(GetInternalNameReplacement(stage));
m_stages.push_back(stage);
wxArrayString name;
name.Add(stage.GetName());
m_stagesList->InsertItems(name, m_stagesList->GetCount());
}
void StagesPanel::DoRemoveWeightStage() {
if (m_stagesList->GetCount() == 0)
return;
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
m_stagesList->Delete(selection);
m_subStagesList->Clear();
m_subAdd->Disable();
m_subRemove->Disable();
m_stages.erase(m_stages.begin() + selection);
EnableForm(false);
ClearForm();
}
void StagesPanel::DoAddWeightStageSub(Starpounds::WeightStageSub sub) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
sub.SetName(GetInternalNameReplacement(sub));
subs.push_back(sub);
stage.SetSubs(subs);
wxArrayString name;
name.Add(sub.GetName());
m_subStagesList->InsertItems(name, m_subStagesList->GetCount());
}
void StagesPanel::DoRemoveWeightStageSub() {
if (m_subStagesList->GetCount() == 0)
return;
int selection = m_subStagesList->GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
if (stageSelection == wxNOT_FOUND)
stageSelection = 0;
Starpounds::WeightStage &stage = m_stages.at(stageSelection);
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
m_subStagesList->Delete(selection);
subs.erase(subs.begin() + selection);
stage.SetSubs(subs);
EnableForm(false);
ClearForm();
}
void StagesPanel::DoClickCheckboxID(const bool isChecked) {
Starpounds::WeightStage &stage = m_stages.at(m_stagesList->GetSelection());
stage.SetID(isChecked);
EnableForm(true, isChecked);
}
std::vector<Starpounds::WeightStage> StagesPanel::GetWeightStages() const {
return m_stages;
}
size_t StagesPanel::CheckForErrors() {
size_t errorCount = 0;
if (m_stagesList->GetCount() == 0) {
m_errorLog.push_back("No available weightstages, please fill it or"
" restore the defaults.");
errorCount++;
}
if (HasDuplicateNoID()) {
m_errorLog.push_back("More than one weightstages have \"Has ID\""
" unchecked.");
errorCount++;
}
return errorCount;
}
void StagesPanel::EnableForm(const bool enable, const bool id, const bool sub) {
m_name->Enable(enable);
m_friendlyName->Enable(enable && id);
m_descriptionChest->Enable(enable && id);
m_descriptionLeg->Enable(enable && id && !sub);
m_typeChest->Enable(enable && id);
m_typeLeg->Enable(enable && id && !sub);
m_frames->Enable(enable && !sub);
m_id->Enable(enable && !sub);
m_nameText->Enable(enable);
m_friendlyNameText->Enable(enable && id);
m_descriptionChestText->Enable(enable && id);
m_descriptionLegText->Enable(enable && id && !sub);
m_typeChestText->Enable(enable && id);
m_typeLegText->Enable(enable && id && !sub);
}
void StagesPanel::ClearForm() {
m_name->ChangeValue(wxEmptyString);
m_friendlyName->ChangeValue(wxEmptyString);
m_descriptionChest->ChangeValue(wxEmptyString);
m_descriptionLeg->ChangeValue(wxEmptyString);
m_typeChest->SetSelection(2);
m_typeLeg->SetSelection(0);
m_frames->SetValue(false);
m_id->SetValue(false);
}
void StagesPanel::PopulateForm(const Starpounds::WeightStage &stage) {
m_name->ChangeValue(stage.GetName());
m_friendlyName->ChangeValue(stage.GetFriendlyName());
m_descriptionChest->ChangeValue(stage.GetChestDescription());
m_descriptionLeg->ChangeValue(stage.GetLegDescription());
m_typeChest->SetSelection(magic_enum::enum_integer(stage.GetChestType()));
m_typeLeg->SetSelection(magic_enum::enum_integer(stage.GetLegType()));
m_frames->SetValue(stage.HasFrames());
m_id->SetValue(stage.HasID());
EnableForm(true, stage.HasID());
}
void StagesPanel::PopulateForm(const Starpounds::WeightStageSub &sub) {
m_name->ChangeValue(sub.GetName());
m_friendlyName->ChangeValue(sub.GetFriendlyName());
m_descriptionChest->ChangeValue(sub.GetChestDescription());
m_typeChest->SetSelection(magic_enum::enum_integer(sub.GetChestType()));
EnableForm(true, true, true);
}
void StagesPanel::DoResetWeightStages() {
m_stages.clear();
m_stagesList->Clear();
m_subStagesList->Clear();
DoAddWeightStage(Starpounds::WeightStage(
"skinny", false, false,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"Someone is a bit well developed."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"You can hear the sloshing with every bounce."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Someone is a bit well developed."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Saturated,
"Got a nice small gut from that meal you just had."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"Quite a large meal you had with that big gut."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Packed,
"You've since past the point you could try sucking in this gut."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Glutted,
"Either you're just that gluttonous or "
"your stomach is quite elastic."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"You can start visualizing how much padding you're gonna get from "
"all this food."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Every pound in your stomach you can feel "
"turning into fat right now.")}));
DoAddWeightStage(Starpounds::WeightStage(
"soft", "Soft", "Your stomach is looking a little less flat nowadays.",
Starpounds::Types::Chests::Belly,
"Your hips are a bit flared. No stick legs for you.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"You might be a bit out of shape but at "
"least you got some boob to balance it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"It's okay that you got a bit of a belly. "
"Those sloshing milkers are hiding it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Got some real nice melons there."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"A bit out of shape and having a big meal, huh?"),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Packed,
"You certainly ain't gonna lose that chub with a meal like this."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Glutted,
"Either you're just that gluttonous or "
"your stomach is quite elastic."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"No wonder you've packed on weight with meals like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"You won't be just thick with meals like this.")}));
DoAddWeightStage(Starpounds::WeightStage(
"thick", "Thick",
"First sign of being out of shape is a soft gut that can't be sucked "
"in.",
Starpounds::Types::Chests::Belly,
"Thighs touching one another? Seems like someone is a bit thicker than "
"the most.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"You might be a bit out of shape but at "
"least you got some boob to balance it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"It's okay that you got a bit of a belly. "
"Those sloshing milkers are hiding it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Got some real nice melons there."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"A bit out of shape and having a big meal, huh?"),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Packed,
"You certainly ain't gonna lose that chub with a meal like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"No wonder you've packed on weight with meals like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"You won't be just thick with meals like this.")}));
DoAddWeightStage(Starpounds::WeightStage(
"chubster", "Chubby",
"So wide, so chubby. Someone's been eating too many sweets.",
Starpounds::Types::Chests::Belly,
"Log sized legs, door jamming hips, ultra soft rear. You've been "
"snacking heavily.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"It's hard to tell your boobs are that big "
"with a gut that still dwarfs them."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"Those sloshing milk tanks help to obscure "
"that chubby belly of yours."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Hyper,
"My, my. Your breasts are bigger than your own head."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Stuffed,
"It's okay. It's hard to tell you've eaten "
"with that much padding."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Filled,
"No wonder you've been packing on the "
"pounds with that much food eaten."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Is this a sign you've given up on losing "
"weight? Or can you not stop yourself?")}));
DoAddWeightStage(Starpounds::WeightStage(
"plump", "Plump",
"When your gut is resting on a table, it's pretty fat porky.",
Starpounds::Types::Chests::Belly,
"A rear the size of a couch? You're really out of shape.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(
Starpounds::Types::Subs::Busty,
"When your gut is resting on a table, it's pretty fat porky."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"When your gut is resting on a table, it's pretty fat porky."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Tables must fear a rack of that size."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"It's hard to even tell you've just eaten."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"A meal like this must just be an appetizer for you."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"The food in your stomach weighs more than a person, tubs.")}));
DoAddWeightStage(Starpounds::WeightStage(
"fatty", "Fatty",
"Your gut is the size of a person, you're just a hopeless, fat "
"glutton.",
Starpounds::Types::Chests::Belly,
"That butt is an absolute dumptruck. Only good for sitting down every "
"single day.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"Such impressive boobs you have. If they "
"weren't dwarfed by a big fat gut."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"From a certain angle. Your chest can give "
"the illusion your stomach isn't as big as it is."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Those boobs are as wide as you are tall."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Stuffed,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Filled,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton.")}));
DoAddWeightStage(Starpounds::WeightStage(
"blob", "Blobby", "A bit of arm fat that can't be missed.",
Starpounds::Types::Chests::Arms,
"It'd be amazing if you can fit into a house since you're now a whale.",
Starpounds::Types::Legs::Body, true, true));
DoAddWeightStage(Starpounds::WeightStage(
"immobile", "Blobby", "A bit of arm fat that can't be missed.",
Starpounds::Types::Chests::Arms,
"Now you can't even move fatty. Your gluttony knows no bounds.",
Starpounds::Types::Legs::Body, true, true));
}
std::string
StagesPanel::GetInternalNameReplacement(const Starpounds::WeightStage &stage) {
size_t i = 0;
const std::string name = stage.GetName();
std::string newName = name;
while (HasDuplicateInternalName(newName, false))
newName = wxString::Format("%s%d", name, ++i);
return newName;
}
std::string
StagesPanel::GetInternalNameReplacement(const Starpounds::WeightStageSub &sub) {
size_t i = 0;
const std::string name = sub.GetName();
std::string newName = name;
while (HasDuplicateInternalName(newName, true))
newName = wxString::Format("%s%d", name, ++i);
return newName;
}
bool StagesPanel::HasDuplicateInternalName(const std::string &name,
const bool subs) {
if (subs) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
const Starpounds::WeightStage &stage = m_stages.at(selection);
for (const Starpounds::WeightStageSub sub : stage.GetSubs()) {
if (sub.GetName() == name)
return true;
}
} else {
for (const Starpounds::WeightStage &stage : m_stages) {
if (stage.GetName() == name)
return true;
}
}
return false;
}
bool StagesPanel::HasDuplicateNoID() {
bool hasNoID = false;
for (const Starpounds::WeightStage &stage : m_stages) {
if (!stage.HasID()) {
if (hasNoID)
return true;
else
hasNoID = true;
}
}
return false;
}
void StagesPanel::OnClickWeightStage(wxCommandEvent &event) {
if (event.IsSelection()) {
ClearForm();
const int selection = event.GetSelection();
const Starpounds::WeightStage &stage = m_stages.at(selection);
wxArrayString names;
for (const Starpounds::WeightStageSub &sub : stage.GetSubs())
names.Add(sub.GetName());
m_subStagesList->Clear();
m_subStagesList->InsertItems(names, 0);
m_subAdd->Enable();
m_subRemove->Enable();
PopulateForm(stage);
} else {
m_subAdd->Disable();
m_subRemove->Disable();
EnableForm(false);
ClearForm();
}
}
void StagesPanel::OnClickWeightStageSub(wxCommandEvent &event) {
if (event.IsSelection()) {
ClearForm();
const int selection = event.GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (stageSelection == wxNOT_FOUND)
stageSelection = 0;
const Starpounds::WeightStage &stage = m_stages.at(stageSelection);
const Starpounds::WeightStageSub sub = stage.GetSubs().at(selection);
PopulateForm(sub);
} else {
EnableForm(false);
ClearForm();
}
}
void StagesPanel::OnClickCheckboxFrames(wxCommandEvent &event) {
const bool isChecked = event.IsChecked();
Starpounds::WeightStage &stage = m_stages.at(m_stagesList->GetSelection());
stage.SetFrames(isChecked);
}
void StagesPanel::OnSelectComboBoxChest(wxCommandEvent &event) {
const int selection = event.GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (stageSelection == wxNOT_FOUND)
stageSelection = 0;
Starpounds::WeightStage &stage = m_stages.at(stageSelection);
stage.SetChestType(
magic_enum::enum_value<Starpounds::Types::Chests>(selection));
}
void StagesPanel::OnSelectComboBoxLeg(wxCommandEvent &event) {
const int selection = event.GetSelection();
int parentSelection = m_stagesList->GetSelection();
if (parentSelection == wxNOT_FOUND)
parentSelection = 0;
Starpounds::WeightStage &stage = m_stages.at(parentSelection);
stage.SetLegType(
magic_enum::enum_value<Starpounds::Types::Legs>(selection));
}
void StagesPanel::OnInternalNameEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
int subSelection = m_subStagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
if (subSelection != wxNOT_FOUND) {
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
Starpounds::WeightStageSub &sub = subs.at(subSelection);
sub.SetName(m_name->GetValue().ToStdString());
stage.SetSubs(subs);
m_subStagesList->SetString(subSelection, m_name->GetValue());
} else {
stage.SetName(m_name->GetValue().ToStdString());
m_stagesList->SetString(selection, m_name->GetValue());
}
}
void StagesPanel::OnFriendlyNameEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
int subSelection = m_subStagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
if (subSelection != wxNOT_FOUND) {
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
Starpounds::WeightStageSub &sub = subs.at(subSelection);
sub.SetFriendlyName(m_friendlyName->GetValue().ToStdString());
stage.SetSubs(subs);
} else {
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetFriendlyName(m_friendlyName->GetValue().ToStdString());
}
}
void StagesPanel::OnDescriptionChestEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetChestDescription(m_descriptionChest->GetValue().ToStdString());
}
void StagesPanel::OnDescriptionLegEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND)
selection = 0;
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetLegDescription(m_descriptionLeg->GetValue().ToStdString());
}
void StagesPanel::OnResetWeightStages(wxCommandEvent &WXUNUSED(event)) {
DoResetWeightStages();
}
//----------------------------------------------------------------------
// SpritesPanel
//----------------------------------------------------------------------