diff --git a/src/wx/CMakeLists.txt b/src/wx/CMakeLists.txt index 6cf1b787..765e7cbe 100644 --- a/src/wx/CMakeLists.txt +++ b/src/wx/CMakeLists.txt @@ -31,6 +31,8 @@ set(VBAM_WX_COMMON config/user-input.h dialogs/accel-config.cpp dialogs/accel-config.h + dialogs/base-dialog.cpp + dialogs/base-dialog.h dialogs/directories-config.cpp dialogs/directories-config.h dialogs/display-config.cpp @@ -45,7 +47,6 @@ set(VBAM_WX_COMMON dialogs/joypad-config.h dialogs/sound-config.cpp dialogs/sound-config.h - dialogs/validated-child.h drawing.h extra-translations.cpp gfxviewers.cpp @@ -79,6 +80,8 @@ set(VBAM_WX_COMMON widgets/user-input-ctrl.h widgets/sdljoy.cpp widgets/sdljoy.h + widgets/utils.cpp + widgets/utils.h widgets/webupdatedef.h widgets/wxmisc.h widgets/wxmisc.cpp diff --git a/src/wx/cmdevents.cpp b/src/wx/cmdevents.cpp index 0fd99727..62471ca8 100644 --- a/src/wx/cmdevents.cpp +++ b/src/wx/cmdevents.cpp @@ -1714,7 +1714,7 @@ EVT_HANDLER_MASK(Disassemble, "Disassemble...", CMDEN_GB | CMDEN_GBA) EVT_HANDLER(Logging, "Logging...") { - wxDialog* dlg = wxGetApp().frame->logdlg; + wxDialog* dlg = wxGetApp().frame->logdlg.get(); dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER); dlg->Show(); dlg->Raise(); diff --git a/src/wx/dialogs/accel-config.cpp b/src/wx/dialogs/accel-config.cpp index 4ec92180..104501cf 100644 --- a/src/wx/dialogs/accel-config.cpp +++ b/src/wx/dialogs/accel-config.cpp @@ -5,12 +5,10 @@ #include #include #include -#include #include "wx/config/shortcuts.h" #include "wx/config/user-input.h" -#include "wx/dialogs/validated-child.h" -#include "wx/opts.h" +#include "wx/dialogs/base-dialog.h" #include "wx/widgets/user-input-ctrl.h" #include "wx/wxvbam.h" @@ -132,21 +130,16 @@ AccelConfig* AccelConfig::NewInstance(wxWindow* parent, wxMenuBar* menu, wxMenu* } AccelConfig::AccelConfig(wxWindow* parent, wxMenuBar* menu, wxMenu* recents) - : wxDialog(), keep_on_top_styler_(this) { - assert(parent); + : BaseDialog(parent, "AccelConfig") { assert(menu); - // Load the dialog XML. - const bool success = wxXmlResource::Get()->LoadDialog(this, parent, "AccelConfig"); - assert(success); - // Loads the various dialog elements. - tree_ = GetValidatedChild(this, "Commands"); - current_keys_ = GetValidatedChild(this, "Current"); - assign_button_ = GetValidatedChild(this, "Assign"); - remove_button_ = GetValidatedChild(this, "Remove"); - key_input_ = GetValidatedChild(this, "Shortcut"); - currently_assigned_label_ = GetValidatedChild(this, "AlreadyThere"); + tree_ = GetValidatedChild("Commands"); + current_keys_ = GetValidatedChild("Current"); + assign_button_ = GetValidatedChild("Assign"); + remove_button_ = GetValidatedChild("Remove"); + key_input_ = GetValidatedChild("Shortcut"); + currently_assigned_label_ = GetValidatedChild("AlreadyThere"); // Configure the key input. key_input_->MoveBeforeInTabOrder(assign_button_); diff --git a/src/wx/dialogs/accel-config.h b/src/wx/dialogs/accel-config.h index b999d34c..11c9ce42 100644 --- a/src/wx/dialogs/accel-config.h +++ b/src/wx/dialogs/accel-config.h @@ -3,11 +3,10 @@ #include -#include #include #include "wx/config/shortcuts.h" -#include "wx/widgets/keep-on-top-styler.h" +#include "wx/dialogs/base-dialog.h" // Forward declarations. class wxControl; @@ -23,7 +22,7 @@ class UserInputCtrl; namespace dialogs { // Manages the shortcuts editor dialog. -class AccelConfig : public wxDialog { +class AccelConfig : public BaseDialog { public: static AccelConfig* NewInstance(wxWindow* parent, wxMenuBar* menu_bar, wxMenu* recents); @@ -74,8 +73,6 @@ private: config::Shortcuts config_shortcuts_; int selected_command_ = 0; - - const widgets::KeepOnTopStyler keep_on_top_styler_; }; } // namespace dialogs diff --git a/src/wx/dialogs/base-dialog.cpp b/src/wx/dialogs/base-dialog.cpp new file mode 100644 index 00000000..0817782b --- /dev/null +++ b/src/wx/dialogs/base-dialog.cpp @@ -0,0 +1,137 @@ +#include "wx/dialogs/base-dialog.h" + +#include + +#include +#include +#include + +#include "wx/config/option-proxy.h" +#include "wx/widgets/utils.h" + +namespace dialogs { + +namespace { + +// Due to the way wxWidgets handles initialization, we need to use a custom +// persistent object to save and restore the dialog's position. In particular, +// when the dialog is constructed, the the main window is not (yet) in its final +// position. This means we need to differentiate between 2 states here: +// 1. The dialog was registered for the first time and never shown. +// We don't want to save the position in this case. +// 2. The dialog was registered and shown at least once. +// We want to save the position in this case. However, on restore, we need +// to check we are not drawing out of bounds. +// +// We can't use the built-in wxPersistenceManager for this, as it doesn't allow +// us to differentiate between these 2 states. +class PersistentBaseDialog : public wxPersistentWindow { +public: + PersistentBaseDialog(BaseDialog* window) : wxPersistentWindow(window) {} + +private: + // wxPersistentObject implementation. + wxString GetKind() const override { return "Dialog"; } + + void Save() const override { + if (!dialog_shown_) { + // Do not update the position if the dialog was not shown. + return; + } + + const wxRect dialog_rect = this->Get()->GetRect(); + this->SaveValue("x", dialog_rect.x); + this->SaveValue("y", dialog_rect.y); + this->SaveValue("width", dialog_rect.width); + this->SaveValue("height", dialog_rect.height); + } + + bool Restore() override { + dialog_shown_ = true; + wxRect dialog_rect(0, 0, 0, 0); + if (!this->RestoreValue("x", &dialog_rect.x)) { + return false; + }; + if (!this->RestoreValue("y", &dialog_rect.y)) { + return false; + }; + if (!this->RestoreValue("width", &dialog_rect.width)) { + return false; + }; + if (!this->RestoreValue("height", &dialog_rect.height)) { + return false; + }; + + this->Get()->SetSize(dialog_rect); + return true; + } + + bool dialog_shown_ = false; +}; + +} // namespace + +// static +wxDialog* BaseDialog::LoadDialog(wxWindow* parent, const wxString& xrc_file) { + assert(parent); + return new BaseDialog(parent, xrc_file); +} + +BaseDialog::BaseDialog(wxWindow* parent, const wxString& xrc_file) + : wxDialog(), keep_on_top_styler_(this) { +#if !wxCHECK_VERSION(3, 1, 0) + // This needs to be set before loading any element on the window. This also + // has no effect since wx 3.1.0, where it became the default. + this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); +#endif + + [[maybe_unused]] const bool success = wxXmlResource::Get()->LoadDialog(this, parent, xrc_file); + assert(success); + + // Bind the event handler. + this->Bind(wxEVT_SHOW, &BaseDialog::OnBaseDialogShow, this); + + wxPersistenceManager::Get().Register(this, new PersistentBaseDialog(this)); +} + +wxWindow* BaseDialog::GetValidatedChild(const wxString& name) const { + wxWindow* window = this->FindWindow(name); + assert(window); + return window; +} + +void BaseDialog::OnBaseDialogShow(wxShowEvent& event) { + if (event.IsShown()) { + // Restore the dialog saved position. + if (wxPersistenceManager::Get().Restore(this)) { + // Ensure we are not restoring the dialog out of bounds. + if (!widgets::GetDisplayRect().Intersects(this->GetRect())) { + this->RepositionDialog(); + } + } else { + // First-time use. + this->RepositionDialog(); + } + + // Do not run this again. + this->Unbind(wxEVT_SHOW, &BaseDialog::OnBaseDialogShow, this); + } + + // Let the event propagate. + event.Skip(); +} + +void BaseDialog::RepositionDialog() { + // Re-position the dialog slightly to the bottom-right of the parent. + const wxWindow* parent = this->GetParent(); + wxPoint parent_pos; + if (parent) { + parent_pos = parent->GetPosition(); + } else { + parent_pos = wxPoint(OPTION(kGeomWindowX), OPTION(kGeomWindowY)); + } + const wxPoint dialog_pos = parent_pos + wxPoint(40, 40); + this->SetPosition(dialog_pos); +} + +} // namespace dialogs diff --git a/src/wx/dialogs/base-dialog.h b/src/wx/dialogs/base-dialog.h new file mode 100644 index 00000000..7ac7451d --- /dev/null +++ b/src/wx/dialogs/base-dialog.h @@ -0,0 +1,42 @@ +#ifndef VBAM_WX_DIALOGS_BASE_DIALOG_H_ +#define VBAM_WX_DIALOGS_BASE_DIALOG_H_ + +#include +#include + +#include "wx/widgets/keep-on-top-styler.h" + +namespace dialogs { + +class BaseDialog : public wxDialog { +public: + static wxDialog* LoadDialog(wxWindow* parent, const wxString& xrc_file); + + ~BaseDialog() override = default; + +protected: + BaseDialog(wxWindow* parent, const wxString& xrc_file); + + // Helper function to assert on the returned value. + wxWindow* GetValidatedChild(const wxString& name) const; + + template + T* GetValidatedChild(const wxString& name) const { + T* child = wxDynamicCast(this->GetValidatedChild(name), T); + assert(child); + return child; + } + +private: + // Handler for the wxEVT_SHOW event. + void OnBaseDialogShow(wxShowEvent& event); + + // Repositions the dialog to the bottom-right of the parent. + void RepositionDialog(); + + const widgets::KeepOnTopStyler keep_on_top_styler_; +}; + +} // namespace dialogs + +#endif // VBAM_WX_DIALOGS_BASE_DIALOG_H_ \ No newline at end of file diff --git a/src/wx/dialogs/directories-config.cpp b/src/wx/dialogs/directories-config.cpp index ff38a0b7..5e58a322 100644 --- a/src/wx/dialogs/directories-config.cpp +++ b/src/wx/dialogs/directories-config.cpp @@ -2,9 +2,7 @@ #include -#include - -#include "wx/dialogs/validated-child.h" +#include "wx/dialogs/base-dialog.h" #include "wx/widgets/option-validator.h" namespace dialogs { @@ -58,29 +56,23 @@ DirectoriesConfig* DirectoriesConfig::NewInstance(wxWindow* parent) { return new DirectoriesConfig(parent); } -DirectoriesConfig::DirectoriesConfig(wxWindow* parent) - : wxDialog(), keep_on_top_styler_(this) { -#if !wxCHECK_VERSION(3, 1, 0) - // This needs to be set before loading any element on the window. This also - // has no effect since wx 3.1.0, where it became the default. - this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); -#endif - wxXmlResource::Get()->LoadDialog(this, parent, "DirectoriesConfig"); - - SetUpDirPicker(GetValidatedChild(this, "GBARoms"), +DirectoriesConfig::DirectoriesConfig(wxWindow* parent) : BaseDialog(parent, "DirectoriesConfig") { + // clang-format off + SetUpDirPicker(GetValidatedChild("GBARoms"), config::OptionID::kGBAROMDir); - SetUpDirPicker(GetValidatedChild(this, "GBRoms"), + SetUpDirPicker(GetValidatedChild("GBRoms"), config::OptionID::kGBROMDir); - SetUpDirPicker(GetValidatedChild(this, "GBCRoms"), + SetUpDirPicker(GetValidatedChild("GBCRoms"), config::OptionID::kGBGBCROMDir); - SetUpDirPicker(GetValidatedChild(this, "BatSaves"), + SetUpDirPicker(GetValidatedChild("BatSaves"), config::OptionID::kGenBatteryDir); - SetUpDirPicker(GetValidatedChild(this, "StateSaves"), + SetUpDirPicker(GetValidatedChild("StateSaves"), config::OptionID::kGenStateDir); - SetUpDirPicker(GetValidatedChild(this, "Screenshots"), + SetUpDirPicker(GetValidatedChild("Screenshots"), config::OptionID::kGenScreenshotDir); - SetUpDirPicker(GetValidatedChild(this, "Recordings"), + SetUpDirPicker(GetValidatedChild("Recordings"), config::OptionID::kGenRecordingDir); + // clang-format on this->Fit(); } diff --git a/src/wx/dialogs/directories-config.h b/src/wx/dialogs/directories-config.h index 8ead7bf0..0b42b468 100644 --- a/src/wx/dialogs/directories-config.h +++ b/src/wx/dialogs/directories-config.h @@ -1,14 +1,12 @@ #ifndef VBAM_WX_DIALOGS_DIRECTORIES_CONFIG_H_ #define VBAM_WX_DIALOGS_DIRECTORIES_CONFIG_H_ -#include - -#include "wx/widgets/keep-on-top-styler.h" +#include "wx/dialogs/base-dialog.h" namespace dialogs { // Manages the directories configuration dialog. -class DirectoriesConfig : public wxDialog { +class DirectoriesConfig : public BaseDialog { public: static DirectoriesConfig* NewInstance(wxWindow* parent); ~DirectoriesConfig() override = default; @@ -18,8 +16,6 @@ private: // static method. This is because this class is destroyed when its // owner, `parent` is destroyed. This prevents accidental deletion. DirectoriesConfig(wxWindow* parent); - - const widgets::KeepOnTopStyler keep_on_top_styler_; }; } // namespace dialogs diff --git a/src/wx/dialogs/display-config.cpp b/src/wx/dialogs/display-config.cpp index de656df0..797b5fde 100644 --- a/src/wx/dialogs/display-config.cpp +++ b/src/wx/dialogs/display-config.cpp @@ -16,7 +16,7 @@ #include "wx/config/option-id.h" #include "wx/config/option-proxy.h" #include "wx/config/option.h" -#include "wx/dialogs/validated-child.h" +#include "wx/dialogs/base-dialog.h" #include "wx/rpi.h" #include "wx/widgets/option-validator.h" #include "wx/widgets/render-plugin.h" @@ -225,7 +225,7 @@ DisplayConfig* DisplayConfig::NewInstance(wxWindow* parent) { } DisplayConfig::DisplayConfig(wxWindow* parent) - : wxDialog(), + : BaseDialog(parent, "DisplayConfig"), filter_observer_(config::OptionID::kDispFilter, std::bind(&DisplayConfig::OnFilterChanged, this, @@ -233,77 +233,69 @@ DisplayConfig::DisplayConfig(wxWindow* parent) interframe_observer_(config::OptionID::kDispIFB, std::bind(&DisplayConfig::OnInterframeChanged, this, - std::placeholders::_1)), - keep_on_top_styler_(this) { -#if !wxCHECK_VERSION(3, 1, 0) - // This needs to be set before loading any element on the window. This also - // has no effect since wx 3.1.0, where it became the default. - this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); -#endif - wxXmlResource::Get()->LoadDialog(this, parent, "DisplayConfig"); - + std::placeholders::_1)) { // Speed - GetValidatedChild(this, "FrameSkip") + GetValidatedChild("FrameSkip") ->SetValidator( widgets::OptionIntValidator(config::OptionID::kPrefFrameSkip)); // On-Screen Display - GetValidatedChild(this, "SpeedIndicator") + GetValidatedChild("SpeedIndicator") ->SetValidator( widgets::OptionChoiceValidator(config::OptionID::kPrefShowSpeed)); // Zoom - GetValidatedChild(this, "DefaultScale")->SetValidator(ScaleValidator()); + GetValidatedChild("DefaultScale")->SetValidator(ScaleValidator()); // this was a choice, but I'd rather not have to make an off-by-one // validator just for this, and spinctrl is good enough. - GetValidatedChild(this, "MaxScale") + GetValidatedChild("MaxScale") ->SetValidator(wxGenericValidator(&gopts.max_scale)); // Basic - GetValidatedChild(this, "OutputSimple") + GetValidatedChild("OutputSimple") ->SetValidator(RenderValidator(config::RenderMethod::kSimple)); #if defined(__WXMAC__) - GetValidatedChild(this, "OutputQuartz2D") + GetValidatedChild("OutputQuartz2D") ->SetValidator(RenderValidator(config::RenderMethod::kQuartz2d)); #else - GetValidatedChild(this, "OutputQuartz2D")->Hide(); + GetValidatedChild("OutputQuartz2D")->Hide(); #endif #ifdef NO_OGL - GetValidatedChild(this, "OutputOpenGL")->Hide(); + GetValidatedChild("OutputOpenGL")->Hide(); #elif defined(HAVE_WAYLAND_SUPPORT) && !defined(HAVE_WAYLAND_EGL) // wxGLCanvas segfaults on Wayland before wx 3.2. if (IsWayland()) { - GetValidatedChild(this, "OutputOpenGL")->Hide(); + GetValidatedChild("OutputOpenGL")->Hide(); } else { - GetValidatedChild(this, "OutputOpenGL") + GetValidatedChild("OutputOpenGL") ->SetValidator(RenderValidator(config::RenderMethod::kOpenGL)); } #else - GetValidatedChild(this, "OutputOpenGL") + GetValidatedChild("OutputOpenGL") ->SetValidator(RenderValidator(config::RenderMethod::kOpenGL)); #endif // NO_OGL #if defined(__WXMSW__) && !defined(NO_D3D) // Enable the Direct3D option on Windows. - GetValidatedChild(this, "OutputDirect3D") + GetValidatedChild("OutputDirect3D") ->SetValidator(RenderValidator(config::RenderMethod::kDirect3d)); #else - GetValidatedChild(this, "OutputDirect3D")->Hide(); + GetValidatedChild("OutputDirect3D")->Hide(); #endif - filter_selector_ = GetValidatedChild(this, "Filter"); + filter_selector_ = GetValidatedChild("Filter"); filter_selector_->SetValidator(FilterValidator()); filter_selector_->Bind(wxEVT_CHOICE, &DisplayConfig::UpdatePlugin, this, GetId()); // These are filled and/or hidden at dialog load time. - plugin_label_ = GetValidatedChild(this, "PluginLab"); - plugin_selector_ = GetValidatedChild(this, "Plugin"); + plugin_label_ = GetValidatedChild("PluginLab"); + plugin_selector_ = GetValidatedChild("Plugin"); - interframe_selector_ = GetValidatedChild(this, "IFB"); + interframe_selector_ = GetValidatedChild("IFB"); interframe_selector_->SetValidator(InterframeValidator()); Bind(wxEVT_SHOW, &DisplayConfig::OnDialogShowEvent, this, GetId()); diff --git a/src/wx/dialogs/display-config.h b/src/wx/dialogs/display-config.h index ec99b2a3..82bbfee1 100644 --- a/src/wx/dialogs/display-config.h +++ b/src/wx/dialogs/display-config.h @@ -1,11 +1,8 @@ #ifndef VBAM_WX_DIALOGS_DISPLAY_CONFIG_H_ #define VBAM_WX_DIALOGS_DISPLAY_CONFIG_H_ -#include -#include - +#include "wx/dialogs/base-dialog.h" #include "wx/config/option-observer.h" -#include "wx/widgets/keep-on-top-styler.h" // Forward declarations. class wxChoice; @@ -19,7 +16,7 @@ class Option; namespace dialogs { // Manages the display configuration dialog. -class DisplayConfig : public wxDialog { +class DisplayConfig : public BaseDialog { public: static DisplayConfig* NewInstance(wxWindow* parent); ~DisplayConfig() override = default; @@ -58,7 +55,6 @@ private: wxChoice* interframe_selector_; const config::OptionsObserver filter_observer_; const config::OptionsObserver interframe_observer_; - const widgets::KeepOnTopStyler keep_on_top_styler_; }; } // namespace dialogs diff --git a/src/wx/dialogs/game-boy-config.cpp b/src/wx/dialogs/game-boy-config.cpp index ec7f53a2..757fb694 100644 --- a/src/wx/dialogs/game-boy-config.cpp +++ b/src/wx/dialogs/game-boy-config.cpp @@ -15,8 +15,9 @@ #include "wx/config/option-observer.h" #include "wx/config/option-proxy.h" -#include "wx/dialogs/validated-child.h" +#include "wx/dialogs/base-dialog.h" #include "wx/widgets/option-validator.h" +#include "wx/widgets/utils.h" namespace dialogs { @@ -221,23 +222,22 @@ private: GBPalettePanelData::GBPalettePanelData(wxPanel* panel, size_t palette_id) : wxClientData(), - default_selector_(GetValidatedChild(panel, "DefaultPalette")), - option_id_(static_cast( - static_cast(config::OptionID::kGBPalette0) + palette_id)) { + default_selector_(widgets::GetValidatedChild(panel, "DefaultPalette")), + option_id_(static_cast(static_cast(config::OptionID::kGBPalette0) + + palette_id)) { assert(panel); assert(palette_id < kNbPalettes); default_selector_->Bind( wxEVT_CHOICE, &GBPalettePanelData::OnDefaultPaletteSelected, this); - GetValidatedChild(panel, "UsePalette") - ->SetValidator(widgets::OptionSelectedValidator( - config::OptionID::kPrefGBPaletteOption, palette_id)); + widgets::GetValidatedChild(panel, "UsePalette") + ->SetValidator( + widgets::OptionSelectedValidator(config::OptionID::kPrefGBPaletteOption, palette_id)); for (size_t i = 0; i < colour_pickers_.size(); i++) { wxColourPickerCtrl* colour_picker = - GetValidatedChild( - panel, wxString::Format("Color%zu", i)); + widgets::GetValidatedChild(panel, wxString::Format("Color%zu", i)); colour_pickers_[i] = colour_picker; // Update the internal palette reference on colour change. @@ -247,7 +247,7 @@ GBPalettePanelData::GBPalettePanelData(wxPanel* panel, size_t palette_id) colour_picker->GetId()); } - GetValidatedChild(panel, "Reset") + widgets::GetValidatedChild(panel, "Reset") ->Bind(wxEVT_BUTTON, &GBPalettePanelData::OnPaletteReset, this); } @@ -317,39 +317,27 @@ GameBoyConfig* GameBoyConfig::NewInstance(wxWindow* parent) { return new GameBoyConfig(parent); } -GameBoyConfig::GameBoyConfig(wxWindow* parent) - : wxDialog(), keep_on_top_styler_(this) { -#if !wxCHECK_VERSION(3, 1, 0) - // This needs to be set before loading any element on the window. This also - // has no effect since wx 3.1.0, where it became the default. - this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); -#endif - wxXmlResource::Get()->LoadDialog(this, parent, "GameBoyConfig"); - +GameBoyConfig::GameBoyConfig(wxWindow* parent) : BaseDialog(parent, "GameBoyConfig") { // System and Peripherals. - GetValidatedChild(this, "System") - ->SetValidator(widgets::OptionChoiceValidator( - config::OptionID::kPrefEmulatorType)); + GetValidatedChild("System")->SetValidator( + widgets::OptionChoiceValidator(config::OptionID::kPrefEmulatorType)); // "Display borders" corresponds to 2 variables. - GetValidatedChild(this, "Borders")->SetValidator(BorderSelectorValidator()); + GetValidatedChild("Borders")->SetValidator(BorderSelectorValidator()); // GB BIOS ROM - GetValidatedChild(this, "GBBiosPicker") - ->SetValidator(BIOSPickerValidator( - config::OptionID::kGBBiosFile, - GetValidatedChild(this, "GBBiosLabel"))); + GetValidatedChild("GBBiosPicker") + ->SetValidator(BIOSPickerValidator(config::OptionID::kGBBiosFile, + GetValidatedChild("GBBiosLabel"))); // GBC BIOS ROM - GetValidatedChild(this, "GBCBiosPicker") - ->SetValidator(BIOSPickerValidator( - config::OptionID::kGBGBCBiosFile, - GetValidatedChild(this, "GBCBiosLabel"))); + GetValidatedChild("GBCBiosPicker") + ->SetValidator(BIOSPickerValidator(config::OptionID::kGBGBCBiosFile, + GetValidatedChild("GBCBiosLabel"))); for (size_t i = 0; i < kNbPalettes; i++) { // All of the wxPanel logic is handled in its client object. - wxPanel* panel = - GetValidatedChild(this, wxString::Format("cp%zu", i)); + wxPanel* panel = GetValidatedChild(wxString::Format("cp%zu", i)); GBPalettePanelData* palette_data = new GBPalettePanelData(panel, i); // `panel` takes ownership of `palette_data` here. diff --git a/src/wx/dialogs/game-boy-config.h b/src/wx/dialogs/game-boy-config.h index 520473fd..ff765ad4 100644 --- a/src/wx/dialogs/game-boy-config.h +++ b/src/wx/dialogs/game-boy-config.h @@ -2,14 +2,13 @@ #define VBAM_WX_DIALOGS_GAME_BOY_CONFIG_H_ #include -#include -#include "wx/widgets/keep-on-top-styler.h" +#include "wx/dialogs/base-dialog.h" namespace dialogs { // Manages the Game Boy configuration dialog. -class GameBoyConfig : public wxDialog { +class GameBoyConfig : public BaseDialog { public: static GameBoyConfig* NewInstance(wxWindow* parent); ~GameBoyConfig() override = default; @@ -19,8 +18,6 @@ private: // static method. This is because this class is destroyed when its // owner, `parent` is destroyed. This prevents accidental deletion. GameBoyConfig(wxWindow* parent); - - const widgets::KeepOnTopStyler keep_on_top_styler_; }; } // namespace dialogs diff --git a/src/wx/dialogs/gb-rom-info.cpp b/src/wx/dialogs/gb-rom-info.cpp index e5dfef09..cc1dd450 100644 --- a/src/wx/dialogs/gb-rom-info.cpp +++ b/src/wx/dialogs/gb-rom-info.cpp @@ -5,8 +5,8 @@ #include "core/base/sizes.h" #include "core/gb/gb.h" +#include "wx/dialogs/base-dialog.h" #include "wx/dialogs/game-maker.h" -#include "wx/dialogs/validated-child.h" namespace dialogs { @@ -171,14 +171,7 @@ GbRomInfo* GbRomInfo::NewInstance(wxWindow* parent) { return new GbRomInfo(parent); } -GbRomInfo::GbRomInfo(wxWindow* parent) : wxDialog(), keep_on_top_styler_(this) { -#if !wxCHECK_VERSION(3, 1, 0) - // This needs to be set before loading any element on the window. This also - // has no effect since wx 3.1.0, where it became the default. - this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); -#endif - wxXmlResource::Get()->LoadDialog(this, parent, "GBROMInfo"); - +GbRomInfo::GbRomInfo(wxWindow* parent) : BaseDialog(parent, "GBROMInfo") { Bind(wxEVT_SHOW, &GbRomInfo::OnDialogShowEvent, this); } @@ -191,23 +184,23 @@ void GbRomInfo::OnDialogShowEvent(wxShowEvent& event) { } // Populate the dialog. - GetValidatedChild(this, "Title")->SetLabel(g_gbCartData.title()); - GetValidatedChild(this, "MakerCode")->SetLabel(g_gbCartData.maker_code()); - GetValidatedChild(this, "MakerName")->SetLabel(GetGameMakerName(g_gbCartData.maker_code())); - GetValidatedChild(this, "CartridgeType")->SetLabel(GetCartType()); - GetValidatedChild(this, "SGBCode")->SetLabel(GetCartSGBFlag()); - GetValidatedChild(this, "CGBCode")->SetLabel(GetCartCGBFlag()); - GetValidatedChild(this, "ROMSize")->SetLabel(GetCartRomSize()); - GetValidatedChild(this, "RAMSize")->SetLabel(GetCartRamSize()); - GetValidatedChild(this, "DestCode")->SetLabel(GetCartDestinationCode()); - GetValidatedChild(this, "LicCode") + GetValidatedChild("Title")->SetLabel(g_gbCartData.title()); + GetValidatedChild("MakerCode")->SetLabel(g_gbCartData.maker_code()); + GetValidatedChild("MakerName")->SetLabel(GetGameMakerName(g_gbCartData.maker_code())); + GetValidatedChild("CartridgeType")->SetLabel(GetCartType()); + GetValidatedChild("SGBCode")->SetLabel(GetCartSGBFlag()); + GetValidatedChild("CGBCode")->SetLabel(GetCartCGBFlag()); + GetValidatedChild("ROMSize")->SetLabel(GetCartRomSize()); + GetValidatedChild("RAMSize")->SetLabel(GetCartRamSize()); + GetValidatedChild("DestCode")->SetLabel(GetCartDestinationCode()); + GetValidatedChild("LicCode") ->SetLabel(wxString::Format("%02X", g_gbCartData.old_licensee_code())); - GetValidatedChild(this, "Version") + GetValidatedChild("Version") ->SetLabel(wxString::Format("%02X", g_gbCartData.version_flag())); - GetValidatedChild(this, "HeaderChecksum") + GetValidatedChild("HeaderChecksum") ->SetLabel(wxString::Format(_("%02X (Actual: %02X)"), g_gbCartData.header_checksum(), g_gbCartData.actual_header_checksum())); - GetValidatedChild(this, "CartridgeChecksum") + GetValidatedChild("CartridgeChecksum") ->SetLabel(wxString::Format(_("%04X (Actual: %04X)"), g_gbCartData.global_checksum(), g_gbCartData.actual_global_checksum())); diff --git a/src/wx/dialogs/gb-rom-info.h b/src/wx/dialogs/gb-rom-info.h index 1e5b51ec..ed25a221 100644 --- a/src/wx/dialogs/gb-rom-info.h +++ b/src/wx/dialogs/gb-rom-info.h @@ -1,13 +1,11 @@ #ifndef VBAM_WX_DIALOGS_GB_ROM_INFO_H_ #define VBAM_WX_DIALOGS_GB_ROM_INFO_H_ -#include - -#include "wx/widgets/keep-on-top-styler.h" +#include "wx/dialogs/base-dialog.h" namespace dialogs { -class GbRomInfo : public wxDialog { +class GbRomInfo : public BaseDialog { public: static GbRomInfo* NewInstance(wxWindow* parent); ~GbRomInfo() override = default; @@ -20,8 +18,6 @@ private: // Handler for the wxEVT_SHOW event. void OnDialogShowEvent(wxShowEvent& event); - - const widgets::KeepOnTopStyler keep_on_top_styler_; }; } // namespace dialogs diff --git a/src/wx/dialogs/joypad-config.cpp b/src/wx/dialogs/joypad-config.cpp index 9729fe41..43c61311 100644 --- a/src/wx/dialogs/joypad-config.cpp +++ b/src/wx/dialogs/joypad-config.cpp @@ -2,11 +2,11 @@ #include -#include "wx/dialogs/validated-child.h" #include "wx/config/option-proxy.h" -#include "wx/config/option.h" +#include "wx/dialogs/base-dialog.h" #include "wx/widgets/option-validator.h" #include "wx/widgets/user-input-ctrl.h" +#include "wx/widgets/utils.h" #include "wx/wxvbam.h" namespace dialogs { @@ -17,23 +17,17 @@ JoypadConfig* JoypadConfig::NewInstance(wxWindow* parent) { return new JoypadConfig(parent); } -JoypadConfig::JoypadConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(this) { -#if !wxCHECK_VERSION(3, 1, 0) - // This needs to be set before loading any element on the window. This also - // has no effect since wx 3.1.0, where it became the default. - this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); -#endif - wxXmlResource::Get()->LoadDialog(this, parent, "JoypadConfig"); - +JoypadConfig::JoypadConfig(wxWindow* parent) : BaseDialog(parent, "JoypadConfig") { this->Bind(wxEVT_CHECKBOX, std::bind(&JoypadConfig::ToggleSDLGameControllerMode, this), XRCID("SDLGameControllerMode")); - GetValidatedChild(this, "SDLGameControllerMode")->SetValue(OPTION(kSDLGameControllerMode)); + GetValidatedChild("SDLGameControllerMode") + ->SetValue(OPTION(kSDLGameControllerMode)); for (int joypad = 0; joypad < 4; joypad++) { - wxWindow* panel = GetValidatedChild(this, wxString::Format("joy%d", joypad + 1)); + wxWindow* panel = GetValidatedChild(wxString::Format("joy%d", joypad + 1)); - GetValidatedChild(panel, "DefaultConfig") + widgets::GetValidatedChild(panel, "DefaultConfig") ->SetValidator( widgets::OptionSelectedValidator(config::OptionID::kJoyDefault, joypad + 1)); @@ -45,7 +39,7 @@ JoypadConfig::JoypadConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(t for (const config::GameKey& game_key : config::kAllGameKeys) { const wxString game_key_name = config::GameKeyToString(game_key); widgets::UserInputCtrl* game_key_control = - GetValidatedChild(panel, game_key_name); + widgets::GetValidatedChild(panel, game_key_name); wxWindow* current_parent = game_key_control->GetParent(); game_key_control->SetValidator( @@ -77,28 +71,28 @@ JoypadConfig::JoypadConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(t void JoypadConfig::ResetToDefaults(wxWindow* panel) { for (const config::GameKey& game_key : config::kAllGameKeys) { - GetValidatedChild(panel, config::GameKeyToString(game_key)) + widgets::GetValidatedChild(panel, config::GameKeyToString(game_key)) ->SetInputs(kDefaultBindings.find(config::GameControl(0, game_key))->second); } } void JoypadConfig::ClearJoypad(wxWindow* panel) { for (const config::GameKey& game_key : config::kAllGameKeys) { - GetValidatedChild(panel, config::GameKeyToString(game_key)) + widgets::GetValidatedChild(panel, config::GameKeyToString(game_key)) ->Clear(); } } void JoypadConfig::ToggleSDLGameControllerMode() { - OPTION(kSDLGameControllerMode) = GetValidatedChild(this, "SDLGameControllerMode") - ->IsChecked(); + OPTION(kSDLGameControllerMode) = + GetValidatedChild("SDLGameControllerMode")->IsChecked(); ClearAllJoypads(); wxGetApp().frame->PollAllJoysticks(); } void JoypadConfig::ClearAllJoypads() { for (unsigned joypad = 0; joypad < 4; joypad++) { - wxWindow* panel = GetValidatedChild(this, wxString::Format("joy%d", joypad + 1)); + wxWindow* panel = GetValidatedChild(wxString::Format("joy%d", joypad + 1)); ClearJoypad(panel); } diff --git a/src/wx/dialogs/joypad-config.h b/src/wx/dialogs/joypad-config.h index 0ba191d3..92af73f6 100644 --- a/src/wx/dialogs/joypad-config.h +++ b/src/wx/dialogs/joypad-config.h @@ -1,14 +1,11 @@ #ifndef VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_ #define VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_ -#include - -#include "wx/widgets/keep-on-top-styler.h" - +#include "wx/dialogs/base-dialog.h" namespace dialogs { // Manages the Joypad configuration dialog. -class JoypadConfig : public wxDialog { +class JoypadConfig : public BaseDialog { public: static JoypadConfig* NewInstance(wxWindow* parent); ~JoypadConfig() override = default; @@ -30,8 +27,6 @@ private: // Toggle SDL GameController mode for all joysticks. void ToggleSDLGameControllerMode(); - - const widgets::KeepOnTopStyler keep_on_top_styler_; }; } // namespace dialogs diff --git a/src/wx/dialogs/sound-config.cpp b/src/wx/dialogs/sound-config.cpp index 64c07d54..181ec0b7 100644 --- a/src/wx/dialogs/sound-config.cpp +++ b/src/wx/dialogs/sound-config.cpp @@ -16,7 +16,7 @@ #include "wx/config/option-id.h" #include "wx/config/option-proxy.h" #include "wx/config/option.h" -#include "wx/dialogs/validated-child.h" +#include "wx/dialogs/base-dialog.h" #include "wx/widgets/option-validator.h" namespace dialogs { @@ -140,31 +140,24 @@ SoundConfig* SoundConfig::NewInstance(wxWindow* parent) { return new SoundConfig(parent); } -SoundConfig::SoundConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(this) { -#if !wxCHECK_VERSION(3, 1, 0) - // This needs to be set before loading any element on the window. This also - // has no effect since wx 3.1.0, where it became the default. - this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); -#endif - wxXmlResource::Get()->LoadDialog(this, parent, "SoundConfig"); - +SoundConfig::SoundConfig(wxWindow* parent) : BaseDialog(parent, "SoundConfig") { // Volume slider configuration. - wxSlider* volume_slider = GetValidatedChild(this, "Volume"); + wxSlider* volume_slider = GetValidatedChild("Volume"); volume_slider->SetValidator(widgets::OptionIntValidator(config::OptionID::kSoundVolume)); - GetValidatedChild(this, "Volume100") + GetValidatedChild("Volume100") ->Bind(wxEVT_BUTTON, std::bind(&wxSlider::SetValue, volume_slider, 100)); // Sound quality. - GetValidatedChild(this, "Rate")->SetValidator(SoundRateValidator()); + GetValidatedChild("Rate")->SetValidator(SoundRateValidator()); // Audio API selection. - wxWindow* audio_api_button = GetValidatedChild(this, "OpenAL"); + wxWindow* audio_api_button = GetValidatedChild("OpenAL"); audio_api_button->SetValidator(AudioApiValidator(config::AudioApi::kOpenAL)); audio_api_button->Bind(wxEVT_RADIOBUTTON, std::bind(&SoundConfig::OnAudioApiChanged, this, std::placeholders::_1, config::AudioApi::kOpenAL)); - audio_api_button = GetValidatedChild(this, "DirectSound"); + audio_api_button = GetValidatedChild("DirectSound"); #if defined(__WXMSW__) audio_api_button->SetValidator(AudioApiValidator(config::AudioApi::kDirectSound)); audio_api_button->Bind(wxEVT_RADIOBUTTON, @@ -174,7 +167,7 @@ SoundConfig::SoundConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(thi audio_api_button->Hide(); #endif - audio_api_button = GetValidatedChild(this, "XAudio2"); + audio_api_button = GetValidatedChild("XAudio2"); #if defined(VBAM_ENABLE_XAUDIO2) audio_api_button->SetValidator(AudioApiValidator(config::AudioApi::kXAudio2)); audio_api_button->Bind(wxEVT_RADIOBUTTON, @@ -184,7 +177,7 @@ SoundConfig::SoundConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(thi audio_api_button->Hide(); #endif - audio_api_button = GetValidatedChild(this, "FAudio"); + audio_api_button = GetValidatedChild("FAudio"); #if defined(VBAM_ENABLE_FAUDIO) audio_api_button->SetValidator(AudioApiValidator(config::AudioApi::kFAudio)); audio_api_button->Bind(wxEVT_RADIOBUTTON, @@ -195,7 +188,7 @@ SoundConfig::SoundConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(thi #endif // Upmix configuration. - upmix_checkbox_ = GetValidatedChild(this, "Upmix"); + upmix_checkbox_ = GetValidatedChild("Upmix"); #if defined(VBAM_ENABLE_XAUDIO2) || defined(VBAM_ENABLE_FAUDIO) upmix_checkbox_->SetValidator(widgets::OptionBoolValidator(config::OptionID::kSoundUpmix)); #else @@ -203,7 +196,7 @@ SoundConfig::SoundConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(thi #endif // DSound HW acceleration. - hw_accel_checkbox_ = GetValidatedChild(this, "HWAccel"); + hw_accel_checkbox_ = GetValidatedChild("HWAccel"); #if defined(__WXMSW__) hw_accel_checkbox_->SetValidator( widgets::OptionBoolValidator(config::OptionID::kSoundDSoundHWAccel)); @@ -212,23 +205,23 @@ SoundConfig::SoundConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(thi #endif // Buffers configuration. - buffers_info_label_ = GetValidatedChild(this, "BuffersInfo"); - buffers_slider_ = GetValidatedChild(this, "Buffers"); + buffers_info_label_ = GetValidatedChild("BuffersInfo"); + buffers_slider_ = GetValidatedChild("Buffers"); buffers_slider_->SetValidator(widgets::OptionIntValidator(config::OptionID::kSoundBuffers)); buffers_slider_->Bind(wxEVT_SLIDER, &SoundConfig::OnBuffersChanged, this); // Game Boy configuration. - GetValidatedChild(this, "GBEcho") - ->SetValidator(widgets::OptionIntValidator(config::OptionID::kSoundGBEcho)); - GetValidatedChild(this, "GBStereo") + GetValidatedChild("GBEcho")->SetValidator( + widgets::OptionIntValidator(config::OptionID::kSoundGBEcho)); + GetValidatedChild("GBStereo") ->SetValidator(widgets::OptionIntValidator(config::OptionID::kSoundGBStereo)); // Game Boy Advance configuration. - GetValidatedChild(this, "GBASoundFiltering") + GetValidatedChild("GBASoundFiltering") ->SetValidator(widgets::OptionIntValidator(config::OptionID::kSoundGBAFiltering)); // Audio Device configuration. - audio_device_selector_ = GetValidatedChild(this, "Device"); + audio_device_selector_ = GetValidatedChild("Device"); audio_device_selector_->SetValidator(AudioDeviceValidator()); this->Bind(wxEVT_SHOW, &SoundConfig::OnShow, this); diff --git a/src/wx/dialogs/sound-config.h b/src/wx/dialogs/sound-config.h index a9f39f28..a5abe57f 100644 --- a/src/wx/dialogs/sound-config.h +++ b/src/wx/dialogs/sound-config.h @@ -1,11 +1,8 @@ #ifndef VBAM_WX_DIALOGS_SOUND_CONFIG_H_ #define VBAM_WX_DIALOGS_SOUND_CONFIG_H_ -#include -#include - #include "wx/config/option.h" -#include "wx/widgets/keep-on-top-styler.h" +#include "wx/dialogs/base-dialog.h" // Forward declarations. class wxChoice; @@ -17,7 +14,7 @@ class wxWindow; namespace dialogs { // Manages the sound configuration dialog. -class SoundConfig : public wxDialog { +class SoundConfig : public BaseDialog { public: static SoundConfig* NewInstance(wxWindow* parent); ~SoundConfig() override = default; @@ -42,7 +39,6 @@ private: wxCheckBox* upmix_checkbox_; wxCheckBox* hw_accel_checkbox_; config::AudioApi current_audio_api_; - const widgets::KeepOnTopStyler keep_on_top_styler_; }; } // namespace dialogs diff --git a/src/wx/guiinit.cpp b/src/wx/guiinit.cpp index e5688393..6e506c48 100644 --- a/src/wx/guiinit.cpp +++ b/src/wx/guiinit.cpp @@ -40,6 +40,7 @@ #include "core/gba/gbaGlobals.h" #include "wx/config/option-proxy.h" #include "wx/dialogs/accel-config.h" +#include "wx/dialogs/base-dialog.h" #include "wx/dialogs/directories-config.h" #include "wx/dialogs/display-config.h" #include "wx/dialogs/game-boy-config.h" @@ -64,26 +65,8 @@ const #undef wxvbam #endif - // this is supposed to happen automatically if a parent is marked recursive - // but some dialogs don't do it (propertydialog?) - // so go ahead and mark all dialogs for fully recursive validation - static void - mark_recursive(wxWindowBase* w) -{ - w->SetExtraStyle(w->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY); - wxWindowList l = w->GetChildren(); - - for (wxWindowList::iterator ch = l.begin(); ch != l.end(); ++ch) - mark_recursive(*ch); -} - -#if (wxMAJOR_VERSION < 3) -#define GetXRCDialog(n) \ - wxStaticCast(wxGetApp().frame->FindWindow(XRCID(n)), wxDialog) -#else #define GetXRCDialog(n) \ wxStaticCast(wxGetApp().frame->FindWindowByName(n), wxDialog) -#endif // Event handlers must be methods of wxEvtHandler-derived objects @@ -343,11 +326,6 @@ public: wxDialog* subdlg = GetXRCDialog("CheatEdit"); dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER); - if (OPTION(kDispKeepOnTop)) - subdlg->SetWindowStyle(subdlg->GetWindowStyle() | wxSTAY_ON_TOP); - else - subdlg->SetWindowStyle(subdlg->GetWindowStyle() & ~wxSTAY_ON_TOP); - subdlg->ShowModal(); AddCheat(); Reload(ncheats); @@ -566,11 +544,6 @@ public: wxDialog* subdlg = GetXRCDialog("CheatEdit"); dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER); - if (OPTION(kDispKeepOnTop)) - subdlg->SetWindowStyle(subdlg->GetWindowStyle() | wxSTAY_ON_TOP); - else - subdlg->SetWindowStyle(subdlg->GetWindowStyle() & ~wxSTAY_ON_TOP); - if (subdlg->ShowModal() != wxID_OK) return; @@ -1098,11 +1071,6 @@ public: wxDialog* subdlg = GetXRCDialog("CheatAdd"); dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER); - if (OPTION(kDispKeepOnTop)) - subdlg->SetWindowStyle(subdlg->GetWindowStyle() | wxSTAY_ON_TOP); - else - subdlg->SetWindowStyle(subdlg->GetWindowStyle() & ~wxSTAY_ON_TOP); - if (subdlg->ShowModal() != wxID_OK) return; @@ -1629,38 +1597,8 @@ void CheckThrowXRCError(T pointer, const char* name) wxDialog* MainFrame::LoadXRCDialog(const char* name) { wxString dname = wxString::FromUTF8(name); - wxDialog* dialog = wxXmlResource::Get()->LoadDialog(this, dname); + wxDialog* dialog = dialogs::BaseDialog::LoadDialog(this, dname); CheckThrowXRCError(dialog, name); -/* wx-2.9.1 doesn't set parent for propertysheetdialogs for some reason */ -/* this will generate a gtk warning but it is necessary for later */ -/* retrieval using FindWindow() */ -#if (wxMAJOR_VERSION < 3) - - if (!dialog->GetParent()) - dialog->Reparent(this); - -#endif - mark_recursive(dialog); - return dialog; -} - -wxDialog* MainFrame::LoadXRCropertySheetDialog(const char* name) -{ - wxString dname = wxString::FromUTF8(name); - //Seems like the only way to do this - wxObject* anObject = wxXmlResource::Get()->LoadObject(this, dname, wxEmptyString); - wxDialog* dialog = dynamic_cast(anObject); - CheckThrowXRCError(dialog, name); -/* wx-2.9.1 doesn't set parent for propertysheetdialogs for some reason */ -/* this will generate a gtk warning but it is necessary for later */ -/* retrieval using FindWindow() */ -#if (wxMAJOR_VERSION < 3) - - if (!dialog->GetParent()) - dialog->Reparent(this); - -#endif - mark_recursive(dialog); return dialog; } @@ -2488,7 +2426,7 @@ bool MainFrame::BindControls() fp->SetValidator(wxFileDirPickerValidator(&o, l)); \ } while (0) dialogs::GameBoyConfig::NewInstance(this); - d = LoadXRCropertySheetDialog("GameBoyAdvanceConfig"); + d = LoadXRCDialog("GameBoyAdvanceConfig"); { /// System and peripherals ch = GetValidatedChild(d, "SaveType", wxGenericValidator(&coreOptions.cpuSaveType)); @@ -2554,7 +2492,7 @@ bool MainFrame::BindControls() // at popup time. // The only one that can only be popped up once is logging, so allocate // and check it already. - logdlg = new LogDialog; + logdlg = std::make_unique(); // activate OnDropFile event handler #if !defined(__WXGTK__) || wxCHECK_VERSION(2, 8, 10) // may not actually do anything, but verfied to work w/ Linux/Nautilus diff --git a/src/wx/opts.cpp b/src/wx/opts.cpp index c6483998..cdc4d411 100644 --- a/src/wx/opts.cpp +++ b/src/wx/opts.cpp @@ -295,12 +295,14 @@ void load_opts(bool first_time_launch) { for (cont = cfg->GetFirstGroup(s, grp_idx); cont; cont = cfg->GetNextGroup(s, grp_idx)) { // ignore wxWidgets-managed global library settings - if (s == wxT("wxWindows")) + if (s == "Persistent_Options") { continue; + } // ignore file history - if (s == wxT("Recent")) + if (s == "Recent") { continue; + } cfg->SetPath(s); int poff = s.size(); diff --git a/src/wx/sys.cpp b/src/wx/sys.cpp index 590d181f..95ceccc4 100644 --- a/src/wx/sys.cpp +++ b/src/wx/sys.cpp @@ -1428,7 +1428,7 @@ void log(const char* defaultMsg, ...) wxGetApp().log.append(msg); if (wxGetApp().IsMainLoopRunning()) { - LogDialog* d = wxGetApp().frame->logdlg; + LogDialog* d = wxGetApp().frame->logdlg.get(); if (d && d->IsShown()) { d->Update(); diff --git a/src/wx/viewers.cpp b/src/wx/viewers.cpp index 0f892689..e1365694 100644 --- a/src/wx/viewers.cpp +++ b/src/wx/viewers.cpp @@ -544,12 +544,10 @@ void MainFrame::IOViewer() baddialog(); \ cb->SetValidator(wxBoolIntValidator(&systemVerbose, val, val)); \ } while (0) -LogDialog::LogDialog() : keep_on_top_styler_(this) { +LogDialog::LogDialog() : +dialogs::BaseDialog(nullptr, "Logging") { const wxString dname = wxT("Logging"); - if (!wxXmlResource::Get()->LoadDialog(this, wxGetApp().frame, dname)) - baddialog(); - SetEscapeId(wxID_OK); getlogf("SWI", VERBOSE_SWI); getlogf("UnalignedMemory", VERBOSE_UNALIGNED_MEMORY); diff --git a/src/wx/widgets/keep-on-top-styler.h b/src/wx/widgets/keep-on-top-styler.h index 7cb00682..e8ca62cc 100644 --- a/src/wx/widgets/keep-on-top-styler.h +++ b/src/wx/widgets/keep-on-top-styler.h @@ -1,5 +1,5 @@ -#ifndef VBAM_WX_DIALOGS_BASE_DIALOG_H_ -#define VBAM_WX_DIALOGS_BASE_DIALOG_H_ +#ifndef VBAM_WX_WIDGETS_KEEP_ON_TOP_STYLER_H_ +#define VBAM_WX_WIDGETS_KEEP_ON_TOP_STYLER_H_ #include @@ -55,4 +55,4 @@ private: } // namespace widgets -#endif // VBAM_WX_DIALOGS_BASE_DIALOG_H_ +#endif // VBAM_WX_WIDGETS_KEEP_ON_TOP_STYLER_H_ diff --git a/src/wx/widgets/utils.cpp b/src/wx/widgets/utils.cpp new file mode 100644 index 00000000..443f0aa4 --- /dev/null +++ b/src/wx/widgets/utils.cpp @@ -0,0 +1,16 @@ +#include "wx/widgets/utils.h" + +#include + +namespace widgets { + +wxRect GetDisplayRect() { + wxRect display_rect; + for (unsigned int i = 0; i < wxDisplay::GetCount(); i++) { + display_rect.Union(wxDisplay(i).GetClientArea()); + } + + return display_rect; +} + +} // namespace widgets diff --git a/src/wx/dialogs/validated-child.h b/src/wx/widgets/utils.h similarity index 56% rename from src/wx/dialogs/validated-child.h rename to src/wx/widgets/utils.h index e3051e82..a9285e69 100644 --- a/src/wx/dialogs/validated-child.h +++ b/src/wx/widgets/utils.h @@ -1,12 +1,18 @@ -#ifndef VBAM_WX_DIALOGS_VALIDATED_CHILD_H_ -#define VBAM_WX_DIALOGS_VALIDATED_CHILD_H_ +#ifndef VBAM_WX_WIDGETS_UTILS_H_ +#define VBAM_WX_WIDGETS_UTILS_H_ #include -#include #include +#include -namespace dialogs { +// This file contains a collection of various utility functions for wxWidgets. + +namespace widgets { + +// Helper function to get the display rectangle. Useful for avoiding drawing a +// dialog outside the screen. +wxRect GetDisplayRect(); // Helper functions to assert on the returned value. inline wxWindow* GetValidatedChild(const wxWindow* parent, @@ -23,6 +29,7 @@ T* GetValidatedChild(const wxWindow* parent, const wxString& name) { return child; } -} // namespace dialogs -#endif // VBAM_WX_DIALOGS_VALIDATED_CHILD_H_ +} // namespace widgets + +#endif // VBAM_WX_WIDGETS_UTILS_H_ diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index d0b933dd..a7b2c7b0 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -51,6 +51,7 @@ #include "wx/wayland.h" #include "wx/widgets/group-check-box.h" #include "wx/widgets/user-input-ctrl.h" +#include "wx/widgets/utils.h" #ifdef __WXGTK__ #include @@ -567,14 +568,8 @@ bool wxvbamApp::OnInit() { return false; } - // Measure the full display area. - wxRect display_rect; - for (unsigned int i = 0; i < wxDisplay::GetCount(); i++) { - display_rect.Union(wxDisplay(i).GetClientArea()); - } - // Ensure we are not drawing out of bounds. - if (display_rect.Intersects(client_rect)) { + if (widgets::GetDisplayRect().Intersects(client_rect)) { frame->SetSize(client_rect); } @@ -1258,11 +1253,6 @@ int MainFrame::ShowModal(wxDialog* dlg) { dlg->SetWindowStyle(dlg->GetWindowStyle() | wxCAPTION | wxRESIZE_BORDER); - if (OPTION(kDispKeepOnTop)) - dlg->SetWindowStyle(dlg->GetWindowStyle() | wxSTAY_ON_TOP); - else - dlg->SetWindowStyle(dlg->GetWindowStyle() & ~wxSTAY_ON_TOP); - CheckPointer(dlg); StartModal(); int ret = dlg->ShowModal(); diff --git a/src/wx/wxvbam.h b/src/wx/wxvbam.h index 2752a3e8..217bd877 100644 --- a/src/wx/wxvbam.h +++ b/src/wx/wxvbam.h @@ -14,6 +14,7 @@ #include "core/base/system.h" #include "wx/config/option-observer.h" #include "wx/config/option.h" +#include "wx/dialogs/base-dialog.h" #include "wx/widgets/dpi-support.h" #include "wx/widgets/keep-on-top-styler.h" #include "wx/widgets/sdljoy.h" @@ -292,7 +293,7 @@ public: // this won't actually be destroyed, but it needs to be tracked so only // one is ever up and it needs to be pinged when new messages arrive - LogDialog* logdlg; + std::unique_ptr logdlg; // the cheat search dialog isn't destroyed or tracked, but it needs // to be cleared between games @@ -385,8 +386,6 @@ private: void OnSize(wxSizeEvent& event); // Load a named wxDialog from the XRC file wxDialog* LoadXRCDialog(const char* name); - // Load a named wxDialog from the XRC file - wxDialog* LoadXRCropertySheetDialog(const char* name); #include "wx/cmdhandlers.h" }; @@ -695,14 +694,13 @@ public: DrawingPanel(wxWindow* parent, int _width, int _height); }; -class LogDialog : public wxDialog { +class LogDialog : public dialogs::BaseDialog { public: LogDialog(); void Update(); private: wxTextCtrl* log; - widgets::KeepOnTopStyler keep_on_top_styler_; void Save(wxCommandEvent& ev); void Clear(wxCommandEvent& ev);