diff --git a/common/build/Utilities/utilities.vcproj b/common/build/Utilities/utilities.vcproj
index 0dc4a724d3..a6cfc2e79b 100644
--- a/common/build/Utilities/utilities.vcproj
+++ b/common/build/Utilities/utilities.vcproj
@@ -211,6 +211,10 @@
RelativePath="..\..\src\Utilities\Exceptions.cpp"
>
+
+
@@ -263,6 +267,10 @@
RelativePath="..\..\src\Utilities\pxStaticText.cpp"
>
+
+
diff --git a/common/include/Utilities/StringHelpers.h b/common/include/Utilities/StringHelpers.h
index 18389111fa..7f259b1e18 100644
--- a/common/include/Utilities/StringHelpers.h
+++ b/common/include/Utilities/StringHelpers.h
@@ -65,6 +65,9 @@ struct ParsedAssignmentString
ParsedAssignmentString( const wxString& src );
};
+extern wxString FastFormatString_Ascii(const char* fmt, va_list argptr);
+extern wxString FastFormatString_Unicode(const wxChar* fmt, va_list argptr);
+
//////////////////////////////////////////////////////////////////////////////////////////
// Custom internal sprintf functions, which are ASCII only (even in UNICODE builds)
diff --git a/common/include/Utilities/wxGuiTools.h b/common/include/Utilities/wxGuiTools.h
index 63edc3de4e..fb37627eee 100644
--- a/common/include/Utilities/wxGuiTools.h
+++ b/common/include/Utilities/wxGuiTools.h
@@ -455,6 +455,81 @@ protected:
virtual void OnNewLine();
};
+// --------------------------------------------------------------------------------------
+// pxWindowTextWriter
+// --------------------------------------------------------------------------------------
+class pxWindowTextWriter
+{
+protected:
+ wxDC& m_dc;
+
+ wxAlignment m_align;
+ wxPoint m_curpos;
+ int m_leading;
+
+ virtual void _DoWriteLn( const wxChar* msg );
+ void _DoWrite( const wxChar* msg );
+
+public:
+ pxWindowTextWriter( wxDC& dc )
+ : m_dc( dc )
+ {
+ m_curpos = wxPoint();
+ m_align = wxALIGN_CENTER;
+ m_leading = 2;
+
+ OnFontChanged();
+ }
+
+ virtual ~pxWindowTextWriter() throw()
+ {
+
+ }
+
+ virtual void OnFontChanged();
+
+ pxWindowTextWriter& WriteLn();
+ pxWindowTextWriter& WriteLn( const wxChar* fmt, ... );
+ pxWindowTextWriter& SetFont( const wxFont& font );
+ pxWindowTextWriter& Align( const wxAlignment& align );
+
+ pxWindowTextWriter& SetLeading( int lead )
+ {
+ m_leading = lead;
+ return *this;
+ }
+
+ pxWindowTextWriter& SetWeight( int weight );
+ pxWindowTextWriter& SetStyle( int style );
+ pxWindowTextWriter& Normal();
+
+ pxWindowTextWriter& Bold()
+ {
+ return SetWeight(wxBOLD);
+ }
+
+ pxWindowTextWriter& Italic()
+ {
+ return SetStyle(wxITALIC);
+ }
+
+ pxWindowTextWriter& SetPos( const wxPoint& pos );
+ pxWindowTextWriter& MovePos( const wxSize& delta );
+
+ pxWindowTextWriter& SetPos( int xpos, int ypos )
+ {
+ return SetPos( wxPoint(xpos,ypos) );
+ }
+
+ pxWindowTextWriter& MovePos( int xdelta, int ydelta )
+ {
+ return MovePos( wxSize(xdelta, ydelta) );
+ }
+
+ pxWindowTextWriter& SetY( int ypos );
+ pxWindowTextWriter& MoveY( int ydelta );
+};
+
// --------------------------------------------------------------------------------------
// MoreStockCursors
// --------------------------------------------------------------------------------------
diff --git a/common/src/Utilities/Console.cpp b/common/src/Utilities/Console.cpp
index 368d2dfab8..0c520605b1 100644
--- a/common/src/Utilities/Console.cpp
+++ b/common/src/Utilities/Console.cpp
@@ -281,141 +281,6 @@ const IConsoleWriter ConsoleWriter_wxError =
0, // instance-level indentation (should always be 0)
};
-// Sanity check: truncate strings if they exceed 512k in length. Anything like that
-// is either a bug or really horrible code that needs to be stopped before it causes
-// system deadlock.
-static const int MaxFormattedStringLength = 0x80000;
-
-template< typename CharType >
-class FormatBuffer : public Mutex
-{
-public:
- bool& clearbit;
- SafeArray buffer;
- wxMBConvUTF8 ConvUTF8;
-
- FormatBuffer( bool& bit_to_clear_on_destruction )
- : clearbit( bit_to_clear_on_destruction )
- , buffer( 4096, wxsFormat( L"%s Format Buffer", (sizeof(CharType)==1) ? "Ascii" : "Unicode" ) )
- {
- }
-
- virtual ~FormatBuffer() throw()
- {
- clearbit = true;
- Wait(); // lock the mutex, just in case.
- }
-
-};
-
-static bool ascii_buffer_is_deleted = false;
-static bool unicode_buffer_is_deleted = false;
-
-static FormatBuffer ascii_buffer( ascii_buffer_is_deleted );
-static FormatBuffer unicode_buffer( unicode_buffer_is_deleted );
-
-static void format_that_ascii_mess( SafeArray& buffer, const char* fmt, va_list argptr )
-{
-
- while( true )
- {
- int size = buffer.GetLength();
- int len = vsnprintf(buffer.GetPtr(), size, fmt, argptr);
-
- // some implementations of vsnprintf() don't NUL terminate
- // the string if there is not enough space for it so
- // always do it manually
- buffer[size-1] = '\0';
-
- if( size >= MaxFormattedStringLength ) break;
-
- // vsnprintf() may return either -1 (traditional Unix behavior) or the
- // total number of characters which would have been written if the
- // buffer were large enough (newer standards such as Unix98)
-
- if ( len < 0 )
- len = size + (size/4);
-
- if ( len < size ) break;
- buffer.ExactAlloc( len + 1 );
- };
-
- // performing an assertion or log of a truncated string is unsafe, so let's not; even
- // though it'd be kinda nice if we did.
-}
-
-static void format_that_unicode_mess( SafeArray& buffer, const wxChar* fmt, va_list argptr)
-{
- while( true )
- {
- int size = buffer.GetLength();
- int len = wxVsnprintf(buffer.GetPtr(), size, fmt, argptr);
-
- // some implementations of vsnprintf() don't NUL terminate
- // the string if there is not enough space for it so
- // always do it manually
- buffer[size-1] = L'\0';
-
- if( size >= MaxFormattedStringLength ) break;
-
- // vsnprintf() may return either -1 (traditional Unix behavior) or the
- // total number of characters which would have been written if the
- // buffer were large enough (newer standards such as Unix98)
-
- if ( len < 0 )
- len = size + (size/4);
-
- if ( len < size ) break;
- buffer.ExactAlloc( len + 1 );
- };
-
- // performing an assertion or log of a truncated string is unsafe, so let's not; even
- // though it'd be kinda nice if we did.
-}
-
-static wxString ascii_format_string(const char* fmt, va_list argptr)
-{
- if( ascii_buffer_is_deleted )
- {
- // This means that the program is shutting down and the C++ destructors are
- // running, randomly deallocating static variables from existence. We handle it
- // as gracefully as possible by allocating local vars to do our bidding (slow, but
- // ultimately necessary!)
-
- SafeArray localbuf( 4096, L"Temporary Ascii Formatting Buffer" );
- format_that_ascii_mess( localbuf, fmt, argptr );
- return fromUTF8( localbuf.GetPtr() );
- }
- else
- {
- // This is normal operation. The static buffers are available for use, and we use
- // them for sake of efficiency (fewer heap allocs, for sure!)
-
- ScopedLock locker( ascii_buffer );
- format_that_ascii_mess( ascii_buffer.buffer, fmt, argptr );
- return fromUTF8( ascii_buffer.buffer.GetPtr() );
- }
-}
-
-
-static wxString unicode_format_string(const wxChar* fmt, va_list argptr)
-{
- // See above for the explanation on the _is_deleted flags.
-
- if( unicode_buffer_is_deleted )
- {
- SafeArray localbuf( 4096, L"Temporary Unicode Formatting Buffer" );
- format_that_unicode_mess( localbuf, fmt, argptr );
- return localbuf.GetPtr();
- }
- else
- {
- ScopedLock locker( unicode_buffer );
- format_that_unicode_mess( unicode_buffer.buffer, fmt, argptr );
- return unicode_buffer.buffer.GetPtr();
- }
-}
-
// =====================================================================================================
// IConsole Interfaces
// =====================================================================================================
@@ -494,7 +359,7 @@ bool IConsoleWriter::Write( const char* fmt, ... ) const
va_list args;
va_start(args,fmt);
- DoWrite( ascii_format_string(fmt, args) );
+ DoWrite( FastFormatString_Ascii(fmt, args) );
va_end(args);
return false;
@@ -507,7 +372,7 @@ bool IConsoleWriter::Write( ConsoleColors color, const char* fmt, ... ) const
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
- DoWrite( ascii_format_string(fmt, args) );
+ DoWrite( FastFormatString_Ascii(fmt, args) );
va_end(args);
return false;
@@ -519,7 +384,7 @@ bool IConsoleWriter::WriteLn( const char* fmt, ... ) const
va_list args;
va_start(args,fmt);
- DoWriteLn( _addIndentation( ascii_format_string(fmt, args), conlog_Indent ) );
+ DoWriteLn( _addIndentation( FastFormatString_Ascii(fmt, args), conlog_Indent ) );
va_end(args);
return false;
@@ -531,7 +396,7 @@ bool IConsoleWriter::WriteLn( ConsoleColors color, const char* fmt, ... ) const
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
- DoWriteLn( _addIndentation( ascii_format_string(fmt, args), conlog_Indent ) );
+ DoWriteLn( _addIndentation( FastFormatString_Ascii(fmt, args), conlog_Indent ) );
va_end(args);
return false;
@@ -544,7 +409,7 @@ bool IConsoleWriter::Error( const char* fmt, ... ) const
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongRed );
- DoWriteLn( _addIndentation( ascii_format_string(fmt, args) ) );
+ DoWriteLn( _addIndentation( FastFormatString_Ascii(fmt, args) ) );
va_end(args);
return false;
@@ -557,7 +422,7 @@ bool IConsoleWriter::Warning( const char* fmt, ... ) const
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongOrange );
- DoWriteLn( _addIndentation( ascii_format_string(fmt, args) ) );
+ DoWriteLn( _addIndentation( FastFormatString_Ascii(fmt, args) ) );
va_end(args);
return false;
@@ -573,7 +438,7 @@ bool IConsoleWriter::Write( const wxChar* fmt, ... ) const
va_list args;
va_start(args,fmt);
- DoWrite( unicode_format_string( fmt, args ) );
+ DoWrite( FastFormatString_Unicode( fmt, args ) );
va_end(args);
return false;
@@ -586,7 +451,7 @@ bool IConsoleWriter::Write( ConsoleColors color, const wxChar* fmt, ... ) const
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
- DoWrite( unicode_format_string( fmt, args ) );
+ DoWrite( FastFormatString_Unicode( fmt, args ) );
va_end(args);
return false;
@@ -598,7 +463,7 @@ bool IConsoleWriter::WriteLn( const wxChar* fmt, ... ) const
va_list args;
va_start(args,fmt);
- DoWriteLn( _addIndentation( unicode_format_string( fmt, args ), conlog_Indent ) );
+ DoWriteLn( _addIndentation( FastFormatString_Unicode( fmt, args ), conlog_Indent ) );
va_end(args);
return false;
@@ -611,7 +476,7 @@ bool IConsoleWriter::WriteLn( ConsoleColors color, const wxChar* fmt, ... ) cons
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
- DoWriteLn( _addIndentation( unicode_format_string( fmt, args ), conlog_Indent ) );
+ DoWriteLn( _addIndentation( FastFormatString_Unicode( fmt, args ), conlog_Indent ) );
va_end(args);
return false;
@@ -624,7 +489,7 @@ bool IConsoleWriter::Error( const wxChar* fmt, ... ) const
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongRed );
- DoWriteLn( _addIndentation( unicode_format_string( fmt, args ) ) );
+ DoWriteLn( _addIndentation( FastFormatString_Unicode( fmt, args ) ) );
va_end(args);
return false;
@@ -637,7 +502,7 @@ bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongOrange );
- DoWriteLn( _addIndentation( unicode_format_string( fmt, args ) ) );
+ DoWriteLn( _addIndentation( FastFormatString_Unicode( fmt, args ) ) );
va_end(args);
return false;
@@ -653,7 +518,7 @@ bool IConsoleWriter::WriteFromStdout( const char* fmt, ... ) const
va_list args;
va_start(args,fmt);
- DoWrite( ascii_format_string(fmt, args) );
+ DoWrite( FastFormatString_Ascii(fmt, args) );
va_end(args);
return false;
@@ -666,7 +531,7 @@ bool IConsoleWriter::WriteFromStdout( ConsoleColors color, const char* fmt, ...
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
- DoWrite( ascii_format_string(fmt, args) );
+ DoWrite( FastFormatString_Ascii(fmt, args) );
va_end(args);
return false;
diff --git a/common/src/Utilities/FastFormatString.cpp b/common/src/Utilities/FastFormatString.cpp
new file mode 100644
index 0000000000..d39229be11
--- /dev/null
+++ b/common/src/Utilities/FastFormatString.cpp
@@ -0,0 +1,163 @@
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 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 .
+ */
+
+#include "PrecompiledHeader.h"
+#include "Threading.h"
+
+using namespace Threading;
+
+// Sanity check: truncate strings if they exceed 512k in length. Anything like that
+// is either a bug or really horrible code that needs to be stopped before it causes
+// system deadlock.
+static const int MaxFormattedStringLength = 0x80000;
+
+// --------------------------------------------------------------------------------------
+// FormatBuffer
+// --------------------------------------------------------------------------------------
+// This helper class provides a "safe" way for us to check if the global handles for the
+// string format buffer have been initialized or destructed by the C++ global heap manager.
+// (C++ has no way to enforce init/destruct order on complex globals, thus the convoluted
+// use of booleans to check the status of the type initializers).
+//
+template< typename CharType >
+class FormatBuffer : public Mutex
+{
+public:
+ bool& clearbit;
+ SafeArray buffer;
+ wxMBConvUTF8 ConvUTF8;
+
+ FormatBuffer( bool& bit_to_clear_on_destruction )
+ : clearbit( bit_to_clear_on_destruction )
+ , buffer( 4096, wxsFormat( L"%s Format Buffer", (sizeof(CharType)==1) ? "Ascii" : "Unicode" ) )
+ {
+ bit_to_clear_on_destruction = false;
+ }
+
+ virtual ~FormatBuffer() throw()
+ {
+ clearbit = true;
+ Wait(); // lock the mutex, just in case.
+ }
+};
+
+// Assume the buffer is 'deleted' -- technically it's never existed on startup,
+// but "deleted" is well enough.
+
+static bool ascii_buffer_is_deleted = true;
+static bool unicode_buffer_is_deleted = true;
+
+static FormatBuffer ascii_buffer( ascii_buffer_is_deleted );
+static FormatBuffer unicode_buffer( unicode_buffer_is_deleted );
+
+static void format_that_ascii_mess( SafeArray& buffer, const char* fmt, va_list argptr )
+{
+ while( true )
+ {
+ int size = buffer.GetLength();
+ int len = vsnprintf(buffer.GetPtr(), size, fmt, argptr);
+
+ // some implementations of vsnprintf() don't NUL terminate
+ // the string if there is not enough space for it so
+ // always do it manually
+ buffer[size-1] = '\0';
+
+ if( size >= MaxFormattedStringLength ) break;
+
+ // vsnprintf() may return either -1 (traditional Unix behavior) or the
+ // total number of characters which would have been written if the
+ // buffer were large enough (newer standards such as Unix98)
+
+ if ( len < 0 )
+ len = size + (size/4);
+
+ if ( len < size ) break;
+ buffer.ExactAlloc( len + 1 );
+ };
+
+ // performing an assertion or log of a truncated string is unsafe, so let's not; even
+ // though it'd be kinda nice if we did.
+}
+
+static void format_that_unicode_mess( SafeArray& buffer, const wxChar* fmt, va_list argptr)
+{
+ while( true )
+ {
+ int size = buffer.GetLength();
+ int len = wxVsnprintf(buffer.GetPtr(), size, fmt, argptr);
+
+ // some implementations of vsnprintf() don't NUL terminate
+ // the string if there is not enough space for it so
+ // always do it manually
+ buffer[size-1] = L'\0';
+
+ if( size >= MaxFormattedStringLength ) break;
+
+ // vsnprintf() may return either -1 (traditional Unix behavior) or the
+ // total number of characters which would have been written if the
+ // buffer were large enough (newer standards such as Unix98)
+
+ if ( len < 0 )
+ len = size + (size/4);
+
+ if ( len < size ) break;
+ buffer.ExactAlloc( len + 1 );
+ };
+
+ // performing an assertion or log of a truncated string is unsafe, so let's not; even
+ // though it'd be kinda nice if we did.
+}
+
+wxString FastFormatString_Ascii(const char* fmt, va_list argptr)
+{
+ if( ascii_buffer_is_deleted )
+ {
+ // This means that the program is shutting down and the C++ destructors are
+ // running, randomly deallocating static variables from existence. We handle it
+ // as gracefully as possible by allocating local vars to do our bidding (slow, but
+ // ultimately necessary!)
+
+ SafeArray localbuf( 4096, L"Temporary Ascii Formatting Buffer" );
+ format_that_ascii_mess( localbuf, fmt, argptr );
+ return fromUTF8( localbuf.GetPtr() );
+ }
+ else
+ {
+ // This is normal operation. The static buffers are available for use, and we use
+ // them for sake of efficiency (fewer heap allocs, for sure!)
+
+ ScopedLock locker( ascii_buffer );
+ format_that_ascii_mess( ascii_buffer.buffer, fmt, argptr );
+ return fromUTF8( ascii_buffer.buffer.GetPtr() );
+ }
+}
+
+wxString FastFormatString_Unicode(const wxChar* fmt, va_list argptr)
+{
+ // See above for the explanation on the _is_deleted flags.
+
+ if( unicode_buffer_is_deleted )
+ {
+ SafeArray localbuf( 4096, L"Temporary Unicode Formatting Buffer" );
+ format_that_unicode_mess( localbuf, fmt, argptr );
+ return localbuf.GetPtr();
+ }
+ else
+ {
+ ScopedLock locker( unicode_buffer );
+ format_that_unicode_mess( unicode_buffer.buffer, fmt, argptr );
+ return unicode_buffer.buffer.GetPtr();
+ }
+}
diff --git a/common/src/Utilities/pxWindowTextWriter.cpp b/common/src/Utilities/pxWindowTextWriter.cpp
new file mode 100644
index 0000000000..d8cebfeede
--- /dev/null
+++ b/common/src/Utilities/pxWindowTextWriter.cpp
@@ -0,0 +1,136 @@
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 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 .
+ */
+
+#include "PrecompiledHeader.h"
+#include "wxGuiTools.h"
+
+// --------------------------------------------------------------------------------------
+// pxWindowTextWriter Implementations
+// --------------------------------------------------------------------------------------
+void pxWindowTextWriter::OnFontChanged()
+{
+}
+
+pxWindowTextWriter& pxWindowTextWriter::SetWeight( int weight )
+{
+ wxFont curfont( m_dc.GetFont() );
+ curfont.SetWeight( weight );
+ m_dc.SetFont( curfont );
+
+ return *this;
+}
+
+pxWindowTextWriter& pxWindowTextWriter::SetStyle( int style )
+{
+ wxFont curfont( m_dc.GetFont() );
+ curfont.SetStyle( style );
+ m_dc.SetFont( curfont );
+ return *this;
+}
+
+pxWindowTextWriter& pxWindowTextWriter::Normal()
+{
+ wxFont curfont( m_dc.GetFont() );
+ curfont.SetStyle( wxNORMAL );
+ curfont.SetWeight( wxNORMAL );
+ m_dc.SetFont( curfont );
+
+ return *this;
+}
+
+pxWindowTextWriter& pxWindowTextWriter::SetPos( const wxPoint& pos )
+{
+ m_curpos = pos;
+ return *this;
+}
+
+pxWindowTextWriter& pxWindowTextWriter::MovePos( const wxSize& delta )
+{
+ m_curpos += delta;
+ return *this;
+}
+
+pxWindowTextWriter& pxWindowTextWriter::SetY( int ypos )
+{
+ m_curpos.y = ypos;
+ return *this;
+}
+
+pxWindowTextWriter& pxWindowTextWriter::MoveY( int ydelta )
+{
+ m_curpos.y += ydelta;
+ return *this;
+}
+
+void pxWindowTextWriter::_DoWriteLn( const wxChar* msg )
+{
+ pxAssume( msg );
+ int tWidth, tHeight;
+ m_dc.GetTextExtent( msg, &tWidth, &tHeight );
+
+ wxPoint dispos( m_curpos );
+
+ if( m_align & wxALIGN_CENTER_HORIZONTAL )
+ {
+ dispos.x = (m_dc.GetSize().GetWidth() - tWidth) / 2;
+ }
+ else if( m_align & wxALIGN_RIGHT )
+ {
+ dispos.x = m_dc.GetSize().GetWidth() - tWidth;
+ }
+
+ m_dc.DrawText( msg, dispos );
+ m_curpos.y += tHeight + m_leading;
+}
+
+// Splits incoming multi-line strings into pieces, and dispatches each line individually
+// to the text writer.
+void pxWindowTextWriter::_DoWrite( const wxChar* msg )
+{
+ pxAssume( msg );
+
+ wxArrayString parts;
+ SplitString( parts, msg, L'\n' );
+
+ for( size_t i=0; i
void AppOpenDialog( wxWindow* parent=NULL )
{
- if( wxWindow* window = wxFindWindowByName( DialogType::GetNameStatic() ) )
+ if( wxWindow* window = wxFindWindowByName( L"Dialog:" + DialogType::GetNameStatic() ) )
window->SetFocus();
else
(new DialogType( parent ))->Show();
diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp
index 26845adcd2..33873bc51e 100644
--- a/pcsx2/gui/AppMain.cpp
+++ b/pcsx2/gui/AppMain.cpp
@@ -50,7 +50,7 @@ ConfigOverrides OverrideOptions;
template
int AppOpenModalDialog( wxWindow* parent=NULL )
{
- if( wxWindow* window = wxFindWindowByName( DialogType::GetNameStatic() ) )
+ if( wxWindow* window = wxFindWindowByName( L"Dialog:" + DialogType::GetNameStatic() ) )
{
window->SetFocus();
if( wxDialog* dialog = wxDynamicCast( window, wxDialog ) )
diff --git a/pcsx2/gui/ApplyState.h b/pcsx2/gui/ApplyState.h
index c204042b95..457aa42d24 100644
--- a/pcsx2/gui/ApplyState.h
+++ b/pcsx2/gui/ApplyState.h
@@ -21,6 +21,12 @@
#include "AppCommon.h"
class BaseApplicableConfigPanel;
+class BaseApplicableDialog;
+
+BEGIN_DECLARE_EVENT_TYPES()
+ DECLARE_EVENT_TYPE( pxEvt_OnWindowCreated, -1 )
+ DECLARE_EVENT_TYPE( pxEvt_ApplySettings, -1 )
+END_DECLARE_EVENT_TYPES()
namespace Exception
{
@@ -109,6 +115,39 @@ public:
virtual ApplyStateStruct& GetApplyState() { return m_ApplyState; }
};
+class BaseApplicableDialog
+ : public wxDialogWithHelpers
+ , public IApplyState
+{
+ DECLARE_DYNAMIC_CLASS_NO_COPY(BaseApplicableDialog)
+
+public:
+ BaseApplicableDialog() {}
+ virtual ~BaseApplicableDialog() throw();
+
+ // 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 );
+ BaseApplicableDialog(wxWindow* parent, const wxString& title, wxOrientation sizerOrient );
+
+ void OnSettingsApplied( wxCommandEvent& evt );
+ void OnWindowCreated( 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_OnSettingsLoadSave( const AppSettingsEventInfo& ) {}
+ virtual void AppStatusEvent_OnExit() {}
+};
+
// --------------------------------------------------------------------------------------
// BaseApplicableConfigPanel
// --------------------------------------------------------------------------------------
@@ -119,7 +158,8 @@ public:
// 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
+class BaseApplicableConfigPanel
+ : public wxPanelWithHelpers
{
protected:
int m_OwnerPage;
diff --git a/pcsx2/gui/Dialogs/AboutBoxDialog.cpp b/pcsx2/gui/Dialogs/AboutBoxDialog.cpp
index 91038df9a4..3209bf7ceb 100644
--- a/pcsx2/gui/Dialogs/AboutBoxDialog.cpp
+++ b/pcsx2/gui/Dialogs/AboutBoxDialog.cpp
@@ -53,8 +53,6 @@ Dialogs::AboutBoxDialog::AboutBoxDialog( wxWindow* parent )
wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN
)
{
- SetName( GetNameStatic() );
-
static const wxString LabelAuthors = fromUTF8(
"Developers"
"\n\n"
diff --git a/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp b/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp
index eafa3576de..fa4bac5f54 100644
--- a/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp
+++ b/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp
@@ -28,6 +28,9 @@
#include
#include
+DEFINE_EVENT_TYPE( pxEvt_OnWindowCreated )
+DEFINE_EVENT_TYPE( pxEvt_ApplySettings )
+
using namespace Panels;
// configure the orientation of the listbox based on the platform
@@ -38,33 +41,63 @@ using namespace Panels;
static const int s_orient = wxBK_LEFT;
#endif
-IMPLEMENT_DYNAMIC_CLASS(Dialogs::BaseApplicableDialog, wxDialogWithHelpers)
+IMPLEMENT_DYNAMIC_CLASS(BaseApplicableDialog, wxDialogWithHelpers)
-Dialogs::BaseApplicableDialog::BaseApplicableDialog( wxWindow* parent, const wxString& title )
+BaseApplicableDialog::BaseApplicableDialog( wxWindow* parent, const wxString& title )
: wxDialogWithHelpers( parent, title, false )
{
+ Init();
}
-Dialogs::BaseApplicableDialog::BaseApplicableDialog( wxWindow* parent, const wxString& title, wxOrientation sizerOrient )
+BaseApplicableDialog::BaseApplicableDialog( wxWindow* parent, const wxString& title, wxOrientation sizerOrient )
: wxDialogWithHelpers( parent, title, sizerOrient )
{
+ Init();
}
-Dialogs::BaseApplicableDialog::~BaseApplicableDialog() throw()
+BaseApplicableDialog::~BaseApplicableDialog() throw()
{
m_ApplyState.DoCleanup();
}
-Dialogs::BaseConfigurationDialog::BaseConfigurationDialog( wxWindow* parent, const wxString& title, wxImageList& bookicons, int idealWidth )
- : _parent( parent, title, wxVERTICAL )
- , m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) )
+wxString BaseApplicableDialog::GetDialogName() const
{
- m_idealWidth = idealWidth;
+ pxFailDev( "This class must implement GetDialogName!" );
+ return L"Unnamed";
+}
- m_listbook.SetImageList( &bookicons );
- m_ApplyState.StartBook( &m_listbook );
- *this += m_listbook | pxExpand.Border( wxLEFT | wxRIGHT, 2 );
+void BaseApplicableDialog::Init()
+{
+ Connect( pxEvt_OnWindowCreated, wxCommandEventHandler (BaseApplicableDialog::OnWindowCreated) );
+ Connect( pxEvt_ApplySettings, wxCommandEventHandler (BaseApplicableDialog::OnSettingsApplied) );
+
+ wxCommandEvent applyEvent( pxEvt_ApplySettings );
+ applyEvent.SetId( GetId() );
+ AddPendingEvent( applyEvent );
+}
+
+void BaseApplicableDialog::OnSettingsApplied( wxCommandEvent& evt )
+{
+ evt.Skip();
+ if( evt.GetId() == GetId() ) AppStatusEvent_OnSettingsApplied();
+}
+
+void BaseApplicableDialog::OnWindowCreated( wxCommandEvent& evt )
+{
+ evt.Skip();
+ if( evt.GetId() == GetId() ) SetName( L"Dialog:" + GetDialogName() );
+}
+
+
+// --------------------------------------------------------------------------------------
+// BaseConfigurationDialog Implementations
+// --------------------------------------------------------------------------------------
+Dialogs::BaseConfigurationDialog::BaseConfigurationDialog( wxWindow* parent, const wxString& title, int idealWidth )
+ : _parent( parent, title, wxVERTICAL )
+{
+ m_idealWidth = idealWidth;
+ m_listbook = NULL;
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BaseConfigurationDialog::OnOk_Click ) );
Connect( wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BaseConfigurationDialog::OnCancel_Click ) );
@@ -94,6 +127,19 @@ Dialogs::BaseConfigurationDialog::BaseConfigurationDialog( wxWindow* parent, con
ConnectSomethingChanged( DIRPICKER_CHANGED );
}
+void Dialogs::BaseConfigurationDialog::AddListbook( wxSizer* sizer )
+{
+ if( !sizer ) sizer = GetSizer();
+ sizer += m_listbook | pxExpand.Border( wxLEFT | wxRIGHT, 2 );
+}
+
+void Dialogs::BaseConfigurationDialog::CreateListbook( wxImageList& bookicons )
+{
+ m_listbook = new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient );
+ m_listbook->SetImageList( &bookicons );
+ m_ApplyState.StartBook( m_listbook );
+}
+
void Dialogs::BaseConfigurationDialog::AddOkCancel( wxSizer* sizer )
{
_parent::AddOkCancel( sizer, true );
@@ -131,7 +177,7 @@ void Dialogs::BaseConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
if( m_ApplyState.ApplyAll() )
{
FindWindow( wxID_APPLY )->Disable();
- GetConfSettingsTabName() = m_labels[m_listbook.GetSelection()];
+ if( m_listbook ) GetConfSettingsTabName() = m_labels[m_listbook->GetSelection()];
AppSaveSettings();
evt.Skip();
}
@@ -140,7 +186,7 @@ void Dialogs::BaseConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
void Dialogs::BaseConfigurationDialog::OnCancel_Click( wxCommandEvent& evt )
{
evt.Skip();
- GetConfSettingsTabName() = m_labels[m_listbook.GetSelection()];
+ if( m_listbook ) GetConfSettingsTabName() = m_labels[m_listbook->GetSelection()];
}
void Dialogs::BaseConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
@@ -148,7 +194,7 @@ void Dialogs::BaseConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
if( m_ApplyState.ApplyAll() )
FindWindow( wxID_APPLY )->Disable();
- GetConfSettingsTabName() = m_labels[m_listbook.GetSelection()];
+ if( m_listbook ) GetConfSettingsTabName() = m_labels[m_listbook->GetSelection()];
AppSaveSettings();
}
@@ -164,8 +210,9 @@ void Dialogs::BaseConfigurationDialog::OnScreenshot_Click( wxCommandEvent& evt )
memDC.Blit( wxPoint(), dcsize, &dc, wxPoint() );
}
+ wxString pagename( m_listbook ? (L"_" + m_listbook->GetPageText( m_listbook->GetSelection() )) : wxString() );
wxString filenameDefault;
- filenameDefault.Printf( L"pcsx2_settings_%s.png", m_listbook.GetPageText( m_listbook.GetSelection() ).c_str() );
+ filenameDefault.Printf( L"pcsx2_%s%s.png", GetDialogName().c_str(), pagename.c_str() );
filenameDefault.Replace( L"/", L"-" );
wxString filename( wxFileSelector( _("Save dialog screenshots to..."), g_Conf->Folders.Snapshots.ToString(),
diff --git a/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl b/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl
index 03a7bb0795..c17d06fb1e 100644
--- a/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl
+++ b/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl
@@ -23,6 +23,6 @@ void Dialogs::BaseConfigurationDialog::AddPage( const char* label, int iconid )
const wxString labelstr( fromUTF8( label ) );
const int curidx = m_labels.Add( labelstr );
m_ApplyState.SetCurrentPage( curidx );
- m_listbook.AddPage( new T( &m_listbook ), wxGetTranslation( labelstr ),
+ m_listbook->AddPage( new T( m_listbook ), wxGetTranslation( labelstr ),
( labelstr == GetConfSettingsTabName() ), iconid );
}
diff --git a/pcsx2/gui/Dialogs/BiosSelectorDialog.cpp b/pcsx2/gui/Dialogs/BiosSelectorDialog.cpp
index 6ef113376c..9812404096 100644
--- a/pcsx2/gui/Dialogs/BiosSelectorDialog.cpp
+++ b/pcsx2/gui/Dialogs/BiosSelectorDialog.cpp
@@ -30,8 +30,6 @@ using namespace pxSizerFlags;
Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent )
: BaseApplicableDialog( parent, _("BIOS Selector"), wxVERTICAL )
{
- SetName( GetNameStatic() );
-
m_idealWidth = 500;
m_selpan = new Panels::BiosSelectorPanel( this );
diff --git a/pcsx2/gui/Dialogs/ConfigurationDialog.h b/pcsx2/gui/Dialogs/ConfigurationDialog.h
index 5485e7e5ab..cf4fb672f9 100644
--- a/pcsx2/gui/Dialogs/ConfigurationDialog.h
+++ b/pcsx2/gui/Dialogs/ConfigurationDialog.h
@@ -25,27 +25,13 @@
namespace Panels
{
class BaseSelectorPanel;
- class MemoryCardListPanel;
+ class MemoryCardListPanel_Advanced;
+ class McdConfigPanel_Toggles;
+ class BaseMcdListPanel;
}
namespace Dialogs
{
- class BaseApplicableDialog : public wxDialogWithHelpers, public IApplyState
- {
- DECLARE_DYNAMIC_CLASS_NO_COPY(BaseApplicableDialog)
-
- public:
- BaseApplicableDialog() {}
-
- protected:
- BaseApplicableDialog(wxWindow* parent, const wxString& title );
- BaseApplicableDialog(wxWindow* parent, const wxString& title, wxOrientation sizerOrient );
-
- public:
- virtual ~BaseApplicableDialog() throw();
- //ApplyStateStruct& GetApplyState() { return m_ApplyState; }
- };
-
// --------------------------------------------------------------------------------------
// BaseConfigurationDialog
// --------------------------------------------------------------------------------------
@@ -54,15 +40,17 @@ namespace Dialogs
typedef BaseApplicableDialog _parent;
protected:
- wxListbook& m_listbook;
+ wxListbook* m_listbook;
wxArrayString m_labels;
public:
virtual ~BaseConfigurationDialog() throw();
- BaseConfigurationDialog(wxWindow* parent, const wxString& title, wxImageList& bookicons, int idealWidth);
+ BaseConfigurationDialog(wxWindow* parent, const wxString& title, int idealWidth);
public:
void AddOkCancel( wxSizer* sizer=NULL );
+ void AddListbook( wxSizer* sizer=NULL );
+ void CreateListbook( wxImageList& bookicons );
template< typename T >
void AddPage( const char* label, int iconid );
@@ -86,7 +74,8 @@ namespace Dialogs
public:
virtual ~SysConfigDialog() throw() {}
SysConfigDialog(wxWindow* parent=NULL);
- static const wxChar* GetNameStatic() { return L"Dialog:CoreSettings"; }
+ static wxString GetNameStatic() { return L"CoreSettings"; }
+ wxString GetDialogName() const { return GetNameStatic(); }
protected:
virtual wxString& GetConfSettingsTabName() const { return g_Conf->SysSettingsTabName; }
@@ -97,15 +86,16 @@ namespace Dialogs
// --------------------------------------------------------------------------------------
class McdConfigDialog : public BaseConfigurationDialog
{
- typedef BaseApplicableDialog _parent;
+ typedef BaseConfigurationDialog _parent;
protected:
- Panels::MemoryCardListPanel* m_panel_mcdlist;
+ Panels::BaseMcdListPanel* m_panel_mcdlist;
public:
virtual ~McdConfigDialog() throw() {}
McdConfigDialog(wxWindow* parent=NULL);
- static const wxChar* GetNameStatic() { return L"Dialog:MemoryCardSettings"; }
+ static wxString GetNameStatic() { return L"McdConfig"; }
+ wxString GetDialogName() const { return GetNameStatic(); }
virtual bool Show( bool show=true );
virtual int ShowModal();
@@ -124,7 +114,8 @@ namespace Dialogs
public:
virtual ~AppConfigDialog() throw() {}
AppConfigDialog(wxWindow* parent=NULL);
- static const wxChar* GetNameStatic() { return L"Dialog:AppSettings"; }
+ static wxString GetNameStatic() { return L"AppSettings"; }
+ wxString GetDialogName() const { return GetNameStatic(); }
protected:
virtual wxString& GetConfSettingsTabName() const { return g_Conf->AppSettingsTabName; }
@@ -144,7 +135,8 @@ namespace Dialogs
virtual ~BiosSelectorDialog() throw() {}
BiosSelectorDialog( wxWindow* parent=NULL );
- static const wxChar* GetNameStatic() { return L"Dialog:BiosSelector"; }
+ static wxString GetNameStatic() { return L"BiosSelector"; }
+ wxString GetDialogName() const { return GetNameStatic(); }
virtual bool Show( bool show=true );
virtual int ShowModal();
@@ -157,7 +149,7 @@ namespace Dialogs
// --------------------------------------------------------------------------------------
// CreateMemoryCardDialog
// --------------------------------------------------------------------------------------
- class CreateMemoryCardDialog : public BaseApplicableDialog
+ class CreateMemoryCardDialog : public wxDialogWithHelpers
{
protected:
wxFilePickerCtrl* m_filepicker;
@@ -171,8 +163,6 @@ namespace Dialogs
virtual ~CreateMemoryCardDialog() throw() {}
CreateMemoryCardDialog( wxWindow* parent, uint port, uint slot, const wxString& filepath=wxEmptyString );
- static const wxChar* GetNameStatic() { return L"Dialog:CreateMemoryCard"; }
-
protected:
void OnOk_Click( wxCommandEvent& evt );
void OnDoubleClicked( wxCommandEvent& evt );
diff --git a/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp b/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp
index 9b9fa69110..b743a740ac 100644
--- a/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp
+++ b/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp
@@ -39,7 +39,7 @@ wxFilePickerCtrl* CreateMemoryCardFilePicker( wxWindow* parent, uint portidx, ui
) );*/
Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint port, uint slot, const wxString& filepath )
- : BaseApplicableDialog( parent, _("Create a new MemoryCard..."), wxVERTICAL )
+ : wxDialogWithHelpers( parent, _("Create a new MemoryCard..."), wxVERTICAL )
{
m_idealWidth = 620;
diff --git a/pcsx2/gui/Dialogs/LogOptionsDialog.cpp b/pcsx2/gui/Dialogs/LogOptionsDialog.cpp
index 10c05e2476..29c4693685 100644
--- a/pcsx2/gui/Dialogs/LogOptionsDialog.cpp
+++ b/pcsx2/gui/Dialogs/LogOptionsDialog.cpp
@@ -24,8 +24,6 @@ using namespace Panels;
Dialogs::LogOptionsDialog::LogOptionsDialog( wxWindow* parent )
: BaseApplicableDialog( parent, _("Trace Logging"), wxVERTICAL )
{
- SetName( GetNameStatic() );
-
m_idealWidth = 480;
*this += new LogOptionsPanel( this );
diff --git a/pcsx2/gui/Dialogs/LogOptionsDialog.h b/pcsx2/gui/Dialogs/LogOptionsDialog.h
index 53cda64726..957c2c965a 100644
--- a/pcsx2/gui/Dialogs/LogOptionsDialog.h
+++ b/pcsx2/gui/Dialogs/LogOptionsDialog.h
@@ -32,7 +32,8 @@ public:
LogOptionsDialog( wxWindow* parent=NULL );
virtual ~LogOptionsDialog() throw() { }
- static const wxChar* GetNameStatic() { return L"Dialog:TraceLogSettings"; }
+ static wxString GetNameStatic() { return L"TraceLogSettings"; }
+ wxString GetDialogName() const { return GetNameStatic(); }
protected:
void OnOk_Click( wxCommandEvent& evt );
diff --git a/pcsx2/gui/Dialogs/McdConfigDialog.cpp b/pcsx2/gui/Dialogs/McdConfigDialog.cpp
index 1f0d02c051..5528e63b68 100644
--- a/pcsx2/gui/Dialogs/McdConfigDialog.cpp
+++ b/pcsx2/gui/Dialogs/McdConfigDialog.cpp
@@ -86,7 +86,8 @@ void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
#endif
}
-Panels::McdConfigPanel_Standard::McdConfigPanel_Standard(wxWindow *parent) : _parent( parent )
+Panels::McdConfigPanel_Standard::McdConfigPanel_Standard(wxWindow *parent)
+ : _parent( parent )
{
m_panel_cardinfo[0] = new MemoryCardInfoPanel( this, 0, 0 );
m_panel_cardinfo[1] = new MemoryCardInfoPanel( this, 1, 0 );
@@ -139,29 +140,43 @@ using namespace Panels;
using namespace pxSizerFlags;
Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
- : BaseConfigurationDialog( parent, _("MemoryCard Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
+ : BaseConfigurationDialog( parent, _("MemoryCard Manager"), 600 )
{
- SetName( GetNameStatic() );
-
// [TODO] : Discover and use a good multitap port icon! Possibility might be a
// simple 3x memorycards icon, in cascading form.
// (for now everything defaults to the redundant memorycard icon)
- const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
+ if( false ) //g_Conf->McdAdvancedMode )
+ {
+ m_panel_mcdlist = new MemoryCardListPanel_Advanced( this );
- AddPage ( wxLt("Settings"), cfgid.MemoryCard );
- AddPage ( wxLt("Slots 1/2"), cfgid.MemoryCard );
- AddPage ( wxLt("Multitap 1"), cfgid.MemoryCard );
- AddPage ( wxLt("Multitap 2"), cfgid.MemoryCard );
+ CreateListbook( wxGetApp().GetImgList_Config() );
+
+ const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
+ AddPage ( wxLt("Settings"), cfgid.MemoryCard );
+ AddPage ( wxLt("Slots 1/2"), cfgid.MemoryCard );
+ AddPage ( wxLt("Multitap 1"), cfgid.MemoryCard );
+ AddPage ( wxLt("Multitap 2"), cfgid.MemoryCard );
- MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth );
+ MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth );
- m_panel_mcdlist = new MemoryCardListPanel( this );
+ AddListbook();
- *this += StdPadding;
- *this += new wxStaticLine( this ) | StdExpand();
- *this += StdPadding;
- *this += m_panel_mcdlist | StdExpand();
+ *this += StdPadding;
+ *this += new wxStaticLine( this ) | StdExpand();
+ *this += StdPadding;
+ *this += m_panel_mcdlist | StdExpand();
+ }
+ else
+ {
+ m_panel_mcdlist = new MemoryCardListPanel_Simple( this );
+
+ *this += m_panel_mcdlist | StdExpand();
+ //*this += StdPadding;
+ *this += new wxStaticLine( this ) | StdExpand();
+ *this += StdPadding;
+ *this += new McdConfigPanel_Toggles( this ) | StdExpand();
+ }
AddOkCancel();
}
diff --git a/pcsx2/gui/Dialogs/ModalPopups.h b/pcsx2/gui/Dialogs/ModalPopups.h
index 02fadeeede..b5fca843d0 100644
--- a/pcsx2/gui/Dialogs/ModalPopups.h
+++ b/pcsx2/gui/Dialogs/ModalPopups.h
@@ -87,7 +87,8 @@ namespace Dialogs
AboutBoxDialog( wxWindow* parent=NULL );
virtual ~AboutBoxDialog() throw() {}
- static const wxChar* GetNameStatic() { return L"Dialog:AboutBox"; }
+ static wxString GetNameStatic() { return L"AboutBox"; }
+ wxString GetDialogName() const { return GetNameStatic(); }
};
diff --git a/pcsx2/gui/Dialogs/SysConfigDialog.cpp b/pcsx2/gui/Dialogs/SysConfigDialog.cpp
index a7837b750a..21235ff65b 100644
--- a/pcsx2/gui/Dialogs/SysConfigDialog.cpp
+++ b/pcsx2/gui/Dialogs/SysConfigDialog.cpp
@@ -28,10 +28,9 @@
using namespace Panels;
Dialogs::SysConfigDialog::SysConfigDialog(wxWindow* parent)
- : BaseConfigurationDialog( parent, _("PS2 Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
+ : BaseConfigurationDialog( parent, _("PS2 Settings - PCSX2"), 600 )
{
- SetName( GetNameStatic() );
-
+ CreateListbook( wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage ( wxLt("EE/IOP"), cfgid.Cpu );
@@ -43,14 +42,14 @@ Dialogs::SysConfigDialog::SysConfigDialog(wxWindow* parent)
MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth );
+ AddListbook();
AddOkCancel();
}
Dialogs::AppConfigDialog::AppConfigDialog(wxWindow* parent)
- : BaseConfigurationDialog( parent, _("Application Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
+ : BaseConfigurationDialog( parent, _("Application Settings - PCSX2"), 600 )
{
- SetName( GetNameStatic() );
-
+ CreateListbook( wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage ( wxLt("GS Window"), cfgid.Paths );
@@ -58,5 +57,6 @@ Dialogs::AppConfigDialog::AppConfigDialog(wxWindow* parent)
MSW_ListView_SetIconSpacing( m_listbook, GetClientSize().GetWidth() );
+ AddListbook();
AddOkCancel();
}
diff --git a/pcsx2/gui/MSWstuff.cpp b/pcsx2/gui/MSWstuff.cpp
index ec1fe0c0c0..3f4437e1d0 100644
--- a/pcsx2/gui/MSWstuff.cpp
+++ b/pcsx2/gui/MSWstuff.cpp
@@ -60,6 +60,13 @@ void MSW_ListView_SetIconSpacing( wxListbook& listbook, int width )
#endif
}
+void MSW_ListView_SetIconSpacing( wxListbook* listbook, int width )
+{
+ if( listbook == NULL ) return;
+ MSW_ListView_SetIconSpacing( *listbook, width );
+}
+
+
#ifdef __WXMSW__
WXLRESULT GSPanel::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
diff --git a/pcsx2/gui/MSWstuff.h b/pcsx2/gui/MSWstuff.h
index b24035bb68..f28148b50b 100644
--- a/pcsx2/gui/MSWstuff.h
+++ b/pcsx2/gui/MSWstuff.h
@@ -20,6 +20,7 @@ class wxListbook;
extern void MSW_SetWindowAfter( WXWidget hwnd, WXWidget hwndAfter );
extern void MSW_OutputDebugString( const wxString& text );
extern void MSW_ListView_SetIconSpacing( wxListbook& listbook, int width );
+extern void MSW_ListView_SetIconSpacing( wxListbook* listbook, int width );
extern void pxDwm_Load();
extern void pxDwm_Unload();
diff --git a/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp b/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp
index 7cafa831bd..c8c1295991 100644
--- a/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp
+++ b/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp
@@ -167,12 +167,6 @@ void BaseApplicableConfigPanel::SetFocusToMe()
m_OwnerBook->SetSelection( m_OwnerPage );
}
-BEGIN_DECLARE_EVENT_TYPES()
- DECLARE_EVENT_TYPE( pxEvt_ApplySettings, -1 )
-END_DECLARE_EVENT_TYPES()
-
-DEFINE_EVENT_TYPE( pxEvt_ApplySettings )
-
void BaseApplicableConfigPanel::Init()
{
// We need to bind to an event that occurs *after* all window and child
@@ -196,7 +190,6 @@ void BaseApplicableConfigPanel::Init()
AddPendingEvent( applyEvent );
}
-//void BaseApplicableConfigPanel::OnCreateWindow( wxWindowCreateEvent& evt )
void BaseApplicableConfigPanel::OnSettingsApplied( wxCommandEvent& evt )
{
evt.Skip();
diff --git a/pcsx2/gui/Panels/ConfigurationPanels.h b/pcsx2/gui/Panels/ConfigurationPanels.h
index a5406fa6f6..ab86ebfa54 100644
--- a/pcsx2/gui/Panels/ConfigurationPanels.h
+++ b/pcsx2/gui/Panels/ConfigurationPanels.h
@@ -411,7 +411,7 @@ namespace Panels
virtual bool ValidateEnumerationStatus();
};
- class MemoryCardListPanel;
+ class MemoryCardListPanel_Advanced;
class MemoryCardInfoPanel;
// --------------------------------------------------------------------------------------
@@ -420,7 +420,7 @@ namespace Panels
class MemoryCardsPanel : public BaseApplicableConfigPanel
{
protected:
- MemoryCardListPanel* m_panel_AllKnownCards;
+ MemoryCardListPanel_Advanced* m_panel_AllKnownCards;
MemoryCardInfoPanel* m_panel_cardinfo[2][4];
pxCheckBox* m_check_Ejection;
pxCheckBox* m_check_Multitap[2];
diff --git a/pcsx2/gui/Panels/MemoryCardListPanel.cpp b/pcsx2/gui/Panels/MemoryCardListPanel.cpp
index 815fa5ff92..b35b1dc2ed 100644
--- a/pcsx2/gui/Panels/MemoryCardListPanel.cpp
+++ b/pcsx2/gui/Panels/MemoryCardListPanel.cpp
@@ -36,10 +36,17 @@ static bool IsMcdFormatted( wxFFile& fhand )
return memcmp( formatted_string, dest, fmtstrlen ) == 0;
}
-static bool EnumerateMemoryCard( McdListItem& dest, const wxString& filename )
+bool EnumerateMemoryCard( McdListItem& dest, const wxFileName& filename )
{
- Console.WriteLn( filename.c_str() );
- wxFFile mcdFile( filename );
+ dest.IsFormatted = false;
+ dest.IsEnabled = false;
+ dest.IsPresent = false;
+
+ const wxString fullpath( filename.GetFullPath() );
+ if( !filename.FileExists() ) return false;
+
+ Console.WriteLn( fullpath );
+ wxFFile mcdFile( fullpath );
if( !mcdFile.IsOpened() ) return false; // wx should log the error for us.
if( mcdFile.Length() < (1024*528) )
{
@@ -47,10 +54,12 @@ static bool EnumerateMemoryCard( McdListItem& dest, const wxString& filename )
return false;
}
+ dest.IsPresent = true;
+ dest.IsEnabled = true;
dest.Filename = filename;
dest.SizeInMB = (uint)(mcdFile.Length() / (1024 * 528 * 2));
dest.IsFormatted = IsMcdFormatted( mcdFile );
- wxFileName(filename).GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
+ filename.GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
return true;
}
@@ -77,19 +86,55 @@ static int EnumerateMemoryCards( McdList& dest, const wxArrayString& files )
return pushed;
}
+// =====================================================================================================
+// BaseMcdListPanel (implementations)
+// =====================================================================================================
+Panels::BaseMcdListPanel::BaseMcdListPanel( wxWindow* parent )
+ : _parent( parent )
+{
+ m_FolderPicker = new DirPickerPanel( this, FolderId_MemoryCards,
+ //_("MemoryCard Search Path:"), // static box label
+ _("Select folder with PS2 MemoryCards") // dir picker popup label
+ );
+
+ m_listview = NULL;
+
+ m_btn_Refresh = new wxButton( this, wxID_ANY, _("Refresh list") );
+
+ Connect( m_btn_Refresh->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BaseMcdListPanel::OnRefresh) );
+}
+
+void Panels::BaseMcdListPanel::CreateLayout()
+{
+ if( m_listview ) m_listview->SetMinSize( wxSize( m_idealWidth, 140 ) );
+
+ wxBoxSizer& s_buttons(*new wxBoxSizer( wxHORIZONTAL ));
+ s_leftside_buttons = new wxBoxSizer( wxHORIZONTAL );
+ s_rightside_buttons = new wxBoxSizer( wxHORIZONTAL );
+
+ s_buttons += s_leftside_buttons | pxAlignLeft;
+ s_buttons += pxStretchSpacer();
+ s_buttons += s_rightside_buttons | pxAlignRight;
+
+ if( m_FolderPicker ) *this += m_FolderPicker | pxExpand;
+ if( m_listview ) *this += m_listview | pxExpand;
+ *this += s_buttons | pxExpand;
+
+ *s_leftside_buttons += m_btn_Refresh;
+}
// =====================================================================================================
-// MemoryCardListPanel
+// MemoryCardListPanel_Advanced (implementations)
// =====================================================================================================
-Panels::MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
- : BaseSelectorPanel( parent )
+Panels::MemoryCardListPanel_Advanced::MemoryCardListPanel_Advanced( wxWindow* parent )
+ : _parent( parent )
{
m_FolderPicker = new DirPickerPanel( this, FolderId_MemoryCards,
//_("MemoryCard Search Path:"), // static box label
_("Select folder with PS2 MemoryCards") // dir picker popup label
);
- m_listview = new MemoryCardListView(this);
+ m_listview = new MemoryCardListView_Advanced(this);
wxButton* button_Create = new wxButton(this, wxID_ANY, _("Create new card..."));
@@ -97,35 +142,22 @@ Panels::MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
// Sizer / Layout Section
// ------------------------------------
- wxBoxSizer& s_buttons (*new wxBoxSizer( wxHORIZONTAL ));
- wxBoxSizer& s_leftside (*new wxBoxSizer( wxHORIZONTAL ));
- wxBoxSizer& s_rightside (*new wxBoxSizer( wxHORIZONTAL ));
-
- s_leftside += button_Create | StdSpace();
-
- s_buttons += s_leftside | pxAlignLeft;
- s_buttons += pxStretchSpacer();
- s_buttons += s_rightside | pxAlignRight;
-
- *this += m_FolderPicker | pxExpand;
- *this += m_listview | pxExpand;
- *this += s_buttons | pxExpand;
-
- m_listview->SetMinSize( wxSize( m_idealWidth, 120 ) );
+ CreateLayout();
+ *s_leftside_buttons += button_Create | StdSpace();
- Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel::OnListDrag));
- Connect( button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel::OnCreateNewCard));
+ Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel_Advanced::OnListDrag));
+ Connect( button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Advanced::OnCreateNewCard));
}
-void Panels::MemoryCardListPanel::Apply()
+void Panels::MemoryCardListPanel_Advanced::Apply()
{
}
-void Panels::MemoryCardListPanel::AppStatusEvent_OnSettingsApplied()
+void Panels::MemoryCardListPanel_Advanced::AppStatusEvent_OnSettingsApplied()
{
}
-bool Panels::MemoryCardListPanel::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
+bool Panels::MemoryCardListPanel_Advanced::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
{
if( filenames.GetCount() == 1 && wxFileName(filenames[0]).IsDir() )
{
@@ -135,7 +167,7 @@ bool Panels::MemoryCardListPanel::OnDropFiles(wxCoord x, wxCoord y, const wxArra
return false;
}
-bool Panels::MemoryCardListPanel::ValidateEnumerationStatus()
+bool Panels::MemoryCardListPanel_Advanced::ValidateEnumerationStatus()
{
bool validated = true;
@@ -159,7 +191,7 @@ bool Panels::MemoryCardListPanel::ValidateEnumerationStatus()
return validated;
}
-void Panels::MemoryCardListPanel::DoRefresh()
+void Panels::MemoryCardListPanel_Advanced::DoRefresh()
{
if( !m_KnownCards ) return;
@@ -188,12 +220,12 @@ void Panels::MemoryCardListPanel::DoRefresh()
//m_listview->SetCardCount( m_KnownCards->size() );
}
-void Panels::MemoryCardListPanel::OnCreateNewCard(wxCommandEvent& evt)
+void Panels::MemoryCardListPanel_Advanced::OnCreateNewCard(wxCommandEvent& evt)
{
}
-void Panels::MemoryCardListPanel::OnListDrag(wxListEvent& evt)
+void Panels::MemoryCardListPanel_Advanced::OnListDrag(wxListEvent& evt)
{
wxFileDataObject my_data;
my_data.AddFile( (*m_KnownCards)[m_listview->GetItemData(m_listview->GetFirstSelected())].Filename.GetFullPath() );
@@ -203,19 +235,218 @@ void Panels::MemoryCardListPanel::OnListDrag(wxListEvent& evt)
wxDragResult result = dragSource.DoDragDrop();
}
-int Panels::MemoryCardListPanel::GetLength() const
+int Panels::MemoryCardListPanel_Advanced::GetLength() const
{
return m_KnownCards ? m_KnownCards->size() : 0;
}
-const McdListItem& Panels::MemoryCardListPanel::Get( int idx ) const
+const McdListItem& Panels::MemoryCardListPanel_Advanced::GetCard( int idx ) const
{
pxAssume(!!m_KnownCards);
return (*m_KnownCards)[idx];
}
-McdListItem& Panels::MemoryCardListPanel::Get( int idx )
+McdListItem& Panels::MemoryCardListPanel_Advanced::GetCard( int idx )
{
pxAssume(!!m_KnownCards);
return (*m_KnownCards)[idx];
}
+
+uint Panels::MemoryCardListPanel_Advanced::GetPort( int idx ) const
+{
+ pxAssume(!!m_KnownCards);
+ return (*m_KnownCards)[idx].Port;
+}
+
+uint Panels::MemoryCardListPanel_Advanced::GetSlot( int idx ) const
+{
+ pxAssume(!!m_KnownCards);
+ return (*m_KnownCards)[idx].Slot;
+}
+
+// =====================================================================================================
+// MemoryCardListPanel_Simple (implementations)
+// =====================================================================================================
+Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent )
+ : _parent( parent )
+{
+ m_MultitapEnabled[0] = false;
+ m_MultitapEnabled[1] = false;
+
+ m_listview = new MemoryCardListView_Simple(this);
+
+ m_button_Create = new wxButton(this, wxID_ANY, _("Create"));
+ m_button_Mount = new wxButton(this, wxID_ANY, _("Mount"));
+
+ // ------------------------------------
+ // Sizer / Layout Section
+ // ------------------------------------
+
+ CreateLayout();
+
+ *s_leftside_buttons += m_button_Create;
+ *s_leftside_buttons += 2;
+ *s_leftside_buttons += m_button_Mount;
+ //*s_leftside_buttons += 2;
+
+ Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel_Simple::OnListDrag));
+ Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(MemoryCardListPanel_Simple::OnListSelectionChanged));
+ Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(MemoryCardListPanel_Simple::OnListSelectionChanged));
+
+ Connect( m_button_Mount->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard));
+ Connect( m_button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateCard));
+}
+
+void Panels::MemoryCardListPanel_Simple::UpdateUI()
+{
+ if( !m_listview ) return;
+
+ int sel = m_listview->GetFirstSelected();
+
+ /*if( !pxAssertDev( m_listview->GetItemData(sel), "Selected memorycard item data is NULL!" ) )
+ {
+ m_button_Create->Disable();
+ m_button_Mount->Disable();
+ return;
+ }*/
+
+ //const McdListItem& item( *(McdListItem*)m_listview->GetItemData(sel) );
+ const McdListItem& item( m_Cards[GetPort(sel)][GetSlot(sel)] );
+
+ m_button_Create->SetLabel( item.IsPresent ? _("Delete") : _("Create") );
+ pxSetToolTip( m_button_Create,
+ item.IsPresent
+ ? _("Deletes the existing MemoryCard from disk (all contents are lost)." )
+ : _("Creates a new MemoryCard in the empty slot." )
+ );
+
+ m_button_Mount->Enable( item.IsPresent );
+ m_button_Mount->SetLabel( item.IsEnabled ? _("Disable") : _("Enable") );
+ pxSetToolTip( m_button_Mount,
+ item.IsEnabled
+ ? _("Disables the selected MemoryCard, so that it will not be seen by games or BIOS.")
+ : _("Mounts the selected MemoryCard, so that games can see it again.")
+ );
+
+}
+
+void Panels::MemoryCardListPanel_Simple::Apply()
+{
+}
+
+void Panels::MemoryCardListPanel_Simple::AppStatusEvent_OnSettingsApplied()
+{
+}
+
+bool Panels::MemoryCardListPanel_Simple::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
+{
+ if( filenames.GetCount() == 1 && wxFileName(filenames[0]).IsDir() )
+ {
+ m_FolderPicker->SetPath( filenames[0] );
+ return true;
+ }
+ return false;
+}
+
+static wxString GetAutoMcdName(uint port, uint slot)
+{
+ if( slot > 0 )
+ return wxsFormat( L"mcd-port%u-slot%02u.ps2", port+1, slot+1 );
+ else
+ return wxsFormat( L"Mcd%03u.ps2", port+1 );
+}
+
+bool Panels::MemoryCardListPanel_Simple::ValidateEnumerationStatus()
+{
+ if( m_listview ) m_listview->SetInterface( NULL );
+ return false;
+}
+
+void Panels::MemoryCardListPanel_Simple::DoRefresh()
+{
+ for( uint port=0; port<2; ++port )
+ {
+ for( uint slot=0; slot<4; ++slot )
+ {
+ wxFileName fullpath( m_FolderPicker->GetPath() + GetAutoMcdName(port,slot) );
+ EnumerateMemoryCard( m_Cards[port][slot], fullpath );
+
+ if( (slot > 0) && !m_MultitapEnabled[port] )
+ m_Cards[port][slot].IsEnabled = false;
+ }
+ }
+
+ if( m_listview ) m_listview->SetInterface( this );
+}
+
+void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
+{
+
+}
+
+void Panels::MemoryCardListPanel_Simple::OnMountCard(wxCommandEvent& evt)
+{
+
+}
+
+void Panels::MemoryCardListPanel_Simple::OnListDrag(wxListEvent& evt)
+{
+ wxFileDataObject my_data;
+ /*my_data.AddFile( (*m_KnownCards)[m_listview->GetItemData(m_listview->GetFirstSelected())].Filename.GetFullPath() );
+
+ wxDropSource dragSource( m_listview );
+ dragSource.SetData( my_data );
+ wxDragResult result = dragSource.DoDragDrop();*/
+}
+
+void Panels::MemoryCardListPanel_Simple::OnListSelectionChanged(wxListEvent& evt)
+{
+ UpdateUI();
+}
+
+// Interface Implementation for IMcdList
+int Panels::MemoryCardListPanel_Simple::GetLength() const
+{
+ uint baselen = 2;
+ if( m_MultitapEnabled[0] ) baselen += 3;
+ if( m_MultitapEnabled[1] ) baselen += 3;
+ return baselen;
+}
+
+const McdListItem& Panels::MemoryCardListPanel_Simple::GetCard( int idx ) const
+{
+ return m_Cards[GetPort(idx)][GetSlot(idx)];
+}
+
+McdListItem& Panels::MemoryCardListPanel_Simple::GetCard( int idx )
+{
+ return m_Cards[GetPort(idx)][GetSlot(idx)];
+}
+
+uint Panels::MemoryCardListPanel_Simple::GetPort( int idx ) const
+{
+ if( !m_MultitapEnabled[0] && !m_MultitapEnabled[1] )
+ {
+ pxAssume( idx < 2 );
+ return idx;
+ }
+
+ if( !m_MultitapEnabled[0] )
+ return (idx==0) ? 0 : 1;
+ else
+ return idx / 4;
+}
+
+uint Panels::MemoryCardListPanel_Simple::GetSlot( int idx ) const
+{
+ if( !m_MultitapEnabled[0] && !m_MultitapEnabled[1] )
+ {
+ pxAssume( idx < 2 );
+ return 0;
+ }
+
+ if( !m_MultitapEnabled[0] )
+ return (idx==0) ? 0 : (idx-1);
+ else
+ return idx & 3;
+}
diff --git a/pcsx2/gui/Panels/MemoryCardListView.cpp b/pcsx2/gui/Panels/MemoryCardListView.cpp
new file mode 100644
index 0000000000..983f2e47a6
--- /dev/null
+++ b/pcsx2/gui/Panels/MemoryCardListView.cpp
@@ -0,0 +1,119 @@
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 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 .
+ */
+
+#include "PrecompiledHeader.h"
+#include "ConfigurationPanels.h"
+#include "MemoryCardPanels.h"
+
+#include "Dialogs/ConfigurationDialog.h"
+
+using namespace pxSizerFlags;
+using namespace Panels;
+
+enum McdColumnType_Simple
+{
+ McdColS_PortSlot, // port and slot of the card
+ McdColS_Status, // either Enabled/Disabled, or Missing (no card).
+ McdColS_Size,
+ McdColS_Formatted,
+ McdColS_DateModified,
+ McdColS_DateCreated,
+ McdColS_Count
+};
+
+void MemoryCardListView_Simple::CreateColumns()
+{
+ struct ColumnInfo
+ {
+ wxString name;
+ wxListColumnFormat align;
+ };
+
+ const ColumnInfo columns[] =
+ {
+ { _("Slot"), wxLIST_FORMAT_LEFT },
+ { _("Status"), wxLIST_FORMAT_CENTER },
+ { _("Size"), wxLIST_FORMAT_LEFT },
+ { _("Formatted"), wxLIST_FORMAT_CENTER },
+ { _("Modified"), wxLIST_FORMAT_LEFT },
+ { _("Created On"), wxLIST_FORMAT_LEFT },
+ };
+
+ for( int i=0; iGetCard(item) );
+
+ switch( column )
+ {
+ case McdColS_PortSlot: return wxsFormat( L"%u/%u", m_CardProvider->GetPort(item)+1, m_CardProvider->GetSlot(item)+1);
+ case McdColS_Status: return it.IsPresent ? ( it.IsEnabled ? _("Enabled") : _("Disabled")) : _("Missing");
+ case McdColS_Size: return it.IsPresent ? wxsFormat( L"%u MB", it.SizeInMB ) : _("N/A");
+ case McdColS_Formatted: return it.IsFormatted ? _("Yes") : _("No");
+ case McdColS_DateModified: return it.DateModified.FormatDate();
+ case McdColS_DateCreated: return it.DateCreated.FormatDate();
+ //case McdCol_Path: return it.Filename.GetPath();
+ }
+
+ pxFail( "Unknown column index in MemoryCardListView_Advanced -- returning an empty string." );
+ return wxEmptyString;
+}
+
+// return the icon for the given item. In report view, OnGetItemImage will
+// only be called for the first column. See OnGetItemColumnImage for
+// details.
+int MemoryCardListView_Simple::OnGetItemImage(long item) const
+{
+ return _parent::OnGetItemImage( item );
+}
+
+// return the icon for the given item and column.
+int MemoryCardListView_Simple::OnGetItemColumnImage(long item, long column) const
+{
+ return _parent::OnGetItemColumnImage( item, column );
+}
+
+// return the attribute for the item (may return NULL if none)
+wxListItemAttr* MemoryCardListView_Simple::OnGetItemAttr(long item) const
+{
+ wxListItemAttr* retval = _parent::OnGetItemAttr(item);
+ //const McdListItem& it( (*m_KnownCards)[item] );
+ return retval;
+}
diff --git a/pcsx2/gui/Panels/MemoryCardPanels.h b/pcsx2/gui/Panels/MemoryCardPanels.h
index 40a5799028..c88f166689 100644
--- a/pcsx2/gui/Panels/MemoryCardPanels.h
+++ b/pcsx2/gui/Panels/MemoryCardPanels.h
@@ -25,27 +25,43 @@
// --------------------------------------------------------------------------------------
struct McdListItem
{
- uint SizeInMB; // size, in megabytes!
+ bool IsPresent;
+ bool IsEnabled;
bool IsFormatted;
+
+ uint SizeInMB; // size, in megabytes!
wxDateTime DateCreated;
wxDateTime DateModified;
- wxFileName Filename; // full pathname
int Port;
int Slot;
+ wxFileName Filename; // full pathname (optional)
+
McdListItem()
{
Port = -1;
Slot = -1;
+
+ IsPresent = false;
+ IsEnabled = false;
}
+ // Compares two cards -- If this equality comparison is used on items where
+ // no filename is specified, then the check will include port and slot.
bool operator==( const McdListItem& right ) const
{
- return
+ bool fileEqu;
+
+ if( Filename.GetFullName().IsEmpty() )
+ fileEqu = OpEqu(Port) && OpEqu(Slot);
+ else
+ fileEqu = OpEqu(Filename);
+
+ return fileEqu &&
+ OpEqu(IsPresent) && OpEqu(IsEnabled) &&
OpEqu(SizeInMB) && OpEqu(IsFormatted) &&
- OpEqu(DateCreated) && OpEqu(DateModified) &&
- OpEqu(Filename);
+ OpEqu(DateCreated) && OpEqu(DateModified);
}
bool operator!=( const McdListItem& right ) const
@@ -56,36 +72,79 @@ struct McdListItem
typedef std::vector McdList;
-class IMemoryCardList
+class IMcdList
{
public:
virtual int GetLength() const=0;
- virtual const McdListItem& Get( int idx ) const=0;
- virtual McdListItem& Get( int idx )=0;
+ virtual const McdListItem& GetCard( int idx ) const=0;
+ virtual McdListItem& GetCard( int idx )=0;
+
+ virtual uint GetPort( int idx ) const=0;
+ virtual uint GetSlot( int idx ) const=0;
};
-// --------------------------------------------------------------------------------------
-// MemoryCardListView
-// --------------------------------------------------------------------------------------
-class MemoryCardListView : public wxListView
+class BaseMcdListView : public wxListView
{
typedef wxListView _parent;
protected:
- IMemoryCardList* m_CardsList;
+ const IMcdList* m_CardProvider;
public:
- virtual ~MemoryCardListView() throw() { }
- MemoryCardListView( wxWindow* parent );
+ virtual ~BaseMcdListView() throw() { }
+ BaseMcdListView( wxWindow* parent )
+ : _parent( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL )
+ {
+ m_CardProvider = NULL;
+ }
+
+ virtual void SetCardCount( int length )=0;
+
+ virtual void SetInterface( IMcdList* face )
+ {
+ m_CardProvider = face;
+ SetCardCount( m_CardProvider ? m_CardProvider->GetLength() : 0 );
+ }
+};
+
+// --------------------------------------------------------------------------------------
+// MemoryCardListView_Simple
+// --------------------------------------------------------------------------------------
+class MemoryCardListView_Simple : public BaseMcdListView
+{
+ typedef BaseMcdListView _parent;
+
+public:
+ virtual ~MemoryCardListView_Simple() throw() { }
+ MemoryCardListView_Simple( wxWindow* parent );
virtual void OnListDrag(wxListEvent& evt);
- virtual void CreateColumns();
+ void CreateColumns();
+ virtual void SetCardCount( int length );
+
+protected:
+ // Overrides for wxLC_VIRTUAL
+ virtual wxString OnGetItemText(long item, long column) const;
+ virtual int OnGetItemImage(long item) const;
+ virtual int OnGetItemColumnImage(long item, long column) const;
+ virtual wxListItemAttr *OnGetItemAttr(long item) const;
+};
+
+
+// --------------------------------------------------------------------------------------
+// MemoryCardListView_Advanced
+// --------------------------------------------------------------------------------------
+class MemoryCardListView_Advanced : public BaseMcdListView
+{
+ typedef BaseMcdListView _parent;
+
+public:
+ virtual ~MemoryCardListView_Advanced() throw() { }
+ MemoryCardListView_Advanced( wxWindow* parent );
+
+ virtual void OnListDrag(wxListEvent& evt);
+ void CreateColumns();
virtual void SetCardCount( int length );
- virtual void SetInterface( IMemoryCardList* face )
- {
- m_CardsList = face;
- SetCardCount( m_CardsList ? m_CardsList->GetLength() : 0 );
- }
protected:
// Overrides for wxLC_VIRTUAL
@@ -98,29 +157,102 @@ protected:
namespace Panels
{
// --------------------------------------------------------------------------------------
- // MemoryCardListPanel
+ // BaseMcdListPanel
// --------------------------------------------------------------------------------------
- class MemoryCardListPanel
+ class BaseMcdListPanel
: public BaseSelectorPanel
, public wxFileDropTarget
- , public IMemoryCardList
{
+ typedef BaseSelectorPanel _parent;
+
protected:
DirPickerPanel* m_FolderPicker;
- MemoryCardListView* m_listview;
+ BaseMcdListView* m_listview;
+ wxButton* m_btn_Refresh;
+
+ wxBoxSizer* s_leftside_buttons;
+ wxBoxSizer* s_rightside_buttons;
+
+ public:
+ virtual ~BaseMcdListPanel() throw() {}
+ BaseMcdListPanel( wxWindow* parent );
+
+ void CreateLayout();
+ };
+
+ // --------------------------------------------------------------------------------------
+ // MemoryCardListPanel_Simple
+ // --------------------------------------------------------------------------------------
+ class MemoryCardListPanel_Simple
+ : public BaseMcdListPanel
+ , public IMcdList
+ {
+ typedef BaseMcdListPanel _parent;
+
+ protected:
+ McdListItem m_Cards[2][4];
+
+ // Doubles as Create and Delete buttons
+ wxButton* m_button_Create;
+
+ // Doubles as Mount and Unmount buttons
+ wxButton* m_button_Mount;
+
+ bool m_MultitapEnabled[2];
+
+ public:
+ virtual ~MemoryCardListPanel_Simple() throw() {}
+ MemoryCardListPanel_Simple( wxWindow* parent );
+
+ void UpdateUI();
+
+ // Interface Implementation for IMcdList
+ virtual int GetLength() const;
+ virtual const McdListItem& GetCard( int idx ) const;
+ virtual McdListItem& GetCard( int idx );
+ virtual uint GetPort( int idx ) const;
+ virtual uint GetSlot( int idx ) const;
+
+ protected:
+ void OnCreateCard(wxCommandEvent& evt);
+ void OnMountCard(wxCommandEvent& evt);
+
+ virtual void OnListDrag(wxListEvent& evt);
+ virtual void OnListSelectionChanged(wxListEvent& evt);
+ virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames);
+
+ virtual void Apply();
+ virtual void AppStatusEvent_OnSettingsApplied();
+ virtual void DoRefresh();
+ virtual bool ValidateEnumerationStatus();
+ };
+
+ // --------------------------------------------------------------------------------------
+ // MemoryCardListPanel_Advanced
+ // --------------------------------------------------------------------------------------
+ class MemoryCardListPanel_Advanced
+ : public BaseMcdListPanel
+ , public IMcdList
+ {
+ typedef BaseMcdListPanel _parent;
+
+ protected:
ScopedPtr m_KnownCards;
public:
- virtual ~MemoryCardListPanel() throw() {}
- MemoryCardListPanel( wxWindow* parent );
+ virtual ~MemoryCardListPanel_Advanced() throw() {}
+ MemoryCardListPanel_Advanced( wxWindow* parent );
- // Interface Implementation for IMemoryCardList
+ // Interface Implementation for IMcdList
virtual int GetLength() const;
- virtual const McdListItem& Get( int idx ) const;
- virtual McdListItem& Get( int idx );
+ virtual const McdListItem& GetCard( int idx ) const;
+ virtual McdListItem& GetCard( int idx );
+ virtual uint GetPort( int idx ) const;
+ virtual uint GetSlot( int idx ) const;
protected:
- virtual void OnCreateNewCard(wxCommandEvent& evt);
+ void OnCreateNewCard(wxCommandEvent& evt);
+
virtual void OnListDrag(wxListEvent& evt);
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames);
@@ -139,12 +271,15 @@ namespace Panels
uint m_port;
uint m_slot;
- wxFileName m_filename;
+ wxString m_DisplayName;
+ wxString m_ErrorMessage;
+ ScopedPtr m_cardInfo;
public:
virtual ~MemoryCardInfoPanel() throw() {}
MemoryCardInfoPanel( wxWindow* parent, uint port, uint slot );
void Apply();
+ void Eject();
protected:
void AppStatusEvent_OnSettingsApplied();
@@ -211,3 +346,6 @@ namespace Panels
};
};
+
+extern bool EnumerateMemoryCard( McdListItem& dest, const wxFileName& filename );
+//extern bool EnumerateMemoryCard( SimpleMcdItem& dest, const wxFileName& filename );
diff --git a/pcsx2/gui/Panels/MemoryCardsPanel.cpp b/pcsx2/gui/Panels/MemoryCardsPanel.cpp
index 7d090c78df..2d6943c95e 100644
--- a/pcsx2/gui/Panels/MemoryCardsPanel.cpp
+++ b/pcsx2/gui/Panels/MemoryCardsPanel.cpp
@@ -27,7 +27,7 @@ using namespace pxSizerFlags;
using namespace Panels;
-enum McdColumnType
+enum McdColumnType_Advanced
{
McdCol_Filename,
McdCol_Mounted,
@@ -35,11 +35,10 @@ enum McdColumnType
McdCol_Formatted,
McdCol_DateModified,
McdCol_DateCreated,
- //McdCol_Path,
McdCol_Count
};
-void MemoryCardListView::CreateColumns()
+void MemoryCardListView_Advanced::CreateColumns()
{
struct ColumnInfo
{
@@ -62,33 +61,31 @@ void MemoryCardListView::CreateColumns()
InsertColumn( i, columns[i].name, columns[i].align, -1 );
}
-void MemoryCardListView::SetCardCount( int length )
+void MemoryCardListView_Advanced::SetCardCount( int length )
{
- if( !m_CardsList ) length = 0;
+ if( !m_CardProvider ) length = 0;
SetItemCount( length );
Refresh();
}
-MemoryCardListView::MemoryCardListView( wxWindow* parent )
- : wxListView( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL )
+MemoryCardListView_Advanced::MemoryCardListView_Advanced( wxWindow* parent )
+ : _parent( parent )
{
- m_CardsList = NULL;
CreateColumns();
-
- Connect( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListView::OnListDrag));
+ Connect( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListView_Advanced::OnListDrag));
}
-void MemoryCardListView::OnListDrag(wxListEvent& evt)
+void MemoryCardListView_Advanced::OnListDrag(wxListEvent& evt)
{
evt.Skip();
}
// return the text for the given column of the given item
-wxString MemoryCardListView::OnGetItemText(long item, long column) const
+wxString MemoryCardListView_Advanced::OnGetItemText(long item, long column) const
{
- if( !m_CardsList ) return _parent::OnGetItemText(item, column);
+ if( !m_CardProvider ) return _parent::OnGetItemText(item, column);
- const McdListItem& it( m_CardsList->Get(item) );
+ const McdListItem& it( m_CardProvider->GetCard(item) );
switch( column )
{
@@ -106,26 +103,26 @@ wxString MemoryCardListView::OnGetItemText(long item, long column) const
//case McdCol_Path: return it.Filename.GetPath();
}
- pxFail( "Unknown column index in MemoryCardListView -- returning an empty string." );
+ pxFail( "Unknown column index in MemoryCardListView_Advanced -- returning an empty string." );
return wxEmptyString;
}
// return the icon for the given item. In report view, OnGetItemImage will
// only be called for the first column. See OnGetItemColumnImage for
// details.
-int MemoryCardListView::OnGetItemImage(long item) const
+int MemoryCardListView_Advanced::OnGetItemImage(long item) const
{
return _parent::OnGetItemImage( item );
}
// return the icon for the given item and column.
-int MemoryCardListView::OnGetItemColumnImage(long item, long column) const
+int MemoryCardListView_Advanced::OnGetItemColumnImage(long item, long column) const
{
return _parent::OnGetItemColumnImage( item, column );
}
// return the attribute for the item (may return NULL if none)
-wxListItemAttr* MemoryCardListView::OnGetItemAttr(long item) const
+wxListItemAttr* MemoryCardListView_Advanced::OnGetItemAttr(long item) const
{
wxListItemAttr* retval = _parent::OnGetItemAttr(item);
//const McdListItem& it( (*m_KnownCards)[item] );
@@ -145,57 +142,129 @@ MemoryCardInfoPanel::MemoryCardInfoPanel( wxWindow* parent, uint port, uint slot
SetMinSize( wxSize(128, 48) );
Connect( wxEVT_PAINT, wxPaintEventHandler(MemoryCardInfoPanel::paintEvent) );
+
+ // [TODO] Add Unmount button.
}
-static void DrawTextCentered( wxDC& dc, const wxString msg )
-{
- int tWidth, tHeight;
- dc.GetTextExtent( msg, &tWidth, &tHeight );
- dc.DrawText( msg, (dc.GetSize().GetWidth() - tWidth) / 2, 0 );
-}
void MemoryCardInfoPanel::paintEvent(wxPaintEvent & evt)
{
- // Collect Info and Format Strings
-
- wxString fname( m_filename.GetFullPath() );
- if( fname.IsEmpty() ) fname = _("No Card (empty)");
+ wxPaintDC dc( this );
+ pxWindowTextWriter writer( dc );
+
+ writer.Bold();
// Create DC and plot some text (and images!)
-
- wxPaintDC dc( this );
- wxFont normal( dc.GetFont() );
- wxFont bold( normal );
- normal.SetWeight( wxNORMAL );
- bold.SetWeight( wxBOLD );
-
- dc.SetFont( bold );
- DrawTextCentered( dc, fname );
+ writer.WriteLn( m_DisplayName );
//dc.DrawCircle( dc.GetSize().GetWidth()/2, 24, dc.GetSize().GetWidth()/4 );
+
+ if( !m_ErrorMessage.IsEmpty() )
+ {
+ writer.WriteLn();
+ writer.WriteLn( m_ErrorMessage );
+ }
+ else if( m_cardInfo )
+ {
+ writer.Normal();
+
+ writer.WriteLn( wxsFormat( L"%d MB (%s)",
+ m_cardInfo->SizeInMB,
+ m_cardInfo->IsFormatted ? _("Formatted") : _("Unformatted") )
+ );
+ }
+}
+
+void MemoryCardInfoPanel::Eject()
+{
+ m_cardInfo = NULL;
+ Refresh();
}
void MemoryCardInfoPanel::Apply()
{
- if( m_filename.IsDir() )
+ if( m_cardInfo && m_cardInfo->Filename.GetFullName().IsEmpty() ) m_cardInfo = NULL;
+
+ if( m_cardInfo )
{
- throw Exception::CannotApplySettings( this,
- wxLt("Cannot use or create memorycard: the filename is an existing directory."),
- true
- );
- }
+ wxFileName absfile( Path::Combine( g_Conf->Folders.MemoryCards, m_cardInfo->Filename ) );
- if( m_filename.FileExists() )
+ // The following checks should be theoretically unreachable, unless the user's
+ // filesystem is changed form under our nose. A little validation goes a
+ // long way. :p
+
+ if( absfile.IsDir() )
+ {
+ Eject();
+ throw Exception::CannotApplySettings( this,
+ // Diagnostic
+ wxsFormat( L"Memorycard in Port %u, Slot %u conflicts with an existing directory.", m_port, m_slot ),
+ // Translated
+ wxsFormat(
+ _("Cannot use or create the memorycard in Port %u, Slot %u: the filename conflicts with an existing directory."),
+ m_port, m_slot
+ )
+ );
+ }
+
+ if( !absfile.FileExists() )
+ {
+ Eject();
+ throw Exception::CannotApplySettings( this,
+ // Diagnostic
+ wxsFormat( L"Memorycard in Port %u, Slot %u is no longer valid.", m_port, m_slot ),
+ // Translated
+ wxsFormat(
+ _("The configured memorycard in Port %u, Slot %u no longer exists. Please create a new memory card, or leave the slot unmounted."),
+ m_port, m_slot
+ )
+ );
+ }
+
+ g_Conf->Mcd[m_port][m_slot].Filename = m_cardInfo->Filename;
+ g_Conf->Mcd[m_port][m_slot].Enabled = true;
+ }
+ else
{
- // TODO : Prompt user to create non-existing files. For now we just creat them implicitly.
- }
+ // Card is either disabled or in an error state.
- g_Conf->Mcd[m_port][m_slot].Filename = m_filename;
+ g_Conf->Mcd[m_port][m_slot].Enabled = false;
+ g_Conf->Mcd[m_port][m_slot].Filename.Clear();
+ }
}
void MemoryCardInfoPanel::AppStatusEvent_OnSettingsApplied()
{
- m_filename = g_Conf->Mcd[m_port][m_slot].Filename;
+ m_cardInfo = NULL;
+
+ // Collect Info and Format Strings
+
+ wxString fname( g_Conf->Mcd[m_port][m_slot].Filename.GetFullPath() );
+ if( fname.IsEmpty() )
+ {
+ m_DisplayName = _("No Card (empty)");
+ m_cardInfo = NULL;
+ }
+ else
+ {
+ wxFileName absfile( Path::Combine( g_Conf->Folders.MemoryCards, fname ) );
+ wxFileName relfile( fname );
+
+ if( !m_cardInfo )
+ {
+ m_cardInfo = new McdListItem();
+ if( !EnumerateMemoryCard( *m_cardInfo, absfile.GetFullPath() ) )
+ {
+ m_ErrorMessage = _("Read Error: Card is truncated or corrupted.");
+ }
+ }
+
+ absfile.Normalize();
+ relfile.Normalize();
+
+ m_DisplayName = ( absfile == relfile ) ? relfile.GetFullName() : relfile.GetFullPath();
+ }
+
Refresh();
}
@@ -206,8 +275,7 @@ void MemoryCardInfoPanel::AppStatusEvent_OnSettingsApplied()
Panels::MemoryCardsPanel::MemoryCardsPanel( wxWindow* parent )
: BaseApplicableConfigPanel( parent )
{
- m_panel_AllKnownCards = new MemoryCardListPanel( this );
-
+ m_panel_AllKnownCards = new MemoryCardListPanel_Advanced( this );
for( uint port=0; port<2; ++port )
{
@@ -251,4 +319,3 @@ void Panels::MemoryCardsPanel::AppStatusEvent_OnSettingsApplied()
//m_panel_cardinfo[port][slot]->Enable( emuconf.MultitapEnabled(port) );
}
}
-
diff --git a/pcsx2/gui/pxLogTextCtrl.cpp b/pcsx2/gui/pxLogTextCtrl.cpp
index bfbdfe4ab6..9251c8baec 100644
--- a/pcsx2/gui/pxLogTextCtrl.cpp
+++ b/pcsx2/gui/pxLogTextCtrl.cpp
@@ -70,7 +70,7 @@ void pxLogTextCtrl::OnResize( wxSizeEvent& evt )
// Windows has retarded console window update patterns. This helps smarten them up.
int ctrly = GetSize().y;
int fonty;
- GetTextExtent( L"blaH yeah", NULL, &fonty );
+ GetTextExtent( L"blH yh", NULL, &fonty );
m_win32_LinesPerPage = (ctrly / fonty) + 1;
m_win32_LinesPerScroll = m_win32_LinesPerPage * 0.40;
#endif
diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
index 01eda5e273..0c0a2eb70b 100644
--- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
+++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
@@ -2665,6 +2665,10 @@
RelativePath="..\..\gui\Panels\MemoryCardListPanel.cpp"
>
+
+