示例#1
0
void TASInputDlg::CreateGCLayout()
{
	if (m_has_layout)
		return;

	CreateBaseLayout();

	m_buttons[6] = &m_x;
	m_buttons[7] = &m_y;
	m_buttons[8] = &m_z;
	m_buttons[9] = &m_l;
	m_buttons[10] = &m_r;
	m_buttons[11] = &m_start;

	m_controls[2] = &m_c_stick.x_cont;
	m_controls[3] = &m_c_stick.y_cont;
	m_controls[4] = &m_l_cont;
	m_controls[5] = &m_r_cont;

	wxBoxSizer* const top_box = new wxBoxSizer(wxHORIZONTAL);
	wxBoxSizer* const bottom_box = new wxBoxSizer(wxHORIZONTAL);
	m_main_stick = CreateStick(ID_MAIN_STICK, 255, 255, 128, 128, false, true);
	wxStaticBoxSizer* const main_box = CreateStickLayout(&m_main_stick, _("Main Stick"));

	m_c_stick = CreateStick(ID_C_STICK, 255, 255, 128, 128, false, true);
	wxStaticBoxSizer* const c_box = CreateStickLayout(&m_c_stick, _("C Stick"));

	wxStaticBoxSizer* const shoulder_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Shoulder Buttons"));
	m_l_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 255, 0);
	m_r_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 255, 0);
	shoulder_box->Add(m_l_cont.slider, 0, wxALIGN_CENTER_VERTICAL);
	shoulder_box->Add(m_l_cont.text, 0, wxALIGN_CENTER_VERTICAL);
	shoulder_box->Add(m_r_cont.slider, 0, wxALIGN_CENTER_VERTICAL);
	shoulder_box->Add(m_r_cont.text, 0, wxALIGN_CENTER_VERTICAL);

	for (Control* const control : m_controls)
	{
		if (control != nullptr)
			control->slider->Bind(wxEVT_RIGHT_UP, &TASInputDlg::OnRightClickSlider, this);
	}

	wxStaticBoxSizer* const m_buttons_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Buttons"));
	wxGridSizer* const m_buttons_grid = new wxGridSizer(4);

	m_x = CreateButton("X");
	m_y = CreateButton("Y");
	m_l = CreateButton("L");
	m_r = CreateButton("R");
	m_z = CreateButton("Z");
	m_start = CreateButton("Start");

	for (unsigned int i = 4; i < ArraySize(m_buttons); ++i)
		if (m_buttons[i] != nullptr)
			m_buttons_grid->Add(m_buttons[i]->checkbox, false);
	m_buttons_grid->AddSpacer(5);

	m_buttons_box->Add(m_buttons_grid);
	m_buttons_box->Add(m_buttons_dpad);

	wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);

	top_box->Add(main_box, 0, wxALL, 5);
	top_box->Add(c_box, 0, wxTOP | wxRIGHT, 5);
	bottom_box->Add(shoulder_box, 0, wxLEFT | wxRIGHT, 5);
	bottom_box->Add(m_buttons_box, 0, wxBOTTOM, 5);
	main_szr->Add(top_box);
	main_szr->Add(bottom_box);
	SetSizerAndFit(main_szr);

	ResetValues();
	m_has_layout = true;
}
示例#2
0
wxBoxSizer* TASInputDlg::CreateCCLayout()
{
	wxBoxSizer* const szr = new wxBoxSizer(wxHORIZONTAL);

	for (size_t i = 0; i < ArraySize(m_cc_buttons); ++i)
		m_cc_buttons[i] = CreateButton(m_cc_button_names[i]);

	m_cc_l_stick = CreateStick(ID_CC_L_STICK, 63, 63, WiimoteEmu::Classic::LEFT_STICK_CENTER_X, WiimoteEmu::Classic::LEFT_STICK_CENTER_Y, false, true);
	m_cc_r_stick = CreateStick(ID_CC_R_STICK, 31, 31, WiimoteEmu::Classic::RIGHT_STICK_CENTER_X, WiimoteEmu::Classic::RIGHT_STICK_CENTER_Y, false, true);

	m_cc_controls[CC_L_STICK_X] = &m_cc_l_stick.x_cont;
	m_cc_controls[CC_L_STICK_Y] = &m_cc_l_stick.y_cont;
	m_cc_controls[CC_R_STICK_X] = &m_cc_r_stick.x_cont;
	m_cc_controls[CC_R_STICK_Y] = &m_cc_r_stick.y_cont;
	m_cc_controls[CC_L_TRIGGER] = &m_cc_l;
	m_cc_controls[CC_R_TRIGGER] = &m_cc_r;

	m_cc_l_stick_szr = CreateStickLayout(&m_cc_l_stick, _("Left stick"));
	m_cc_r_stick_szr = CreateStickLayout(&m_cc_r_stick, _("Right stick"));

	m_cc_l = CreateControl(wxSL_VERTICAL, -1, 100, false, 31, 0);;
	m_cc_r = CreateControl(wxSL_VERTICAL, -1, 100, false, 31, 0);;

	wxStaticBoxSizer* const shoulder_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Shoulder Buttons"));
	shoulder_box->Add(m_cc_l.slider, 0, wxALIGN_CENTER_VERTICAL);
	shoulder_box->Add(m_cc_l.text, 0, wxALIGN_CENTER_VERTICAL);
	shoulder_box->Add(m_cc_r.slider, 0, wxALIGN_CENTER_VERTICAL);
	shoulder_box->Add(m_cc_r.text, 0, wxALIGN_CENTER_VERTICAL);

	wxStaticBoxSizer* const cc_buttons_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Buttons"));
	wxGridSizer* const cc_buttons_grid = new wxGridSizer(4);
	wxGridSizer* const cc_buttons_dpad = new wxGridSizer(3);

	cc_buttons_dpad->AddSpacer(20);
	cc_buttons_dpad->Add(m_cc_buttons[1].checkbox);
	cc_buttons_dpad->AddSpacer(20);
	cc_buttons_dpad->Add(m_cc_buttons[2].checkbox);
	cc_buttons_dpad->AddSpacer(20);
	cc_buttons_dpad->Add(m_cc_buttons[3].checkbox);
	cc_buttons_dpad->AddSpacer(20);
	cc_buttons_dpad->Add(m_cc_buttons[0].checkbox);
	cc_buttons_dpad->AddSpacer(20);


	for (auto button : m_cc_buttons)
		cc_buttons_grid->Add(button.checkbox);
	cc_buttons_grid->AddSpacer(5);

	cc_buttons_box->Add(cc_buttons_grid);
	cc_buttons_box->Add(cc_buttons_dpad);

	szr->Add(m_cc_l_stick_szr, 0, wxALL, 5);
	szr->Add(m_cc_r_stick_szr, 0, wxALL, 5);
	szr->Add(shoulder_box, 0, wxLEFT | wxRIGHT, 5);
	szr->Add(cc_buttons_box, 0, wxTOP | wxRIGHT, 5);

	for (Control* const control : m_cc_controls)
	{
		if (control != nullptr)
			control->slider->Bind(wxEVT_RIGHT_UP, &TASInputDlg::OnRightClickSlider, this);
	}
	return szr;
}
示例#3
0
void TASInputDlg::CreateWiiLayout(int num)
{
	if (m_has_layout)
		return;

	CreateBaseLayout();

	m_buttons[6] = &m_one;
	m_buttons[7] = &m_two;
	m_buttons[8] = &m_plus;
	m_buttons[9] = &m_minus;
	m_buttons[10] = &m_home;

	m_controls[4] = &m_x_cont;
	m_controls[5] = &m_y_cont;
	m_controls[6] = &m_z_cont;

	m_main_stick = CreateStick(ID_MAIN_STICK, 1024, 768, 512, 384, true, false);
	m_main_stick_szr = CreateStickLayout(&m_main_stick, _("IR"));

	m_x_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
	m_y_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
	m_z_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 616);
	wxStaticBoxSizer* const axisBox = CreateAccelLayout(&m_x_cont, &m_y_cont, &m_z_cont, _("Orientation"));

	wxStaticBoxSizer* const m_buttons_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Buttons"));
	wxGridSizer* const m_buttons_grid = new wxGridSizer(4);

	m_plus = CreateButton("+");
	m_minus = CreateButton("-");
	m_one = CreateButton("1");
	m_two = CreateButton("2");
	m_home = CreateButton("Home");

	m_main_szr = new wxBoxSizer(wxVERTICAL);
	m_wiimote_szr = new wxBoxSizer(wxHORIZONTAL);
	m_ext_szr = new wxBoxSizer(wxHORIZONTAL);
	m_cc_szr = CreateCCLayout();

	if (Core::IsRunning())
	{
		m_ext = ((WiimoteEmu::Wiimote*)Wiimote::GetConfig()->controllers[num])->CurrentExtension();
	}
	else
	{
		IniFile ini;
		ini.Load(File::GetUserPath(D_CONFIG_IDX) + "WiimoteNew.ini");
		std::string extension;
		ini.GetIfExists("Wiimote" + std::to_string(num + 1), "Extension", &extension);

		if (extension == "Nunchuk")
			m_ext = 1;
		if (extension == "Classic")
			m_ext = 2;
	}

	m_buttons[11] = &m_c;
	m_buttons[12] = &m_z;
	m_controls[2] = &m_c_stick.x_cont;
	m_controls[3] = &m_c_stick.y_cont;
	m_controls[7] = &m_nx_cont;
	m_controls[8] = &m_ny_cont;
	m_controls[9] = &m_nz_cont;

	m_c_stick = CreateStick(ID_C_STICK, 255, 255, 128, 128, false, true);
	m_c_stick_szr = CreateStickLayout(&m_c_stick, _("Nunchuk stick"));

	m_nx_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
	m_ny_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
	m_nz_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
	wxStaticBoxSizer* const nunchukaxisBox = CreateAccelLayout(&m_nx_cont, &m_ny_cont, &m_nz_cont, _("Nunchuk orientation"));

	m_c = CreateButton("C");
	m_z = CreateButton("Z");
	m_ext_szr->Add(m_c_stick_szr, 0, wxLEFT | wxBOTTOM | wxRIGHT, 5);
	m_ext_szr->Add(nunchukaxisBox);

	for (Control* const control : m_controls)
	{
		if (control != nullptr)
			control->slider->Bind(wxEVT_RIGHT_UP, &TASInputDlg::OnRightClickSlider, this);
	}

	for (unsigned int i = 4; i < ArraySize(m_buttons); ++i)
		if (m_buttons[i] != nullptr)
			m_buttons_grid->Add(m_buttons[i]->checkbox);
	m_buttons_grid->AddSpacer(5);

	m_buttons_box->Add(m_buttons_grid);
	m_buttons_box->Add(m_buttons_dpad);

	m_wiimote_szr->Add(m_main_stick_szr, 0, wxALL, 5);
	m_wiimote_szr->Add(axisBox, 0, wxTOP | wxRIGHT, 5);
	m_wiimote_szr->Add(m_buttons_box, 0, wxTOP | wxRIGHT, 5);
	m_main_szr->Add(m_wiimote_szr);
	m_main_szr->Add(m_ext_szr);
	m_main_szr->Add(m_cc_szr);

	HandleExtensionChange();
	m_has_layout = true;
}
示例#4
0
void TASInputDlg::CreateGCLayout()
{
  if (m_has_layout)
    return;

  CreateBaseLayout();

  m_buttons[6] = &m_x;
  m_buttons[7] = &m_y;
  m_buttons[8] = &m_z;
  m_buttons[9] = &m_l;
  m_buttons[10] = &m_r;
  m_buttons[11] = &m_start;

  m_controls[2] = &m_c_stick.x_cont;
  m_controls[3] = &m_c_stick.y_cont;
  m_controls[4] = &m_l_cont;
  m_controls[5] = &m_r_cont;

  m_main_stick = CreateStick(ID_MAIN_STICK, 255, 255, 128, 128, false, true);
  wxStaticBoxSizer* const main_box = CreateStickLayout(&m_main_stick, _("Main Stick"));

  m_c_stick = CreateStick(ID_C_STICK, 255, 255, 128, 128, false, true);
  wxStaticBoxSizer* const c_box = CreateStickLayout(&m_c_stick, _("C Stick"));

  auto* const shoulder_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Shoulder Buttons"));
  m_l_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 255, 0);
  m_r_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 255, 0);
  shoulder_box->Add(m_l_cont.slider, 0, wxALIGN_CENTER_VERTICAL);
  shoulder_box->Add(m_l_cont.text, 0, wxALIGN_CENTER_VERTICAL);
  shoulder_box->Add(m_r_cont.slider, 0, wxALIGN_CENTER_VERTICAL);
  shoulder_box->Add(m_r_cont.text, 0, wxALIGN_CENTER_VERTICAL);

  for (Control* const control : m_controls)
  {
    if (control != nullptr)
      control->slider->Bind(wxEVT_RIGHT_UP, &TASInputDlg::OnRightClickSlider, this);
  }

  m_x = CreateButton("X");
  m_x.checkbox->SetClientData(&m_x);
  m_y = CreateButton("Y");
  m_y.checkbox->SetClientData(&m_y);
  m_l = CreateButton("L");
  m_l.checkbox->SetClientData(&m_l);
  m_r = CreateButton("R");
  m_r.checkbox->SetClientData(&m_r);
  m_z = CreateButton("Z");
  m_z.checkbox->SetClientData(&m_z);
  // i18n: The START/PAUSE button on GameCube controllers
  m_start = CreateButton(_("START"));
  m_start.checkbox->SetClientData(&m_start);

  const int space5 = FromDIP(5);

  // Add non-DPad related buttons first.
  auto* const buttons_grid = new wxGridSizer(4);
  for (size_t i = 4; i < m_buttons.size(); ++i)
  {
    if (m_buttons[i] != nullptr)
      buttons_grid->Add(m_buttons[i]->checkbox, false);
  }
  buttons_grid->Add(space5, space5);

  auto* const buttons_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Buttons"));
  buttons_box->Add(buttons_grid);
  buttons_box->Add(m_buttons_dpad);

  auto* const top_box = new wxBoxSizer(wxHORIZONTAL);
  top_box->Add(main_box);
  top_box->Add(c_box, 0, wxLEFT, space5);

  auto* const bottom_box = new wxBoxSizer(wxHORIZONTAL);
  bottom_box->Add(shoulder_box);
  bottom_box->Add(buttons_box, 0, wxLEFT, space5);

  auto* const main_szr = new wxBoxSizer(wxVERTICAL);
  main_szr->AddSpacer(space5);
  main_szr->Add(top_box, 0, wxLEFT | wxRIGHT, space5);
  main_szr->AddSpacer(space5);
  main_szr->Add(bottom_box, 0, wxLEFT | wxRIGHT, space5);
  main_szr->AddSpacer(space5);
  SetSizerAndFit(main_szr);

  ResetValues();
  FinishLayout();
}
示例#5
0
wxBoxSizer* TASInputDlg::CreateCCLayout()
{
  const std::array<wxString, 15> button_names{{_("Down"), _("Up"), _("Left"), _("Right"), "A", "B",
                                               "X", "Y", "+", "-", "L", "R", "ZR", "ZL", "HOME"}};
  for (size_t i = 0; i < button_names.size(); ++i)
  {
    m_cc_buttons[i] = CreateButton(button_names[i]);
    m_cc_buttons[i].checkbox->SetClientData(&m_cc_buttons[i]);
  }

  m_cc_l_stick = CreateStick(ID_CC_L_STICK, 63, 63, WiimoteEmu::Classic::LEFT_STICK_CENTER_X,
                             WiimoteEmu::Classic::LEFT_STICK_CENTER_Y, false, true);
  m_cc_r_stick = CreateStick(ID_CC_R_STICK, 31, 31, WiimoteEmu::Classic::RIGHT_STICK_CENTER_X,
                             WiimoteEmu::Classic::RIGHT_STICK_CENTER_Y, false, true);

  m_cc_controls[CC_L_STICK_X] = &m_cc_l_stick.x_cont;
  m_cc_controls[CC_L_STICK_Y] = &m_cc_l_stick.y_cont;
  m_cc_controls[CC_R_STICK_X] = &m_cc_r_stick.x_cont;
  m_cc_controls[CC_R_STICK_Y] = &m_cc_r_stick.y_cont;
  m_cc_controls[CC_L_TRIGGER] = &m_cc_l;
  m_cc_controls[CC_R_TRIGGER] = &m_cc_r;

  m_cc_l_stick_szr = CreateStickLayout(&m_cc_l_stick, _("Left stick"));
  m_cc_r_stick_szr = CreateStickLayout(&m_cc_r_stick, _("Right stick"));

  m_cc_l = CreateControl(wxSL_VERTICAL, -1, 100, false, 31, 0);
  m_cc_r = CreateControl(wxSL_VERTICAL, -1, 100, false, 31, 0);

  const int space5 = FromDIP(5);
  const int space20 = FromDIP(20);

  auto* const shoulder_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Shoulder Buttons"));
  shoulder_box->Add(m_cc_l.slider, 0, wxALIGN_CENTER_VERTICAL);
  shoulder_box->Add(m_cc_l.text, 0, wxALIGN_CENTER_VERTICAL);
  shoulder_box->Add(m_cc_r.slider, 0, wxALIGN_CENTER_VERTICAL);
  shoulder_box->Add(m_cc_r.text, 0, wxALIGN_CENTER_VERTICAL);

  auto* const cc_buttons_dpad = new wxGridSizer(3);
  cc_buttons_dpad->Add(space20, space20);
  cc_buttons_dpad->Add(m_cc_buttons[1].checkbox);
  cc_buttons_dpad->Add(space20, space20);
  cc_buttons_dpad->Add(m_cc_buttons[2].checkbox);
  cc_buttons_dpad->Add(space20, space20);
  cc_buttons_dpad->Add(m_cc_buttons[3].checkbox);
  cc_buttons_dpad->Add(space20, space20);
  cc_buttons_dpad->Add(m_cc_buttons[0].checkbox);
  cc_buttons_dpad->Add(space20, space20);

  auto* const cc_buttons_grid = new wxGridSizer(4);
  for (auto& button : m_cc_buttons)
    if (!button.checkbox->GetContainingSizer())
      cc_buttons_grid->Add(button.checkbox);
  cc_buttons_grid->Add(space5, space5);

  auto* const cc_buttons_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Buttons"));
  cc_buttons_box->Add(cc_buttons_grid);
  cc_buttons_box->Add(cc_buttons_dpad, 0, wxTOP, space5);

  auto* const szr = new wxBoxSizer(wxHORIZONTAL);
  szr->AddSpacer(space5);
  szr->Add(m_cc_l_stick_szr, 0, wxTOP | wxBOTTOM, space5);
  szr->AddSpacer(space5);
  szr->Add(m_cc_r_stick_szr, 0, wxTOP | wxBOTTOM, space5);
  szr->AddSpacer(space5);
  szr->Add(shoulder_box, 0, wxTOP | wxBOTTOM, space5);
  szr->AddSpacer(space5);
  szr->Add(cc_buttons_box, 0, wxTOP | wxBOTTOM, space5);
  szr->AddSpacer(space5);

  for (Control* const control : m_cc_controls)
  {
    if (control != nullptr)
      control->slider->Bind(wxEVT_RIGHT_UP, &TASInputDlg::OnRightClickSlider, this);
  }
  return szr;
}
示例#6
0
void TASInputDlg::CreateWiiLayout(int num)
{
  if (m_has_layout)
    return;
  const int space5 = FromDIP(5);

  CreateBaseLayout();

  m_buttons[6] = &m_one;
  m_buttons[7] = &m_two;
  m_buttons[8] = &m_plus;
  m_buttons[9] = &m_minus;
  m_buttons[10] = &m_home;

  m_controls[4] = &m_x_cont;
  m_controls[5] = &m_y_cont;
  m_controls[6] = &m_z_cont;

  m_main_stick = CreateStick(ID_MAIN_STICK, 1024, 768, 512, 384, true, false);
  // i18n: IR stands for infrared and refers to the pointer functionality of Wii Remotes
  m_main_stick_szr = CreateStickLayout(&m_main_stick, _("IR"));

  m_x_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
  m_y_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
  m_z_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 616);
  wxStaticBoxSizer* const axisBox =
      CreateAccelLayout(&m_x_cont, &m_y_cont, &m_z_cont, _("Orientation"));

  m_plus = CreateButton("+");
  m_plus.checkbox->SetClientData(&m_plus);
  m_minus = CreateButton("-");
  m_minus.checkbox->SetClientData(&m_minus);
  m_one = CreateButton("1");
  m_one.checkbox->SetClientData(&m_one);
  m_two = CreateButton("2");
  m_two.checkbox->SetClientData(&m_two);
  m_home = CreateButton("HOME");
  m_home.checkbox->SetClientData(&m_home);

  m_cc_szr = CreateCCLayout();

  if (Core::IsRunning())
  {
    m_ext = static_cast<WiimoteEmu::Wiimote*>(Wiimote::GetConfig()->GetController(num))
                ->CurrentExtension();
  }
  else
  {
    IniFile ini;
    ini.Load(File::GetUserPath(D_CONFIG_IDX) + "WiimoteNew.ini");
    std::string extension;
    ini.GetIfExists("Wiimote" + std::to_string(num + 1), "Extension", &extension);

    if (extension == "Nunchuk")
      m_ext = 1;
    if (extension == "Classic")
      m_ext = 2;
  }

  m_buttons[11] = &m_c;
  m_buttons[12] = &m_z;
  m_controls[2] = &m_c_stick.x_cont;
  m_controls[3] = &m_c_stick.y_cont;
  m_controls[7] = &m_nx_cont;
  m_controls[8] = &m_ny_cont;
  m_controls[9] = &m_nz_cont;

  m_c_stick = CreateStick(ID_C_STICK, 255, 255, 128, 128, false, true);
  m_c_stick_szr = CreateStickLayout(&m_c_stick, _("Nunchuk stick"));

  m_nx_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
  m_ny_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
  m_nz_cont = CreateControl(wxSL_VERTICAL, -1, 100, false, 1023, 512);
  wxStaticBoxSizer* const nunchukaxisBox =
      CreateAccelLayout(&m_nx_cont, &m_ny_cont, &m_nz_cont, _("Nunchuk orientation"));

  m_c = CreateButton("C");
  m_c.checkbox->SetClientData(&m_c);
  m_z = CreateButton("Z");
  m_z.checkbox->SetClientData(&m_z);

  for (Control* const control : m_controls)
  {
    if (control != nullptr)
      control->slider->Bind(wxEVT_RIGHT_UP, &TASInputDlg::OnRightClickSlider, this);
  }

  m_ext_szr = new wxBoxSizer(wxHORIZONTAL);
  m_ext_szr->Add(m_c_stick_szr, 0, wxBOTTOM, space5);
  m_ext_szr->AddSpacer(space5);
  m_ext_szr->Add(nunchukaxisBox, 0, wxBOTTOM, space5);

  // Add non-DPad related buttons first.
  auto* const buttons_grid = new wxGridSizer(4);
  for (size_t i = 4; i < m_buttons.size(); ++i)
  {
    if (m_buttons[i] != nullptr)
      buttons_grid->Add(m_buttons[i]->checkbox);
  }
  buttons_grid->Add(space5, space5);

  auto* const buttons_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Buttons"));
  buttons_box->Add(buttons_grid);
  buttons_box->Add(m_buttons_dpad, 0, wxTOP, space5);

  m_wiimote_szr = new wxBoxSizer(wxHORIZONTAL);
  m_wiimote_szr->AddSpacer(space5);
  m_wiimote_szr->Add(m_main_stick_szr);
  m_wiimote_szr->Add(axisBox, 0, wxLEFT, space5);
  m_wiimote_szr->Add(buttons_box, 0, wxLEFT, space5);
  m_wiimote_szr->AddSpacer(space5);

  // NOTE: Not all of these are visible at the same time.
  m_main_szr = new wxBoxSizer(wxVERTICAL);
  m_main_szr->Add(m_wiimote_szr, 0, wxTOP | wxBOTTOM, space5);
  m_main_szr->Add(m_ext_szr, 0, wxLEFT | wxRIGHT, space5);
  m_main_szr->Add(m_cc_szr, 0, wxLEFT | wxRIGHT, space5);

  SetSizer(m_main_szr);
  HandleExtensionChange();
  FinishLayout();
}