[Dialogs] Save and restore dialog positions
This changes most dialogs in the wx frontend to use a common base abstraction, `dialogs::BaseDialog`. This base class sets up common style options for every dialog and automatically saves and restores the dialog position. In addition, this moves the first time show position of the dialog to be slightly to the bottom and right of the main window, even if the main window is on a screen other than the main screen.
This commit is contained in:
parent
41952d0625
commit
32627f6b85
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -5,12 +5,10 @@
|
|||
#include <wx/listbox.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#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<wxTreeCtrl>(this, "Commands");
|
||||
current_keys_ = GetValidatedChild<wxListBox>(this, "Current");
|
||||
assign_button_ = GetValidatedChild(this, "Assign");
|
||||
remove_button_ = GetValidatedChild(this, "Remove");
|
||||
key_input_ = GetValidatedChild<widgets::UserInputCtrl>(this, "Shortcut");
|
||||
currently_assigned_label_ = GetValidatedChild<wxControl>(this, "AlreadyThere");
|
||||
tree_ = GetValidatedChild<wxTreeCtrl>("Commands");
|
||||
current_keys_ = GetValidatedChild<wxListBox>("Current");
|
||||
assign_button_ = GetValidatedChild("Assign");
|
||||
remove_button_ = GetValidatedChild("Remove");
|
||||
key_input_ = GetValidatedChild<widgets::UserInputCtrl>("Shortcut");
|
||||
currently_assigned_label_ = GetValidatedChild<wxControl>("AlreadyThere");
|
||||
|
||||
// Configure the key input.
|
||||
key_input_->MoveBeforeInTabOrder(assign_button_);
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/treectrl.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
#include "wx/dialogs/base-dialog.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <wx/persist.h>
|
||||
#include <wx/persist/toplevel.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#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<BaseDialog> {
|
||||
public:
|
||||
PersistentBaseDialog(BaseDialog* window) : wxPersistentWindow<BaseDialog>(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
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef VBAM_WX_DIALOGS_BASE_DIALOG_H_
|
||||
#define VBAM_WX_DIALOGS_BASE_DIALOG_H_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
#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 <class T>
|
||||
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_
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
#include <wx/filepicker.h>
|
||||
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#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<wxDirPickerCtrl>(this, "GBARoms"),
|
||||
DirectoriesConfig::DirectoriesConfig(wxWindow* parent) : BaseDialog(parent, "DirectoriesConfig") {
|
||||
// clang-format off
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>("GBARoms"),
|
||||
config::OptionID::kGBAROMDir);
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>(this, "GBRoms"),
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>("GBRoms"),
|
||||
config::OptionID::kGBROMDir);
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>(this, "GBCRoms"),
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>("GBCRoms"),
|
||||
config::OptionID::kGBGBCROMDir);
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>(this, "BatSaves"),
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>("BatSaves"),
|
||||
config::OptionID::kGenBatteryDir);
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>(this, "StateSaves"),
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>("StateSaves"),
|
||||
config::OptionID::kGenStateDir);
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>(this, "Screenshots"),
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>("Screenshots"),
|
||||
config::OptionID::kGenScreenshotDir);
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>(this, "Recordings"),
|
||||
SetUpDirPicker(GetValidatedChild<wxDirPickerCtrl>("Recordings"),
|
||||
config::OptionID::kGenRecordingDir);
|
||||
// clang-format on
|
||||
|
||||
this->Fit();
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
#ifndef VBAM_WX_DIALOGS_DIRECTORIES_CONFIG_H_
|
||||
#define VBAM_WX_DIALOGS_DIRECTORIES_CONFIG_H_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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<wxChoice>(this, "Filter");
|
||||
filter_selector_ = GetValidatedChild<wxChoice>("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<wxControl>(this, "PluginLab");
|
||||
plugin_selector_ = GetValidatedChild<wxChoice>(this, "Plugin");
|
||||
plugin_label_ = GetValidatedChild<wxControl>("PluginLab");
|
||||
plugin_selector_ = GetValidatedChild<wxChoice>("Plugin");
|
||||
|
||||
interframe_selector_ = GetValidatedChild<wxChoice>(this, "IFB");
|
||||
interframe_selector_ = GetValidatedChild<wxChoice>("IFB");
|
||||
interframe_selector_->SetValidator(InterframeValidator());
|
||||
|
||||
Bind(wxEVT_SHOW, &DisplayConfig::OnDialogShowEvent, this, GetId());
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#ifndef VBAM_WX_DIALOGS_DISPLAY_CONFIG_H_
|
||||
#define VBAM_WX_DIALOGS_DISPLAY_CONFIG_H_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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<wxChoice>(panel, "DefaultPalette")),
|
||||
option_id_(static_cast<config::OptionID>(
|
||||
static_cast<size_t>(config::OptionID::kGBPalette0) + palette_id)) {
|
||||
default_selector_(widgets::GetValidatedChild<wxChoice>(panel, "DefaultPalette")),
|
||||
option_id_(static_cast<config::OptionID>(static_cast<size_t>(config::OptionID::kGBPalette0) +
|
||||
palette_id)) {
|
||||
assert(panel);
|
||||
assert(palette_id < kNbPalettes);
|
||||
|
||||
default_selector_->Bind(
|
||||
wxEVT_CHOICE, &GBPalettePanelData::OnDefaultPaletteSelected, this);
|
||||
|
||||
GetValidatedChild<wxCheckBox>(panel, "UsePalette")
|
||||
->SetValidator(widgets::OptionSelectedValidator(
|
||||
config::OptionID::kPrefGBPaletteOption, palette_id));
|
||||
widgets::GetValidatedChild<wxCheckBox>(panel, "UsePalette")
|
||||
->SetValidator(
|
||||
widgets::OptionSelectedValidator(config::OptionID::kPrefGBPaletteOption, palette_id));
|
||||
|
||||
for (size_t i = 0; i < colour_pickers_.size(); i++) {
|
||||
wxColourPickerCtrl* colour_picker =
|
||||
GetValidatedChild<wxColourPickerCtrl>(
|
||||
panel, wxString::Format("Color%zu", i));
|
||||
widgets::GetValidatedChild<wxColourPickerCtrl>(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<wxStaticText>(this, "GBBiosLabel")));
|
||||
GetValidatedChild("GBBiosPicker")
|
||||
->SetValidator(BIOSPickerValidator(config::OptionID::kGBBiosFile,
|
||||
GetValidatedChild<wxStaticText>("GBBiosLabel")));
|
||||
|
||||
// GBC BIOS ROM
|
||||
GetValidatedChild(this, "GBCBiosPicker")
|
||||
->SetValidator(BIOSPickerValidator(
|
||||
config::OptionID::kGBGBCBiosFile,
|
||||
GetValidatedChild<wxStaticText>(this, "GBCBiosLabel")));
|
||||
GetValidatedChild("GBCBiosPicker")
|
||||
->SetValidator(BIOSPickerValidator(config::OptionID::kGBGBCBiosFile,
|
||||
GetValidatedChild<wxStaticText>("GBCBiosLabel")));
|
||||
|
||||
for (size_t i = 0; i < kNbPalettes; i++) {
|
||||
// All of the wxPanel logic is handled in its client object.
|
||||
wxPanel* panel =
|
||||
GetValidatedChild<wxPanel>(this, wxString::Format("cp%zu", i));
|
||||
wxPanel* panel = GetValidatedChild<wxPanel>(wxString::Format("cp%zu", i));
|
||||
GBPalettePanelData* palette_data = new GBPalettePanelData(panel, i);
|
||||
|
||||
// `panel` takes ownership of `palette_data` here.
|
||||
|
|
|
@ -2,14 +2,13 @@
|
|||
#define VBAM_WX_DIALOGS_GAME_BOY_CONFIG_H_
|
||||
|
||||
#include <wx/clrpicker.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
#ifndef VBAM_WX_DIALOGS_GB_ROM_INFO_H_
|
||||
#define VBAM_WX_DIALOGS_GB_ROM_INFO_H_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#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<wxCheckBox>(this, "SDLGameControllerMode")->SetValue(OPTION(kSDLGameControllerMode));
|
||||
GetValidatedChild<wxCheckBox>("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<widgets::UserInputCtrl>(panel, game_key_name);
|
||||
widgets::GetValidatedChild<widgets::UserInputCtrl>(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<widgets::UserInputCtrl>(panel, config::GameKeyToString(game_key))
|
||||
widgets::GetValidatedChild<widgets::UserInputCtrl>(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<widgets::UserInputCtrl>(panel, config::GameKeyToString(game_key))
|
||||
widgets::GetValidatedChild<widgets::UserInputCtrl>(panel, config::GameKeyToString(game_key))
|
||||
->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void JoypadConfig::ToggleSDLGameControllerMode() {
|
||||
OPTION(kSDLGameControllerMode) = GetValidatedChild<wxCheckBox>(this, "SDLGameControllerMode")
|
||||
->IsChecked();
|
||||
OPTION(kSDLGameControllerMode) =
|
||||
GetValidatedChild<wxCheckBox>("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);
|
||||
}
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
#ifndef VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
||||
#define VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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<wxSlider>(this, "Volume");
|
||||
wxSlider* volume_slider = GetValidatedChild<wxSlider>("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<wxCheckBox>(this, "Upmix");
|
||||
upmix_checkbox_ = GetValidatedChild<wxCheckBox>("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<wxCheckBox>(this, "HWAccel");
|
||||
hw_accel_checkbox_ = GetValidatedChild<wxCheckBox>("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<wxControl>(this, "BuffersInfo");
|
||||
buffers_slider_ = GetValidatedChild<wxSlider>(this, "Buffers");
|
||||
buffers_info_label_ = GetValidatedChild<wxControl>("BuffersInfo");
|
||||
buffers_slider_ = GetValidatedChild<wxSlider>("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<wxChoice>(this, "Device");
|
||||
audio_device_selector_ = GetValidatedChild<wxChoice>("Device");
|
||||
audio_device_selector_->SetValidator(AudioDeviceValidator());
|
||||
|
||||
this->Bind(wxEVT_SHOW, &SoundConfig::OnShow, this);
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#ifndef VBAM_WX_DIALOGS_SOUND_CONFIG_H_
|
||||
#define VBAM_WX_DIALOGS_SOUND_CONFIG_H_
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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<wxDialog*>(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<wxChoice, wxGenericValidator>(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<LogDialog>();
|
||||
// activate OnDropFile event handler
|
||||
#if !defined(__WXGTK__) || wxCHECK_VERSION(2, 8, 10)
|
||||
// may not actually do anything, but verfied to work w/ Linux/Nautilus
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <wx/event.h>
|
||||
|
||||
|
@ -55,4 +55,4 @@ private:
|
|||
|
||||
} // namespace widgets
|
||||
|
||||
#endif // VBAM_WX_DIALOGS_BASE_DIALOG_H_
|
||||
#endif // VBAM_WX_WIDGETS_KEEP_ON_TOP_STYLER_H_
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
#include "wx/widgets/utils.h"
|
||||
|
||||
#include <wx/display.h>
|
||||
|
||||
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
|
|
@ -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 <cassert>
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/window.h>
|
||||
#include <wx/gdicmn.h>
|
||||
|
||||
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_
|
|
@ -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 <gdk/gdk.h>
|
||||
|
@ -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();
|
||||
|
|
|
@ -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<LogDialog> 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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue