diff --git a/src/common/ui/MI_ImageSelectField.cpp b/src/common/ui/MI_ImageSelectField.cpp index e5c56457..a237b79c 100644 --- a/src/common/ui/MI_ImageSelectField.cpp +++ b/src/common/ui/MI_ImageSelectField.cpp @@ -15,36 +15,28 @@ MI_ImageSelectField::MI_ImageSelectField( std::string name, short width, short indent, short imageHeight, short imageWidth) - : MI_SelectField(nspr, x, y, std::move(name), width, indent) + : MI_SelectFieldDyn(nspr, x, y, std::move(name), width, indent) , spr_image(nspr_image) , iImageWidth(imageWidth) , iImageHeight(imageHeight) {} -MI_ImageSelectField::MI_ImageSelectField(const MI_ImageSelectField& other) - : MI_SelectField(other) -{ - spr_image = other.spr_image; - iImageWidth = other.iImageWidth; - iImageHeight = other.iImageHeight; -} - void MI_ImageSelectField::Draw() { if (!fShow) return; - spr->draw(ix, iy, 0, (fSelected ? 32 : 0), iIndent - 16, 32); - spr->draw(ix + iIndent - 16, iy, 0, (fSelected ? 96 : 64), 32, 32); - spr->draw(ix + iIndent + 16, iy, 528 - iWidth + iIndent, (fSelected ? 32 : 0), iWidth - iIndent - 16, 32); + m_spr->draw(ix, iy, 0, (fSelected ? 32 : 0), m_indent - 16, 32); + m_spr->draw(ix + m_indent - 16, iy, 0, (fSelected ? 96 : 64), 32, 32); + m_spr->draw(ix + m_indent + 16, iy, 528 - m_width + m_indent, (fSelected ? 32 : 0), m_width - m_indent - 16, 32); - rm->menu_font_large.drawChopRight(ix + 16, iy + 5, iIndent - 8, szName.c_str()); + rm->menu_font_large.drawChopRight(ix + 16, iy + 5, m_indent - 8, m_name.c_str()); - if (!items.empty()) { - rm->menu_font_large.drawChopRight(ix + iIndent + iImageWidth + 10, iy + 5, iWidth - iIndent - 24, (*current)->sName.c_str()); + if (!m_items.empty()) { + rm->menu_font_large.drawChopRight(ix + m_indent + iImageWidth + 10, iy + 5, m_width - m_indent - 24, currentItem().name.c_str()); } - spr_image->draw(ix + iIndent + 8, iy + 16 - (iImageHeight >> 1), ((*current)->iIconOverride >= 0 ? (*current)->iIconOverride : (*current)->iValue) * iImageWidth, 0, iImageWidth, iImageHeight); + spr_image->draw(ix + m_indent + 8, iy + 16 - (iImageHeight >> 1), (currentItem().iconOverride >= 0 ? currentItem().iconOverride : currentItem().value) * iImageWidth, 0, iImageWidth, iImageHeight); miModifyImageRight->Draw(); miModifyImageLeft->Draw(); diff --git a/src/common/ui/MI_ImageSelectField.h b/src/common/ui/MI_ImageSelectField.h index 2916a1bd..92ca6f8a 100644 --- a/src/common/ui/MI_ImageSelectField.h +++ b/src/common/ui/MI_ImageSelectField.h @@ -3,7 +3,7 @@ #include "ui/MI_SelectField.h" -class MI_ImageSelectField : public MI_SelectField { +class MI_ImageSelectField : public MI_SelectFieldDyn { public: MI_ImageSelectField( gfxSprite* nspr, gfxSprite* nspr_image, @@ -11,7 +11,6 @@ class MI_ImageSelectField : public MI_SelectField { std::string name, short width, short indent, short imageHeight, short imageWidth); - MI_ImageSelectField(const MI_ImageSelectField&); virtual ~MI_ImageSelectField() = default; void Draw() override; diff --git a/src/common/ui/MI_SelectField.cpp b/src/common/ui/MI_SelectField.cpp index eb5651cd..19073d01 100644 --- a/src/common/ui/MI_SelectField.cpp +++ b/src/common/ui/MI_SelectField.cpp @@ -499,6 +499,33 @@ MI_SelectFieldDyn::MI_SelectFieldDyn(gfxSprite* nspr, short x, short y, std:: } +template +MI_SelectFieldDyn::MI_SelectFieldDyn(const MI_SelectFieldDyn& other) + : UI_Control(other) + , m_spr(other.m_spr) + , m_name(other.m_name) + , mcItemChangedCode(other.mcItemChangedCode) + , mcControlSelectedCode(other.mcControlSelectedCode) + , m_autoAdvance(other.m_autoAdvance) + , m_wraps(other.m_wraps) + , m_fastScroll(other.m_fastScroll) + , m_adjustmentY(other.m_adjustmentY) + , m_width(other.m_width) + , m_indent(other.m_indent) + , m_items(other.m_items) + , m_goodRandomIndices(other.m_goodRandomIndices) + , m_outputPtr(other.m_outputPtr) +{ + setCurrentIndex(other.m_index); + + miModifyImageLeft = std::make_unique(m_spr, ix + m_indent - 26, iy + 4, 32, 64, 26, 24, 4, 1, 8); + miModifyImageLeft->Show(false); + + miModifyImageRight = std::make_unique(m_spr, ix + m_width - 16, iy + 4, 32, 88, 26, 24, 4, 1, 8); + miModifyImageRight->Show(false); +} + + template void MI_SelectFieldDyn::Update() { @@ -690,7 +717,7 @@ void MI_SelectFieldDyn::updateOutput() const template -void MI_SelectFieldDyn::add(std::string name, T value, bool hidden, bool goodRandom) +SF_ListItemDyn& MI_SelectFieldDyn::add(std::string name, T value, bool hidden, bool goodRandom) { size_t new_idx = m_items.size(); m_items.emplace_back(std::move(name), std::move(value), hidden, -1); @@ -698,6 +725,8 @@ void MI_SelectFieldDyn::add(std::string name, T value, bool hidden, bool good if (goodRandom) m_goodRandomIndices.push_back(new_idx); + + return m_items.back(); } diff --git a/src/common/ui/MI_SelectField.h b/src/common/ui/MI_SelectField.h index 2e87a493..5c1cb2c7 100644 --- a/src/common/ui/MI_SelectField.h +++ b/src/common/ui/MI_SelectField.h @@ -176,13 +176,6 @@ struct SF_ListItemDyn { static_assert(std::is_trivially_copyable::value, ""); } - /*SF_ListItemDyn(const SF_ListItemDyn& other) - : name(other.name) - , value(other.value) - , hidden(other.hidden) - , iconOverride(other.iconOverride) - {}*/ - const std::string name; //!< Display name const T value; bool hidden = false; @@ -196,6 +189,7 @@ class MI_SelectFieldDyn : public UI_Control { public: MI_SelectFieldDyn(gfxSprite* nspr, short x, short y, std::string name, short width, short indent); + MI_SelectFieldDyn(const MI_SelectFieldDyn&); virtual ~MI_SelectFieldDyn() = default; //! Set the displayed name. @@ -243,7 +237,7 @@ class MI_SelectFieldDyn : public UI_Control { //! Sets the currently selected item bool setCurrentIndex(size_t index); //! Adds an item to the list - void add(std::string name, T value, bool hidden = false, bool goodRandom = true); + Item& add(std::string name, T value, bool hidden = false, bool goodRandom = true); //! Removes all items void clear(); //! Hides the items containing the specified value diff --git a/src/smw/menu/GameSettingsMenu.cpp b/src/smw/menu/GameSettingsMenu.cpp index 35dc571f..454623c2 100644 --- a/src/smw/menu/GameSettingsMenu.cpp +++ b/src/smw/menu/GameSettingsMenu.cpp @@ -33,11 +33,11 @@ UI_GameSettingsMenu::UI_GameSettingsMenu() miModeField = new MI_ImageSelectField(&rm->spr_selectfield, &rm->menu_mode_small, 70, 85, "Mode", 500, 120, 16, 16); for (short iGameMode = 0; iGameMode < GAMEMODE_LAST; iGameMode++) { - miModeField->Add(gamemodes[iGameMode]->GetModeName(), iGameMode, "", false, false); + miModeField->add(gamemodes[iGameMode]->GetModeName(), iGameMode); } - miModeField->SetData(¤tgamemode, NULL, NULL); - miModeField->SetKey(0); - miModeField->SetItemChangedCode(MENU_CODE_MODE_CHANGED); + miModeField->setOutputPtr(¤tgamemode); + miModeField->setCurrentValue(0); + miModeField->setItemChangedCode(MENU_CODE_MODE_CHANGED); for (short iGameMode = 0; iGameMode < GAMEMODE_LAST; iGameMode++) { miGoalField[iGameMode] = new MI_SelectField(&rm->spr_selectfield, 70, 125, gamemodes[iGameMode]->GetGoalName().c_str(), 352, 120); @@ -142,11 +142,11 @@ UI_GameSettingsMenu::UI_GameSettingsMenu() void UI_GameSettingsMenu::RefreshGameModeButtons() { // Unhide/hide the settings button - miModeSettingsButton->Show(miModeField->GetShortValue() != game_mode_owned); + miModeSettingsButton->Show(miModeField->currentValue() != game_mode_owned); // Show the approprate goal field for (short iMode = 0; iMode < GAMEMODE_LAST; iMode++) { - miGoalField[iMode]->Show(miModeField->GetShortValue() == iMode); + miGoalField[iMode]->Show(miModeField->currentValue() == iMode); } } @@ -208,7 +208,7 @@ void UI_GameSettingsMenu::SetHeaderText(const char* string) void UI_GameSettingsMenu::GameModeChanged(short gmID) { - miModeField->SetKey(gmID); + miModeField->setCurrentValue(gmID); RefreshGameModeButtons(); } @@ -220,7 +220,7 @@ void UI_GameSettingsMenu::HideGMSettingsBtn() short UI_GameSettingsMenu::GetCurrentGameModeID() { - return miModeField->GetShortValue(); + return miModeField->currentValue(); } const char* UI_GameSettingsMenu::GetCurrentMapName() diff --git a/src/smw/menu/network/NetNewRoomSettingsMenu.cpp b/src/smw/menu/network/NetNewRoomSettingsMenu.cpp index d67d3c26..a6071f2a 100644 --- a/src/smw/menu/network/NetNewRoomSettingsMenu.cpp +++ b/src/smw/menu/network/NetNewRoomSettingsMenu.cpp @@ -73,7 +73,7 @@ UI_NetNewRoomSettingsMenu::UI_NetNewRoomSettingsMenu(const UI_GameSettingsMenu* void UI_NetNewRoomSettingsMenu::RefreshGameModeButtons() { for (short iMode = 0; iMode < GAMEMODE_LAST; iMode++) - miGoalField[iMode]->Show(miModeField->GetShortValue() == iMode); + miGoalField[iMode]->Show(miModeField->currentValue() == iMode); } std::string UI_NetNewRoomSettingsMenu::getCurrentMapPath() const diff --git a/src/smw/ui/MI_TourStop.cpp b/src/smw/ui/MI_TourStop.cpp index 74b5e543..28e60e8e 100644 --- a/src/smw/ui/MI_TourStop.cpp +++ b/src/smw/ui/MI_TourStop.cpp @@ -130,7 +130,7 @@ void MI_TourStop::Refresh(short iTourStop) TourStop * tourstop = game_values.tourstops[iTourStop]; if (tourstop->iStageType == 0) { - miModeField->Clear(); + miModeField->clear(); CGameMode * gamemode = NULL; short tourstopicon = 0; @@ -149,7 +149,7 @@ void MI_TourStop::Refresh(short iTourStop) tourstopicon = tourstop->iMode; } - miModeField->Add(gamemode->GetModeName(), tourstopicon, "", false, false); + miModeField->add(gamemode->GetModeName(), tourstopicon); miGoalField->Clear(); char szTemp[16]; diff --git a/src/worldeditor/worldeditor.cpp b/src/worldeditor/worldeditor.cpp index 9c2859c1..d8c7207c 100644 --- a/src/worldeditor/worldeditor.cpp +++ b/src/worldeditor/worldeditor.cpp @@ -650,27 +650,27 @@ int main(int argc, char *argv[]) miModeField = new MI_ImageSelectField(&rm->spr_selectfield, &rm->menu_mode_small, 70, 60, "Mode", 500, 120, 16, 16); //miModeField->SetData(game_values.tourstops[0]->iMode, NULL, NULL); //miModeField->SetKey(0); - miModeField->SetItemChangedCode(MENU_CODE_MODE_CHANGED); + miModeField->setItemChangedCode(MENU_CODE_MODE_CHANGED); for (short iGameMode = 0; iGameMode < GAMEMODE_LAST; iGameMode++) { - miModeField->Add(stagemodes[iGameMode].szName, iGameMode, "", false, false); + miModeField->add(stagemodes[iGameMode].szName, iGameMode); miGoalField[iGameMode] = new MI_SelectField(&rm->spr_selectfield, 70, 100, stagemodes[iGameMode].szGoal, 352, 120); miGoalField[iGameMode]->Show(iGameMode == 0); for (short iGameModeOption = 0; iGameModeOption < GAMEMODE_NUM_OPTIONS - 1; iGameModeOption++) { StageModeOption * option = &stagemodes[iGameMode].options[iGameModeOption]; - miGoalField[iGameMode]->Add(option->szName, option->iValue, "", false, false); + miGoalField[iGameMode]->Add(option->szName, option->iValue); } //miGoalField[iGameMode]->SetData(&gamemodes[iGameMode]->goal, NULL, NULL); //miGoalField[iGameMode]->SetKey(gamemodes[iGameMode]->goal); } - miModeField->Add("Bonus House", 24); - miModeField->Add("Pipe Minigame", 25); - miModeField->Add("Boss Minigame", 26); - miModeField->Add("Boxes Minigame", 27); + miModeField->add("Bonus House", 24); + miModeField->add("Pipe Minigame", 25); + miModeField->add("Boss Minigame", 26); + miModeField->add("Boxes Minigame", 27); //Create goal field for pipe game miSpecialGoalField[0] = new MI_SelectField(&rm->spr_selectfield, 70, 100, "Points", 352, 120); @@ -838,20 +838,20 @@ int main(int argc, char *argv[]) //Create Vehicle Menu miVehicleSpriteField = new MI_ImageSelectField(&rm->spr_selectfield, &spr_vehicleicons, 70, 80, "Sprite", 500, 150, 16, 16); - miVehicleSpriteField->Add("Hammer Brother", 0); - miVehicleSpriteField->Add("Boomerang Brother", 1); - miVehicleSpriteField->Add("Fire Brother", 2); - miVehicleSpriteField->Add("Tank 1", 3); - miVehicleSpriteField->Add("Boat 1", 4); - miVehicleSpriteField->Add("Boat 2", 5); - miVehicleSpriteField->Add("Airship 1", 6); - miVehicleSpriteField->Add("Airship 2", 7); - miVehicleSpriteField->Add("Tank 2", 8); - miVehicleSpriteField->SetData(&g_wvVehicleStamp.iDrawSprite, NULL, NULL); - miVehicleSpriteField->SetKey(g_wvVehicleStamp.iDrawSprite); + miVehicleSpriteField->add("Hammer Brother", 0); + miVehicleSpriteField->add("Boomerang Brother", 1); + miVehicleSpriteField->add("Fire Brother", 2); + miVehicleSpriteField->add("Tank 1", 3); + miVehicleSpriteField->add("Boat 1", 4); + miVehicleSpriteField->add("Boat 2", 5); + miVehicleSpriteField->add("Airship 1", 6); + miVehicleSpriteField->add("Airship 2", 7); + miVehicleSpriteField->add("Tank 2", 8); + miVehicleSpriteField->setOutputPtr(&g_wvVehicleStamp.iDrawSprite); + miVehicleSpriteField->setCurrentValue(g_wvVehicleStamp.iDrawSprite); miVehicleStageField = new MI_ImageSelectField(&rm->spr_selectfield, &rm->menu_mode_small, 70, 120, "Stage", 500, 150, 16, 16); - miVehicleStageField->SetData(&g_wvVehicleStamp.iActionId, NULL, NULL); + miVehicleStageField->setOutputPtr(&g_wvVehicleStamp.iActionId); miVehicleMinMovesField = new MI_SelectField(&rm->spr_selectfield, 70, 160, "Min Moves", 500, 150); @@ -1195,8 +1195,8 @@ int editor_edit() g_wvVehicleStamp.iDrawDirection = vehicle->iDrawDirection; g_wvVehicleStamp.iBoundary = vehicle->iBoundary; - miVehicleSpriteField->SetKey(g_wvVehicleStamp.iDrawSprite); - miVehicleStageField->SetKey(g_wvVehicleStamp.iActionId); + miVehicleSpriteField->setCurrentValue(g_wvVehicleStamp.iDrawSprite); + miVehicleStageField->setCurrentValue(g_wvVehicleStamp.iActionId); miVehicleMinMovesField->SetKey(g_wvVehicleStamp.iMinMoves); miVehicleMaxMovesField->SetKey(g_wvVehicleStamp.iMaxMoves); miVehiclePacesField->SetKey(g_wvVehicleStamp.fSpritePaces ? 1 : 0); @@ -3297,16 +3297,18 @@ int editor_vehicles() bool done = false; - miVehicleStageField->Clear(); + miVehicleStageField->clear(); for (short iStage = 0; iStage < g_worldmap.iNumStages; iStage++) { TourStop * ts = game_values.tourstops[iStage]; char szStageName[256]; sprintf(szStageName, "(%d) %s", iStage + 1, ts->szName); - miVehicleStageField->Add(szStageName, iStage, false, true, ts->iStageType == 1 ? 24 : (ts->iMode >= 1000 ? ts->iMode - 975 : ts->iMode)); + + SF_ListItemDyn& item = miVehicleStageField->add(szStageName, iStage, false, true); + item.iconOverride = ts->iStageType == 1 ? 24 : (ts->iMode >= 1000 ? ts->iMode - 975 : ts->iMode); } - miVehicleStageField->SetKey(g_wvVehicleStamp.iActionId); + miVehicleStageField->setCurrentValue(g_wvVehicleStamp.iActionId); while (!done) { int framestart = SDL_GetTicks(); @@ -3705,7 +3707,7 @@ void EditStage(short iEditStage) //Set fields to write data to the selected stage TourStop * ts = game_values.tourstops[iEditStage]; - miModeField->SetData(&ts->iMode, NULL, NULL); + miModeField->setOutputPtr(&ts->iMode); miNameField->SetData(ts->szName, 128); miPointsField->SetData(&ts->iPoints, NULL, NULL); @@ -3750,7 +3752,7 @@ void EditStage(short iEditStage) miBonusItemsButton->SetPosition(430, iStageType == 0 ? 220 : 340); if (iStageType == 0 && iMode >= 0 && iMode < GAMEMODE_LAST) { - miModeField->SetKey(iMode); + miModeField->setCurrentValue(iMode); miModeSettingsButton->Show(iMode != game_mode_owned); @@ -3774,9 +3776,9 @@ void EditStage(short iEditStage) } if (iStageType == 1) { //Bonus House - miModeField->SetKey(24); + miModeField->setCurrentValue(24); } else if (iMode >= 1000 && iMode <= 1002) { //Pipe, Boss and Boxes Game - miModeField->SetKey(iMode - 975); + miModeField->setCurrentValue(iMode - 975); miSpecialGoalField[iMode-1000]->SetData(&game_values.tourstops[iEditStage]->iGoal, NULL, NULL); miSpecialGoalField[iMode-1000]->SetKey(game_values.tourstops[iEditStage]->iGoal); miPointsField->SetKey(game_values.tourstops[iEditStage]->iPoints); @@ -4064,7 +4066,7 @@ int editor_stage() //We are no longer working on a specific stage iEditStage = -1; } else if (MENU_CODE_MODE_CHANGED == code) { - short iMode = miModeField->GetShortValue(); + short iMode = miModeField->currentValue(); miPointsField->Show(iMode != 24); miFinalStageField->Show(iMode != 24);