From ac76212b8015b9e7570bb2bf407a8d16e72ed13f Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 4 May 2025 17:50:31 +0100 Subject: [PATCH] Fix: Closing the Game Options window closes all textfile windows. Record the parent window that opens a textfile window so only child windows are closed instead of all. --- src/ai/ai_gui.cpp | 2 +- src/game/game_gui.cpp | 2 +- src/help_gui.cpp | 2 +- src/network/network_content_gui.cpp | 10 +++++----- src/network/network_gui.cpp | 10 +++++----- src/network/network_gui.h | 2 +- src/newgrf_gui.cpp | 29 ++++++++++++++--------------- src/script/script_gui.cpp | 8 ++++---- src/script/script_gui.h | 2 +- src/settings_gui.cpp | 17 ++++++++--------- src/textfile_gui.cpp | 3 ++- src/textfile_gui.h | 2 +- 12 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 04c39eb30d..27ee9156a0 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -218,7 +218,7 @@ struct AIConfigWindow : public Window { if (widget >= WID_AIC_TEXTFILE && widget < WID_AIC_TEXTFILE + TFT_CONTENT_END) { if (this->selected_slot == CompanyID::Invalid() || AIConfig::GetConfig(this->selected_slot) == nullptr) return; - ShowScriptTextfileWindow((TextfileType)(widget - WID_AIC_TEXTFILE), this->selected_slot); + ShowScriptTextfileWindow(this, (TextfileType)(widget - WID_AIC_TEXTFILE), this->selected_slot); return; } diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index c58cde9654..498b3b2689 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -228,7 +228,7 @@ struct GSConfigWindow : public Window { if (widget >= WID_GSC_TEXTFILE && widget < WID_GSC_TEXTFILE + TFT_CONTENT_END) { if (GameConfig::GetConfig() == nullptr) return; - ShowScriptTextfileWindow((TextfileType)(widget - WID_GSC_TEXTFILE), (CompanyID)OWNER_DEITY); + ShowScriptTextfileWindow(this, (TextfileType)(widget - WID_GSC_TEXTFILE), (CompanyID)OWNER_DEITY); return; } diff --git a/src/help_gui.cpp b/src/help_gui.cpp index b15e50bdb4..14c18652a8 100644 --- a/src/help_gui.cpp +++ b/src/help_gui.cpp @@ -61,7 +61,7 @@ static std::optional FindGameManualFilePath(std::string_view filena /** Window class displaying the game manual textfile viewer. */ struct GameManualTextfileWindow : public TextfileWindow { - GameManualTextfileWindow(std::string_view filename, Subdirectory subdir) : TextfileWindow(TFT_GAME_MANUAL) + GameManualTextfileWindow(std::string_view filename, Subdirectory subdir) : TextfileWindow(nullptr, TFT_GAME_MANUAL) { this->ConstructWindow(); diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index be629022a0..97e6cb88dc 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -44,7 +44,7 @@ static bool _accepted_external_search = false; struct ContentTextfileWindow : public TextfileWindow { const ContentInfo *ci = nullptr; ///< View the textfile of this ContentInfo. - ContentTextfileWindow(TextfileType file_type, const ContentInfo *ci) : TextfileWindow(file_type), ci(ci) + ContentTextfileWindow(Window *parent, TextfileType file_type, const ContentInfo *ci) : TextfileWindow(parent, file_type), ci(ci) { this->ConstructWindow(); @@ -79,10 +79,10 @@ struct ContentTextfileWindow : public TextfileWindow { } }; -void ShowContentTextfileWindow(TextfileType file_type, const ContentInfo *ci) +static void ShowContentTextfileWindow(Window *parent, TextfileType file_type, const ContentInfo *ci) { - CloseWindowById(WC_TEXTFILE, file_type); - new ContentTextfileWindow(file_type, ci); + parent->CloseChildWindowById(WC_TEXTFILE, file_type); + new ContentTextfileWindow(parent, file_type, ci); } /** Nested widgets for the download window. */ @@ -776,7 +776,7 @@ public: if (widget >= WID_NCL_TEXTFILE && widget < WID_NCL_TEXTFILE + TFT_CONTENT_END) { if (this->selected == nullptr || this->selected->state != ContentInfo::ALREADY_HERE) return; - ShowContentTextfileWindow((TextfileType)(widget - WID_NCL_TEXTFILE), this->selected); + ShowContentTextfileWindow(this, (TextfileType)(widget - WID_NCL_TEXTFILE), this->selected); return; } diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 2527ba7c99..4b294c743c 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -2323,7 +2323,7 @@ struct NetworkAskSurveyWindow : public Window { { switch (widget) { case WID_NAS_PREVIEW: - ShowSurveyResultTextfileWindow(); + ShowSurveyResultTextfileWindow(this); break; case WID_NAS_LINK: @@ -2388,7 +2388,7 @@ void ShowNetworkAskSurvey() struct SurveyResultTextfileWindow : public TextfileWindow { const GRFConfig *grf_config; ///< View the textfile of this GRFConfig. - SurveyResultTextfileWindow(TextfileType file_type) : TextfileWindow(file_type) + SurveyResultTextfileWindow(Window *parent, TextfileType file_type) : TextfileWindow(parent, file_type) { this->ConstructWindow(); @@ -2398,8 +2398,8 @@ struct SurveyResultTextfileWindow : public TextfileWindow { } }; -void ShowSurveyResultTextfileWindow() +void ShowSurveyResultTextfileWindow(Window *parent) { - CloseWindowById(WC_TEXTFILE, TFT_SURVEY_RESULT); - new SurveyResultTextfileWindow(TFT_SURVEY_RESULT); + parent->CloseChildWindowById(WC_TEXTFILE, TFT_SURVEY_RESULT); + new SurveyResultTextfileWindow(parent, TFT_SURVEY_RESULT); } diff --git a/src/network/network_gui.h b/src/network/network_gui.h index e80851ac44..a717db2f90 100644 --- a/src/network/network_gui.h +++ b/src/network/network_gui.h @@ -24,7 +24,7 @@ void ShowNetworkGameWindow(); void ShowClientList(); void ShowNetworkAskRelay(std::string_view server_connection_string, std::string &&relay_connection_string, std::string &&token); void ShowNetworkAskSurvey(); -void ShowSurveyResultTextfileWindow(); +void ShowSurveyResultTextfileWindow(Window *parent); /** Company information stored at the client side */ struct NetworkCompanyInfo : NetworkCompanyStats { diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index ddd057ab1b..82bf4565b4 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -551,7 +551,7 @@ void OpenGRFParameterWindow(bool is_baseset, GRFConfig &c, bool editable) struct NewGRFTextfileWindow : public TextfileWindow { const GRFConfig *grf_config = nullptr; ///< View the textfile of this GRFConfig. - NewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) : TextfileWindow(file_type), grf_config(c) + NewGRFTextfileWindow(Window *parent, TextfileType file_type, const GRFConfig *c) : TextfileWindow(parent, file_type), grf_config(c) { this->ConstructWindow(); @@ -569,10 +569,10 @@ struct NewGRFTextfileWindow : public TextfileWindow { } }; -void ShowNewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) +void ShowNewGRFTextfileWindow(Window *parent, TextfileType file_type, const GRFConfig *c) { - CloseWindowById(WC_TEXTFILE, file_type); - new NewGRFTextfileWindow(file_type, c); + parent->CloseChildWindowById(WC_TEXTFILE, file_type); + new NewGRFTextfileWindow(parent, file_type, c); } typedef std::map GrfIdMap; ///< Map of grfid to the grf config. @@ -664,7 +664,6 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { void Close([[maybe_unused]] int data = 0) override { CloseWindowByClass(WC_GRF_PARAMETERS); - CloseWindowByClass(WC_TEXTFILE); CloseWindowByClass(WC_SAVE_PRESET); if (this->editable && this->modified && !this->execute && !_exit_game) { @@ -721,7 +720,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } if (this->active_sel == c->get()) { CloseWindowByClass(WC_GRF_PARAMETERS); - CloseWindowByClass(WC_TEXTFILE); + this->CloseChildWindows(WC_TEXTFILE); this->active_sel = nullptr; } *c = std::move(d); @@ -930,7 +929,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { if (widget >= WID_NS_NEWGRF_TEXTFILE && widget < WID_NS_NEWGRF_TEXTFILE + TFT_CONTENT_END) { if (this->active_sel == nullptr && this->avail_sel == nullptr) return; - ShowNewGRFTextfileWindow((TextfileType)(widget - WID_NS_NEWGRF_TEXTFILE), this->active_sel != nullptr ? this->active_sel : this->avail_sel); + ShowNewGRFTextfileWindow(this, (TextfileType)(widget - WID_NS_NEWGRF_TEXTFILE), this->active_sel != nullptr ? this->active_sel : this->avail_sel); return; } @@ -1011,7 +1010,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } if (this->active_sel != old_sel) { CloseWindowByClass(WC_GRF_PARAMETERS); - CloseWindowByClass(WC_TEXTFILE); + this->CloseChildWindows(WC_TEXTFILE); } this->avail_sel = nullptr; this->avail_pos = -1; @@ -1028,7 +1027,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WID_NS_REMOVE: { // Remove GRF if (this->active_sel == nullptr || !this->editable) break; CloseWindowByClass(WC_GRF_PARAMETERS); - CloseWindowByClass(WC_TEXTFILE); + this->CloseChildWindows(WC_TEXTFILE); /* Choose the next GRF file to be the selected file. */ int pos = this->GetCurrentActivePosition(); @@ -1065,7 +1064,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->active_sel = nullptr; CloseWindowByClass(WC_GRF_PARAMETERS); if (it != std::end(this->avails)) { - if (this->avail_sel != *it) CloseWindowByClass(WC_TEXTFILE); + if (this->avail_sel != *it) this->CloseChildWindows(WC_TEXTFILE); this->avail_sel = *it; this->avail_pos = static_cast(std::distance(std::begin(this->avails), it)); } @@ -1139,7 +1138,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { void OnNewGRFsScanned() override { - if (this->active_sel == nullptr) CloseWindowByClass(WC_TEXTFILE); + if (this->active_sel == nullptr) this->CloseChildWindows(WC_TEXTFILE); this->avail_sel = nullptr; this->avail_pos = -1; this->avails.ForceRebuild(); @@ -1161,7 +1160,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { ResetObjectToPlace(); CloseWindowByClass(WC_GRF_PARAMETERS); - CloseWindowByClass(WC_TEXTFILE); + this->CloseChildWindows(WC_TEXTFILE); this->active_sel = nullptr; this->InvalidateData(GOID_NEWGRF_CHANGES_MADE); } @@ -1312,7 +1311,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { if (this->avail_pos >= 0) { this->active_sel = nullptr; CloseWindowByClass(WC_GRF_PARAMETERS); - if (this->avail_sel != this->avails[this->avail_pos]) CloseWindowByClass(WC_TEXTFILE); + if (this->avail_sel != this->avails[this->avail_pos]) this->CloseChildWindows(WC_TEXTFILE); this->avail_sel = this->avails[this->avail_pos]; this->vscroll2->ScrollTowards(this->avail_pos); this->InvalidateData(0); @@ -1473,7 +1472,7 @@ private: { if (this->avail_sel == nullptr || !this->editable || this->avail_sel->flags.Test(GRFConfigFlag::Invalid)) return false; - CloseWindowByClass(WC_TEXTFILE); + this->CloseChildWindows(WC_TEXTFILE); /* Get number of non-static NewGRFs. */ size_t count = std::ranges::count_if(this->actives, [](const auto &gc) { return !gc->flags.Test(GRFConfigFlag::Static); }); @@ -1928,7 +1927,7 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed) { if (confirmed) { CloseWindowByClass(WC_GRF_PARAMETERS); - CloseWindowByClass(WC_TEXTFILE); + w->CloseChildWindows(WC_TEXTFILE); NewGRFWindow *nw = dynamic_cast(w); assert(nw != nullptr); diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index 9c64d4bda8..15d35fb33a 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -609,7 +609,7 @@ void ShowScriptSettingsWindow(CompanyID slot) struct ScriptTextfileWindow : public TextfileWindow { CompanyID slot{}; ///< View the textfile of this CompanyID slot. - ScriptTextfileWindow(TextfileType file_type, CompanyID slot) : TextfileWindow(file_type), slot(slot) + ScriptTextfileWindow(Window *parent, TextfileType file_type, CompanyID slot) : TextfileWindow(parent, file_type), slot(slot) { this->ConstructWindow(); this->OnInvalidateData(); @@ -640,10 +640,10 @@ struct ScriptTextfileWindow : public TextfileWindow { * @param file_type The type of textfile to display. * @param slot The slot the Script is using. */ -void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot) +void ShowScriptTextfileWindow(Window *parent, TextfileType file_type, CompanyID slot) { - CloseWindowById(WC_TEXTFILE, file_type); - new ScriptTextfileWindow(file_type, slot); + parent->CloseChildWindowById(WC_TEXTFILE, file_type); + new ScriptTextfileWindow(parent, file_type, slot); } diff --git a/src/script/script_gui.h b/src/script/script_gui.h index 3ba6e423fe..abb2063679 100644 --- a/src/script/script_gui.h +++ b/src/script/script_gui.h @@ -18,7 +18,7 @@ struct Window; void ShowScriptListWindow(CompanyID slot, bool show_all); Window *ShowScriptDebugWindow(CompanyID show_company = CompanyID::Invalid(), bool new_window = false); void ShowScriptSettingsWindow(CompanyID slot); -void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot); +void ShowScriptTextfileWindow(Window *parent, TextfileType file_type, CompanyID slot); void ShowScriptDebugWindowIfScriptError(); void InitializeScriptGui(); diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 70e3553733..94a073d904 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -103,7 +103,7 @@ struct BaseSetTextfileWindow : public TextfileWindow { const std::string name; ///< Name of the content. const StringID content_type; ///< STR_CONTENT_TYPE_xxx for title. - BaseSetTextfileWindow(TextfileType file_type, const std::string &name, const std::string &textfile, StringID content_type) : TextfileWindow(file_type), name(name), content_type(content_type) + BaseSetTextfileWindow(Window *parent, TextfileType file_type, const std::string &name, const std::string &textfile, StringID content_type) : TextfileWindow(parent, file_type), name(name), content_type(content_type) { this->ConstructWindow(); this->LoadTextfile(textfile, BASESET_DIR); @@ -126,10 +126,10 @@ struct BaseSetTextfileWindow : public TextfileWindow { * @param content_type STR_CONTENT_TYPE_xxx for title. */ template -void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet *baseset, StringID content_type) +void ShowBaseSetTextfileWindow(Window *parent, TextfileType file_type, const TBaseSet *baseset, StringID content_type) { - CloseWindowById(WC_TEXTFILE, file_type); - new BaseSetTextfileWindow(file_type, baseset->name, *baseset->GetTextfile(file_type), content_type); + parent->CloseChildWindowById(WC_TEXTFILE, file_type); + new BaseSetTextfileWindow(parent, file_type, baseset->name, *baseset->GetTextfile(file_type), content_type); } /** @@ -464,7 +464,6 @@ struct GameOptionsWindow : Window { void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_CUSTOM_CURRENCY, 0); - CloseWindowByClass(WC_TEXTFILE); if (this->reload) _switch_mode = SM_MENU; this->Window::Close(); } @@ -939,19 +938,19 @@ struct GameOptionsWindow : Window { if (widget >= WID_GO_BASE_GRF_TEXTFILE && widget < WID_GO_BASE_GRF_TEXTFILE + TFT_CONTENT_END) { if (BaseGraphics::GetUsedSet() == nullptr) return; - ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_GRF_TEXTFILE), BaseGraphics::GetUsedSet(), STR_CONTENT_TYPE_BASE_GRAPHICS); + ShowBaseSetTextfileWindow(this, (TextfileType)(widget - WID_GO_BASE_GRF_TEXTFILE), BaseGraphics::GetUsedSet(), STR_CONTENT_TYPE_BASE_GRAPHICS); return; } if (widget >= WID_GO_BASE_SFX_TEXTFILE && widget < WID_GO_BASE_SFX_TEXTFILE + TFT_CONTENT_END) { if (BaseSounds::GetUsedSet() == nullptr) return; - ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_SFX_TEXTFILE), BaseSounds::GetUsedSet(), STR_CONTENT_TYPE_BASE_SOUNDS); + ShowBaseSetTextfileWindow(this, (TextfileType)(widget - WID_GO_BASE_SFX_TEXTFILE), BaseSounds::GetUsedSet(), STR_CONTENT_TYPE_BASE_SOUNDS); return; } if (widget >= WID_GO_BASE_MUSIC_TEXTFILE && widget < WID_GO_BASE_MUSIC_TEXTFILE + TFT_CONTENT_END) { if (BaseMusic::GetUsedSet() == nullptr) return; - ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_MUSIC_TEXTFILE), BaseMusic::GetUsedSet(), STR_CONTENT_TYPE_BASE_MUSIC); + ShowBaseSetTextfileWindow(this, (TextfileType)(widget - WID_GO_BASE_MUSIC_TEXTFILE), BaseMusic::GetUsedSet(), STR_CONTENT_TYPE_BASE_MUSIC); return; } switch (widget) { @@ -984,7 +983,7 @@ struct GameOptionsWindow : Window { break; case WID_GO_SURVEY_PREVIEW_BUTTON: - ShowSurveyResultTextfileWindow(); + ShowSurveyResultTextfileWindow(this); break; case WID_GO_FULLSCREEN_BUTTON: // Click fullscreen on/off diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 1046af2813..10b85ab1cd 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -83,10 +83,11 @@ static WindowDesc _textfile_desc( _nested_textfile_widgets ); -TextfileWindow::TextfileWindow(TextfileType file_type) : Window(_textfile_desc), file_type(file_type) +TextfileWindow::TextfileWindow(Window *parent, TextfileType file_type) : Window(_textfile_desc), file_type(file_type) { /* Init of nested tree is deferred. * TextfileWindow::ConstructWindow must be called by the inheriting window. */ + this->parent = parent; } void TextfileWindow::ConstructWindow() diff --git a/src/textfile_gui.h b/src/textfile_gui.h index 5e66611691..8e24ed92a4 100644 --- a/src/textfile_gui.h +++ b/src/textfile_gui.h @@ -41,7 +41,7 @@ struct TextfileWindow : public Window, MissingGlyphSearcher { virtual void LoadTextfile(const std::string &textfile, Subdirectory dir); protected: - TextfileWindow(TextfileType file_type); + TextfileWindow(Window *parent, TextfileType file_type); void ConstructWindow(); struct Line {