Minor user interface cleanups and tweaks; most notable being some better "spam" protection on the console logger.

Details: Console logger now freezes updates for 100ms after every update.  This means it responds quickly to most logs, but limits series of log spams to 10 updates per second.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2978 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-05-11 07:17:31 +00:00
parent 2a05b6d449
commit a1870a845b
14 changed files with 371 additions and 357 deletions

View File

@ -339,21 +339,9 @@ bool AppPluginManager::OpenPlugin_GS()
return retval; return retval;
} }
static int _guard = 0;
// Yay, this plugin is guaranteed to always be opened first and closed last. // Yay, this plugin is guaranteed to always be opened first and closed last.
void AppPluginManager::ClosePlugin_GS() void AppPluginManager::ClosePlugin_GS()
{ {
/*if( GSopen2 == NULL || CloseViewportWithPlugins )
{
// All other plugins must be closed before the GS, because they all rely on
// the GS window handle being valid. The recursion guard will protect this
// function from being called a million times. ;)
RecursionGuard mess( _guard );
if( !mess.IsReentrant() ) Close();
}*/
_parent::ClosePlugin_GS(); _parent::ClosePlugin_GS();
if( GetMTGS().IsSelf() && GSopen2 && CloseViewportWithPlugins ) sApp.CloseGsPanel(); if( GetMTGS().IsSelf() && GSopen2 && CloseViewportWithPlugins ) sApp.CloseGsPanel();
} }

View File

@ -230,24 +230,17 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A
: wxFrame(parent, wxID_ANY, title) : wxFrame(parent, wxID_ANY, title)
, m_conf( options ) , m_conf( options )
, m_TextCtrl( *new pxLogTextCtrl(this) ) , m_TextCtrl( *new pxLogTextCtrl(this) )
, m_timer_FlushLimiter( this ) , m_timer_FlushUnlocker( this )
, m_ColorTable( options.FontSize ) , m_ColorTable( options.FontSize )
, m_QueueColorSection( L"ConsoleLog::QueueColorSection" ) , m_QueueColorSection( L"ConsoleLog::QueueColorSection" )
, m_QueueBuffer( L"ConsoleLog::QueueBuffer" ) , m_QueueBuffer( L"ConsoleLog::QueueBuffer" )
, m_threadlogger( EnableThreadedLoggingTest ? new ConsoleTestThread() : NULL ) , m_threadlogger( EnableThreadedLoggingTest ? new ConsoleTestThread() : NULL )
{ {
m_flushevent_counter = 0;
m_CurQueuePos = 0; m_CurQueuePos = 0;
m_pendingFlushes = 0;
m_WaitingThreadsForFlush = 0; m_WaitingThreadsForFlush = 0;
m_ThreadedLogInQueue = false;
m_pendingFlushMsg = false; m_pendingFlushMsg = false;
m_FlushRefreshLocked = false;
m_ThawThrottle = 0;
m_ThawNeeded = false;
m_ThawPending = false;
SetIcons( wxGetApp().GetIconBundle() ); SetIcons( wxGetApp().GetIconBundle() );
@ -329,8 +322,7 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A
Connect( pxEvt_DockConsole, wxCommandEventHandler (ConsoleLogFrame::OnDockedMove) ); Connect( pxEvt_DockConsole, wxCommandEventHandler (ConsoleLogFrame::OnDockedMove) );
Connect( pxEvt_FlushQueue, wxCommandEventHandler (ConsoleLogFrame::OnFlushEvent) ); Connect( pxEvt_FlushQueue, wxCommandEventHandler (ConsoleLogFrame::OnFlushEvent) );
Connect( wxEVT_IDLE, wxIdleEventHandler (ConsoleLogFrame::OnIdleEvent) ); Connect( m_timer_FlushUnlocker.GetId(), wxEVT_TIMER, wxTimerEventHandler (ConsoleLogFrame::OnFlushUnlockerTimer) );
Connect( wxEVT_TIMER, wxTimerEventHandler (ConsoleLogFrame::OnFlushLimiterTimer) );
m_item_Deci2 ->Check( g_Conf->EmuOptions.Log.Deci2 ); m_item_Deci2 ->Check( g_Conf->EmuOptions.Log.Deci2 );
m_item_StdoutEE ->Check( g_Conf->EmuOptions.Log.StdoutEE ); m_item_StdoutEE ->Check( g_Conf->EmuOptions.Log.StdoutEE );
@ -388,26 +380,27 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
wxCommandEvent evt( pxEvt_FlushQueue ); wxCommandEvent evt( pxEvt_FlushQueue );
evt.SetInt( 0 ); evt.SetInt( 0 );
if( wxThread::IsMain() ) if( wxThread::IsMain() )
GetEventHandler()->ProcessEvent( evt );
else
{ {
GetEventHandler()->AddPendingEvent( evt ); OnFlushEvent( evt );
return;
} }
else
GetEventHandler()->AddPendingEvent( evt );
lock.Acquire(); lock.Acquire();
} }
++m_pendingFlushes;
if( !wxThread::IsMain() ) if( !wxThread::IsMain() )
{ {
m_ThreadedLogInQueue = true; // Too many color changes causes huge slowdowns when decorating the rich textview, so
// include a secodary check to avoid having a colorful log spam from killing gui responsiveness.
if( m_pendingFlushes > 48 )
if( m_CurQueuePos > 0x100000 || m_QueueColorSection.GetLength() > 256 )
{ {
++m_WaitingThreadsForFlush; ++m_WaitingThreadsForFlush;
lock.Release(); lock.Release();
if( !m_sem_QueueFlushed.Wait( wxTimeSpan( 0,0,0,500 ) ) ) if( !m_sem_QueueFlushed.Wait( wxTimeSpan( 0,0,0,250 ) ) )
{ {
// Necessary since the main thread could grab the lock and process before // Necessary since the main thread could grab the lock and process before
// the above function actually returns (gotta love threading!) // the above function actually returns (gotta love threading!)
@ -418,7 +411,6 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
{ {
// give gui thread time to repaint and handle other pending messages. // give gui thread time to repaint and handle other pending messages.
//pxYield( 1 );
wxGetApp().Ping(); wxGetApp().Ping();
} }
} }
@ -609,36 +601,8 @@ void ConsoleLogFrame::OnSetTitle( wxCommandEvent& event )
SetTitle( event.GetString() ); SetTitle( event.GetString() );
} }
void ConsoleLogFrame::OnIdleEvent( wxIdleEvent& ) void ConsoleLogFrame::DoFlushEvent( bool isPending )
{ {
// When the GUI is idle then it's a safe bet we can resume suspended console log
// flushing, on the theory that the user's had a good chance to field user input.
if( m_flushevent_counter > 0 )
{
m_flushevent_counter = 0;
m_timer_FlushLimiter.Stop();
wxCommandEvent sendevt( pxEvt_FlushQueue );
GetEventHandler()->AddPendingEvent( sendevt );
}
}
void ConsoleLogFrame::OnFlushLimiterTimer( wxTimerEvent& )
{
if( m_flushevent_counter == 0 ) return;
m_flushevent_counter = 0;
wxCommandEvent sendevt( pxEvt_FlushQueue );
GetEventHandler()->AddPendingEvent( sendevt );
}
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
{
ScopedLock locker( m_mtx_Queue );
m_pendingFlushMsg = false;
// recursion guard needed due to Mutex lock/acquire code below, which can end up yielding // recursion guard needed due to Mutex lock/acquire code below, which can end up yielding
// to the gui and attempting to process more messages (which in turn would result in re- // to the gui and attempting to process more messages (which in turn would result in re-
// entering this handler). // entering this handler).
@ -647,38 +611,11 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
RecursionGuard recguard( recursion_counter ); RecursionGuard recguard( recursion_counter );
if( recguard.IsReentrant() ) return; if( recguard.IsReentrant() ) return;
ScopedLock locker( m_mtx_Queue );
if( m_CurQueuePos != 0 ) if( m_CurQueuePos != 0 )
{ {
if( !m_timer_FlushLimiter.IsRunning() ) DoFlushQueue();
{
m_timer_FlushLimiter.Start( 500, true );
m_flushevent_counter = 0;
}
else
{
if( m_flushevent_counter >= 1000 )
return;
++m_flushevent_counter;
}
if( m_ThreadedLogInQueue && (m_pendingFlushes < 20) )
{
// Hacky Speedup -->
// Occasionally the EEcore thread can send ups some serious amounts of spam, and
// if we don't sleep the main thread some, the stupid text control refresh will
// drive framerates toward zero as it tries to refresh for every single log.
// This hack checks if a thread has been posting logs and, if so, we "rest" the
// main thread so that other threads can accumulate a more sizable log chunk.
locker.Release();
Sleep( 2 );
locker.Acquire();
}
if( m_CurQueuePos != 0 )
DoFlushQueue();
//m_TextCtrl.Thaw();
} }
// Implementation note: I tried desperately to move this into wxEVT_IDLE, on the theory that // Implementation note: I tried desperately to move this into wxEVT_IDLE, on the theory that
@ -695,6 +632,24 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
int count = m_sem_QueueFlushed.Count(); int count = m_sem_QueueFlushed.Count();
while( count < 0 ) m_sem_QueueFlushed.Post(); while( count < 0 ) m_sem_QueueFlushed.Post();
} }
m_pendingFlushMsg = isPending;
}
void ConsoleLogFrame::OnFlushUnlockerTimer( wxTimerEvent& )
{
m_FlushRefreshLocked = false;
DoFlushEvent( false );
}
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
{
if( m_FlushRefreshLocked ) return;
DoFlushEvent( true );
m_FlushRefreshLocked = true;
m_timer_FlushUnlocker.Start( 100, true );
} }
void ConsoleLogFrame::DoFlushQueue() void ConsoleLogFrame::DoFlushQueue()
@ -710,12 +665,14 @@ void ConsoleLogFrame::DoFlushQueue()
// Manual InsertionPoint tracking avoids a lot of overhead in SetInsertionPointEnd() // Manual InsertionPoint tracking avoids a lot of overhead in SetInsertionPointEnd()
wxTextPos insertPoint = m_TextCtrl.GetLastPosition(); wxTextPos insertPoint = m_TextCtrl.GetLastPosition();
// cap at 256k for now... // cap at 512k for now...
// fixme - 256k runs well on win32 but appears to be very sluggish on linux (but that could // fixme - 512k runs well on win32 but appears to be very sluggish on linux (but that could
// be a result of my using Xming + CoLinux). Might need platform dependent defaults here. --air // be a result of my using Xming + CoLinux). Might need platform dependent defaults here. --air
if( (insertPoint + m_CurQueuePos) > 0x40000 )
static const int BufferSize = 0x80000;
if( (insertPoint + m_CurQueuePos) > BufferSize )
{ {
int toKeep = 0x40000 - m_CurQueuePos; int toKeep = BufferSize - m_CurQueuePos;
if( toKeep <= 10 ) if( toKeep <= 10 )
{ {
m_TextCtrl.Clear(); m_TextCtrl.Clear();
@ -723,8 +680,8 @@ void ConsoleLogFrame::DoFlushQueue()
} }
else else
{ {
int toRemove = 0x40000 - toKeep; int toRemove = BufferSize - toKeep;
if( toRemove < 0x10000 ) toRemove = 0x10000; if( toRemove < BufferSize / 4 ) toRemove = BufferSize;
m_TextCtrl.Remove( 0, toRemove ); m_TextCtrl.Remove( 0, toRemove );
insertPoint -= toRemove; insertPoint -= toRemove;
} }
@ -732,6 +689,13 @@ void ConsoleLogFrame::DoFlushQueue()
m_TextCtrl.SetInsertionPoint( insertPoint ); m_TextCtrl.SetInsertionPoint( insertPoint );
// fixme : Writing a lot of colored logs to the console can be quite slow when "spamming"
// is happening, due to the overhead of SetDefaultStyle and WriteText calls. I'm not sure
// if there's a better way to go about this? Using Freeze/Thaw helps a little bit, but it's
// still magnitudes slower than dumping a straight run. --air
if( len > 64 ) m_TextCtrl.Freeze();
for( int i=0; i<len; ++i ) for( int i=0; i<len; ++i )
{ {
if( m_QueueColorSection[i].color != Color_Current ) if( m_QueueColorSection[i].color != Color_Current )
@ -740,12 +704,12 @@ void ConsoleLogFrame::DoFlushQueue()
m_TextCtrl.WriteText( &m_QueueBuffer[m_QueueColorSection[i].startpoint] ); m_TextCtrl.WriteText( &m_QueueBuffer[m_QueueColorSection[i].startpoint] );
} }
m_TextCtrl.ConcludeIssue( m_pendingFlushes ); if( len > 64 ) m_TextCtrl.Thaw();
m_TextCtrl.ConcludeIssue();
m_QueueColorSection.Clear(); m_QueueColorSection.Clear();
m_CurQueuePos = 0; m_CurQueuePos = 0;
m_pendingFlushes = 0;
m_ThreadedLogInQueue= false;
} }
ConsoleLogFrame* Pcsx2App::GetProgramLog() ConsoleLogFrame* Pcsx2App::GetProgramLog()

View File

@ -109,7 +109,7 @@ public:
virtual ~pxLogTextCtrl() throw(); virtual ~pxLogTextCtrl() throw();
bool HasWriteLock() const { return m_FreezeWrites; } bool HasWriteLock() const { return m_FreezeWrites; }
void ConcludeIssue( int lines ); void ConcludeIssue();
#ifdef __WXMSW__ #ifdef __WXMSW__
virtual void WriteText(const wxString& text); virtual void WriteText(const wxString& text);
@ -173,33 +173,16 @@ protected:
ConLogConfig& m_conf; ConLogConfig& m_conf;
pxLogTextCtrl& m_TextCtrl; pxLogTextCtrl& m_TextCtrl;
wxTimer m_timer_FlushLimiter; wxTimer m_timer_FlushLimiter;
wxTimer m_timer_FlushUnlocker;
ColorArray m_ColorTable; ColorArray m_ColorTable;
int m_flushevent_counter; int m_flushevent_counter;
bool m_FlushRefreshLocked;
// this int throttles freeze/thaw of the display, by cycling from -2 to 4, roughly.
// (negative values force thaw, positive values indicate thaw is disabled. This is
// needed because the wxWidgets Thaw implementation uses a belated paint message,
// and if we Freeze on the very next queued message after thawing, the repaint
// never happens)
int m_ThawThrottle;
// If a freeze is executed, this is set true (without this, wx asserts)
bool m_ThawNeeded;
// Set true when a Thaw message is sent (avoids cluttering the message pump with redundant
// requests)
bool m_ThawPending;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Queue State Management Vars // Queue State Management Vars
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// This is a counter of the total number of pending flushes across all threads.
// If the value exceeds a threshold, threads begin throttling to avoid deadlocking
// the GUI.
volatile int m_pendingFlushes;
// Boolean indicating if a flush message is already in the Main message queue. Used // Boolean indicating if a flush message is already in the Main message queue. Used
// to prevent spamming the main thread with redundant messages. // to prevent spamming the main thread with redundant messages.
volatile bool m_pendingFlushMsg; volatile bool m_pendingFlushMsg;
@ -217,7 +200,7 @@ protected:
// Lock object for accessing or modifying the following three vars: // Lock object for accessing or modifying the following three vars:
// m_QueueBuffer, m_QueueColorSelection, m_CurQueuePos // m_QueueBuffer, m_QueueColorSelection, m_CurQueuePos
MutexRecursive m_mtx_Queue; Mutex m_mtx_Queue;
// Describes a series of colored text sections in the m_QueueBuffer. // Describes a series of colored text sections in the m_QueueBuffer.
SafeList<ColorSection> m_QueueColorSection; SafeList<ColorSection> m_QueueColorSection;
@ -271,14 +254,14 @@ protected:
void OnSetTitle( wxCommandEvent& event ); void OnSetTitle( wxCommandEvent& event );
void OnDockedMove( wxCommandEvent& event ); void OnDockedMove( wxCommandEvent& event );
void OnIdleEvent( wxIdleEvent& event ); void OnFlushUnlockerTimer( wxTimerEvent& evt );
void OnFlushLimiterTimer( wxTimerEvent& evt );
void OnFlushEvent( wxCommandEvent& event ); void OnFlushEvent( wxCommandEvent& event );
// common part of OnClose() and OnCloseWindow() // common part of OnClose() and OnCloseWindow()
virtual void DoClose(); virtual void DoClose();
void DoFlushQueue(); void DoFlushQueue();
void DoFlushEvent( bool isPending );
void OnMoveAround( wxMoveEvent& evt ); void OnMoveAround( wxMoveEvent& evt );
void OnResize( wxSizeEvent& evt ); void OnResize( wxSizeEvent& evt );
void OnActivate( wxActivateEvent& evt ); void OnActivate( wxActivateEvent& evt );

View File

@ -24,6 +24,7 @@
#include <wx/filepicker.h> #include <wx/filepicker.h>
using namespace Panels; using namespace Panels;
using namespace pxSizerFlags;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent ) Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent )
@ -33,15 +34,29 @@ Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent )
m_idealWidth = 500; m_idealWidth = 500;
Panels::BaseSelectorPanel* selpan = new Panels::BiosSelectorPanel( this ); m_selpan = new Panels::BiosSelectorPanel( this );
*this += selpan | pxSizerFlags::StdExpand(); *this += m_selpan | StdExpand();
AddOkCancel( *GetSizer(), false ); AddOkCancel();
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BiosSelectorDialog::OnOk_Click) ); Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BiosSelectorDialog::OnOk_Click) );
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler(BiosSelectorDialog::OnDoubleClicked) ); Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler(BiosSelectorDialog::OnDoubleClicked) );
}
selpan->OnShown(); bool Dialogs::BiosSelectorDialog::Show( bool show )
{
if( show && m_selpan )
m_selpan->OnShown();
return _parent::Show( show );
}
int Dialogs::BiosSelectorDialog::ShowModal()
{
if( m_selpan )
m_selpan->OnShown();
return _parent::ShowModal();
} }
void Dialogs::BiosSelectorDialog::OnOk_Click( wxCommandEvent& evt ) void Dialogs::BiosSelectorDialog::OnOk_Click( wxCommandEvent& evt )

View File

@ -22,6 +22,12 @@
#include "AppCommon.h" #include "AppCommon.h"
#include "ApplyState.h" #include "ApplyState.h"
namespace Panels
{
class BaseSelectorPanel;
class MemoryCardListPanel;
}
namespace Dialogs namespace Dialogs
{ {
class BaseApplicableDialog : public wxDialogWithHelpers, public IApplyState class BaseApplicableDialog : public wxDialogWithHelpers, public IApplyState
@ -91,11 +97,19 @@ namespace Dialogs
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class McdConfigDialog : public BaseConfigurationDialog class McdConfigDialog : public BaseConfigurationDialog
{ {
typedef BaseApplicableDialog _parent;
protected:
Panels::MemoryCardListPanel* m_panel_mcdlist;
public: public:
virtual ~McdConfigDialog() throw() {} virtual ~McdConfigDialog() throw() {}
McdConfigDialog(wxWindow* parent=NULL); McdConfigDialog(wxWindow* parent=NULL);
static const wxChar* GetNameStatic() { return L"Dialog:MemoryCardSettings"; } static const wxChar* GetNameStatic() { return L"Dialog:MemoryCardSettings"; }
virtual bool Show( bool show=true );
virtual int ShowModal();
protected: protected:
virtual wxString& GetConfSettingsTabName() const { return g_Conf->McdSettingsTabName; } virtual wxString& GetConfSettingsTabName() const { return g_Conf->McdSettingsTabName; }
}; };
@ -121,7 +135,10 @@ namespace Dialogs
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class BiosSelectorDialog : public BaseApplicableDialog class BiosSelectorDialog : public BaseApplicableDialog
{ {
typedef BaseApplicableDialog _parent;
protected: protected:
Panels::BaseSelectorPanel* m_selpan;
public: public:
virtual ~BiosSelectorDialog() throw() {} virtual ~BiosSelectorDialog() throw() {}
@ -129,6 +146,9 @@ namespace Dialogs
static const wxChar* GetNameStatic() { return L"Dialog:BiosSelector"; } static const wxChar* GetNameStatic() { return L"Dialog:BiosSelector"; }
virtual bool Show( bool show=true );
virtual int ShowModal();
protected: protected:
void OnOk_Click( wxCommandEvent& evt ); void OnOk_Click( wxCommandEvent& evt );
void OnDoubleClicked( wxCommandEvent& evt ); void OnDoubleClicked( wxCommandEvent& evt );

View File

@ -1,163 +1,183 @@
/* PCSX2 - PS2 Emulator for PCs /* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team * Copyright (C) 2002-2010 PCSX2 Dev Team
* *
* PCSX2 is free software: you can redistribute it and/or modify it under the terms * 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- * 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. * 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; * 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 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details. * 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. * You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "ConfigurationDialog.h" #include "ConfigurationDialog.h"
#include "BaseConfigurationDialog.inl" #include "BaseConfigurationDialog.inl"
#include "ModalPopups.h" #include "ModalPopups.h"
#include "MSWstuff.h" #include "MSWstuff.h"
#include "Panels/ConfigurationPanels.h" #include "Panels/ConfigurationPanels.h"
#include "Panels/MemoryCardPanels.h" #include "Panels/MemoryCardPanels.h"
using namespace pxSizerFlags; using namespace pxSizerFlags;
namespace Panels namespace Panels
{ {
// Helper class since the 'AddPage' template system needs a single-parameter constructor. // Helper class since the 'AddPage' template system needs a single-parameter constructor.
class McdConfigPanel_Multitap2 : public McdConfigPanel_Multitap class McdConfigPanel_Multitap2 : public McdConfigPanel_Multitap
{ {
public: public:
McdConfigPanel_Multitap2( wxWindow* parent ) : McdConfigPanel_Multitap( parent, 1 ) {} McdConfigPanel_Multitap2( wxWindow* parent ) : McdConfigPanel_Multitap( parent, 1 ) {}
virtual ~McdConfigPanel_Multitap2() throw() { } virtual ~McdConfigPanel_Multitap2() throw() { }
}; };
} }
wxString GetMsg_McdNtfsCompress() wxString GetMsg_McdNtfsCompress()
{ {
return pxE( ".Dialog:Memorycards:NtfsCompress", return pxE( ".Dialog:Memorycards:NtfsCompress",
L"NTFS compression is built-in, fast, and completely reliable; and typically compresses MemoryCards " L"NTFS compression is built-in, fast, and completely reliable; and typically compresses MemoryCards "
L"very well (this option is highly recommended)." L"very well (this option is highly recommended)."
); );
} }
Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent) Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
: _parent( parent ) : _parent( parent )
{ {
m_idealWidth -= 48; m_idealWidth -= 48;
m_check_Ejection = new pxCheckBox( this, m_check_Ejection = new pxCheckBox( this,
_("Auto-eject memorycards when loading savestates"), _("Auto-eject memorycards when loading savestates"),
pxE( ".Dialog:Memorycards:EnableEjection", pxE( ".Dialog:Memorycards:EnableEjection",
L"Avoids memorycard corruption by forcing games to re-index card contents after " L"Avoids memorycard corruption by forcing games to re-index card contents after "
L"loading from savestates. May not be compatible with all games (Guitar Hero)." L"loading from savestates. May not be compatible with all games (Guitar Hero)."
) )
); );
*this += m_check_Ejection | pxExpand; *this += m_check_Ejection | pxExpand;
#ifdef __WXMSW__ #ifdef __WXMSW__
m_check_CompressNTFS = new pxCheckBox( this, m_check_CompressNTFS = new pxCheckBox( this,
_("Enable NTFS Compression on all cards by default."), _("Enable NTFS Compression on all cards by default."),
GetMsg_McdNtfsCompress() GetMsg_McdNtfsCompress()
); );
*this += m_check_CompressNTFS | pxExpand; *this += m_check_CompressNTFS | pxExpand;
#endif #endif
} }
void Panels::McdConfigPanel_Toggles::Apply() void Panels::McdConfigPanel_Toggles::Apply()
{ {
g_Conf->McdEnableEjection = m_check_Ejection->GetValue(); g_Conf->McdEnableEjection = m_check_Ejection->GetValue();
#ifdef __WXMSW__ #ifdef __WXMSW__
g_Conf->McdCompressNTFS = m_check_CompressNTFS->GetValue(); g_Conf->McdCompressNTFS = m_check_CompressNTFS->GetValue();
#endif #endif
} }
void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied() void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
{ {
m_check_Ejection ->SetValue( g_Conf->McdEnableEjection ); m_check_Ejection ->SetValue( g_Conf->McdEnableEjection );
#ifdef __WXMSW__ #ifdef __WXMSW__
m_check_CompressNTFS ->SetValue( g_Conf->McdCompressNTFS ); m_check_CompressNTFS ->SetValue( g_Conf->McdCompressNTFS );
#endif #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[0] = new MemoryCardInfoPanel( this, 0, 0 );
m_panel_cardinfo[1] = new MemoryCardInfoPanel( this, 1, 0 ); m_panel_cardinfo[1] = new MemoryCardInfoPanel( this, 1, 0 );
for( uint port=0; port<2; ++port ) for( uint port=0; port<2; ++port )
{ {
wxStaticBoxSizer& portSizer( *new wxStaticBoxSizer( wxVERTICAL, this, wxsFormat(_("Port %u"), port+1) ) ); wxStaticBoxSizer& portSizer( *new wxStaticBoxSizer( wxVERTICAL, this, wxsFormat(_("Port %u"), port+1) ) );
portSizer += m_panel_cardinfo[port] | pxExpand; portSizer += m_panel_cardinfo[port] | pxExpand;
*this += portSizer | StdExpand(); *this += portSizer | StdExpand();
} }
} }
void Panels::McdConfigPanel_Standard::Apply() void Panels::McdConfigPanel_Standard::Apply()
{ {
} }
void Panels::McdConfigPanel_Standard::AppStatusEvent_OnSettingsApplied() void Panels::McdConfigPanel_Standard::AppStatusEvent_OnSettingsApplied()
{ {
} }
Panels::McdConfigPanel_Multitap::McdConfigPanel_Multitap(wxWindow *parent, int port) : _parent( parent ) Panels::McdConfigPanel_Multitap::McdConfigPanel_Multitap(wxWindow *parent, int port) : _parent( parent )
{ {
m_port = port; m_port = port;
m_check_Multitap = new pxCheckBox( this, wxsFormat(_("Enable Multitap on Port %u"), m_port+1) ); m_check_Multitap = new pxCheckBox( this, wxsFormat(_("Enable Multitap on Port %u"), m_port+1) );
m_check_Multitap->SetFont( wxFont( m_check_Multitap->GetFont().GetPointSize()+1, wxFONTFAMILY_MODERN, wxNORMAL, wxNORMAL, false, L"Lucida Console" ) ); m_check_Multitap->SetFont( wxFont( m_check_Multitap->GetFont().GetPointSize()+1, wxFONTFAMILY_MODERN, wxNORMAL, wxNORMAL, false, L"Lucida Console" ) );
Connect( m_check_Multitap->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(McdConfigPanel_Multitap::OnMultitapChecked)); *this += m_check_Multitap;
}
Connect( m_check_Multitap->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(McdConfigPanel_Multitap::OnMultitapChecked));
void Panels::McdConfigPanel_Multitap::OnMultitapChecked( wxCommandEvent& evt ) }
{
void Panels::McdConfigPanel_Multitap::OnMultitapChecked( wxCommandEvent& evt )
} {
void Panels::McdConfigPanel_Multitap::Apply() }
{
void Panels::McdConfigPanel_Multitap::Apply()
} {
void Panels::McdConfigPanel_Multitap::AppStatusEvent_OnSettingsApplied() }
{
void Panels::McdConfigPanel_Multitap::AppStatusEvent_OnSettingsApplied()
} {
using namespace Panels; }
using namespace pxSizerFlags;
using namespace Panels;
Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent ) using namespace pxSizerFlags;
: BaseConfigurationDialog( parent, _("MemoryCard Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
{ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
SetName( GetNameStatic() ); : BaseConfigurationDialog( parent, _("MemoryCard Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
{
// [TODO] : Discover and use a good multitap port icon! Possibility might be a SetName( GetNameStatic() );
// simple 3x memorycards icon, in cascading form.
// (for now everything defaults to the redundant memorycard icon) // [TODO] : Discover and use a good multitap port icon! Possibility might be a
// simple 3x memorycards icon, in cascading form.
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config ); // (for now everything defaults to the redundant memorycard icon)
AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), cfgid.MemoryCard ); const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<McdConfigPanel_Standard> ( wxLt("Slots 1/2"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Multitap> ( wxLt("Multitap 1"), cfgid.MemoryCard ); AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Multitap2> ( wxLt("Multitap 2"), cfgid.MemoryCard ); AddPage<McdConfigPanel_Standard> ( wxLt("Slots 1/2"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Multitap> ( wxLt("Multitap 1"), cfgid.MemoryCard );
//MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth ); AddPage<McdConfigPanel_Multitap2> ( wxLt("Multitap 2"), cfgid.MemoryCard );
*this += StdPadding; MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth );
*this += new wxStaticLine( this ) | pxExpand;
*this += StdPadding; m_panel_mcdlist = new MemoryCardListPanel( this );
*this += new MemoryCardListPanel( this ) | pxExpand;
*this += StdPadding;
AddOkCancel(); *this += new wxStaticLine( this ) | StdExpand();
} *this += StdPadding;
*this += m_panel_mcdlist | StdExpand();
AddOkCancel();
}
bool Dialogs::McdConfigDialog::Show( bool show )
{
if( show && m_panel_mcdlist )
m_panel_mcdlist->OnShown();
return _parent::Show( show );
}
int Dialogs::McdConfigDialog::ShowModal()
{
if( m_panel_mcdlist )
m_panel_mcdlist->OnShown();
return _parent::ShowModal();
}

View File

@ -20,6 +20,10 @@
using namespace pxSizerFlags; using namespace pxSizerFlags;
using namespace Threading; using namespace Threading;
// NOTE: Currently unused module. Stuck Threads are not detected or handled at this time,
// though I would like to have something in place in the distant future. --air
Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, PersistentThread& stuck_thread ) Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, PersistentThread& stuck_thread )
: wxDialogWithHelpers( parent, _("PCSX2 Thread is not responding"), wxVERTICAL ) : wxDialogWithHelpers( parent, _("PCSX2 Thread is not responding"), wxVERTICAL )
{ {

View File

@ -103,31 +103,6 @@ void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent &event)
} }
} }
// Old 'auto-restart' method; avoids shutting down the PCSX2 process, but tends to
// be bug prone in odd ways (namely QueryPerformanceFrequency hangs for a number of
// seconds .. wtf?)
/*
m_RestartEmuOnDelete = true;
Destroy();
if( CoreThread.IsRunning() )
{
new RestartEverything_WhenCoreThreadStops();
if( StateCopy_IsBusy() )
{
new CancelCoreThread_WhenSaveStateDone();
throw Exception::CancelEvent( "Savestate in progress, app restart event delayed until action is complete." );
}
CoreThread.Cancel();
}
else
{
WipeSettings();
}
*/
WipeSettings(); WipeSettings();
wxGetApp().PostMenuAction( MenuId_Exit ); wxGetApp().PostMenuAction( MenuId_Exit );
} }
@ -328,9 +303,9 @@ void MainEmuFrame::Menu_CdvdSource_Click( wxCommandEvent &event )
switch( event.GetId() ) switch( event.GetId() )
{ {
case MenuId_Src_Iso: newsrc = CDVDsrc_Iso; break; case MenuId_Src_Iso: newsrc = CDVDsrc_Iso; break;
case MenuId_Src_Plugin: newsrc = CDVDsrc_Plugin; break; case MenuId_Src_Plugin: newsrc = CDVDsrc_Plugin; break;
case MenuId_Src_NoDisc: newsrc = CDVDsrc_NoDisc; break; case MenuId_Src_NoDisc: newsrc = CDVDsrc_NoDisc; break;
jNO_DEFAULT jNO_DEFAULT
} }

View File

@ -16,6 +16,8 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "ConfigurationPanels.h" #include "ConfigurationPanels.h"
using namespace pxSizerFlags;
Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) : Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) :
BaseApplicableConfigPanel( parent ) BaseApplicableConfigPanel( parent )
{ {
@ -60,7 +62,13 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) :
}, },
{ {
_("EE timing hack / FFX videos fix - Multi purpose hack. Try if all else fails."), _("EE timing hack / FFX videos fix - Multi purpose hack. Try if all else fails."),
_("Known to affect following games:\n * Final Fantasy 10 (Fixes FMV)\n * Digital Devil Saga (Fixes FMV and crashes)\n * SSX (Fixes bad graphics and crashes)\n * Resident Evil: Dead Aim (Causes garbled textures)") pxE( ".Tooltips:Gamefixes:EE Timing Hack",
L"Known to affect following games:\n"
L" * Final Fantasy 10 (Fixes FMV)\n"
L" * Digital Devil Saga (Fixes FMV and crashes)\n"
L" * SSX (Fixes bad graphics and crashes)\n"
L" * Resident Evil: Dead Aim (Causes garbled textures)"
)
} }
}; };
@ -71,21 +79,21 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) :
} }
m_check_Enable = new pxCheckBox( this, _("Enable game fixes"), m_check_Enable = new pxCheckBox( this, _("Enable game fixes"),
_("(Warning, can cause compatibility or performance issues!)")); _("(Warning! Game fixes can cause compatibility or performance issues!)"));
m_check_Enable->SetToolTip(_("The safest way to make sure that all game fixes are completely disabled.")); m_check_Enable->SetToolTip(_("The safest way to make sure that all game fixes are completely disabled."));
m_check_Enable ->SetValue( g_Conf->EnableGameFixes ); m_check_Enable->SetValue( g_Conf->EnableGameFixes );
*this += groupSizer | wxSF.Centre(); *this += groupSizer | pxCenter;
*this += m_check_Enable; *this += m_check_Enable | StdExpand();
*this += new pxStaticHeading( this, pxE( ".Panels:Gamefixes:Compat Warning", *this += Heading( pxE( ".Panels:Gamefixes:Compat Warning",
L"Enabling game fixes can cause compatibility or performance issues in other games. You " L"Enabling game fixes can cause compatibility or performance issues in other games. You "
L"will need to turn off fixes manually when changing games." L"will need to turn off fixes manually when changing games."
)); ));
Connect( m_check_Enable->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( GameFixesPanel::OnEnable_Toggled ) );
EnableStuff();
AppStatusEvent_OnSettingsApplied(); Connect( m_check_Enable->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( GameFixesPanel::OnEnable_Toggled ) );
EnableStuff();
} }
// I could still probably get rid of the for loop, but I think this is clearer. // I could still probably get rid of the for loop, but I think this is clearer.

View File

@ -93,8 +93,6 @@ Panels::MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
wxButton* button_Create = new wxButton(this, wxID_ANY, _("Create new card...")); wxButton* button_Create = new wxButton(this, wxID_ANY, _("Create new card..."));
//Connect( m_list_AllKnownCards->GetId(), wxEVT_COMMAND_LEFT_CLICK, MemoryCardsPanel::OnListDrag);
// ------------------------------------ // ------------------------------------
// Sizer / Layout Section // Sizer / Layout Section
// ------------------------------------ // ------------------------------------
@ -114,8 +112,9 @@ Panels::MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
*this += s_buttons | pxExpand; *this += s_buttons | pxExpand;
m_listview->SetMinSize( wxSize( m_idealWidth, 120 ) ); m_listview->SetMinSize( wxSize( m_idealWidth, 120 ) );
Disable(); Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel::OnListDrag));
Connect( button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel::OnCreateNewCard));
} }
void Panels::MemoryCardListPanel::Apply() void Panels::MemoryCardListPanel::Apply()
@ -124,7 +123,6 @@ void Panels::MemoryCardListPanel::Apply()
void Panels::MemoryCardListPanel::AppStatusEvent_OnSettingsApplied() void Panels::MemoryCardListPanel::AppStatusEvent_OnSettingsApplied()
{ {
} }
bool Panels::MemoryCardListPanel::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) bool Panels::MemoryCardListPanel::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
@ -155,7 +153,7 @@ bool Panels::MemoryCardListPanel::ValidateEnumerationStatus()
if( !m_KnownCards || (*mcdlist != *m_KnownCards) ) if( !m_KnownCards || (*mcdlist != *m_KnownCards) )
validated = false; validated = false;
m_listview->AssignCardsList( NULL ); m_listview->SetInterface( NULL );
m_KnownCards.SwapPtr( mcdlist ); m_KnownCards.SwapPtr( mcdlist );
return validated; return validated;
@ -165,9 +163,6 @@ void Panels::MemoryCardListPanel::DoRefresh()
{ {
if( !m_KnownCards ) return; if( !m_KnownCards ) return;
//m_listview->ClearAll();
//m_listview->CreateColumns();
for( size_t i=0; i<m_KnownCards->size(); ++i ) for( size_t i=0; i<m_KnownCards->size(); ++i )
{ {
McdListItem& mcditem( (*m_KnownCards)[i] ); McdListItem& mcditem( (*m_KnownCards)[i] );
@ -189,5 +184,38 @@ void Panels::MemoryCardListPanel::DoRefresh()
} }
} }
m_listview->AssignCardsList( m_KnownCards ); m_listview->SetInterface( this );
//m_listview->SetCardCount( m_KnownCards->size() );
}
void Panels::MemoryCardListPanel::OnCreateNewCard(wxCommandEvent& evt)
{
}
void Panels::MemoryCardListPanel::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();
}
int Panels::MemoryCardListPanel::GetLength() const
{
return m_KnownCards ? m_KnownCards->size() : 0;
}
const McdListItem& Panels::MemoryCardListPanel::Get( int idx ) const
{
pxAssume(!!m_KnownCards);
return (*m_KnownCards)[idx];
}
McdListItem& Panels::MemoryCardListPanel::Get( int idx )
{
pxAssume(!!m_KnownCards);
return (*m_KnownCards)[idx];
} }

View File

@ -56,6 +56,14 @@ struct McdListItem
typedef std::vector<McdListItem> McdList; typedef std::vector<McdListItem> McdList;
class IMemoryCardList
{
public:
virtual int GetLength() const=0;
virtual const McdListItem& Get( int idx ) const=0;
virtual McdListItem& Get( int idx )=0;
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// MemoryCardListView // MemoryCardListView
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -64,7 +72,7 @@ class MemoryCardListView : public wxListView
typedef wxListView _parent; typedef wxListView _parent;
protected: protected:
McdList* m_KnownCards; IMemoryCardList* m_CardsList;
public: public:
virtual ~MemoryCardListView() throw() { } virtual ~MemoryCardListView() throw() { }
@ -72,7 +80,12 @@ public:
virtual void OnListDrag(wxListEvent& evt); virtual void OnListDrag(wxListEvent& evt);
virtual void CreateColumns(); virtual void CreateColumns();
virtual void AssignCardsList( McdList* knownCards, int length=0 ); virtual void SetCardCount( int length );
virtual void SetInterface( IMemoryCardList* face )
{
m_CardsList = face;
SetCardCount( m_CardsList ? m_CardsList->GetLength() : 0 );
}
protected: protected:
// Overrides for wxLC_VIRTUAL // Overrides for wxLC_VIRTUAL
@ -90,6 +103,7 @@ namespace Panels
class MemoryCardListPanel class MemoryCardListPanel
: public BaseSelectorPanel : public BaseSelectorPanel
, public wxFileDropTarget , public wxFileDropTarget
, public IMemoryCardList
{ {
protected: protected:
DirPickerPanel* m_FolderPicker; DirPickerPanel* m_FolderPicker;
@ -100,7 +114,14 @@ namespace Panels
virtual ~MemoryCardListPanel() throw() {} virtual ~MemoryCardListPanel() throw() {}
MemoryCardListPanel( wxWindow* parent ); MemoryCardListPanel( wxWindow* parent );
// Interface Implementation for IMemoryCardList
virtual int GetLength() const;
virtual const McdListItem& Get( int idx ) const;
virtual McdListItem& Get( int idx );
protected: protected:
virtual void OnCreateNewCard(wxCommandEvent& evt);
virtual void OnListDrag(wxListEvent& evt);
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames); virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames);
virtual void Apply(); virtual void Apply();

View File

@ -35,7 +35,7 @@ enum McdColumnType
McdCol_Formatted, McdCol_Formatted,
McdCol_DateModified, McdCol_DateModified,
McdCol_DateCreated, McdCol_DateCreated,
McdCol_Path, //McdCol_Path,
McdCol_Count McdCol_Count
}; };
@ -55,50 +55,40 @@ void MemoryCardListView::CreateColumns()
{ _("Formatted"), wxLIST_FORMAT_CENTER }, { _("Formatted"), wxLIST_FORMAT_CENTER },
{ _("Last Modified"), wxLIST_FORMAT_LEFT }, { _("Last Modified"), wxLIST_FORMAT_LEFT },
{ _("Created On"), wxLIST_FORMAT_LEFT }, { _("Created On"), wxLIST_FORMAT_LEFT },
{ _("Path"), wxLIST_FORMAT_LEFT } //{ _("Path"), wxLIST_FORMAT_LEFT }
}; };
for( int i=0; i<McdCol_Count; ++i ) for( int i=0; i<McdCol_Count; ++i )
InsertColumn( i, columns[i].name, columns[i].align, -1 ); InsertColumn( i, columns[i].name, columns[i].align, -1 );
} }
void MemoryCardListView::AssignCardsList( McdList* knownCards, int length ) void MemoryCardListView::SetCardCount( int length )
{ {
if( knownCards == NULL ) length = 0; if( !m_CardsList ) length = 0;
m_KnownCards = knownCards;
SetItemCount( length ); SetItemCount( length );
RefreshItems( 0, length ); Refresh();
} }
MemoryCardListView::MemoryCardListView( wxWindow* parent ) MemoryCardListView::MemoryCardListView( wxWindow* parent )
: wxListView( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL ) : wxListView( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL )
{ {
m_KnownCards = NULL; m_CardsList = NULL;
CreateColumns(); CreateColumns();
//m_KnownCards;
Connect( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListView::OnListDrag)); Connect( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListView::OnListDrag));
} }
void MemoryCardListView::OnListDrag(wxListEvent& evt) void MemoryCardListView::OnListDrag(wxListEvent& evt)
{ {
evt.Skip(); evt.Skip();
wxFileDataObject my_data;
my_data.AddFile( (*m_KnownCards)[ GetItemData(GetFirstSelected()) ].Filename.GetFullPath() );
wxDropSource dragSource( this );
dragSource.SetData( my_data );
wxDragResult result = dragSource.DoDragDrop();
} }
// return the text for the given column of the given item // return the text for the given column of the given item
wxString MemoryCardListView::OnGetItemText(long item, long column) const wxString MemoryCardListView::OnGetItemText(long item, long column) const
{ {
if( m_KnownCards == NULL ) return _parent::OnGetItemText(item, column); if( !m_CardsList ) return _parent::OnGetItemText(item, column);
const McdListItem& it( (*m_KnownCards)[item] ); const McdListItem& it( m_CardsList->Get(item) );
switch( column ) switch( column )
{ {
@ -113,7 +103,7 @@ wxString MemoryCardListView::OnGetItemText(long item, long column) const
case McdCol_Formatted: return it.IsFormatted ? L"Yes" : L"No"; case McdCol_Formatted: return it.IsFormatted ? L"Yes" : L"No";
case McdCol_DateModified: return it.DateModified.FormatDate(); case McdCol_DateModified: return it.DateModified.FormatDate();
case McdCol_DateCreated: return it.DateModified.FormatDate(); case McdCol_DateCreated: return it.DateModified.FormatDate();
case McdCol_Path: return it.Filename.GetPath(); //case McdCol_Path: return it.Filename.GetPath();
} }
pxFail( "Unknown column index in MemoryCardListView -- returning an empty string." ); pxFail( "Unknown column index in MemoryCardListView -- returning an empty string." );

View File

@ -107,7 +107,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
) ); ) );
m_check_Enable = new pxCheckBox( this, _("Enable speedhacks"), m_check_Enable = new pxCheckBox( this, _("Enable speedhacks"),
_("(Warning, can cause false FPS readings and many bugs!)")); _("(Warning! Speedhacks can cause false FPS readings, choppy audio, and many other bugs!)"));
m_check_Enable->SetToolTip(_("The safest way to make sure that all speedhacks are completely disabled.")); m_check_Enable->SetToolTip(_("The safest way to make sure that all speedhacks are completely disabled."));
m_button_Defaults = new wxButton( this, wxID_DEFAULT, _("Restore Defaults") ); m_button_Defaults = new wxButton( this, wxID_DEFAULT, _("Restore Defaults") );
@ -266,8 +266,6 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
Connect( m_slider_vustealer->GetId(), wxEVT_SCROLL_CHANGED, wxScrollEventHandler( SpeedHacksPanel::VUCycleRate_Scroll ) ); Connect( m_slider_vustealer->GetId(), wxEVT_SCROLL_CHANGED, wxScrollEventHandler( SpeedHacksPanel::VUCycleRate_Scroll ) );
Connect( m_check_Enable->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SpeedHacksPanel::OnEnable_Toggled ) ); Connect( m_check_Enable->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SpeedHacksPanel::OnEnable_Toggled ) );
Connect( wxID_DEFAULT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SpeedHacksPanel::Defaults_Click ) ); Connect( wxID_DEFAULT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SpeedHacksPanel::Defaults_Click ) );
AppStatusEvent_OnSettingsApplied();
} }
void Panels::SpeedHacksPanel::EnableStuff() void Panels::SpeedHacksPanel::EnableStuff()

View File

@ -104,7 +104,7 @@ pxLogTextCtrl::~pxLogTextCtrl() throw()
{ {
} }
void pxLogTextCtrl::ConcludeIssue( int lines ) void pxLogTextCtrl::ConcludeIssue()
{ {
if( HasWriteLock() ) return; if( HasWriteLock() ) return;
SetInsertionPointEnd(); SetInsertionPointEnd();