mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-03 11:54:27 +00:00
803030de7b
Also disabled some code in the same place that caused the application to hang in linux. This means that if you select keys from the key list you will have to click Set to make it take effect. At least until I can figure out how to get that working. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5368 8ced0084-cf51-0410-be5f-012b33b47a6e
910 lines
30 KiB
C++
910 lines
30 KiB
C++
|
|
#include "ConfigDiag.h"
|
|
|
|
#define _connect_macro_( b, f, c, s ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s );
|
|
|
|
void GamepadPage::ConfigExtension( wxCommandEvent& event )
|
|
{
|
|
ControllerEmu::Extension* const ex = ((ExtensionButton*)event.GetEventObject())->extension;
|
|
|
|
// show config diag, if "none" isn't selected
|
|
if ( ex->switch_extension )
|
|
{
|
|
wxDialog* const dlg = new wxDialog( this, -1, wxString::FromAscii(ex->attachments[ex->switch_extension]->GetName().c_str()), wxDefaultPosition );
|
|
wxPanel* const pnl = new wxPanel( dlg, -1, wxDefaultPosition );
|
|
wxBoxSizer* const pnl_szr = new wxBoxSizer( wxHORIZONTAL );
|
|
|
|
const std::size_t orig_size = control_groups.size();
|
|
|
|
ControlGroupsSizer* const szr = new ControlGroupsSizer( ex->attachments[ex->switch_extension], pnl, this, &control_groups );
|
|
pnl->SetSizerAndFit( szr );
|
|
pnl_szr->Add( pnl, 0, wxLEFT, 5 );
|
|
dlg->SetSizerAndFit( pnl_szr );
|
|
|
|
dlg->Center();
|
|
|
|
dlg->ShowModal();
|
|
dlg->Destroy();
|
|
|
|
// remove the new groups that were just added, now that the window closed
|
|
control_groups.resize( orig_size );
|
|
}
|
|
}
|
|
|
|
PadSettingExtension::PadSettingExtension( wxWindow* const parent, ControllerEmu::Extension* const ext )
|
|
: wxChoice( parent, -1 )
|
|
, extension(ext)
|
|
{
|
|
|
|
std::vector<ControllerEmu*>::const_iterator
|
|
i = extension->attachments.begin(),
|
|
e = extension->attachments.end();
|
|
|
|
for ( ; i!=e; ++i )
|
|
Append( wxString::FromAscii( (*i)->GetName().c_str() ) );
|
|
|
|
UpdateGUI();
|
|
}
|
|
|
|
void PadSettingExtension::UpdateGUI()
|
|
{
|
|
Select( extension->switch_extension );
|
|
}
|
|
|
|
void PadSettingExtension::UpdateValue()
|
|
{
|
|
extension->switch_extension = GetSelection();
|
|
}
|
|
|
|
PadSettingCheckBox::PadSettingCheckBox( wxWindow* const parent, ControlState& _value, const char* const label )
|
|
: wxCheckBox( parent, -1, wxString::FromAscii( label ), wxDefaultPosition )
|
|
, value(_value)
|
|
{
|
|
UpdateGUI();
|
|
}
|
|
|
|
void PadSettingCheckBox::UpdateGUI()
|
|
{
|
|
SetValue( value > 0 );
|
|
}
|
|
|
|
void PadSettingCheckBox::UpdateValue()
|
|
{
|
|
// 0.01 so its saved to the ini file as just 1. :(
|
|
value = 0.01 * GetValue();
|
|
}
|
|
|
|
PadSettingChoice::PadSettingChoice( wxWindow* const parent, ControlState& _value, int min, int max )
|
|
: wxChoice( parent, -1, wxDefaultPosition, wxSize( 54, -1 ) )
|
|
, value(_value)
|
|
{
|
|
Append( wxT("0") );
|
|
for ( ; min<=max; ++min )
|
|
{
|
|
std::ostringstream ss;
|
|
ss << min;
|
|
Append( wxString::FromAscii( ss.str().c_str() ) );
|
|
}
|
|
|
|
UpdateGUI();
|
|
}
|
|
|
|
void PadSettingChoice::UpdateGUI()
|
|
{
|
|
std::ostringstream ss;
|
|
ss << int(value * 100);
|
|
SetSelection( FindString( wxString::FromAscii( ss.str().c_str() ) ) );
|
|
}
|
|
|
|
void PadSettingChoice::UpdateValue()
|
|
{
|
|
value = float( atoi( GetStringSelection().mb_str() ) ) / 100;
|
|
}
|
|
|
|
ControlDialog::ControlDialog( wxWindow* const parent, ControllerInterface::ControlReference* const ref, const std::vector<ControllerInterface::Device*>& devs )
|
|
:wxDialog( parent, -1, wxT("Configure Control"), wxDefaultPosition )
|
|
,control_reference(ref)
|
|
{
|
|
|
|
device_cbox = new wxComboBox( this, -1, wxString::FromAscii( ref->device_qualifier.ToString().c_str() ), wxDefaultPosition, wxSize(256,-1), wxArrayString(), wxTE_PROCESS_ENTER );
|
|
|
|
//#define _connect_macro2_( b, f, c ) (b)->Connect( wxID_ANY, c, wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)parent );
|
|
|
|
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_COMBOBOX_SELECTED, parent );
|
|
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_TEXT_ENTER, parent );
|
|
|
|
std::vector< ControllerInterface::Device* >::const_iterator i = devs.begin(),
|
|
e = devs.end();
|
|
ControllerInterface::DeviceQualifier dq;
|
|
for ( ; i!=e; ++i )
|
|
{
|
|
dq.FromDevice( *i );
|
|
device_cbox->Append( wxString::FromAscii( dq.ToString().c_str() ) );
|
|
}
|
|
|
|
control_chooser = new ControlChooser( this, ref, parent );
|
|
|
|
wxStaticBoxSizer* d_szr = new wxStaticBoxSizer( wxVERTICAL, this, wxT("Device") );
|
|
d_szr->Add( device_cbox, 0, wxEXPAND|wxALL, 5 );
|
|
|
|
wxBoxSizer* szr = new wxBoxSizer( wxVERTICAL );
|
|
szr->Add( d_szr, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
|
|
szr->Add( control_chooser, 0, wxEXPAND|wxALL, 5 );
|
|
|
|
SetSizerAndFit( szr );
|
|
|
|
}
|
|
|
|
ControlButton::ControlButton( wxWindow* const parent, ControllerInterface::ControlReference* const _ref, const unsigned int width, const std::string& label )
|
|
: wxButton( parent, -1, wxT(""), wxDefaultPosition, wxSize( width,20) )
|
|
, control_reference( _ref )
|
|
{
|
|
if ( label.empty() )
|
|
SetLabel( wxString::FromAscii( _ref->control_qualifier.name.c_str() ) );
|
|
else
|
|
SetLabel( wxString::FromAscii( label.c_str() ) );
|
|
}
|
|
|
|
void ConfigDialog::UpdateProfileComboBox()
|
|
{
|
|
std::string pname( File::GetUserPath(D_CONFIG_IDX) );
|
|
pname += PROFILES_PATH; pname += m_plugin.profile_name;
|
|
|
|
CFileSearch::XStringVector exts;
|
|
exts.push_back("*.ini");
|
|
CFileSearch::XStringVector dirs;
|
|
dirs.push_back( pname );
|
|
CFileSearch cfs( exts, dirs );
|
|
const CFileSearch::XStringVector& sv = cfs.GetFileNames();
|
|
|
|
wxArrayString strs;
|
|
CFileSearch::XStringVector::const_iterator si = sv.begin(),
|
|
se = sv.end();
|
|
for ( ; si!=se; ++si )
|
|
{
|
|
std::string str( si->begin() + si->find_last_of('/') + 1 , si->end() - 4 ) ;
|
|
strs.push_back( wxString::FromAscii( str.c_str() ) );
|
|
}
|
|
|
|
std::vector< GamepadPage* >::iterator i = m_padpages.begin(),
|
|
e = m_padpages.end();
|
|
for ( ; i != e; ++i )
|
|
{
|
|
(*i)->profile_cbox->Clear();
|
|
(*i)->profile_cbox->Append(strs);
|
|
}
|
|
}
|
|
|
|
void ConfigDialog::UpdateControlReferences()
|
|
{
|
|
std::vector< GamepadPage* >::iterator i = m_padpages.begin(),
|
|
e = m_padpages.end();
|
|
for ( ; i != e; ++i )
|
|
(*i)->controller->UpdateReferences( m_plugin.controller_interface );
|
|
}
|
|
|
|
void ConfigDialog::ClickSave( wxCommandEvent& event )
|
|
{
|
|
m_plugin.SaveConfig();
|
|
Close();
|
|
};
|
|
|
|
void ControlChooser::UpdateGUI()
|
|
{
|
|
control_lbox->Clear();
|
|
|
|
// make sure it's a valid device
|
|
if ( control_reference->device )
|
|
{
|
|
if ( control_reference->is_input )
|
|
{
|
|
// for inputs
|
|
std::vector<ControllerInterface::Device::Input*>::const_iterator
|
|
i = control_reference->device->Inputs().begin(),
|
|
e = control_reference->device->Inputs().end();
|
|
for ( ; i!=e; ++i )
|
|
control_lbox->Append( wxString::FromAscii( (*i)->GetName().c_str() ) );
|
|
}
|
|
else
|
|
{
|
|
// for outputs
|
|
std::vector<ControllerInterface::Device::Output*>::const_iterator
|
|
i = control_reference->device->Outputs().begin(),
|
|
e = control_reference->device->Outputs().end();
|
|
for ( ; i!=e; ++i )
|
|
control_lbox->Append( wxString::FromAscii( (*i)->GetName().c_str() ) );
|
|
}
|
|
}
|
|
|
|
// logic not 100% right here for a poorly formated qualifier
|
|
// but its just for selecting crap in the listbox
|
|
wxArrayString control_names = control_lbox->GetStrings();
|
|
const std::string cname = control_reference->control_qualifier.name;
|
|
for ( int i = int(control_names.size()) - 1; i >=0; --i )
|
|
{
|
|
if ( cname == std::string(control_names[i].ToAscii()) ||
|
|
cname.find( control_names[i].Prepend(wxT('|')).Append(wxT('|')).ToAscii() ) != std::string::npos )
|
|
control_lbox->Select( i );
|
|
else
|
|
control_lbox->Deselect( i );
|
|
}
|
|
|
|
size_t bound = control_reference->controls.size();
|
|
std::ostringstream ss;
|
|
ss << "Bound Controls: ";
|
|
if ( bound ) ss << bound; else ss << "None";
|
|
m_bound_label->SetLabel( wxString::FromAscii(ss.str().c_str()) );
|
|
|
|
textctrl->SetValue(wxString::FromAscii(control_reference->control_qualifier.name.c_str()));
|
|
};
|
|
|
|
void GamepadPage::UpdateGUI()
|
|
{
|
|
device_cbox->SetValue( wxString::FromAscii( controller->default_device.ToString().c_str() ) );
|
|
|
|
std::vector< ControlGroupBox* >::const_iterator g = control_groups.begin(),
|
|
ge = control_groups.end();
|
|
for ( ; g!=ge; ++g )
|
|
{
|
|
// buttons
|
|
std::vector<ControlButton*>::const_iterator i = (*g)->control_buttons.begin()
|
|
, e = (*g)->control_buttons.end();
|
|
for ( ; i!=e; ++i )
|
|
(*i)->SetLabel( wxString::FromAscii( (*i)->control_reference->control_qualifier.name.c_str() ) );
|
|
|
|
// cboxes
|
|
std::vector<PadSetting*>::const_iterator si = (*g)->options.begin()
|
|
, se = (*g)->options.end();
|
|
for ( ; si!=se; ++si )
|
|
(*si)->UpdateGUI();
|
|
}
|
|
}
|
|
|
|
void GamepadPage::ClearAll( wxCommandEvent& event )
|
|
{
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
// just load an empty ini section to clear everything :P
|
|
IniSection section;
|
|
controller->LoadConfig( section );
|
|
|
|
// no point in using the real ControllerInterface i guess
|
|
ControllerInterface face;
|
|
controller->UpdateReferences( face );
|
|
|
|
UpdateGUI();
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
}
|
|
|
|
void GamepadPage::SetControl( wxCommandEvent& event )
|
|
{
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
m_control_dialog->control_reference->control_qualifier.name =
|
|
std::string( m_control_dialog->control_chooser->textctrl->GetValue().ToAscii() );
|
|
m_control_dialog->control_reference->UpdateControls();
|
|
m_control_dialog->control_chooser->UpdateGUI();
|
|
|
|
UpdateGUI();
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
}
|
|
|
|
void GamepadPage::SetDevice( wxCommandEvent& event )
|
|
{
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
// TODO: need to handle the ConfigControl device in here
|
|
|
|
// default device
|
|
if ( event.GetEventObject() == device_cbox )
|
|
{
|
|
controller->default_device.FromString( std::string( device_cbox->GetValue().ToAscii() ) );
|
|
|
|
// show user what it was validated as
|
|
device_cbox->SetValue( wxString::FromAscii( controller->default_device.ToString().c_str() ) );
|
|
|
|
// this will set all the controls to this default device
|
|
controller->UpdateDefaultDevice();
|
|
|
|
// update references
|
|
controller->UpdateReferences( m_plugin.controller_interface );
|
|
}
|
|
// control dialog
|
|
else
|
|
{
|
|
m_control_dialog->control_reference->device_qualifier.FromString( std::string( m_control_dialog->device_cbox->GetValue().ToAscii() ) );
|
|
|
|
m_control_dialog->device_cbox->SetValue( wxString::FromAscii( m_control_dialog->control_reference->device_qualifier.ToString().c_str() ) );
|
|
|
|
m_plugin.controller_interface.UpdateReference( m_control_dialog->control_reference );
|
|
|
|
m_control_dialog->control_chooser->UpdateGUI();
|
|
|
|
}
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
|
|
}
|
|
|
|
void GamepadPage::ClearControl( wxCommandEvent& event )
|
|
{
|
|
m_control_dialog->control_reference->control_qualifier.name.clear();
|
|
m_control_dialog->control_reference->UpdateControls();
|
|
m_control_dialog->control_chooser->UpdateGUI();
|
|
UpdateGUI();
|
|
}
|
|
|
|
void GamepadPage::AdjustSetting( wxCommandEvent& event )
|
|
{
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
// updates the setting value from the GUI control
|
|
(dynamic_cast<PadSetting*>(event.GetEventObject()))->UpdateValue();
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
}
|
|
|
|
void GamepadPage::AdjustControlOption( wxCommandEvent& event )
|
|
{
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
m_control_dialog->control_reference->range = ControlState( m_control_dialog->control_chooser->range_slider->GetValue() ) / SLIDER_TICK_COUNT;
|
|
|
|
if ( m_control_dialog->control_reference->is_input )
|
|
{
|
|
((ControllerInterface::InputReference*)m_control_dialog->control_reference)->mode = m_control_dialog->control_chooser->mode_cbox->GetSelection();
|
|
}
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
}
|
|
|
|
void GamepadPage::ConfigControl( wxCommandEvent& event )
|
|
{
|
|
m_control_dialog = new ControlDialog( this, ((ControlButton*)event.GetEventObject())->control_reference, m_plugin.controller_interface.Devices() );
|
|
m_control_dialog->ShowModal();
|
|
m_control_dialog->Destroy();
|
|
}
|
|
|
|
void GamepadPage::ConfigDetectControl( wxCommandEvent& event )
|
|
{
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
// major major hacks
|
|
wxChar num = ((wxButton*)event.GetEventObject())->GetLabel()[0];
|
|
if ( num > '9' )
|
|
num = 1;
|
|
else
|
|
num -= 0x30;
|
|
|
|
if ( m_control_dialog->control_reference->Detect( DETECT_WAIT_TIME, num ) ) // if we got input, update control
|
|
{
|
|
UpdateGUI();
|
|
m_control_dialog->control_chooser->UpdateGUI();
|
|
}
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
}
|
|
|
|
void GamepadPage::DetectControl( wxCommandEvent& event )
|
|
{
|
|
ControlButton* btn = (ControlButton*)event.GetEventObject();
|
|
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
btn->control_reference->Detect( DETECT_WAIT_TIME );
|
|
btn->SetLabel( wxString::FromAscii( btn->control_reference->control_qualifier.name.c_str() ) );
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
}
|
|
|
|
void ControlDialog::SelectControl( wxCommandEvent& event )
|
|
{
|
|
wxListBox* lb = (wxListBox*)event.GetEventObject();
|
|
|
|
wxArrayInt sels;
|
|
lb->GetSelections( sels );
|
|
wxArrayString names = lb->GetStrings();
|
|
|
|
wxString final_label;
|
|
|
|
if (sels.GetCount() == 1)
|
|
final_label = names[ sels[0] ];
|
|
//else if ( sels.size() == lb->GetCount() )
|
|
// final_label = "||";
|
|
else
|
|
{
|
|
final_label = wxT('|');
|
|
for ( unsigned int i=0; i<sels.GetCount(); ++i )
|
|
final_label += names[ sels[i] ] + wxT('|');
|
|
}
|
|
|
|
#ifdef __linux__
|
|
if (!((wxWindow*)this)->IsBeingDeleted())
|
|
#endif
|
|
control_chooser->textctrl->SetValue( final_label );
|
|
|
|
#ifndef __linux__ // This causes the application to hang in linux
|
|
// kinda dumb
|
|
wxCommandEvent nullevent;
|
|
((GamepadPage*)m_parent)->SetControl( nullevent );
|
|
#endif
|
|
}
|
|
|
|
ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::ControlReference* const ref, wxWindow* const eventsink )
|
|
: wxStaticBoxSizer( wxVERTICAL, parent, ref->is_input ? wxT("Input") : wxT("Output") )
|
|
, control_reference(ref)
|
|
{
|
|
//#define _connect_macro_( b, f, c ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)eventsink );
|
|
|
|
textctrl = new wxTextCtrl( parent, -1 );
|
|
wxButton* detect_button = new wxButton( parent, -1, ref->is_input ? wxT("Detect 1") : wxT("Test") );
|
|
wxButton* clear_button = new wxButton( parent, -1, wxT("Clear"), wxDefaultPosition );
|
|
wxButton* set_button = new wxButton( parent, -1, wxT("Set")/*, wxDefaultPosition, wxSize( 32, -1 )*/ );
|
|
|
|
control_lbox = new wxListBox( parent, -1, wxDefaultPosition, wxSize( 256, 128 ), wxArrayString(), wxLB_EXTENDED );
|
|
|
|
control_lbox->Connect( wxID_ANY, wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( ControlDialog::SelectControl ), (wxObject*)0, parent );
|
|
|
|
wxBoxSizer* button_sizer = new wxBoxSizer( wxHORIZONTAL );
|
|
button_sizer->Add( detect_button, 1, 0, 5 );
|
|
if ( ref->is_input )
|
|
for ( unsigned int i = 2; i<5; ++i )
|
|
{
|
|
wxButton* d_btn = new wxButton( parent, -1, wxChar( '0'+i ), wxDefaultPosition, wxSize(20,-1) );
|
|
_connect_macro_( d_btn, GamepadPage::ConfigDetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
|
button_sizer->Add( d_btn );
|
|
}
|
|
button_sizer->Add( clear_button, 1, 0, 5 );
|
|
button_sizer->Add( set_button, 1, 0, 5 );
|
|
|
|
range_slider = new wxSlider( parent, -1, SLIDER_TICK_COUNT, 0, SLIDER_TICK_COUNT, wxDefaultPosition, wxDefaultSize, wxSL_TOP | wxSL_LABELS /*| wxSL_AUTOTICKS*/ );
|
|
|
|
range_slider->SetValue( control_reference->range * SLIDER_TICK_COUNT );
|
|
|
|
_connect_macro_( detect_button, GamepadPage::ConfigDetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink);
|
|
_connect_macro_( clear_button, GamepadPage::ClearControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink);
|
|
_connect_macro_( set_button, GamepadPage::SetControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink);
|
|
|
|
_connect_macro_( range_slider, GamepadPage::AdjustControlOption, wxEVT_SCROLL_CHANGED, eventsink);
|
|
wxStaticText* range_label = new wxStaticText( parent, -1, wxT("Range"));
|
|
m_bound_label = new wxStaticText( parent, -1, wxT("") );
|
|
|
|
wxBoxSizer* range_sizer = new wxBoxSizer( wxHORIZONTAL );
|
|
range_sizer->Add( range_label, 0, wxCENTER|wxLEFT, 5 );
|
|
range_sizer->Add( range_slider, 1, wxEXPAND|wxLEFT, 5 );
|
|
|
|
wxBoxSizer* txtbox_szr = new wxBoxSizer( wxHORIZONTAL );
|
|
|
|
txtbox_szr->Add( textctrl, 1, wxEXPAND, 0 );
|
|
|
|
wxBoxSizer* mode_szr;
|
|
if ( control_reference->is_input )
|
|
{
|
|
mode_cbox = new wxChoice( parent, -1 );
|
|
mode_cbox->Append( wxT("OR") );
|
|
mode_cbox->Append( wxT("AND") );
|
|
mode_cbox->Append( wxT("NOT") );
|
|
mode_cbox->Select( ((ControllerInterface::InputReference*)control_reference)->mode );
|
|
|
|
_connect_macro_( mode_cbox, GamepadPage::AdjustControlOption, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
|
|
|
mode_szr = new wxBoxSizer( wxHORIZONTAL );
|
|
mode_szr->Add( new wxStaticText( parent, -1, wxT("Mode") ), 0, wxCENTER|wxLEFT|wxRIGHT, 5 );
|
|
mode_szr->Add( mode_cbox, 0, wxLEFT, 5 );
|
|
}
|
|
|
|
Add( range_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
|
if ( control_reference->is_input )
|
|
Add( mode_szr, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
|
Add( txtbox_szr, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
|
|
Add( button_sizer, 0, wxEXPAND|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
|
|
Add( control_lbox, 0, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
|
|
Add( m_bound_label, 0, wxEXPAND|wxLEFT, 80 );
|
|
|
|
UpdateGUI();
|
|
}
|
|
|
|
void GamepadPage::LoadProfile( wxCommandEvent& event )
|
|
{
|
|
// TODO: check for dumb characters maybe
|
|
if ( profile_cbox->GetValue().empty() )
|
|
return;
|
|
|
|
m_plugin.controls_crit.Enter();
|
|
|
|
std::ifstream file;
|
|
std::string fname( File::GetUserPath(D_CONFIG_IDX) );
|
|
fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/';
|
|
fname += profile_cbox->GetValue().ToAscii(); fname += ".ini";
|
|
|
|
if ( false == File::Exists( fname.c_str() ) )
|
|
return;
|
|
|
|
file.open( fname.c_str() );
|
|
IniFile inifile;
|
|
inifile.Load( file );
|
|
controller->LoadConfig( inifile["Profile"] );
|
|
file.close();
|
|
|
|
controller->UpdateReferences( m_plugin.controller_interface );
|
|
|
|
m_plugin.controls_crit.Leave();
|
|
|
|
UpdateGUI();
|
|
}
|
|
|
|
void GamepadPage::SaveProfile( wxCommandEvent& event )
|
|
{
|
|
// TODO: check for dumb characters
|
|
if ( profile_cbox->GetValue().empty() )
|
|
return;
|
|
|
|
// don't need lock
|
|
IniFile inifile;
|
|
controller->SaveConfig( inifile["Profile"] );
|
|
std::ofstream file;
|
|
std::string fname( File::GetUserPath(D_CONFIG_IDX) );
|
|
fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/';
|
|
|
|
if ( false == File::Exists( fname.c_str() ) )
|
|
File::CreateFullPath( fname.c_str() );
|
|
|
|
fname += profile_cbox->GetValue().ToAscii(); fname += ".ini";
|
|
|
|
file.open( fname.c_str() );
|
|
inifile.Save( file );
|
|
file.close();
|
|
|
|
m_config_dialog->UpdateProfileComboBox();
|
|
}
|
|
|
|
void GamepadPage::DeleteProfile( wxCommandEvent& event )
|
|
{
|
|
// TODO: check for dumb characters maybe
|
|
if ( profile_cbox->GetValue().empty() )
|
|
return;
|
|
|
|
// don't need lock
|
|
std::string fname( File::GetUserPath(D_CONFIG_IDX) );
|
|
fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/';
|
|
fname += profile_cbox->GetValue().ToAscii(); fname += ".ini";
|
|
if ( File::Exists( fname.c_str() ) )
|
|
File::Delete( fname.c_str() );
|
|
|
|
m_config_dialog->UpdateProfileComboBox();
|
|
}
|
|
|
|
void ConfigDialog::UpdateDeviceComboBox()
|
|
{
|
|
std::vector< GamepadPage* >::iterator i = m_padpages.begin(),
|
|
e = m_padpages.end();
|
|
ControllerInterface::DeviceQualifier dq;
|
|
for ( ; i != e; ++i )
|
|
{
|
|
(*i)->device_cbox->Clear();
|
|
std::vector<ControllerInterface::Device*>::const_iterator di = m_plugin.controller_interface.Devices().begin(),
|
|
de = m_plugin.controller_interface.Devices().end();
|
|
for ( ; di!=de; ++di )
|
|
{
|
|
dq.FromDevice( *di );
|
|
(*i)->device_cbox->Append( wxString::FromAscii( dq.ToString().c_str() ) );
|
|
}
|
|
(*i)->device_cbox->SetValue( wxString::FromAscii( (*i)->controller->default_device.ToString().c_str() ) );
|
|
}
|
|
}
|
|
|
|
void GamepadPage::RefreshDevices( wxCommandEvent& event )
|
|
{
|
|
m_plugin.controls_crit.Enter(); // enter
|
|
|
|
// refresh devices
|
|
m_plugin.controller_interface.DeInit();
|
|
m_plugin.controller_interface.Init();
|
|
|
|
// update all control references
|
|
m_config_dialog->UpdateControlReferences();
|
|
|
|
// update device cbox
|
|
m_config_dialog->UpdateDeviceComboBox();
|
|
|
|
m_plugin.controls_crit.Leave(); // leave
|
|
}
|
|
|
|
ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent, wxWindow* const eventsink )
|
|
: wxStaticBoxSizer( wxVERTICAL, parent, wxString::FromAscii( group->name ) )
|
|
{
|
|
|
|
control_group = group;
|
|
static_bitmap = NULL;
|
|
|
|
wxFont m_SmallFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
|
|
for ( unsigned int c = 0; c < group->controls.size(); ++c )
|
|
{
|
|
|
|
wxStaticText* label = new wxStaticText( parent, -1, wxString::FromAscii( group->controls[c]->name )/*.append(wxT(" :"))*/ );
|
|
|
|
ControlButton* control_button = new ControlButton( parent, group->controls[c]->control_ref, 80 );
|
|
control_button->SetFont(m_SmallFont);
|
|
ControlButton* adv_button = new ControlButton( parent, group->controls[c]->control_ref, 18, "+" );
|
|
adv_button->SetFont(m_SmallFont);
|
|
|
|
controls.push_back( control_button );
|
|
control_buttons.push_back( control_button );
|
|
|
|
_connect_macro_( control_button, GamepadPage::DetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
|
_connect_macro_( adv_button, GamepadPage::ConfigControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
|
|
|
wxBoxSizer* control_sizer = new wxBoxSizer( wxHORIZONTAL );
|
|
control_sizer->AddStretchSpacer( 1 );
|
|
control_sizer->Add( label, 0, wxCENTER | wxRIGHT, 5 );
|
|
control_sizer->Add( control_button, 0, 0, 0 );
|
|
control_sizer->Add( adv_button, 0, 0, 5 );
|
|
|
|
Add( control_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
|
|
|
}
|
|
|
|
switch ( group->type )
|
|
{
|
|
case GROUP_TYPE_STICK :
|
|
case GROUP_TYPE_TILT :
|
|
{
|
|
wxBitmap bitmap(64, 64);
|
|
wxMemoryDC dc;
|
|
dc.SelectObject(bitmap);
|
|
dc.Clear();
|
|
dc.SelectObject(wxNullBitmap);
|
|
|
|
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
|
|
|
PadSettingChoice* deadzone_cbox = new PadSettingChoice( parent, group->settings[0]->value, 1, 50 );
|
|
PadSettingChoice* diagonal_cbox = new PadSettingChoice( parent, group->settings[1]->value, 1, 100 );
|
|
|
|
_connect_macro_( deadzone_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
|
_connect_macro_( diagonal_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
|
|
|
options.push_back( deadzone_cbox );
|
|
options.push_back( diagonal_cbox );
|
|
|
|
wxBoxSizer* szr = new wxBoxSizer( wxVERTICAL );
|
|
szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( group->settings[0]->name ) ) );
|
|
szr->Add( deadzone_cbox, 0, wxLEFT, 0 );
|
|
szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( group->settings[1]->name ) ) );
|
|
szr->Add( diagonal_cbox, 0, wxLEFT, 0 );
|
|
|
|
wxBoxSizer* h_szr = new wxBoxSizer( wxHORIZONTAL );
|
|
h_szr->Add( szr, 1, 0, 5 );
|
|
h_szr->Add( static_bitmap, 0, wxALL|wxCENTER, 5 );
|
|
|
|
Add( h_szr, 0, wxEXPAND|wxLEFT|wxCENTER|wxTOP, 5 );
|
|
}
|
|
break;
|
|
case GROUP_TYPE_BUTTONS :
|
|
{
|
|
wxBitmap bitmap(int(12*group->controls.size()+1), 12);
|
|
wxMemoryDC dc;
|
|
dc.SelectObject(bitmap);
|
|
dc.Clear();
|
|
dc.SelectObject(wxNullBitmap);
|
|
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
|
|
|
PadSettingChoice* threshold_cbox = new PadSettingChoice( parent, group->settings[0]->value, 1, 99 );
|
|
_connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
|
|
|
options.push_back( threshold_cbox );
|
|
|
|
wxBoxSizer* szr = new wxBoxSizer( wxHORIZONTAL );
|
|
szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( group->settings[0]->name ) ), 0, wxCENTER|wxRIGHT, 5 );
|
|
szr->Add( threshold_cbox, 0, wxRIGHT, 5 );
|
|
|
|
Add( szr, 0, wxALL|wxCENTER, 5 );
|
|
Add( static_bitmap, 0, wxALL|wxCENTER, 5 );
|
|
}
|
|
break;
|
|
case GROUP_TYPE_MIXED_TRIGGERS :
|
|
{
|
|
wxBitmap bitmap(64+12+1, int(6*group->controls.size())+1);
|
|
wxMemoryDC dc;
|
|
dc.SelectObject(bitmap);
|
|
dc.Clear();
|
|
dc.SelectObject(wxNullBitmap);
|
|
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
|
|
|
PadSettingChoice* threshold_cbox = new PadSettingChoice( parent, group->settings[0]->value, 1, 99 );
|
|
_connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
|
|
|
options.push_back( threshold_cbox );
|
|
|
|
wxBoxSizer* szr = new wxBoxSizer( wxHORIZONTAL );
|
|
szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( group->settings[0]->name ) ), 0, wxCENTER|wxRIGHT, 5 );
|
|
szr->Add( threshold_cbox, 0, wxRIGHT, 5 );
|
|
|
|
Add( szr, 0, wxALL|wxCENTER, 5 );
|
|
Add( static_bitmap, 0, wxALL|wxCENTER, 5 );
|
|
}
|
|
break;
|
|
case GROUP_TYPE_EXTENSION :
|
|
{
|
|
PadSettingExtension* const attachments = new PadSettingExtension( parent, (ControllerEmu::Extension*)group );
|
|
wxButton* const configure = new ExtensionButton( parent, (ControllerEmu::Extension*)group );
|
|
|
|
options.push_back( attachments );
|
|
|
|
_connect_macro_( attachments, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
|
_connect_macro_( configure, GamepadPage::ConfigExtension, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
|
|
|
Add( attachments, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND, 5 );
|
|
Add( configure, 0, wxALL|wxEXPAND, 5 );
|
|
}
|
|
break;
|
|
default :
|
|
{
|
|
//options
|
|
|
|
std::vector<ControllerEmu::ControlGroup::Setting*>::const_iterator
|
|
i = group->settings.begin(),
|
|
e = group->settings.end();
|
|
for ( ; i!=e; ++i )
|
|
{
|
|
PadSettingCheckBox* setting_cbox = new PadSettingCheckBox( parent, (*i)->value, (*i)->name );
|
|
_connect_macro_( setting_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHECKBOX_CLICKED, eventsink );
|
|
options.push_back( setting_cbox );
|
|
|
|
Add( setting_cbox, 0, wxALL|wxLEFT, 5 );
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
//AddStretchSpacer( 0 );
|
|
}
|
|
|
|
ControlGroupsSizer::ControlGroupsSizer( ControllerEmu* const controller, wxWindow* const parent, wxWindow* const eventsink, std::vector<ControlGroupBox*>* groups )
|
|
: wxBoxSizer( wxHORIZONTAL )
|
|
{
|
|
|
|
wxBoxSizer* stacked_groups = NULL;
|
|
for ( unsigned int i = 0; i < controller->groups.size(); ++i )
|
|
{
|
|
ControlGroupBox* control_group = new ControlGroupBox( controller->groups[i], parent, eventsink );
|
|
|
|
if ( control_group->control_buttons.size() > 1 )
|
|
{
|
|
if ( stacked_groups )
|
|
Add( stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5 );
|
|
|
|
stacked_groups = new wxBoxSizer( wxVERTICAL );
|
|
stacked_groups->Add( control_group, 0, wxEXPAND );
|
|
}
|
|
else
|
|
stacked_groups->Add( control_group, 0, wxEXPAND );
|
|
|
|
if ( groups )
|
|
groups->push_back( control_group );
|
|
}
|
|
|
|
if ( stacked_groups )
|
|
Add( stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5 );
|
|
|
|
}
|
|
|
|
GamepadPage::GamepadPage( wxWindow* parent, Plugin& plugin, const unsigned int pad_num, ConfigDialog* const config_dialog )
|
|
: wxNotebookPage( parent, -1 , wxDefaultPosition, wxDefaultSize )
|
|
,controller(plugin.controllers[pad_num])
|
|
,m_plugin(plugin)
|
|
,m_config_dialog(config_dialog)
|
|
{
|
|
|
|
wxBoxSizer* control_group_sizer = new ControlGroupsSizer( m_plugin.controllers[pad_num], this, this, &control_groups );
|
|
|
|
wxStaticBoxSizer* profile_sbox = new wxStaticBoxSizer( wxHORIZONTAL, this, wxT("Profile") );
|
|
|
|
// device chooser
|
|
|
|
wxStaticBoxSizer* device_sbox = new wxStaticBoxSizer( wxHORIZONTAL, this, wxT("Device") );
|
|
|
|
device_cbox = new wxComboBox( this, -1, wxT(""), wxDefaultPosition, wxSize(128,-1), 0, 0, wxTE_PROCESS_ENTER );
|
|
|
|
wxButton* refresh_button = new wxButton( this, -1, wxT("Refresh"), wxDefaultPosition, wxSize(60,-1) );
|
|
|
|
//#define _connect_macro3_( b, f, c ) (b)->Connect( wxID_ANY, c, wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)this );
|
|
|
|
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_COMBOBOX_SELECTED, this );
|
|
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_TEXT_ENTER, this );
|
|
_connect_macro_( refresh_button, GamepadPage::RefreshDevices, wxEVT_COMMAND_BUTTON_CLICKED, this );
|
|
|
|
device_sbox->Add( device_cbox, 1, wxLEFT|wxRIGHT, 5 );
|
|
device_sbox->Add( refresh_button, 0, wxRIGHT|wxBOTTOM, 5 );
|
|
|
|
wxStaticBoxSizer* clear_sbox = new wxStaticBoxSizer( wxHORIZONTAL, this, wxT("Clear") );
|
|
wxButton* all_button = new wxButton( this, -1, wxT("All"), wxDefaultPosition, wxSize(48,-1) );
|
|
clear_sbox->Add( all_button, 1, wxLEFT|wxRIGHT, 5 );
|
|
|
|
all_button->Connect( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GamepadPage::ClearAll ),
|
|
(wxObject*)0, (wxEvtHandler*)this );
|
|
|
|
profile_cbox = new wxComboBox( this, -1, wxT(""), wxDefaultPosition, wxSize(128,-1) );
|
|
|
|
wxButton* const pload_btn = new wxButton( this, -1, wxT("Load"), wxDefaultPosition, wxSize(48,-1) );
|
|
wxButton* const psave_btn = new wxButton( this, -1, wxT("Save"), wxDefaultPosition, wxSize(48,-1) );
|
|
wxButton* const pdelete_btn = new wxButton( this, -1, wxT("Delete"), wxDefaultPosition, wxSize(60,-1) );
|
|
|
|
pload_btn->Connect( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GamepadPage::LoadProfile ),
|
|
(wxObject*)0, (wxEvtHandler*)this );
|
|
psave_btn->Connect( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GamepadPage::SaveProfile ),
|
|
(wxObject*)0, (wxEvtHandler*)this );
|
|
pdelete_btn->Connect( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GamepadPage::DeleteProfile ),
|
|
(wxObject*)0, (wxEvtHandler*)this );
|
|
|
|
profile_sbox->Add( profile_cbox, 1, wxLEFT, 5 );
|
|
profile_sbox->Add( pload_btn, 0, wxLEFT, 5 );
|
|
profile_sbox->Add( psave_btn, 0, 0, 5 );
|
|
profile_sbox->Add( pdelete_btn, 0, wxRIGHT|wxBOTTOM, 5 );
|
|
|
|
wxBoxSizer* dio = new wxBoxSizer( wxHORIZONTAL );
|
|
dio->Add( device_sbox, 1, wxEXPAND|wxRIGHT, 5 );
|
|
dio->Add( clear_sbox, 0, wxEXPAND|wxRIGHT, 5 );
|
|
dio->Add( profile_sbox, 1, wxEXPAND|wxRIGHT, 5 );
|
|
|
|
wxBoxSizer* mapping = new wxBoxSizer( wxVERTICAL );
|
|
|
|
mapping->Add( dio, 1, wxEXPAND|wxLEFT|wxTOP|wxBOTTOM, 5 );
|
|
mapping->Add( control_group_sizer, 0, wxLEFT|wxEXPAND, 5 );
|
|
|
|
UpdateGUI();
|
|
|
|
SetSizerAndFit( mapping );
|
|
Layout();
|
|
};
|
|
|
|
ConfigDialog::~ConfigDialog()
|
|
{
|
|
m_update_timer->Stop();
|
|
}
|
|
|
|
ConfigDialog::ConfigDialog( wxWindow* const parent, Plugin& plugin, const std::string& name, const bool _is_game_running )
|
|
: wxDialog( parent, wxID_ANY, wxString::FromAscii(name.c_str()), wxPoint(128,-1), wxDefaultSize )
|
|
, is_game_running(_is_game_running)
|
|
, m_plugin(plugin)
|
|
{
|
|
m_pad_notebook = new wxNotebook( this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT );
|
|
for ( unsigned int i = 0; i < plugin.controllers.size(); ++i )
|
|
{
|
|
GamepadPage* gp = new GamepadPage( m_pad_notebook, plugin, i, this );
|
|
m_padpages.push_back( gp );
|
|
m_pad_notebook->AddPage( gp, wxString::FromAscii( m_plugin.gui_name ) + wxT(' ') + wxChar('1'+i) );
|
|
}
|
|
|
|
UpdateDeviceComboBox();
|
|
UpdateProfileComboBox();
|
|
|
|
wxButton* close_button = new wxButton( this, -1, wxT("Save"));
|
|
|
|
close_button->Connect( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigDialog::ClickSave ), (wxObject*)0, (wxEvtHandler*)this );
|
|
|
|
wxBoxSizer* btns = new wxBoxSizer( wxHORIZONTAL );
|
|
//btns->Add( new wxStaticText( this, -1, wxString::FromAscii(ver.c_str())), 0, wxLEFT|wxTOP, 5 );
|
|
btns->AddStretchSpacer();
|
|
btns->Add( close_button, 0, 0, 0 );
|
|
|
|
wxBoxSizer* szr = new wxBoxSizer( wxVERTICAL );
|
|
szr->Add( m_pad_notebook, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
|
|
szr->Add( btns, 0, wxEXPAND|wxALL, 5 );
|
|
|
|
SetSizerAndFit( szr );
|
|
// not needed here it seems, but it cant hurt
|
|
//Layout();
|
|
|
|
Center();
|
|
|
|
// live preview update timer
|
|
m_update_timer = new wxTimer( this, -1 );
|
|
Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( ConfigDialog::UpdateBitmaps ), (wxObject*)0, this );
|
|
m_update_timer->Start( PREVIEW_UPDATE_TIME, wxTIMER_CONTINUOUS);
|
|
|
|
|
|
}
|