mirror of https://github.com/PCSX2/pcsx2.git
244 lines
8.4 KiB
C++
244 lines
8.4 KiB
C++
/* PCSX2 - PS2 Emulator for PCs
|
|
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
|
*
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <list>
|
|
#include <wx/wizard.h>
|
|
|
|
#include "AppCommon.h"
|
|
|
|
class BaseApplicableConfigPanel;
|
|
class BaseApplicableDialog;
|
|
|
|
wxDECLARE_EVENT(pxEvt_ApplySettings, wxCommandEvent);
|
|
|
|
namespace Exception
|
|
{
|
|
// --------------------------------------------------------------------------
|
|
// Exception used to perform an abort of Apply/Ok action on settings panels.
|
|
// When thrown, the user receives a popup message containing the information
|
|
// specified in the exception message, and is returned to the settings dialog
|
|
// to correct the invalid input fields.
|
|
//
|
|
class CannotApplySettings : public BaseException
|
|
{
|
|
DEFINE_EXCEPTION_COPYTORS( CannotApplySettings, BaseException )
|
|
DEFINE_EXCEPTION_MESSAGES( CannotApplySettings )
|
|
|
|
public:
|
|
bool IsVerbose;
|
|
|
|
protected:
|
|
BaseApplicableConfigPanel* m_Panel;
|
|
|
|
protected:
|
|
CannotApplySettings() { IsVerbose = true; }
|
|
|
|
public:
|
|
explicit CannotApplySettings( BaseApplicableConfigPanel* thispanel )
|
|
{
|
|
SetBothMsgs("Cannot apply new settings, one of the settings is invalid.");
|
|
m_Panel = thispanel;
|
|
IsVerbose = true;
|
|
}
|
|
|
|
virtual CannotApplySettings& Quiet() { IsVerbose = false; return *this; }
|
|
BaseApplicableConfigPanel* GetPanel() { return m_Panel; }
|
|
};
|
|
}
|
|
|
|
typedef std::list<BaseApplicableConfigPanel*> PanelApplyList_t;
|
|
|
|
struct ApplyStateStruct
|
|
{
|
|
// collection of ApplicableConfigPanels that belong to a dialog box.
|
|
PanelApplyList_t PanelList;
|
|
|
|
// Current book page being initialized. Any apply objects created will use
|
|
// this page as their "go here on error" page. (used to take the user to the
|
|
// page with the option that failed apply validation).
|
|
int CurOwnerPage;
|
|
|
|
// TODO : Rename me to CurOwnerBook, or rename the one above to ParentPage.
|
|
wxBookCtrlBase* ParentBook;
|
|
|
|
ApplyStateStruct()
|
|
{
|
|
CurOwnerPage = wxID_NONE;
|
|
ParentBook = NULL;
|
|
}
|
|
|
|
void SetCurrentPage( int page )
|
|
{
|
|
CurOwnerPage = page;
|
|
}
|
|
|
|
void ClearCurrentPage()
|
|
{
|
|
CurOwnerPage = wxID_NONE;
|
|
}
|
|
|
|
void StartBook( wxBookCtrlBase* book );
|
|
void StartWizard();
|
|
bool ApplyAll();
|
|
bool ApplyPage( int pageid );
|
|
void DoCleanup() noexcept;
|
|
};
|
|
|
|
class IApplyState
|
|
{
|
|
protected:
|
|
ApplyStateStruct m_ApplyState;
|
|
|
|
public:
|
|
virtual ApplyStateStruct& GetApplyState() { return m_ApplyState; }
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// BaseApplicableDialog
|
|
// --------------------------------------------------------------------------------------
|
|
class BaseApplicableDialog
|
|
: public wxDialogWithHelpers
|
|
, public IApplyState
|
|
{
|
|
wxDECLARE_DYNAMIC_CLASS_NO_COPY(BaseApplicableDialog);
|
|
|
|
public:
|
|
BaseApplicableDialog() {}
|
|
virtual ~BaseApplicableDialog();
|
|
|
|
// Must return the same thing as GetNameStatic; a name ideal for use in uniquely
|
|
// identifying dialogs. (this version is the 'instance' version, which is called
|
|
// by BaseConfigurationDialog to assign the wxWidgets dialog name, and for saving
|
|
// screenshots to disk)
|
|
virtual wxString GetDialogName() const;
|
|
|
|
protected:
|
|
void Init();
|
|
|
|
BaseApplicableDialog(wxWindow* parent, const wxString& title, const pxDialogCreationFlags& cflags = pxDialogCreationFlags() );
|
|
|
|
virtual void OnSettingsApplied( wxCommandEvent& evt );
|
|
|
|
// Note: This method *will* be called automatically after a successful Apply, but will not
|
|
// be called after a failed Apply (canceled due to error).
|
|
virtual void AppStatusEvent_OnSettingsApplied() {}
|
|
|
|
virtual void AppStatusEvent_OnUiSettingsLoadSave( const AppSettingsEventInfo& ) {}
|
|
virtual void AppStatusEvent_OnExit() {}
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// BaseApplicableConfigPanel
|
|
// --------------------------------------------------------------------------------------
|
|
// Extends the Panel class to add an Apply() method, which is invoked from the parent
|
|
// window (usually the ConfigurationDialog) when either Ok or Apply is clicked.
|
|
//
|
|
// Thread Safety: None. This class is only safe when used from the GUI thread, as it uses
|
|
// static vars and assumes that only one ApplicableConfig system is available to the
|
|
// user at any time (ie, a singular modal dialog).
|
|
//
|
|
class BaseApplicableConfigPanel
|
|
: public wxPanelWithHelpers
|
|
{
|
|
protected:
|
|
int m_OwnerPage;
|
|
wxBookCtrlBase* m_OwnerBook;
|
|
|
|
EventListenerHelper_AppStatus<BaseApplicableConfigPanel> m_AppStatusHelper;
|
|
|
|
public:
|
|
virtual ~BaseApplicableConfigPanel();
|
|
|
|
BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient=wxVERTICAL );
|
|
BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient, const wxString& staticLabel );
|
|
|
|
int GetOwnerPage() const { return m_OwnerPage; }
|
|
wxBookCtrlBase* GetOwnerBook() { return m_OwnerBook; }
|
|
|
|
void SetFocusToMe();
|
|
IApplyState* FindApplyStateManager() const;
|
|
|
|
// Returns true if this ConfigPanel belongs to the specified page. Useful for doing
|
|
// selective application of options for specific pages.
|
|
bool IsOnPage( int pageid ) { return m_OwnerPage == pageid; }
|
|
|
|
// This method attempts to assign the settings for the panel into the given
|
|
// configuration structure (which is typically a copy of g_Conf). If validation
|
|
// of form contents fails, the function should throw Exception::CannotApplySettings.
|
|
// If no exceptions are thrown, then the operation is assumed a success. :)
|
|
virtual void Apply()=0;
|
|
|
|
//Enable the apply button manually if required (in case the auto-trigger doesn't kick in, e.g. when clicking a button)
|
|
void SomethingChanged();
|
|
|
|
|
|
void Init();
|
|
|
|
// Mandatory override: As a rule for proper interface design, all deriving classes need
|
|
// to implement this OnSettingsApplied function. There's no implementation of an options/
|
|
// settings panel that does not heed the changes of application status/settings changes. ;)
|
|
//
|
|
// Note: This method *will* be called automatically after a successful Apply, but will not
|
|
// be called after a failed Apply (canceled due to error).
|
|
virtual void AppStatusEvent_OnSettingsApplied()=0;
|
|
|
|
virtual void AppStatusEvent_OnUiSettingsLoadSave( const AppSettingsEventInfo& ) {}
|
|
virtual void AppStatusEvent_OnVmSettingsLoadSave( const AppSettingsEventInfo& ) {}
|
|
virtual void AppStatusEvent_OnExit() {}
|
|
|
|
virtual bool IsSpecificConfig(){return false;} //lame RTTI
|
|
|
|
protected:
|
|
virtual void OnSettingsApplied( wxCommandEvent& evt );
|
|
};
|
|
|
|
class BaseApplicableConfigPanel_SpecificConfig : public BaseApplicableConfigPanel
|
|
{
|
|
//This class only differs from BaseApplicableConfigPanel by systematically allowing the gui to be updated
|
|
//from a specific config (used by the presets system to trash not g_Conf in case the user pressed "Cancel").
|
|
//Every panel that the Presets affect should be derived from this and not from BaseApplicableConfigPanel.
|
|
//
|
|
//Multiple inheritance would have been better (also for cases of non BaseApplicableConfigPanel which are effected by presets),
|
|
//but multiple inheritance sucks. So, subclass.
|
|
//NOTE: because ApplyConfigToGui is called manually and not via an event, it must consider manuallyPropagate and call sub panels.
|
|
public:
|
|
virtual bool IsSpecificConfig(){return true;};
|
|
BaseApplicableConfigPanel_SpecificConfig( wxWindow* parent, wxOrientation orient=wxVERTICAL );
|
|
BaseApplicableConfigPanel_SpecificConfig( wxWindow* parent, wxOrientation orient, const wxString& staticLabel );
|
|
|
|
//possible flags are: AppConfig: APPLY_FLAG_MANUALLY_PROPAGATE and APPLY_FLAG_IS_FROM_PRESET
|
|
virtual void ApplyConfigToGui(AppConfig& configToApply, int flags=0) = 0;
|
|
};
|
|
|
|
class ApplicableWizardPage : public wxWizardPageSimple, public IApplyState
|
|
{
|
|
wxDECLARE_DYNAMIC_CLASS_NO_COPY(ApplicableWizardPage);
|
|
|
|
public:
|
|
ApplicableWizardPage(
|
|
wxWizard* parent=NULL,
|
|
wxWizardPage *prev = NULL,
|
|
wxWizardPage *next = NULL,
|
|
const wxBitmap& bitmap = wxNullBitmap
|
|
);
|
|
|
|
virtual ~ApplicableWizardPage() { m_ApplyState.DoCleanup(); }
|
|
|
|
virtual bool PrepForApply();
|
|
};
|
|
|