| File: | Source/Core/DolphinWX/Src/InputConfigDiag.cpp |
| Location: | line 242, column 43 |
| Description: | Value stored to 'r' during its initialization is never read |
| 1 | // Copyright 2013 Dolphin Emulator Project |
| 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. |
| 4 | |
| 5 | #include "InputConfigDiag.h" |
| 6 | #include "UDPConfigDiag.h" |
| 7 | #include "WxUtils.h" |
| 8 | #include "HW/Wiimote.h" |
| 9 | |
| 10 | void GamepadPage::ConfigUDPWii(wxCommandEvent &event) |
| 11 | { |
| 12 | UDPWrapper* const wrp = ((UDPConfigButton*)event.GetEventObject())->wrapper; |
| 13 | UDPConfigDiag diag(this, wrp); |
| 14 | diag.ShowModal(); |
| 15 | } |
| 16 | |
| 17 | void GamepadPage::ConfigExtension(wxCommandEvent& event) |
| 18 | { |
| 19 | ControllerEmu::Extension* const ex = ((ExtensionButton*)event.GetEventObject())->extension; |
| 20 | |
| 21 | // show config diag, if "none" isn't selected |
| 22 | if (ex->switch_extension) |
| 23 | { |
| 24 | wxDialog dlg(this, -1, |
| 25 | wxGetTranslation(StrToWxStr(ex->attachments[ex->switch_extension]->GetName())), |
| 26 | wxDefaultPosition, wxDefaultSize); |
| 27 | |
| 28 | wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); |
| 29 | const std::size_t orig_size = control_groups.size(); |
| 30 | |
| 31 | ControlGroupsSizer* const szr = |
| 32 | new ControlGroupsSizer(ex->attachments[ex->switch_extension], &dlg, this, &control_groups); |
| 33 | main_szr->Add(szr, 0, wxLEFT, 5); |
| 34 | main_szr->Add(dlg.CreateButtonSizer(wxOK0x00000004), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); |
| 35 | dlg.SetSizerAndFit(main_szr); |
| 36 | dlg.Center(); |
| 37 | |
| 38 | dlg.ShowModal(); |
| 39 | |
| 40 | // remove the new groups that were just added, now that the window closed |
| 41 | control_groups.resize(orig_size); |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | PadSettingExtension::PadSettingExtension(wxWindow* const parent, ControllerEmu::Extension* const ext) |
| 46 | : PadSetting(new wxChoice(parent, -1)) |
| 47 | , extension(ext) |
| 48 | { |
| 49 | |
| 50 | std::vector<ControllerEmu*>::const_iterator |
| 51 | i = extension->attachments.begin(), |
| 52 | e = extension->attachments.end(); |
| 53 | |
| 54 | for (; i!=e; ++i) |
| 55 | ((wxChoice*)wxcontrol)->Append(wxGetTranslation(StrToWxStr((*i)->GetName()))); |
| 56 | |
| 57 | UpdateGUI(); |
| 58 | } |
| 59 | |
| 60 | void PadSettingExtension::UpdateGUI() |
| 61 | { |
| 62 | ((wxChoice*)wxcontrol)->Select(extension->switch_extension); |
| 63 | } |
| 64 | |
| 65 | void PadSettingExtension::UpdateValue() |
| 66 | { |
| 67 | extension->switch_extension = ((wxChoice*)wxcontrol)->GetSelection(); |
| 68 | } |
| 69 | |
| 70 | PadSettingCheckBox::PadSettingCheckBox(wxWindow* const parent, ControlState& _value, const char* const label) |
| 71 | : PadSetting(new wxCheckBox(parent, -1, wxGetTranslation(StrToWxStr(label)), wxDefaultPosition)) |
| 72 | , value(_value) |
| 73 | { |
| 74 | UpdateGUI(); |
| 75 | } |
| 76 | |
| 77 | void PadSettingCheckBox::UpdateGUI() |
| 78 | { |
| 79 | ((wxCheckBox*)wxcontrol)->SetValue(value > 0); |
| 80 | } |
| 81 | |
| 82 | void PadSettingCheckBox::UpdateValue() |
| 83 | { |
| 84 | // 0.01 so its saved to the ini file as just 1. :( |
| 85 | value = 0.01 * ((wxCheckBox*)wxcontrol)->GetValue(); |
| 86 | } |
| 87 | |
| 88 | void PadSettingSpin::UpdateGUI() |
| 89 | { |
| 90 | ((wxSpinCtrl*)wxcontrol)->SetValue((int)(value * 100)); |
| 91 | } |
| 92 | |
| 93 | void PadSettingSpin::UpdateValue() |
| 94 | { |
| 95 | value = float(((wxSpinCtrl*)wxcontrol)->GetValue()) / 100; |
| 96 | } |
| 97 | |
| 98 | ControlDialog::ControlDialog(GamepadPage* const parent, InputPlugin& plugin, ControllerInterface::ControlReference* const ref) |
| 99 | : wxDialog(parent, -1, _("Configure Control")wxGetTranslation(("Configure Control")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE(0x20000000 | 0x0800 | 0x1000) | wxRESIZE_BORDER0x0040) |
| 100 | , control_reference(ref) |
| 101 | , m_plugin(plugin) |
| 102 | , m_parent(parent) |
| 103 | { |
| 104 | m_devq = m_parent->controller->default_device; |
| 105 | |
| 106 | // GetStrings() sounds slow :/ |
| 107 | //device_cbox = new wxComboBox(this, -1, StrToWxStr(ref->device_qualifier.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER); |
| 108 | device_cbox = new wxComboBox(this, -1, StrToWxStr(m_devq.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER0x0400); |
| 109 | |
| 110 | device_cbox->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &ControlDialog::SetDevice, this); |
| 111 | device_cbox->Bind(wxEVT_COMMAND_TEXT_ENTER, &ControlDialog::SetDevice, this); |
| 112 | |
| 113 | wxStaticBoxSizer* const control_chooser = CreateControlChooser(parent); |
| 114 | |
| 115 | wxStaticBoxSizer* const d_szr = new wxStaticBoxSizer(wxVERTICAL, this, _("Device")wxGetTranslation(("Device"))); |
| 116 | d_szr->Add(device_cbox, 0, wxEXPAND|wxALL, 5); |
| 117 | |
| 118 | wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL); |
| 119 | szr->Add(d_szr, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5); |
| 120 | szr->Add(control_chooser, 1, wxEXPAND|wxALL, 5); |
| 121 | |
| 122 | SetSizerAndFit(szr); // needed |
| 123 | |
| 124 | UpdateGUI(); |
| 125 | SetFocus(); |
| 126 | } |
| 127 | |
| 128 | ControlButton::ControlButton(wxWindow* const parent, ControllerInterface::ControlReference* const _ref, const unsigned int width, const std::string& label) |
| 129 | : wxButton(parent, -1, wxT("")L"", wxDefaultPosition, wxSize(width,20)) |
| 130 | , control_reference(_ref) |
| 131 | { |
| 132 | if (label.empty()) |
| 133 | SetLabel(StrToWxStr(_ref->expression)); |
| 134 | else |
| 135 | SetLabel(StrToWxStr(label)); |
| 136 | } |
| 137 | |
| 138 | void InputConfigDialog::UpdateProfileComboBox() |
| 139 | { |
| 140 | std::string pname(File::GetUserPath(D_CONFIG_IDX)); |
| 141 | pname += PROFILES_PATH"Profiles/"; |
| 142 | pname += m_plugin.profile_name; |
| 143 | |
| 144 | CFileSearch::XStringVector exts; |
| 145 | exts.push_back("*.ini"); |
| 146 | CFileSearch::XStringVector dirs; |
| 147 | dirs.push_back(pname); |
| 148 | CFileSearch cfs(exts, dirs); |
| 149 | const CFileSearch::XStringVector& sv = cfs.GetFileNames(); |
| 150 | |
| 151 | wxArrayString strs; |
| 152 | CFileSearch::XStringVector::const_iterator si = sv.begin(), |
| 153 | se = sv.end(); |
| 154 | for (; si!=se; ++si) |
| 155 | { |
| 156 | std::string str(si->begin() + si->find_last_of('/') + 1 , si->end() - 4) ; |
| 157 | strs.push_back(StrToWxStr(str)); |
| 158 | } |
| 159 | |
| 160 | std::vector< GamepadPage* >::iterator i = m_padpages.begin(), |
| 161 | e = m_padpages.end(); |
| 162 | for (; i != e; ++i) |
| 163 | { |
| 164 | (*i)->profile_cbox->Clear(); |
| 165 | (*i)->profile_cbox->Append(strs); |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | void InputConfigDialog::UpdateControlReferences() |
| 170 | { |
| 171 | std::vector< GamepadPage* >::iterator i = m_padpages.begin(), |
| 172 | e = m_padpages.end(); |
| 173 | for (; i != e; ++i) |
| 174 | (*i)->controller->UpdateReferences(g_controller_interface); |
| 175 | } |
| 176 | |
| 177 | void InputConfigDialog::ClickSave(wxCommandEvent& event) |
| 178 | { |
| 179 | m_plugin.SaveConfig(); |
| 180 | event.Skip(); |
| 181 | } |
| 182 | |
| 183 | void ControlDialog::UpdateListContents() |
| 184 | { |
| 185 | control_lbox->Clear(); |
| 186 | |
| 187 | Device* const dev = g_controller_interface.FindDevice(m_devq); |
| 188 | if (dev) |
| 189 | { |
| 190 | if (control_reference->is_input) |
| 191 | { |
| 192 | // for inputs |
| 193 | std::vector<Device::Input*>::const_iterator |
| 194 | i = dev->Inputs().begin(), |
| 195 | e = dev->Inputs().end(); |
| 196 | for (; i!=e; ++i) |
| 197 | control_lbox->Append(StrToWxStr((*i)->GetName())); |
| 198 | } |
| 199 | else |
| 200 | { |
| 201 | // for outputs |
| 202 | std::vector<Device::Output*>::const_iterator |
| 203 | i = dev->Outputs().begin(), |
| 204 | e = dev->Outputs().end(); |
| 205 | for (; i!=e; ++i) |
| 206 | control_lbox->Append(StrToWxStr((*i)->GetName())); |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | void ControlDialog::SelectControl(const std::string& name) |
| 212 | { |
| 213 | //UpdateGUI(); |
| 214 | |
| 215 | const int f = control_lbox->FindString(StrToWxStr(name)); |
| 216 | if (f >= 0) |
| 217 | control_lbox->Select(f); |
| 218 | } |
| 219 | |
| 220 | void ControlDialog::UpdateGUI() |
| 221 | { |
| 222 | // update textbox |
| 223 | textctrl->SetValue(StrToWxStr(control_reference->expression)); |
| 224 | |
| 225 | // updates the "bound controls:" label |
| 226 | m_bound_label->SetLabel(wxString::Format(_("Bound Controls: %lu")wxGetTranslation(("Bound Controls: %lu")), |
| 227 | (unsigned long)control_reference->BoundCount())); |
| 228 | }; |
| 229 | |
| 230 | void GamepadPage::UpdateGUI() |
| 231 | { |
| 232 | device_cbox->SetValue(StrToWxStr(controller->default_device.ToString())); |
| 233 | |
| 234 | std::vector< ControlGroupBox* >::const_iterator g = control_groups.begin(), |
| 235 | ge = control_groups.end(); |
| 236 | for (; g!=ge; ++g) |
| 237 | { |
| 238 | // buttons |
| 239 | std::vector<ControlButton*>::const_iterator i = (*g)->control_buttons.begin() |
| 240 | , e = (*g)->control_buttons.end(); |
| 241 | for (; i!=e; ++i) { |
| 242 | ControllerInterface::ControlReference *r = (*i)->control_reference; |
Value stored to 'r' during its initialization is never read | |
| 243 | wxString expr = StrToWxStr((*i)->control_reference->expression); |
| 244 | expr.Replace("&", "&&"); |
| 245 | (*i)->SetLabel(expr); |
| 246 | } |
| 247 | |
| 248 | // cboxes |
| 249 | std::vector<PadSetting*>::const_iterator si = (*g)->options.begin() |
| 250 | , se = (*g)->options.end(); |
| 251 | for (; si!=se; ++si) |
| 252 | (*si)->UpdateGUI(); |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | void GamepadPage::ClearAll(wxCommandEvent&) |
| 257 | { |
| 258 | // just load an empty ini section to clear everything :P |
| 259 | IniFile::Section section; |
| 260 | controller->LoadConfig(§ion); |
| 261 | |
| 262 | // no point in using the real ControllerInterface i guess |
| 263 | ControllerInterface face; |
| 264 | |
| 265 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 266 | controller->UpdateReferences(face); |
| 267 | |
| 268 | UpdateGUI(); |
| 269 | } |
| 270 | |
| 271 | void GamepadPage::LoadDefaults(wxCommandEvent&) |
| 272 | { |
| 273 | controller->LoadDefaults(g_controller_interface); |
| 274 | |
| 275 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 276 | controller->UpdateReferences(g_controller_interface); |
| 277 | |
| 278 | UpdateGUI(); |
| 279 | } |
| 280 | |
| 281 | void ControlDialog::SetControl(wxCommandEvent&) |
| 282 | { |
| 283 | control_reference->expression = WxStrToStr(textctrl->GetValue()); |
| 284 | |
| 285 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 286 | g_controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); |
| 287 | |
| 288 | UpdateGUI(); |
| 289 | } |
| 290 | |
| 291 | void GamepadPage::SetDevice(wxCommandEvent&) |
| 292 | { |
| 293 | controller->default_device.FromString(WxStrToStr(device_cbox->GetValue())); |
| 294 | |
| 295 | // show user what it was validated as |
| 296 | device_cbox->SetValue(StrToWxStr(controller->default_device.ToString())); |
| 297 | |
| 298 | // this will set all the controls to this default device |
| 299 | controller->UpdateDefaultDevice(); |
| 300 | |
| 301 | // update references |
| 302 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 303 | controller->UpdateReferences(g_controller_interface); |
| 304 | } |
| 305 | |
| 306 | void ControlDialog::SetDevice(wxCommandEvent&) |
| 307 | { |
| 308 | m_devq.FromString(WxStrToStr(device_cbox->GetValue())); |
| 309 | |
| 310 | // show user what it was validated as |
| 311 | device_cbox->SetValue(StrToWxStr(m_devq.ToString())); |
| 312 | |
| 313 | // update gui |
| 314 | UpdateListContents(); |
| 315 | } |
| 316 | |
| 317 | void ControlDialog::ClearControl(wxCommandEvent&) |
| 318 | { |
| 319 | control_reference->expression.clear(); |
| 320 | |
| 321 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 322 | g_controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); |
| 323 | |
| 324 | UpdateGUI(); |
| 325 | } |
| 326 | |
| 327 | inline bool IsAlphabetic(wxString &str) |
| 328 | { |
| 329 | for (wxString::const_iterator it = str.begin(); it != str.end(); ++it) |
| 330 | if (!isalpha(*it)) |
| 331 | return false; |
| 332 | return true; |
| 333 | } |
| 334 | |
| 335 | inline void GetExpressionForControl(wxString &expr, |
| 336 | wxString &control_name, |
| 337 | DeviceQualifier *control_device = NULL__null, |
| 338 | DeviceQualifier *default_device = NULL__null) |
| 339 | { |
| 340 | expr = ""; |
| 341 | |
| 342 | // non-default device |
| 343 | if (control_device && default_device && !(*control_device == *default_device)) |
| 344 | { |
| 345 | expr += control_device->ToString(); |
| 346 | expr += ":"; |
| 347 | } |
| 348 | |
| 349 | // append the control name |
| 350 | expr += control_name; |
| 351 | |
| 352 | if (!IsAlphabetic(expr)) |
| 353 | expr = wxString::Format("`%s`", expr); |
| 354 | } |
| 355 | |
| 356 | bool ControlDialog::GetExpressionForSelectedControl(wxString &expr) |
| 357 | { |
| 358 | const int num = control_lbox->GetSelection(); |
| 359 | |
| 360 | if (num < 0) |
| 361 | return false; |
| 362 | |
| 363 | wxString control_name = control_lbox->GetString(num); |
| 364 | GetExpressionForControl(expr, |
| 365 | control_name, |
| 366 | &m_devq, |
| 367 | &m_parent->controller->default_device); |
| 368 | |
| 369 | return true; |
| 370 | } |
| 371 | |
| 372 | void ControlDialog::SetSelectedControl(wxCommandEvent&) |
| 373 | { |
| 374 | wxString expr; |
| 375 | |
| 376 | if (!GetExpressionForSelectedControl(expr)) |
| 377 | return; |
| 378 | |
| 379 | textctrl->WriteText(expr); |
| 380 | control_reference->expression = textctrl->GetValue(); |
| 381 | |
| 382 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 383 | g_controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); |
| 384 | |
| 385 | UpdateGUI(); |
| 386 | } |
| 387 | |
| 388 | void ControlDialog::AppendControl(wxCommandEvent& event) |
| 389 | { |
| 390 | wxString device_expr, expr; |
| 391 | |
| 392 | const wxString lbl = ((wxButton*)event.GetEventObject())->GetLabel(); |
| 393 | char op = lbl[0]; |
| 394 | |
| 395 | if (!GetExpressionForSelectedControl(device_expr)) |
| 396 | return; |
| 397 | |
| 398 | // Unary ops (that is, '!') are a special case. When there's a selection, |
| 399 | // put parens around it and prepend it with a '!', but when there's nothing, |
| 400 | // just add a '!device'. |
| 401 | if (op == '!') |
| 402 | { |
| 403 | wxString selection = textctrl->GetStringSelection(); |
| 404 | if (selection == "") |
| 405 | expr = wxString::Format("%c%s", op, device_expr); |
| 406 | else |
| 407 | expr = wxString::Format("%c(%s)", op, selection); |
| 408 | } |
| 409 | else |
| 410 | expr = wxString::Format(" %c %s", op, device_expr); |
| 411 | |
| 412 | textctrl->WriteText(expr); |
| 413 | control_reference->expression = textctrl->GetValue(); |
| 414 | |
| 415 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 416 | g_controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); |
| 417 | |
| 418 | UpdateGUI(); |
| 419 | } |
| 420 | |
| 421 | void GamepadPage::AdjustSetting(wxCommandEvent& event) |
| 422 | { |
| 423 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 424 | ((PadSetting*)((wxControl*)event.GetEventObject())->GetClientData())->UpdateValue(); |
| 425 | } |
| 426 | |
| 427 | void GamepadPage::AdjustControlOption(wxCommandEvent&) |
| 428 | { |
| 429 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 430 | m_control_dialog->control_reference->range = (ControlState)(m_control_dialog->range_slider->GetValue()) / SLIDER_TICK_COUNT100; |
| 431 | } |
| 432 | |
| 433 | void GamepadPage::ConfigControl(wxEvent& event) |
| 434 | { |
| 435 | m_control_dialog = new ControlDialog(this, m_plugin, ((ControlButton*)event.GetEventObject())->control_reference); |
| 436 | m_control_dialog->ShowModal(); |
| 437 | m_control_dialog->Destroy(); |
| 438 | |
| 439 | // update changes that were made in the dialog |
| 440 | UpdateGUI(); |
| 441 | } |
| 442 | |
| 443 | void GamepadPage::ClearControl(wxEvent& event) |
| 444 | { |
| 445 | ControlButton* const btn = (ControlButton*)event.GetEventObject(); |
| 446 | btn->control_reference->expression.clear(); |
| 447 | btn->control_reference->range = 1.0f; |
| 448 | |
| 449 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 450 | controller->UpdateReferences(g_controller_interface); |
| 451 | |
| 452 | // update changes |
| 453 | UpdateGUI(); |
| 454 | } |
| 455 | |
| 456 | void ControlDialog::DetectControl(wxCommandEvent& event) |
| 457 | { |
| 458 | wxButton* const btn = (wxButton*)event.GetEventObject(); |
| 459 | const wxString lbl = btn->GetLabel(); |
| 460 | |
| 461 | Device* const dev = g_controller_interface.FindDevice(m_devq); |
| 462 | if (dev) |
| 463 | { |
| 464 | btn->SetLabel(_("[ waiting ]")wxGetTranslation(("[ waiting ]"))); |
| 465 | |
| 466 | // apparently, this makes the "waiting" text work on Linux |
| 467 | wxTheAppstatic_cast<wxApp*>(wxApp::GetInstance())->Yield(); |
| 468 | |
| 469 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 470 | Device::Control* const ctrl = control_reference->Detect(DETECT_WAIT_TIME1500, dev); |
| 471 | |
| 472 | // if we got input, select it in the list |
| 473 | if (ctrl) |
| 474 | SelectControl(ctrl->GetName()); |
| 475 | |
| 476 | btn->SetLabel(lbl); |
| 477 | } |
| 478 | } |
| 479 | |
| 480 | void GamepadPage::DetectControl(wxCommandEvent& event) |
| 481 | { |
| 482 | ControlButton* btn = (ControlButton*)event.GetEventObject(); |
| 483 | |
| 484 | // find device :/ |
| 485 | Device* const dev = g_controller_interface.FindDevice(controller->default_device); |
| 486 | if (dev) |
| 487 | { |
| 488 | btn->SetLabel(_("[ waiting ]")wxGetTranslation(("[ waiting ]"))); |
| 489 | |
| 490 | // apparently, this makes the "waiting" text work on Linux |
| 491 | wxTheAppstatic_cast<wxApp*>(wxApp::GetInstance())->Yield(); |
| 492 | |
| 493 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 494 | Device::Control* const ctrl = btn->control_reference->Detect(DETECT_WAIT_TIME1500, dev); |
| 495 | |
| 496 | // if we got input, update expression and reference |
| 497 | if (ctrl) |
| 498 | { |
| 499 | wxString control_name = ctrl->GetName(); |
| 500 | wxString expr; |
| 501 | GetExpressionForControl(expr, control_name); |
| 502 | btn->control_reference->expression = expr; |
| 503 | g_controller_interface.UpdateReference(btn->control_reference, controller->default_device); |
| 504 | } |
| 505 | } |
| 506 | |
| 507 | UpdateGUI(); |
| 508 | } |
| 509 | |
| 510 | wxStaticBoxSizer* ControlDialog::CreateControlChooser(GamepadPage* const parent) |
| 511 | { |
| 512 | wxStaticBoxSizer* const main_szr = new wxStaticBoxSizer(wxVERTICAL, this, control_reference->is_input ? _("Input")wxGetTranslation(("Input")) : _("Output")wxGetTranslation(("Output"))); |
| 513 | |
| 514 | textctrl = new wxTextCtrl(this, -1, wxEmptyString, wxDefaultPosition, wxSize(-1, 48), wxTE_MULTILINE0x0020 | wxTE_RICH20x8000); |
| 515 | wxFont font = textctrl->GetFont(); |
| 516 | font.SetFamily(wxFONTFAMILY_MODERN); |
| 517 | textctrl->SetFont(font); |
| 518 | |
| 519 | wxButton* const detect_button = new wxButton(this, -1, control_reference->is_input ? _("Detect")wxGetTranslation(("Detect")) : _("Test")wxGetTranslation(("Test"))); |
| 520 | |
| 521 | wxButton* const clear_button = new wxButton(this, -1, _("Clear")wxGetTranslation(("Clear"))); |
| 522 | wxButton* const set_button = new wxButton(this, -1, _("Set")wxGetTranslation(("Set"))); |
| 523 | |
| 524 | wxButton* const select_button = new wxButton(this, -1, _("Select")wxGetTranslation(("Select"))); |
| 525 | select_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::SetSelectedControl, this); |
| 526 | |
| 527 | wxButton* const not_button = new wxButton(this, -1, _("! NOT")wxGetTranslation(("! NOT")), wxDefaultPosition); |
| 528 | not_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::AppendControl, this); |
| 529 | |
| 530 | wxButton* const or_button = new wxButton(this, -1, _("| OR")wxGetTranslation(("| OR")), wxDefaultPosition); |
| 531 | or_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::AppendControl, this); |
| 532 | |
| 533 | control_lbox = new wxListBox(this, -1, wxDefaultPosition, wxSize(-1, 64)); |
| 534 | |
| 535 | wxBoxSizer* const button_sizer = new wxBoxSizer(wxVERTICAL); |
| 536 | button_sizer->Add(detect_button, 1, 0, 5); |
| 537 | button_sizer->Add(select_button, 1, 0, 5); |
| 538 | button_sizer->Add(or_button, 1, 0, 5); |
| 539 | |
| 540 | if (control_reference->is_input) |
| 541 | { |
| 542 | // TODO: check if && is good on other OS |
| 543 | wxButton* const and_button = new wxButton(this, -1, _("&& AND")wxGetTranslation(("&& AND")), wxDefaultPosition); |
| 544 | wxButton* const add_button = new wxButton(this, -1, _("+ ADD")wxGetTranslation(("+ ADD")), wxDefaultPosition); |
| 545 | |
| 546 | and_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::AppendControl, this); |
| 547 | add_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::AppendControl, this); |
| 548 | |
| 549 | button_sizer->Add(and_button, 1, 0, 5); |
| 550 | button_sizer->Add(not_button, 1, 0, 5); |
| 551 | button_sizer->Add(add_button, 1, 0, 5); |
| 552 | } |
| 553 | |
| 554 | range_slider = new wxSlider(this, -1, SLIDER_TICK_COUNT100, -SLIDER_TICK_COUNT100 * 5, SLIDER_TICK_COUNT100 * 5, wxDefaultPosition, wxDefaultSize, wxSL_TOP0x0080 | wxSL_LABELS(0x2000|0x4000) /*| wxSL_AUTOTICKS*/); |
| 555 | |
| 556 | range_slider->SetValue((int)(control_reference->range * SLIDER_TICK_COUNT100)); |
| 557 | |
| 558 | detect_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::DetectControl, this); |
| 559 | clear_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::ClearControl, this); |
| 560 | set_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ControlDialog::SetControl, this); |
| 561 | |
| 562 | range_slider->Bind(wxEVT_SCROLL_CHANGED, &GamepadPage::AdjustControlOption, parent); |
| 563 | wxStaticText* const range_label = new wxStaticText(this, -1, _("Range")wxGetTranslation(("Range"))); |
| 564 | m_bound_label = new wxStaticText(this, -1, wxT("")L""); |
| 565 | |
| 566 | wxBoxSizer* const range_sizer = new wxBoxSizer(wxHORIZONTAL); |
| 567 | range_sizer->Add(range_label, 0, wxCENTER|wxLEFT, 5); |
| 568 | range_sizer->Add(range_slider, 1, wxEXPAND|wxLEFT, 5); |
| 569 | |
| 570 | wxBoxSizer* const ctrls_sizer = new wxBoxSizer(wxHORIZONTAL); |
| 571 | ctrls_sizer->Add(control_lbox, 1, wxEXPAND, 0); |
| 572 | ctrls_sizer->Add(button_sizer, 0, wxEXPAND, 0); |
| 573 | |
| 574 | wxSizer* const bottom_btns_sizer = CreateButtonSizer(wxOK0x00000004); |
| 575 | bottom_btns_sizer->Prepend(set_button, 0, wxRIGHT, 5); |
| 576 | bottom_btns_sizer->Prepend(clear_button, 0, wxLEFT, 5); |
| 577 | |
| 578 | main_szr->Add(range_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 5); |
| 579 | main_szr->Add(ctrls_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 5); |
| 580 | main_szr->Add(textctrl, 1, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 5); |
| 581 | main_szr->Add(bottom_btns_sizer, 0, wxEXPAND|wxBOTTOM|wxRIGHT, 5); |
| 582 | main_szr->Add(m_bound_label, 0, wxCENTER, 0); |
| 583 | |
| 584 | UpdateListContents(); |
| 585 | |
| 586 | return main_szr; |
| 587 | } |
| 588 | |
| 589 | void GamepadPage::GetProfilePath(std::string& path) |
| 590 | { |
| 591 | const wxString& name = profile_cbox->GetValue(); |
| 592 | if (false == name.empty()) |
| 593 | { |
| 594 | // TODO: check for dumb characters maybe |
| 595 | |
| 596 | path = File::GetUserPath(D_CONFIG_IDX); |
| 597 | path += PROFILES_PATH"Profiles/"; |
| 598 | path += m_plugin.profile_name; |
| 599 | path += '/'; |
| 600 | path += WxStrToStr(profile_cbox->GetValue()); |
| 601 | path += ".ini"; |
| 602 | } |
| 603 | } |
| 604 | |
| 605 | void GamepadPage::LoadProfile(wxCommandEvent&) |
| 606 | { |
| 607 | std::string fname; |
| 608 | GamepadPage::GetProfilePath(fname); |
| 609 | |
| 610 | if (false == File::Exists(fname)) |
| 611 | return; |
| 612 | |
| 613 | IniFile inifile; |
| 614 | inifile.Load(fname); |
| 615 | |
| 616 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 617 | controller->LoadConfig(inifile.GetOrCreateSection("Profile")); |
| 618 | controller->UpdateReferences(g_controller_interface); |
| 619 | |
| 620 | UpdateGUI(); |
| 621 | } |
| 622 | |
| 623 | void GamepadPage::SaveProfile(wxCommandEvent&) |
| 624 | { |
| 625 | std::string fname; |
| 626 | GamepadPage::GetProfilePath(fname); |
| 627 | File::CreateFullPath(fname); |
| 628 | |
| 629 | if (false == fname.empty()) |
| 630 | { |
| 631 | IniFile inifile; |
| 632 | controller->SaveConfig(inifile.GetOrCreateSection("Profile")); |
| 633 | inifile.Save(fname); |
| 634 | |
| 635 | m_config_dialog->UpdateProfileComboBox(); |
| 636 | } |
| 637 | else |
| 638 | { |
| 639 | PanicAlertT("You must enter a valid profile name.")MsgAlert(false, WARNING, "You must enter a valid profile name." ); |
| 640 | } |
| 641 | } |
| 642 | |
| 643 | void GamepadPage::DeleteProfile(wxCommandEvent&) |
| 644 | { |
| 645 | std::string fname; |
| 646 | GamepadPage::GetProfilePath(fname); |
| 647 | |
| 648 | const char* const fnamecstr = fname.c_str(); |
| 649 | |
| 650 | if (File::Exists(fnamecstr) && |
| 651 | AskYesNoT("Are you sure you want to delete \"%s\"?",MsgAlert(true, QUESTION, "Are you sure you want to delete \"%s\"?" , WxStrToStr(profile_cbox->GetValue()).c_str()) |
| 652 | WxStrToStr(profile_cbox->GetValue()).c_str())MsgAlert(true, QUESTION, "Are you sure you want to delete \"%s\"?" , WxStrToStr(profile_cbox->GetValue()).c_str())) |
| 653 | { |
| 654 | File::Delete(fnamecstr); |
| 655 | |
| 656 | m_config_dialog->UpdateProfileComboBox(); |
| 657 | } |
| 658 | } |
| 659 | |
| 660 | void InputConfigDialog::UpdateDeviceComboBox() |
| 661 | { |
| 662 | std::vector< GamepadPage* >::iterator i = m_padpages.begin(), |
| 663 | e = m_padpages.end(); |
| 664 | DeviceQualifier dq; |
| 665 | for (; i != e; ++i) |
| 666 | { |
| 667 | (*i)->device_cbox->Clear(); |
| 668 | std::vector<Device*>::const_iterator |
| 669 | di = g_controller_interface.Devices().begin(), |
| 670 | de = g_controller_interface.Devices().end(); |
| 671 | for (; di!=de; ++di) |
| 672 | { |
| 673 | dq.FromDevice(*di); |
| 674 | (*i)->device_cbox->Append(StrToWxStr(dq.ToString())); |
| 675 | } |
| 676 | (*i)->device_cbox->SetValue(StrToWxStr((*i)->controller->default_device.ToString())); |
| 677 | } |
| 678 | } |
| 679 | |
| 680 | void GamepadPage::RefreshDevices(wxCommandEvent&) |
| 681 | { |
| 682 | std::lock_guard<std::recursive_mutex> lk(m_plugin.controls_lock); |
| 683 | |
| 684 | // refresh devices |
| 685 | g_controller_interface.Shutdown(); |
| 686 | g_controller_interface.Initialize(); |
| 687 | |
| 688 | // update all control references |
| 689 | m_config_dialog->UpdateControlReferences(); |
| 690 | |
| 691 | // update device cbox |
| 692 | m_config_dialog->UpdateDeviceComboBox(); |
| 693 | } |
| 694 | |
| 695 | ControlGroupBox::~ControlGroupBox() |
| 696 | { |
| 697 | std::vector<PadSetting*>::const_iterator |
| 698 | i = options.begin(), |
| 699 | e = options.end(); |
| 700 | for (; i!=e; ++i) |
| 701 | delete *i; |
| 702 | } |
| 703 | |
| 704 | ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWindow* const parent, GamepadPage* const eventsink) |
| 705 | : wxBoxSizer(wxVERTICAL) |
| 706 | , control_group(group) |
| 707 | { |
| 708 | static_bitmap = NULL__null; |
| 709 | |
| 710 | wxFont m_SmallFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); |
| 711 | std::vector<ControllerEmu::ControlGroup::Control*>::iterator |
| 712 | ci = group->controls.begin(), |
| 713 | ce = group->controls.end(); |
| 714 | for (; ci != ce; ++ci) |
| 715 | { |
| 716 | |
| 717 | wxStaticText* const label = new wxStaticText(parent, -1, wxGetTranslation(StrToWxStr((*ci)->name))); |
| 718 | |
| 719 | ControlButton* const control_button = new ControlButton(parent, (*ci)->control_ref, 80); |
| 720 | control_button->SetFont(m_SmallFont); |
| 721 | |
| 722 | control_buttons.push_back(control_button); |
| 723 | |
| 724 | if ((*ci)->control_ref->is_input) |
| 725 | { |
| 726 | control_button->SetToolTip(_("Left-click to detect input.\nMiddle-click to clear.\nRight-click for more options.")wxGetTranslation(("Left-click to detect input.\nMiddle-click to clear.\nRight-click for more options." ))); |
| 727 | control_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::DetectControl, eventsink); |
| 728 | } |
| 729 | else |
| 730 | { |
| 731 | control_button->SetToolTip(_("Left/Right-click for more options.\nMiddle-click to clear.")wxGetTranslation(("Left/Right-click for more options.\nMiddle-click to clear." ))); |
| 732 | control_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::ConfigControl, eventsink); |
| 733 | } |
| 734 | |
| 735 | control_button->Bind(wxEVT_MIDDLE_DOWN, &GamepadPage::ClearControl, eventsink); |
| 736 | control_button->Bind(wxEVT_RIGHT_UP, &GamepadPage::ConfigControl, eventsink); |
| 737 | |
| 738 | wxBoxSizer* const control_sizer = new wxBoxSizer(wxHORIZONTAL); |
| 739 | control_sizer->AddStretchSpacer(1); |
| 740 | control_sizer->Add(label, 0, wxCENTER | wxRIGHT, 3); |
| 741 | control_sizer->Add(control_button, 0, 0, 0); |
| 742 | |
| 743 | Add(control_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 3); |
| 744 | |
| 745 | } |
| 746 | |
| 747 | wxMemoryDC dc; |
| 748 | |
| 749 | switch (group->type) |
| 750 | { |
| 751 | case GROUP_TYPE_STICK: |
| 752 | case GROUP_TYPE_TILT: |
| 753 | case GROUP_TYPE_CURSOR: |
| 754 | case GROUP_TYPE_FORCE: |
| 755 | { |
| 756 | wxBitmap bitmap(64, 64); |
| 757 | dc.SelectObject(bitmap); |
| 758 | dc.Clear(); |
| 759 | static_bitmap = new wxStaticBitmap(parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP); |
| 760 | |
| 761 | std::vector< ControllerEmu::ControlGroup::Setting* >::const_iterator |
| 762 | i = group->settings.begin(), |
| 763 | e = group->settings.end(); |
| 764 | |
| 765 | wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL); |
| 766 | for (; i!=e; ++i) |
| 767 | { |
| 768 | PadSettingSpin* setting = new PadSettingSpin(parent, *i); |
| 769 | setting->wxcontrol->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &GamepadPage::AdjustSetting, eventsink); |
| 770 | options.push_back(setting); |
| 771 | szr->Add(new wxStaticText(parent, -1, wxGetTranslation(StrToWxStr((*i)->name)))); |
| 772 | szr->Add(setting->wxcontrol, 0, wxLEFT, 0); |
| 773 | } |
| 774 | |
| 775 | wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL); |
| 776 | h_szr->Add(szr, 1, 0, 5); |
| 777 | h_szr->Add(static_bitmap, 0, wxALL|wxCENTER, 3); |
| 778 | |
| 779 | Add(h_szr, 0, wxEXPAND|wxLEFT|wxCENTER|wxTOP, 3); |
| 780 | } |
| 781 | break; |
| 782 | case GROUP_TYPE_BUTTONS: |
| 783 | { |
| 784 | wxBitmap bitmap(int(12*group->controls.size()+1), 12); |
| 785 | dc.SelectObject(bitmap); |
| 786 | dc.Clear(); |
| 787 | static_bitmap = new wxStaticBitmap(parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP); |
| 788 | |
| 789 | PadSettingSpin* const threshold_cbox = new PadSettingSpin(parent, group->settings[0]); |
| 790 | threshold_cbox->wxcontrol->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &GamepadPage::AdjustSetting, eventsink); |
| 791 | |
| 792 | threshold_cbox->wxcontrol->SetToolTip(_("Adjust the analog control pressure required to activate buttons.")wxGetTranslation(("Adjust the analog control pressure required to activate buttons." ))); |
| 793 | |
| 794 | options.push_back(threshold_cbox); |
| 795 | |
| 796 | wxBoxSizer* const szr = new wxBoxSizer(wxHORIZONTAL); |
| 797 | szr->Add(new wxStaticText(parent, -1, wxGetTranslation(StrToWxStr(group->settings[0]->name))), |
| 798 | 0, wxCENTER|wxRIGHT, 3); |
| 799 | szr->Add(threshold_cbox->wxcontrol, 0, wxRIGHT, 3); |
| 800 | |
| 801 | Add(szr, 0, wxALL|wxCENTER, 3); |
| 802 | Add(static_bitmap, 0, wxALL|wxCENTER, 3); |
| 803 | } |
| 804 | break; |
| 805 | case GROUP_TYPE_MIXED_TRIGGERS: |
| 806 | case GROUP_TYPE_TRIGGERS: |
| 807 | case GROUP_TYPE_SLIDER: |
| 808 | { |
| 809 | int height = (int)(12 * group->controls.size()); |
| 810 | int width = 64; |
| 811 | |
| 812 | if (GROUP_TYPE_MIXED_TRIGGERS == group->type) |
| 813 | width = 64+12+1; |
| 814 | |
| 815 | if (GROUP_TYPE_TRIGGERS != group->type) |
| 816 | height /= 2; |
| 817 | |
| 818 | wxBitmap bitmap(width, height+1); |
| 819 | dc.SelectObject(bitmap); |
| 820 | dc.Clear(); |
| 821 | static_bitmap = new wxStaticBitmap(parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP); |
| 822 | |
| 823 | std::vector<ControllerEmu::ControlGroup::Setting*>::const_iterator |
| 824 | i = group->settings.begin(), |
| 825 | e = group->settings.end(); |
| 826 | for (; i!=e; ++i) |
| 827 | { |
| 828 | PadSettingSpin* setting = new PadSettingSpin(parent, *i); |
| 829 | setting->wxcontrol->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &GamepadPage::AdjustSetting, eventsink); |
| 830 | options.push_back(setting); |
| 831 | wxBoxSizer* const szr = new wxBoxSizer(wxHORIZONTAL); |
| 832 | szr->Add(new wxStaticText(parent, -1, wxGetTranslation(StrToWxStr((*i)->name))), 0, wxCENTER|wxRIGHT, 3); |
| 833 | szr->Add(setting->wxcontrol, 0, wxRIGHT, 3); |
| 834 | Add(szr, 0, wxALL|wxCENTER, 3); |
| 835 | } |
| 836 | |
| 837 | Add(static_bitmap, 0, wxALL|wxCENTER, 3); |
| 838 | } |
| 839 | break; |
| 840 | case GROUP_TYPE_EXTENSION: |
| 841 | { |
| 842 | PadSettingExtension* const attachments = new PadSettingExtension(parent, (ControllerEmu::Extension*)group); |
| 843 | wxButton* const configure_btn = new ExtensionButton(parent, (ControllerEmu::Extension*)group); |
| 844 | |
| 845 | options.push_back(attachments); |
| 846 | |
| 847 | attachments->wxcontrol->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &GamepadPage::AdjustSetting, eventsink); |
| 848 | configure_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::ConfigExtension, eventsink); |
| 849 | |
| 850 | Add(attachments->wxcontrol, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND, 3); |
| 851 | Add(configure_btn, 0, wxALL|wxEXPAND, 3); |
| 852 | } |
| 853 | break; |
| 854 | case GROUP_TYPE_UDPWII: |
| 855 | { |
| 856 | wxButton* const btn = new UDPConfigButton(parent, (UDPWrapper*)group); |
| 857 | btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::ConfigUDPWii, eventsink); |
| 858 | Add(btn, 0, wxALL|wxEXPAND, 3); |
| 859 | } |
| 860 | break; |
| 861 | default: |
| 862 | { |
| 863 | //options |
| 864 | |
| 865 | std::vector<ControllerEmu::ControlGroup::Setting*>::const_iterator |
| 866 | i = group->settings.begin(), |
| 867 | e = group->settings.end(); |
| 868 | for (; i!=e; ++i) |
| 869 | { |
| 870 | PadSettingCheckBox* setting_cbox = new PadSettingCheckBox(parent, (*i)->value, (*i)->name); |
| 871 | setting_cbox->wxcontrol->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &GamepadPage::AdjustSetting, eventsink); |
| 872 | options.push_back(setting_cbox); |
| 873 | |
| 874 | Add(setting_cbox->wxcontrol, 0, wxALL|wxLEFT, 5); |
| 875 | |
| 876 | } |
| 877 | } |
| 878 | break; |
| 879 | } |
| 880 | |
| 881 | dc.SelectObject(wxNullBitmap); |
| 882 | |
| 883 | //AddStretchSpacer(0); |
| 884 | } |
| 885 | |
| 886 | ControlGroupsSizer::ControlGroupsSizer(ControllerEmu* const controller, wxWindow* const parent, GamepadPage* const eventsink, std::vector<ControlGroupBox*>* groups) |
| 887 | : wxBoxSizer(wxHORIZONTAL) |
| 888 | { |
| 889 | size_t col_size = 0; |
| 890 | |
| 891 | wxBoxSizer* stacked_groups = NULL__null; |
| 892 | for (unsigned int i = 0; i < controller->groups.size(); ++i) |
| 893 | { |
| 894 | ControlGroupBox* control_group_box = new ControlGroupBox(controller->groups[i], parent, eventsink); |
| 895 | wxStaticBoxSizer *control_group = |
| 896 | new wxStaticBoxSizer(wxVERTICAL, parent, wxGetTranslation(StrToWxStr(controller->groups[i]->name))); |
| 897 | control_group->Add(control_group_box); |
| 898 | |
| 899 | const size_t grp_size = controller->groups[i]->controls.size() + controller->groups[i]->settings.size(); |
| 900 | col_size += grp_size; |
| 901 | if (col_size > 8 || NULL__null == stacked_groups) |
| 902 | { |
| 903 | if (stacked_groups) |
| 904 | Add(stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5); |
| 905 | |
| 906 | stacked_groups = new wxBoxSizer(wxVERTICAL); |
| 907 | stacked_groups->Add(control_group, 0, wxEXPAND); |
| 908 | |
| 909 | col_size = grp_size; |
| 910 | } |
| 911 | else |
| 912 | { |
| 913 | stacked_groups->Add(control_group, 0, wxEXPAND); |
| 914 | } |
| 915 | |
| 916 | if (groups) |
| 917 | groups->push_back(control_group_box); |
| 918 | } |
| 919 | |
| 920 | if (stacked_groups) |
| 921 | Add(stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5); |
| 922 | } |
| 923 | |
| 924 | GamepadPage::GamepadPage(wxWindow* parent, InputPlugin& plugin, const unsigned int pad_num, InputConfigDialog* const config_dialog) |
| 925 | : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) |
| 926 | ,controller(plugin.controllers[pad_num]) |
| 927 | , m_config_dialog(config_dialog) |
| 928 | , m_plugin(plugin) |
| 929 | { |
| 930 | |
| 931 | wxBoxSizer* control_group_sizer = new ControlGroupsSizer(m_plugin.controllers[pad_num], this, this, &control_groups); |
| 932 | |
| 933 | wxStaticBoxSizer* profile_sbox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Profile")wxGetTranslation(("Profile"))); |
| 934 | |
| 935 | // device chooser |
| 936 | |
| 937 | wxStaticBoxSizer* const device_sbox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Device")wxGetTranslation(("Device"))); |
| 938 | |
| 939 | device_cbox = new wxComboBox(this, -1, wxT("")L"", wxDefaultPosition, wxSize(64,-1)); |
| 940 | device_cbox->ToggleWindowStyle(wxTE_PROCESS_ENTER0x0400); |
| 941 | |
| 942 | wxButton* refresh_button = new wxButton(this, -1, _("Refresh")wxGetTranslation(("Refresh")), wxDefaultPosition, wxSize(60,-1)); |
| 943 | |
| 944 | device_cbox->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &GamepadPage::SetDevice, this); |
| 945 | device_cbox->Bind(wxEVT_COMMAND_TEXT_ENTER, &GamepadPage::SetDevice, this); |
| 946 | refresh_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::RefreshDevices, this); |
| 947 | |
| 948 | device_sbox->Add(device_cbox, 1, wxLEFT|wxRIGHT, 3); |
| 949 | device_sbox->Add(refresh_button, 0, wxRIGHT|wxBOTTOM, 3); |
| 950 | |
| 951 | wxButton* const default_button = new wxButton(this, -1, _("Default")wxGetTranslation(("Default")), wxDefaultPosition, wxSize(48,-1)); |
| 952 | wxButton* const clearall_button = new wxButton(this, -1, _("Clear")wxGetTranslation(("Clear")), wxDefaultPosition, wxSize(58,-1)); |
| 953 | |
| 954 | wxStaticBoxSizer* const clear_sbox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Reset")wxGetTranslation(("Reset"))); |
| 955 | clear_sbox->Add(default_button, 1, wxLEFT, 3); |
| 956 | clear_sbox->Add(clearall_button, 1, wxRIGHT, 3); |
| 957 | |
| 958 | clearall_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::ClearAll, this); |
| 959 | default_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::LoadDefaults, this); |
| 960 | |
| 961 | profile_cbox = new wxComboBox(this, -1, wxT("")L"", wxDefaultPosition, wxSize(64,-1)); |
| 962 | |
| 963 | wxButton* const pload_btn = new wxButton(this, -1, _("Load")wxGetTranslation(("Load")), wxDefaultPosition, wxSize(48,-1)); |
| 964 | wxButton* const psave_btn = new wxButton(this, -1, _("Save")wxGetTranslation(("Save")), wxDefaultPosition, wxSize(48,-1)); |
| 965 | wxButton* const pdelete_btn = new wxButton(this, -1, _("Delete")wxGetTranslation(("Delete")), wxDefaultPosition, wxSize(60,-1)); |
| 966 | |
| 967 | pload_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::LoadProfile, this); |
| 968 | psave_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::SaveProfile, this); |
| 969 | pdelete_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &GamepadPage::DeleteProfile, this); |
| 970 | |
| 971 | profile_sbox->Add(profile_cbox, 1, wxLEFT, 3); |
| 972 | profile_sbox->Add(pload_btn, 0, wxLEFT, 3); |
| 973 | profile_sbox->Add(psave_btn, 0, 0, 3); |
| 974 | profile_sbox->Add(pdelete_btn, 0, wxRIGHT|wxBOTTOM, 3); |
| 975 | |
| 976 | wxBoxSizer* const dio = new wxBoxSizer(wxHORIZONTAL); |
| 977 | dio->Add(device_sbox, 1, wxEXPAND|wxRIGHT, 5); |
| 978 | dio->Add(clear_sbox, 0, wxEXPAND|wxRIGHT, 5); |
| 979 | dio->Add(profile_sbox, 1, wxEXPAND|wxRIGHT, 5); |
| 980 | |
| 981 | wxBoxSizer* const mapping = new wxBoxSizer(wxVERTICAL); |
| 982 | |
| 983 | mapping->Add(dio, 1, wxEXPAND|wxLEFT|wxTOP|wxBOTTOM, 5); |
| 984 | mapping->Add(control_group_sizer, 0, wxLEFT|wxEXPAND, 5); |
| 985 | |
| 986 | UpdateGUI(); |
| 987 | |
| 988 | SetSizerAndFit(mapping); // needed |
| 989 | Layout(); |
| 990 | }; |
| 991 | |
| 992 | |
| 993 | InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin, const std::string& name, const int tab_num) |
| 994 | : wxDialog(parent, wxID_ANY, wxGetTranslation(StrToWxStr(name)), wxPoint(128,-1), wxDefaultSize) |
| 995 | , m_plugin(plugin) |
| 996 | { |
| 997 | m_pad_notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT0x0000); |
| 998 | for (unsigned int i = 0; i < std::min(plugin.controllers.size(), (size_t)MAX_WIIMOTES); ++i) |
| 999 | { |
| 1000 | GamepadPage* gp = new GamepadPage(m_pad_notebook, m_plugin, i, this); |
| 1001 | m_padpages.push_back(gp); |
| 1002 | m_pad_notebook->AddPage(gp, wxString::Format(wxT("%s %u")L"%s %u", wxGetTranslation(StrToWxStr(m_plugin.gui_name)), 1+i)); |
| 1003 | } |
| 1004 | |
| 1005 | m_pad_notebook->SetSelection(tab_num); |
| 1006 | |
| 1007 | UpdateDeviceComboBox(); |
| 1008 | UpdateProfileComboBox(); |
| 1009 | |
| 1010 | Bind(wxEVT_COMMAND_BUTTON_CLICKED, &InputConfigDialog::ClickSave, this, wxID_OK); |
| 1011 | |
| 1012 | wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL); |
| 1013 | szr->Add(m_pad_notebook, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5); |
| 1014 | szr->Add(CreateButtonSizer(wxOK0x00000004 | wxCANCEL0x00000010 | wxNO_DEFAULT0x00000080), 0, wxEXPAND|wxALL, 5); |
| 1015 | |
| 1016 | SetSizerAndFit(szr); |
| 1017 | Center(); |
| 1018 | |
| 1019 | // live preview update timer |
| 1020 | m_update_timer = new wxTimer(this, -1); |
| 1021 | Bind(wxEVT_TIMER, &InputConfigDialog::UpdateBitmaps, this); |
| 1022 | m_update_timer->Start(PREVIEW_UPDATE_TIME25, wxTIMER_CONTINUOUSfalse); |
| 1023 | } |
| 1024 | |
| 1025 | bool InputConfigDialog::Destroy() |
| 1026 | { |
| 1027 | m_update_timer->Stop(); |
| 1028 | return true; |
| 1029 | } |