From b04af0e6e9b38f5eb8fd91eaf957169e575d2cf9 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 18 Jun 2010 02:44:27 +0000 Subject: [PATCH] UI: * Added 3-state checkbox support to pxCheckBox. * Fixed some buggy behavior when closing PCSX2 with either main window or console window minimized (window positions would get screwy) DevNotes: * Moved ImplementEnumOperators macro to Common headers and improved it a bit. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3220 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/Utilities/Dependencies.h | 46 ++++++++++++++++++++++++- common/include/Utilities/pxCheckBox.h | 17 +++++---- common/include/x86emitter/tools.h | 4 +++ common/include/x86emitter/x86emitter.h | 5 ++- common/src/Utilities/pxCheckBox.cpp | 29 ++++++++++++---- common/src/Utilities/wxHelpers.cpp | 2 +- common/src/x86emitter/simd.cpp | 13 +++++++ pcsx2/Pcsx2Config.cpp | 4 +-- pcsx2/gui/ConsoleLogger.cpp | 2 ++ pcsx2/gui/MainFrame.cpp | 2 ++ 10 files changed, 105 insertions(+), 19 deletions(-) diff --git a/common/include/Utilities/Dependencies.h b/common/include/Utilities/Dependencies.h index 628ad53f22..6c6bf982c5 100644 --- a/common/include/Utilities/Dependencies.h +++ b/common/include/Utilities/Dependencies.h @@ -28,13 +28,57 @@ class wxInputStream; // This should prove useful.... #define wxsFormat wxString::Format +// -------------------------------------------------------------------------------------- +// ImplementEnumOperators (macro) +// -------------------------------------------------------------------------------------- +// This macro implements ++/-- operators for any conforming enumeration. In order for an +// enum to conform, it must have _FIRST and _COUNT members defined, and must have a full +// compliment of sequential members (no custom assignments) --- looking like so: +// +// enum Dummy { +// Dummy_FIRST, +// Dummy_Item = Dummy_FIRST, +// Dummy_Crap, +// Dummy_COUNT +// }; +// +// The macro also defines utility functions for bounds checking enumerations: +// EnumIsValid(value); // returns TRUE if the enum value is between FIRST and COUNT. +// EnumAssert(value); +// +// It also defines a *prototype* for converting the enumeration to a string. Note that this +// method is not implemented! You must implement it yourself if you want to use it: +// EnumToString(value); +// +#define ImplementEnumOperators( enumName ) \ + static __forceinline enumName& operator++ ( enumName& src ) { src = (enumName)((int)src+1); return src; } \ + static __forceinline enumName& operator-- ( enumName& src ) { src = (enumName)((int)src-1); return src; } \ + static __forceinline enumName operator++ ( enumName& src, int ) { enumName orig = src; src = (enumName)((int)src+1); return orig; } \ + static __forceinline enumName operator-- ( enumName& src, int ) { enumName orig = src; src = (enumName)((int)src-1); return orig; } \ + \ + static __forceinline bool operator< ( const enumName& left, const pxEnumEnd_t& ) { return (int)left < enumName##_COUNT; } \ + static __forceinline bool operator!=( const enumName& left, const pxEnumEnd_t& ) { return (int)left != enumName##_COUNT; } \ + static __forceinline bool operator==( const enumName& left, const pxEnumEnd_t& ) { return (int)left == enumName##_COUNT; } \ + \ + static __forceinline bool EnumIsValid( enumName id ) { \ + return ((int)id >= enumName##_FIRST) && ((int)id < enumName##_COUNT); } \ + static __forceinline bool EnumAssert( enumName id ) { \ + return pxAssert( EnumIsValid(id) ); } \ + static __forceinline void EnumAssume( enumName id ) { \ + pxAssume( EnumIsValid(id) ); } \ + \ + extern const wxChar* EnumToString( enumName id ) + +class pxEnumEnd_t { }; +static const pxEnumEnd_t pxEnumEnd = {}; + // -------------------------------------------------------------------------------------- // DeclareNoncopyableObject // -------------------------------------------------------------------------------------- // This macro provides an easy and clean method for ensuring objects are not copyable. // Simply add the macro to the head or tail of your class declaration, and attempts to // copy the class will give you a moderately obtuse compiler error that will have you -// scratching your head for 20 mintes. +// scratching your head for 20 minutes. // // (... but that's probably better than having a weird invalid object copy having you // scratch your head for a day). diff --git a/common/include/Utilities/pxCheckBox.h b/common/include/Utilities/pxCheckBox.h index a45c223f7d..47480f9811 100644 --- a/common/include/Utilities/pxCheckBox.h +++ b/common/include/Utilities/pxCheckBox.h @@ -37,7 +37,8 @@ protected: wxSizerItem* m_sizerItem_subtext; public: - pxCheckBox( wxWindow* parent, const wxString& label, const wxString& subtext=wxEmptyString ); + pxCheckBox( wxWindow* parent, const wxString& label, const wxString& subtext=wxEmptyString, int flags = wxCHK_2STATE ); + pxCheckBox( wxWindow* parent, const wxString& label, int flags ); virtual ~pxCheckBox() throw() {} bool HasSubText() const { return m_subtext != NULL; } @@ -46,11 +47,15 @@ public: pxCheckBox& SetSubPadding( int pad ); pxCheckBox& SetToolTip( const wxString& tip ); pxCheckBox& SetValue( bool val ); - bool GetValue() const; - bool IsChecked() const { pxAssert( m_checkbox != NULL ); return m_checkbox->IsChecked(); } + pxCheckBox& SetIndeterminate(); + pxCheckBox& SetState( wxCheckBoxState state ); - operator wxCheckBox&() { pxAssert( m_checkbox != NULL ); return *m_checkbox; } - operator const wxCheckBox&() const { pxAssert( m_checkbox != NULL ); return *m_checkbox; } + wxCheckBoxState GetState() const { pxAssume( m_checkbox != NULL ); return m_checkbox->Get3StateValue(); } + bool GetValue() const { pxAssume( m_checkbox != NULL ); return m_checkbox->GetValue(); } + bool IsChecked() const { pxAssume( m_checkbox != NULL ); return m_checkbox->IsChecked(); } + bool IsIndeterminate() const { pxAssume( m_checkbox != NULL ); return m_checkbox->Get3StateValue() == wxCHK_UNDETERMINED; } + operator wxCheckBox&() { pxAssume( m_checkbox != NULL ); return *m_checkbox; } + operator const wxCheckBox&() const { pxAssume( m_checkbox != NULL ); return *m_checkbox; } wxCheckBox* GetWxPtr() { return m_checkbox; } const wxCheckBox* GetWxPtr() const { return m_checkbox; } @@ -58,7 +63,7 @@ public: //wxWindowID GetId() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetId(); } protected: - void Init( const wxString& label, const wxString& subtext ); + void Init( const wxString& label, const wxString& subtext, int flags ); void OnCheckpartCommand( wxCommandEvent& evt ); void OnSubtextClicked( wxCommandEvent& evt ); }; diff --git a/common/include/x86emitter/tools.h b/common/include/x86emitter/tools.h index 52cc1d2f21..d87ea1a272 100644 --- a/common/include/x86emitter/tools.h +++ b/common/include/x86emitter/tools.h @@ -126,12 +126,16 @@ protected: enum SSE_RoundMode { + SSE_RoundMode_FIRST = 0, SSEround_Nearest = 0, SSEround_NegInf, SSEround_PosInf, SSEround_Chop, + SSE_RoundMode_COUNT }; +ImplementEnumOperators( SSE_RoundMode ); + // -------------------------------------------------------------------------------------- // SSE_MXCSR - Control/Status Register (bitfield) // -------------------------------------------------------------------------------------- diff --git a/common/include/x86emitter/x86emitter.h b/common/include/x86emitter/x86emitter.h index 2cef5e9d41..cf09e8acd1 100644 --- a/common/include/x86emitter/x86emitter.h +++ b/common/include/x86emitter/x86emitter.h @@ -28,9 +28,8 @@ * sudonim(1@gmail.com) */ -////////////////////////////////////////////////////////////////////////////////////////// -// New C++ Emitter! -// +// PCSX2's New C++ Emitter +// -------------------------------------------------------------------------------------- // To use it just include the x86Emitter namespace into your file/class/function off choice. // // This header file is intended for use by public code. It includes the appropriate diff --git a/common/src/Utilities/pxCheckBox.cpp b/common/src/Utilities/pxCheckBox.cpp index 48a97e6ba6..c5de27aa4e 100644 --- a/common/src/Utilities/pxCheckBox.cpp +++ b/common/src/Utilities/pxCheckBox.cpp @@ -23,17 +23,23 @@ using namespace pxSizerFlags; // pxCheckBox Implementations // -------------------------------------------------------------------------------------- -pxCheckBox::pxCheckBox(wxWindow* parent, const wxString& label, const wxString& subtext) +pxCheckBox::pxCheckBox(wxWindow* parent, const wxString& label, const wxString& subtext, int flags) : wxPanelWithHelpers( parent, wxVERTICAL ) { - Init( label, subtext ); + Init( label, subtext, flags ); } -void pxCheckBox::Init(const wxString& label, const wxString& subtext) +pxCheckBox::pxCheckBox(wxWindow* parent, const wxString& label, int flags) + : wxPanelWithHelpers( parent, wxVERTICAL ) +{ + Init( label, wxEmptyString, flags ); +} + +void pxCheckBox::Init(const wxString& label, const wxString& subtext, int flags) { m_subtext = NULL; m_subPadding= StdPadding*2; - m_checkbox = new wxCheckBox( this, wxID_ANY, label ); + m_checkbox = new wxCheckBox( this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, flags ); *this += m_checkbox | pxSizerFlags::StdExpand(); @@ -77,13 +83,24 @@ pxCheckBox& pxCheckBox::SetToolTip( const wxString& tip ) pxCheckBox& pxCheckBox::SetValue( bool val ) { + pxAssume( m_checkbox ); m_checkbox->SetValue( val ); return *this; } -bool pxCheckBox::GetValue() const +pxCheckBox& pxCheckBox::SetIndeterminate() { - return m_checkbox->GetValue(); + pxAssume( m_checkbox ); + m_checkbox->Set3StateValue( wxCHK_UNDETERMINED ); + return *this; +} + + +pxCheckBox& pxCheckBox::SetState( wxCheckBoxState state ) +{ + pxAssume( m_checkbox ); + m_checkbox->Set3StateValue( state ); + return *this; } // Forwards checkbox actions on the internal checkbox (called 'checkpart') to listeners diff --git a/common/src/Utilities/wxHelpers.cpp b/common/src/Utilities/wxHelpers.cpp index 3b2819223a..29b1323405 100644 --- a/common/src/Utilities/wxHelpers.cpp +++ b/common/src/Utilities/wxHelpers.cpp @@ -282,7 +282,7 @@ void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt ) // ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers // that systematically get closed. Seems like work, maybe later. --air - if( wxConfigBase* cfg = wxConfigBase::Get( false ) ) + if( wxConfigBase* cfg = IsIconized() ? NULL : wxConfigBase::Get( false ) ) { const wxString dlgName( GetDialogName() ); const wxRect screenRect( GetScreenRect() ); diff --git a/common/src/x86emitter/simd.cpp b/common/src/x86emitter/simd.cpp index 3f503ae062..a0794f779e 100644 --- a/common/src/x86emitter/simd.cpp +++ b/common/src/x86emitter/simd.cpp @@ -22,6 +22,19 @@ // AND'ing this mask against an MXCSR prior to LDMXCSR. SSE_MXCSR MXCSR_Mask; +const wxChar* EnumToString( SSE_RoundMode sse ) +{ + switch( sse ) + { + case SSEround_Nearest: return L"Nearest"; + case SSEround_NegInf: return L"NegativeInfinity"; + case SSEround_PosInf: return L"PositiveInfinity"; + case SSEround_Chop: return L"Chop"; + } + + return L"Invalid"; +} + SSE_RoundMode SSE_MXCSR::GetRoundMode() const { return (SSE_RoundMode)RoundingControl; diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index fd956e143d..889719d9f8 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -288,7 +288,7 @@ void Pcsx2Config::GamefixOptions::Set( const wxString& list, bool enabled ) void Pcsx2Config::GamefixOptions::Set( GamefixId id, bool enabled ) { - EnumAssertOnBounds( id ); + EnumAssume( id ); switch(id) { case Fix_VuAddSub: VuAddSubHack = enabled; break; @@ -307,7 +307,7 @@ void Pcsx2Config::GamefixOptions::Set( GamefixId id, bool enabled ) bool Pcsx2Config::GamefixOptions::Get( GamefixId id ) const { - EnumAssertOnBounds( id ); + EnumAssume( id ); switch(id) { case Fix_VuAddSub: return VuAddSubHack; diff --git a/pcsx2/gui/ConsoleLogger.cpp b/pcsx2/gui/ConsoleLogger.cpp index 0269457f4b..bf30de1238 100644 --- a/pcsx2/gui/ConsoleLogger.cpp +++ b/pcsx2/gui/ConsoleLogger.cpp @@ -475,6 +475,8 @@ void ConsoleLogFrame::OnDockedMove( wxCommandEvent& event ) void ConsoleLogFrame::OnMoveAround( wxMoveEvent& evt ) { + if( IsBeingDeleted() || IsIconized() ) return; + // Docking check! If the window position is within some amount // of the main window, enable docking. diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index e37b699f5a..b2881e2313 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -107,6 +107,8 @@ void MainEmuFrame::OnCloseWindow(wxCloseEvent& evt) void MainEmuFrame::OnMoveAround( wxMoveEvent& evt ) { + if( IsBeingDeleted() || IsIconized() ) return; + // Uncomment this when doing logger stress testing (and then move the window around // while the logger spams itself) // ... makes for a good test of the message pump's responsiveness.