diff --git a/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.cpp b/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.cpp index be1173e12e..b685e89b08 100644 --- a/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.cpp +++ b/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.cpp @@ -12,6 +12,8 @@ ChangeGameDialog::ChangeGameDialog(wxWindow* parent, const CGameListCtrl* const game_list) : wxDialog(parent, wxID_ANY, _("Select Game")) { + const int space5 = FromDIP(5); + m_game_lbox = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxLB_SORT); m_game_lbox->Bind(wxEVT_LISTBOX_DCLICK, &ChangeGameDialog::OnPick, this); @@ -22,8 +24,11 @@ ChangeGameDialog::ChangeGameDialog(wxWindow* parent, const CGameListCtrl* const ok_btn->Bind(wxEVT_BUTTON, &ChangeGameDialog::OnPick, this); wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL); - szr->Add(m_game_lbox, 1, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 5); - szr->Add(ok_btn, 0, wxALL | wxALIGN_RIGHT, 5); + szr->AddSpacer(space5); + szr->Add(m_game_lbox, 1, wxEXPAND | wxLEFT | wxRIGHT, space5); + szr->AddSpacer(space5); + szr->Add(ok_btn, 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, space5); + szr->AddSpacer(space5); SetSizerAndFit(szr); SetFocus(); diff --git a/Source/Core/DolphinWX/NetPlay/MD5Dialog.cpp b/Source/Core/DolphinWX/NetPlay/MD5Dialog.cpp index 2eb8547693..c2e7ccfd4f 100644 --- a/Source/Core/DolphinWX/NetPlay/MD5Dialog.cpp +++ b/Source/Core/DolphinWX/NetPlay/MD5Dialog.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "Common/StringUtil.h" @@ -17,43 +18,54 @@ MD5Dialog::MD5Dialog(wxWindow* parent, NetPlayServer* server, std::vectorAdd(new wxStaticText(this, wxID_ANY, _("Computing MD5 Checksum for:") + "\n" + game, - wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL), - 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); + main_sizer->AddSpacer(space5); + main_sizer->Add(new wxStaticText(this, wxID_ANY, + wxString::Format(_("Computing MD5 Checksum for:\n%s"), game), + wxDefaultPosition, wxDefaultSize, + wxALIGN_CENTRE_HORIZONTAL | wxST_NO_AUTORESIZE), + 0, wxEXPAND | wxLEFT | wxRIGHT, space5); for (const Player* player : players) { wxStaticBoxSizer* const player_szr = new wxStaticBoxSizer( wxVERTICAL, this, player->name + " (p" + std::to_string(player->pid) + ")"); - wxGauge* gauge = new wxGauge(this, wxID_ANY, 100); + wxGauge* gauge = new wxGauge(player_szr->GetStaticBox(), wxID_ANY, 100); m_progress_bars[player->pid] = gauge; - player_szr->Add(gauge, 0, wxEXPAND | wxALL, 5); m_result_labels[player->pid] = - new wxStaticText(this, wxID_ANY, _("Computing..."), wxDefaultPosition, wxSize(250, 20), - wxALIGN_CENTRE_HORIZONTAL); + new wxStaticText(player_szr->GetStaticBox(), wxID_ANY, _("Computing...")); - m_result_labels[player->pid]->SetSize(250, 15); - player_szr->Add(m_result_labels[player->pid], 0, wxALL, 5); + player_szr->AddSpacer(space5); + player_szr->Add(gauge, 0, wxEXPAND | wxLEFT | wxRIGHT, space5); + player_szr->AddSpacer(space5); + player_szr->Add(m_result_labels[player->pid], 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, + space5); + player_szr->AddSpacer(space5); + player_szr->SetMinSize(FromDIP(wxSize(250, -1))); - main_sizer->Add(player_szr, 0, wxEXPAND | wxALL, 5); + main_sizer->AddSpacer(space5); + main_sizer->Add(player_szr, 0, wxEXPAND | wxLEFT | wxRIGHT, space5); } m_final_result_label = new wxStaticText(this, wxID_ANY, " ", // so it takes space wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL); - main_sizer->Add(m_final_result_label, 1, wxALL, 5); - - wxButton* close_btn = new wxButton(this, wxID_ANY, _("Close")); - close_btn->Bind(wxEVT_BUTTON, &MD5Dialog::OnCloseBtnPressed, this); - main_sizer->Add(close_btn, 0, wxEXPAND | wxALL, 5); + main_sizer->AddSpacer(space5); + main_sizer->Add(m_final_result_label, 1, wxLEFT | wxRIGHT, space5); + main_sizer->AddSpacer(space5); + main_sizer->Add(CreateStdDialogButtonSizer(wxCLOSE), 0, wxEXPAND | wxLEFT | wxRIGHT, space5); + main_sizer->AddSpacer(space5); SetSizerAndFit(main_sizer); + + Bind(wxEVT_BUTTON, &MD5Dialog::OnCloseBtnPressed, this, wxID_CLOSE); + Bind(wxEVT_CLOSE_WINDOW, &MD5Dialog::OnClose, this); SetFocus(); Center(); } @@ -65,6 +77,7 @@ void MD5Dialog::SetProgress(int pid, int progress) m_progress_bars[pid]->SetValue(progress); m_result_labels[pid]->SetLabel(_("Computing: ") + std::to_string(progress) + "%"); + Layout(); Update(); } @@ -76,11 +89,12 @@ void MD5Dialog::SetResult(int pid, const std::string& result) m_result_labels[pid]->SetLabel(result); m_hashes.push_back(result); - if (m_hashes.size() <= 1) - return; - - wxString label = AllHashesMatch() ? _("Hashes match!") : _("Hashes do not match."); - m_final_result_label->SetLabel(label); + if (m_hashes.size() > 1) + { + wxString label = AllHashesMatch() ? _("Hashes match!") : _("Hashes do not match."); + m_final_result_label->SetLabel(label); + } + Layout(); } bool MD5Dialog::AllHashesMatch() const @@ -89,7 +103,7 @@ bool MD5Dialog::AllHashesMatch() const m_hashes.end(); } -void MD5Dialog::OnClose(wxCloseEvent& event) +void MD5Dialog::OnClose(wxCloseEvent&) { m_netplay_server->AbortMD5(); } diff --git a/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.cpp b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.cpp index c9f0e0f86b..230f12bbe8 100644 --- a/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.cpp +++ b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -41,50 +42,54 @@ NetPlaySetupFrame::NetPlaySetupFrame(wxWindow* const parent, const CGameListCtrl inifile.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay"); - wxPanel* const panel = new wxPanel(this); - panel->Bind(wxEVT_CHAR_HOOK, &NetPlaySetupFrame::OnKeyDown, this); - - // top row - wxBoxSizer* const trav_szr = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer* const nick_szr = new wxBoxSizer(wxHORIZONTAL); + CreateGUI(); { - // Connection Config - wxStaticText* const connectiontype_lbl = new wxStaticText( - panel, wxID_ANY, _("Connection Type:"), wxDefaultPosition, wxSize(100, -1)); + wxIcon icon; + icon.CopyFromBitmap(WxUtils::LoadScaledResourceBitmap("Dolphin", this)); + SetIcon(icon); + } - m_direct_traversal = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(150, -1)); - m_direct_traversal->Bind(wxEVT_CHOICE, &NetPlaySetupFrame::OnDirectTraversalChoice, this); - m_direct_traversal->Append(_("Direct Connection")); - m_direct_traversal->Append(_("Traversal Server")); + { + std::string temp; + netplay_section.Get("Nickname", &temp, "Player"); + m_nickname_text->SetValue(StrToWxStr(temp)); - trav_szr->Add(connectiontype_lbl, 0, wxCENTER, 5); - trav_szr->AddSpacer(5); - trav_szr->Add(m_direct_traversal, 0, wxCENTER, 5); + temp.clear(); + netplay_section.Get("HostCode", &temp, "00000000"); + m_connect_hashcode_text->SetValue(StrToWxStr(temp)); - m_trav_reset_btn = new wxButton(panel, wxID_ANY, _("Reset Traversal Settings"), - wxDefaultPosition, wxSize(-1, 25)); - m_trav_reset_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnResetTraversal, this); + temp.clear(); + netplay_section.Get("Address", &temp, "127.0.0.1"); + m_connect_ip_text->SetValue(StrToWxStr(temp)); - trav_szr->AddSpacer(5); + temp.clear(); + netplay_section.Get("ConnectPort", &temp, + std::to_string(NetPlayHostConfig::DEFAULT_LISTEN_PORT)); + m_connect_port_text->SetValue(StrToWxStr(temp)); - trav_szr->Add(m_trav_reset_btn, 0, wxRIGHT); + temp.clear(); + netplay_section.Get("HostPort", &temp, std::to_string(NetPlayHostConfig::DEFAULT_LISTEN_PORT)); + m_host_port_text->SetValue(StrToWxStr(temp)); - // Nickname - wxStaticText* const nick_lbl = - new wxStaticText(panel, wxID_ANY, _("Nickname:"), wxDefaultPosition, wxSize(100, -1)); + temp.clear(); + if (netplay_section.Get("SelectedHostGame", &temp, "")) + m_game_lbox->SetStringSelection(StrToWxStr(temp)); - std::string nickname; - netplay_section.Get("Nickname", &nickname, "Player"); +#ifdef USE_UPNP + bool use_upnp = false; + netplay_section.Get("UseUPNP", &use_upnp, false); + m_upnp_chk->SetValue(use_upnp); +#endif - m_nickname_text = - new wxTextCtrl(panel, wxID_ANY, StrToWxStr(nickname), wxDefaultPosition, wxSize(150, -1)); + unsigned int listen_port = 0; + netplay_section.Get("ListenPort", &listen_port, 0); + m_traversal_listen_port_enabled->SetValue(listen_port != 0); + m_traversal_listen_port->Enable(m_traversal_listen_port_enabled->IsChecked()); + m_traversal_listen_port->SetValue(listen_port); - nick_szr->Add(nick_lbl, 0, wxCENTER); - nick_szr->Add(m_nickname_text, 0, wxALL, 5); - - std::string travChoice; - netplay_section.Get("TraversalChoice", &travChoice, "direct"); - if (travChoice == "traversal") + temp.clear(); + netplay_section.Get("TraversalChoice", &temp, "direct"); + if (temp == "traversal") { m_direct_traversal->Select(TRAVERSAL_CHOICE); } @@ -93,37 +98,96 @@ NetPlaySetupFrame::NetPlaySetupFrame(wxWindow* const parent, const CGameListCtrl m_direct_traversal->Select(DIRECT_CHOICE); } - m_traversal_lbl = new wxStaticText(panel, wxID_ANY, GetTraversalLabelText(netplay_section)); + m_traversal_lbl->SetLabelText(GetTraversalLabelText(netplay_section)); } - // tabs - m_notebook = new wxNotebook(panel, wxID_ANY); - wxPanel* const connect_tab = new wxPanel(m_notebook, wxID_ANY); - m_notebook->AddPage(connect_tab, _("Connect")); - wxPanel* const host_tab = new wxPanel(m_notebook, wxID_ANY); - m_notebook->AddPage(host_tab, _("Host")); + + Center(); + Show(); + + // Needs to be done last or it set up the spacing on the page correctly + wxCommandEvent ev; + OnDirectTraversalChoice(ev); +} + +void NetPlaySetupFrame::CreateGUI() +{ + const int space5 = FromDIP(5); + + wxPanel* const panel = new wxPanel(this); + panel->Bind(wxEVT_CHAR_HOOK, &NetPlaySetupFrame::OnKeyDown, this); + + // Connection Config + wxStaticText* const connectiontype_lbl = new wxStaticText(panel, wxID_ANY, _("Connection Type:")); + + m_direct_traversal = new wxChoice(panel, wxID_ANY); + m_direct_traversal->Bind(wxEVT_CHOICE, &NetPlaySetupFrame::OnDirectTraversalChoice, this); + m_direct_traversal->Append(_("Direct Connection")); + m_direct_traversal->Append(_("Traversal Server")); + + m_trav_reset_btn = new wxButton(panel, wxID_ANY, _("Reset Traversal Settings")); + m_trav_reset_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnResetTraversal, this); + + // Nickname + wxStaticText* const nick_lbl = new wxStaticText(panel, wxID_ANY, _("Nickname:")); + + m_nickname_text = new wxTextCtrl(panel, wxID_ANY, "Player"); + + m_traversal_lbl = new wxStaticText(panel, wxID_ANY, "Traversal Server"); + + wxButton* const quit_btn = new wxButton(panel, wxID_ANY, _("Quit")); + quit_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnQuit, this); + + wxGridBagSizer* top_sizer = new wxGridBagSizer(space5, space5); + top_sizer->Add(connectiontype_lbl, wxGBPosition(0, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + top_sizer->Add(WxUtils::GiveMinSizeDIP(m_direct_traversal, wxSize(100, -1)), wxGBPosition(0, 1), + wxDefaultSpan, wxEXPAND); + top_sizer->Add(m_trav_reset_btn, wxGBPosition(0, 2), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + top_sizer->Add(nick_lbl, wxGBPosition(1, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + top_sizer->Add(WxUtils::GiveMinSizeDIP(m_nickname_text, wxSize(150, -1)), wxGBPosition(1, 1), + wxDefaultSpan, wxEXPAND); + + m_notebook = CreateNotebookGUI(panel); + m_notebook->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &NetPlaySetupFrame::OnTabChanged, this); + + // main sizer + wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); + main_szr->AddSpacer(space5); + main_szr->Add(top_sizer, 0, wxLEFT | wxRIGHT, space5); + main_szr->AddSpacer(space5); + main_szr->Add(m_traversal_lbl, 0, wxLEFT | wxRIGHT, space5); + main_szr->AddSpacer(space5); + main_szr->Add(m_notebook, 1, wxLEFT | wxRIGHT | wxEXPAND, space5); + main_szr->AddSpacer(space5); + main_szr->Add(quit_btn, 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, space5); + main_szr->AddSpacer(space5); + + panel->SetSizerAndFit(main_szr); + main_szr->SetSizeHints(this); +} + +wxNotebook* NetPlaySetupFrame::CreateNotebookGUI(wxWindow* parent) +{ + const int space5 = FromDIP(5); + + wxNotebook* const notebook = new wxNotebook(parent, wxID_ANY); + wxPanel* const connect_tab = new wxPanel(notebook, wxID_ANY); + notebook->AddPage(connect_tab, _("Connect")); + wxPanel* const host_tab = new wxPanel(notebook, wxID_ANY); + notebook->AddPage(host_tab, _("Host")); // connect tab { m_ip_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Host Code :")); - - std::string last_hash_code; - netplay_section.Get("HostCode", &last_hash_code, "00000000"); - std::string last_ip_address; - netplay_section.Get("Address", &last_ip_address, "127.0.0.1"); - m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(last_ip_address)); - m_connect_hashcode_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(last_hash_code)); + m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, "127.0.0.1"); + m_connect_hashcode_text = new wxTextCtrl(connect_tab, wxID_ANY, "00000000"); // Will be overridden by OnDirectTraversalChoice, but is necessary // so that both inputs do not take up space m_connect_hashcode_text->Hide(); m_client_port_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Port :")); - - // string? w/e - std::string port; - netplay_section.Get("ConnectPort", &port, - std::to_string(NetPlayHostConfig::DEFAULT_LISTEN_PORT)); - m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(port)); + m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, + std::to_string(NetPlayHostConfig::DEFAULT_LISTEN_PORT)); wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, _("Connect")); connect_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnJoin, this); @@ -139,19 +203,22 @@ NetPlaySetupFrame::NetPlaySetupFrame(wxWindow* const parent, const CGameListCtrl "Wiimote netplay is experimental and should not be expected to work.\n")); wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL); - - top_szr->Add(m_ip_lbl, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); - top_szr->Add(m_connect_ip_text, 3); - top_szr->Add(m_connect_hashcode_text, 3); - top_szr->Add(m_client_port_lbl, 0, wxCENTER | wxRIGHT | wxLEFT, 5); - top_szr->Add(m_connect_port_text, 1); + top_szr->Add(m_ip_lbl, 0, wxALIGN_CENTER_VERTICAL); + top_szr->Add(m_connect_ip_text, 3, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + top_szr->Add(m_connect_hashcode_text, 3, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + top_szr->Add(m_client_port_lbl, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + top_szr->Add(m_connect_port_text, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); wxBoxSizer* const con_szr = new wxBoxSizer(wxVERTICAL); - con_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5); + con_szr->AddSpacer(space5); + con_szr->Add(top_szr, 0, wxEXPAND | wxLEFT | wxRIGHT, space5); con_szr->AddStretchSpacer(1); - con_szr->Add(alert_lbl, 0, wxLEFT | wxRIGHT | wxEXPAND, 5); + con_szr->AddSpacer(space5); + con_szr->Add(alert_lbl, 0, wxEXPAND | wxLEFT | wxRIGHT, space5); con_szr->AddStretchSpacer(1); - con_szr->Add(connect_btn, 0, wxALL | wxALIGN_RIGHT, 5); + con_szr->AddSpacer(space5); + con_szr->Add(connect_btn, 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, space5); + con_szr->AddSpacer(space5); connect_tab->SetSizerAndFit(con_szr); } @@ -159,21 +226,13 @@ NetPlaySetupFrame::NetPlaySetupFrame(wxWindow* const parent, const CGameListCtrl // host tab { m_host_port_lbl = new wxStaticText(host_tab, wxID_ANY, _("Port :")); - - // string? w/e - std::string port; - netplay_section.Get("HostPort", &port, std::to_string(NetPlayHostConfig::DEFAULT_LISTEN_PORT)); - m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, StrToWxStr(port)); + m_host_port_text = + new wxTextCtrl(host_tab, wxID_ANY, std::to_string(NetPlayHostConfig::DEFAULT_LISTEN_PORT)); m_traversal_listen_port_enabled = new wxCheckBox(host_tab, wxID_ANY, _("Force Listen Port: ")); m_traversal_listen_port = new wxSpinCtrl(host_tab, wxID_ANY, "", wxDefaultPosition, - wxSize(80, -1), wxSP_ARROW_KEYS, 1, 65535); - - unsigned int listen_port; - netplay_section.Get("ListenPort", &listen_port, 0); - m_traversal_listen_port_enabled->SetValue(listen_port != 0); - m_traversal_listen_port->Enable(m_traversal_listen_port_enabled->IsChecked()); - m_traversal_listen_port->SetValue(listen_port); + wxDefaultSize, wxSP_ARROW_KEYS, 1, 65535); + m_traversal_listen_port->SetMinSize(WxUtils::GetTextWidgetMinSize(m_traversal_listen_port)); m_traversal_listen_port_enabled->Bind(wxEVT_CHECKBOX, &NetPlaySetupFrame::OnTraversalListenPortChanged, this); @@ -187,63 +246,35 @@ NetPlaySetupFrame::NetPlaySetupFrame(wxWindow* const parent, const CGameListCtrl new wxListBox(host_tab, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxLB_SORT); m_game_lbox->Bind(wxEVT_LISTBOX_DCLICK, &NetPlaySetupFrame::OnHost, this); - NetPlayDialog::FillWithGameNames(m_game_lbox, *game_list); - - std::string last_hosted_game; - if (netplay_section.Get("SelectedHostGame", &last_hosted_game, "")) - m_game_lbox->SetStringSelection(last_hosted_game); + NetPlayDialog::FillWithGameNames(m_game_lbox, *m_game_list); wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL); - top_szr->Add(m_host_port_lbl, 0, wxCENTER | wxRIGHT, 5); - top_szr->Add(m_host_port_text, 0); + top_szr->Add(m_host_port_lbl, 0, wxALIGN_CENTER_VERTICAL); + top_szr->Add(m_host_port_text, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); #ifdef USE_UPNP m_upnp_chk = new wxCheckBox(host_tab, wxID_ANY, _("Forward port (UPnP)")); - top_szr->Add(m_upnp_chk, 0, wxALL, 5); + top_szr->Add(m_upnp_chk, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); #endif + wxBoxSizer* const bottom_szr = new wxBoxSizer(wxHORIZONTAL); - bottom_szr->Add(m_traversal_listen_port_enabled, 0, wxCENTER | wxLEFT, 5); - bottom_szr->Add(m_traversal_listen_port, 0, wxCENTER, 0); - wxBoxSizer* const host_btn_szr = new wxBoxSizer(wxVERTICAL); - host_btn_szr->Add(host_btn, 0, wxCENTER | wxALIGN_RIGHT, 0); - bottom_szr->Add(host_btn_szr, 1, wxALL, 5); + bottom_szr->Add(m_traversal_listen_port_enabled, 0, wxALIGN_CENTER_VERTICAL); + bottom_szr->Add(m_traversal_listen_port, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + bottom_szr->AddStretchSpacer(); + bottom_szr->Add(host_btn, 0, wxLEFT, space5); wxBoxSizer* const host_szr = new wxBoxSizer(wxVERTICAL); - host_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5); - host_szr->Add(m_game_lbox, 1, wxLEFT | wxRIGHT | wxEXPAND, 5); - host_szr->Add(bottom_szr, 0, wxEXPAND, 0); + // NOTE: Top row can disappear entirely + host_szr->Add(top_szr, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, space5); + host_szr->AddSpacer(space5); + host_szr->Add(m_game_lbox, 1, wxEXPAND | wxLEFT | wxRIGHT, space5); + host_szr->AddSpacer(space5); + host_szr->Add(bottom_szr, 0, wxEXPAND | wxLEFT | wxRIGHT, space5); + host_szr->AddSpacer(space5); host_tab->SetSizerAndFit(host_szr); } - // bottom row - wxButton* const quit_btn = new wxButton(panel, wxID_ANY, _("Quit")); - quit_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnQuit, this); - - // main sizer - wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); - main_szr->Add(trav_szr, 0, wxALL | wxALIGN_LEFT, 5); - main_szr->Add(nick_szr, 0, wxALL | wxALIGN_LEFT, 5); - main_szr->Add(m_traversal_lbl, 0, wxALL | wxALIGN_LEFT, 5); - main_szr->Add(m_notebook, 1, wxLEFT | wxRIGHT | wxEXPAND, 5); - main_szr->Add(quit_btn, 0, wxALL | wxALIGN_RIGHT, 5); - - panel->SetSizerAndFit(main_szr); - - // Handle focus on tab changes - panel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &NetPlaySetupFrame::OnTabChanged, this); - - // wxBoxSizer* const diag_szr = new wxBoxSizer(wxVERTICAL); - // diag_szr->Add(panel, 1, wxEXPAND); - // SetSizerAndFit(diag_szr); - - main_szr->SetSizeHints(this); - - Center(); - Show(); - - // Needs to be done last or it set up the spacing on the page correctly - wxCommandEvent ev; - OnDirectTraversalChoice(ev); + return notebook; } NetPlaySetupFrame::~NetPlaySetupFrame() @@ -278,6 +309,10 @@ NetPlaySetupFrame::~NetPlaySetupFrame() m_traversal_listen_port->GetValue() : 0); +#ifdef USE_UPNP + netplay_section.Set("UseUPNP", m_upnp_chk->GetValue(), false); +#endif + inifile.Save(dolphin_ini); main_frame->g_NetPlaySetupDiag = nullptr; } @@ -395,7 +430,7 @@ void NetPlaySetupFrame::OnDirectTraversalChoice(wxCommandEvent& event) if (sel == TRAVERSAL_CHOICE) { - m_traversal_lbl->Show(); + m_traversal_lbl->SetLabelText(m_traversal_string); m_trav_reset_btn->Show(); m_connect_hashcode_text->Show(); m_connect_ip_text->Hide(); @@ -420,7 +455,7 @@ void NetPlaySetupFrame::OnDirectTraversalChoice(wxCommandEvent& event) } else { - m_traversal_lbl->Hide(); + m_traversal_lbl->SetLabel(wxEmptyString); m_trav_reset_btn->Hide(); m_connect_hashcode_text->Hide(); m_connect_ip_text->Show(); @@ -446,7 +481,19 @@ void NetPlaySetupFrame::OnDirectTraversalChoice(wxCommandEvent& event) m_upnp_chk->Show(); #endif } - m_connect_ip_text->GetParent()->Layout(); + + // wxWidgets' layout engine sucks. It only updates when a size event occurs so we + // have to manually invoke the layout system. + // Caveat: This only works if the new layout is not substantially different from the + // old one because otherwise the minimum sizes assigned by SetSizerAndFit won't make + // sense and the layout will break (overlapping widgets). You can't just SetSizeHints + // because that will change the current sizes as well as the minimum sizes, it's a mess. + for (wxWindow* tab : m_notebook->GetChildren()) + tab->Layout(); + // Because this is a wxFrame, not a dialog, everything is inside a wxPanel which + // is the only direct child of the frame. + GetChildren()[0]->Layout(); + DispatchFocus(); } @@ -476,16 +523,8 @@ void NetPlaySetupFrame::OnTabChanged(wxCommandEvent& event) // Propagate event event.Skip(); - // Delaying action so the first tab order element doesn't override the focus - m_notebook->Bind(wxEVT_IDLE, &NetPlaySetupFrame::OnAfterTabChange, this); -} - -void NetPlaySetupFrame::OnAfterTabChange(wxIdleEvent&) -{ - // Unbinding so we don't hog the idle event - m_notebook->Unbind(wxEVT_IDLE, &NetPlaySetupFrame::OnAfterTabChange, this); - - DispatchFocus(); + // Let the base class fiddle with the focus first then correct it afterwards + CallAfter(&NetPlaySetupFrame::DispatchFocus); } void NetPlaySetupFrame::DispatchFocus() diff --git a/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.h b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.h index be565b1452..a91e26989b 100644 --- a/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.h +++ b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.h @@ -12,6 +12,7 @@ class CGameListCtrl; class wxCheckBox; class wxChoice; class wxListBox; +class wxNotebook; class wxSpinCtrl; class wxStaticText; class wxTextCtrl; @@ -29,7 +30,9 @@ private: static constexpr int DIRECT_CHOICE = 0; static constexpr int TRAVERSAL_CHOICE = 1; - void GetWindowRect(const IniFile::Section& section, wxRect* rect) const; + void CreateGUI(); + wxNotebook* CreateNotebookGUI(wxWindow* parent); + void OnJoin(wxCommandEvent& event); void OnHost(wxCommandEvent& event); void DoJoin(); @@ -40,7 +43,6 @@ private: void OnTraversalListenPortChanged(wxCommandEvent& event); void OnKeyDown(wxKeyEvent& event); void OnTabChanged(wxCommandEvent& event); - void OnAfterTabChange(wxIdleEvent& event); void DispatchFocus(); wxStaticText* m_ip_lbl; @@ -63,5 +65,6 @@ private: wxCheckBox* m_upnp_chk; #endif + wxString m_traversal_string; const CGameListCtrl* const m_game_list; }; diff --git a/Source/Core/DolphinWX/NetPlay/NetWindow.cpp b/Source/Core/DolphinWX/NetPlay/NetWindow.cpp index 18dabd91e2..1c7a7dc57f 100644 --- a/Source/Core/DolphinWX/NetPlay/NetWindow.cpp +++ b/Source/Core/DolphinWX/NetPlay/NetWindow.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -67,12 +69,51 @@ NetPlayDialog::NetPlayDialog(wxWindow* const parent, const CGameListCtrl* const m_host_copy_btn_is_retry(false), m_is_hosting(is_hosting), m_game_list(game_list) { Bind(wxEVT_THREAD, &NetPlayDialog::OnThread, this); + CreateGUI(); + Center(); + // Remember the window size and position for NetWindow + { + IniFile inifile; + inifile.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); + IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay"); + + int winPosX, winPosY, winWidth, winHeight; + netplay_section.Get("NetWindowPosX", &winPosX, std::numeric_limits::min()); + netplay_section.Get("NetWindowPosY", &winPosY, std::numeric_limits::min()); + netplay_section.Get("NetWindowWidth", &winWidth, -1); + netplay_section.Get("NetWindowHeight", &winHeight, -1); + + WxUtils::SetWindowSizeAndFitToScreen(this, wxPoint(winPosX, winPosY), + wxSize(winWidth, winHeight), GetSize()); + } +} + +void NetPlayDialog::CreateGUI() +{ + const int space5 = FromDIP(5); + + // NOTE: The design operates top down. Margins / padding are handled by the outermost + // sizers, this makes the design easier to change. Inner sizers should only pad between + // widgets, they should never have prepended or appended margins/spacers. wxPanel* const panel = new wxPanel(this); + wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); + main_szr->AddSpacer(space5); + main_szr->Add(CreateTopGUI(panel), 0, wxEXPAND | wxLEFT | wxRIGHT, space5); + main_szr->AddSpacer(space5); + main_szr->Add(CreateMiddleGUI(panel), 1, wxEXPAND | wxLEFT | wxRIGHT, space5); + main_szr->AddSpacer(space5); + main_szr->Add(CreateBottomGUI(panel), 0, wxEXPAND | wxLEFT | wxRIGHT, space5); + main_szr->AddSpacer(space5); - wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL); + panel->SetSizerAndFit(main_szr); + main_szr->SetSizeHints(this); + SetSize(FromDIP(wxSize(768, 768 - 128))); +} - m_game_btn = new wxButton(panel, wxID_ANY, StrToWxStr(m_selected_game).Prepend(_(" Game : ")), +wxSizer* NetPlayDialog::CreateTopGUI(wxWindow* parent) +{ + m_game_btn = new wxButton(parent, wxID_ANY, _(" Game : ") + StrToWxStr(m_selected_game), wxDefaultPosition, wxDefaultSize, wxBU_LEFT); if (m_is_hosting) @@ -80,11 +121,12 @@ NetPlayDialog::NetPlayDialog(wxWindow* const parent, const CGameListCtrl* const else m_game_btn->Disable(); - top_szr->Add(m_game_btn, 1, wxALL | wxEXPAND); + wxBoxSizer* top_szr = new wxBoxSizer(wxHORIZONTAL); + top_szr->Add(m_game_btn, 1, wxEXPAND); if (m_is_hosting) { - m_MD5_choice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(150, -1)); + m_MD5_choice = new wxChoice(parent, wxID_ANY, wxDefaultPosition, FromDIP(wxSize(150, -1))); m_MD5_choice->Bind(wxEVT_CHOICE, &NetPlayDialog::OnMD5ComputeRequested, this); m_MD5_choice->Append(_("MD5 check...")); m_MD5_choice->Append(_("Current game")); @@ -92,59 +134,89 @@ NetPlayDialog::NetPlayDialog(wxWindow* const parent, const CGameListCtrl* const m_MD5_choice->Append(_("SD card")); m_MD5_choice->SetSelection(0); - top_szr->Add(m_MD5_choice, 0, wxALL); + top_szr->Add(m_MD5_choice, 0, wxALIGN_CENTER_VERTICAL); } - // middle crap + return top_szr; +} - // chat - m_chat_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, +wxSizer* NetPlayDialog::CreateMiddleGUI(wxWindow* parent) +{ + const int space5 = FromDIP(5); + + wxBoxSizer* const mid_szr = new wxBoxSizer(wxHORIZONTAL); + mid_szr->Add(CreateChatGUI(parent), 1, wxEXPAND); + mid_szr->Add(CreatePlayerListGUI(parent), 0, wxEXPAND | wxLEFT, space5); + return mid_szr; +} + +wxSizer* NetPlayDialog::CreateChatGUI(wxWindow* parent) +{ + const int space5 = FromDIP(5); + + wxStaticBoxSizer* const chat_szr = new wxStaticBoxSizer(wxVERTICAL, parent, _("Chat")); + parent = chat_szr->GetStaticBox(); + + m_chat_text = new wxTextCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); - m_chat_msg_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString, wxDefaultPosition, - wxSize(-1, 25), wxTE_PROCESS_ENTER); + m_chat_msg_text = new wxTextCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, + wxDefaultSize, wxTE_PROCESS_ENTER); m_chat_msg_text->Bind(wxEVT_TEXT_ENTER, &NetPlayDialog::OnChat, this); m_chat_msg_text->SetMaxLength(2000); wxButton* const chat_msg_btn = - new wxButton(panel, wxID_ANY, _("Send"), wxDefaultPosition, wxSize(-1, 26)); + new wxButton(parent, wxID_ANY, _("Send"), wxDefaultPosition, + wxSize(-1, m_chat_msg_text->GetBestSize().GetHeight())); chat_msg_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnChat, this); wxBoxSizer* const chat_msg_szr = new wxBoxSizer(wxHORIZONTAL); - chat_msg_szr->Add(m_chat_msg_text, 1); - chat_msg_szr->Add(chat_msg_btn, 0); + // NOTE: Remember that fonts are configurable, setting sizes of anything that contains + // text in pixels is dangerous because the text may end up being clipped. + chat_msg_szr->Add(WxUtils::GiveMinSizeDIP(m_chat_msg_text, wxSize(-1, 25)), 1, + wxALIGN_CENTER_VERTICAL); + chat_msg_szr->Add(chat_msg_btn, 0, wxEXPAND); - wxStaticBoxSizer* const chat_szr = new wxStaticBoxSizer(wxVERTICAL, panel, _("Chat")); chat_szr->Add(m_chat_text, 1, wxEXPAND); - chat_szr->Add(chat_msg_szr, 0, wxEXPAND | wxTOP, 5); + chat_szr->Add(chat_msg_szr, 0, wxEXPAND | wxTOP, space5); + return chat_szr; +} - m_player_lbox = new wxListBox(panel, wxID_ANY, wxDefaultPosition, wxSize(256, -1)); +wxSizer* NetPlayDialog::CreatePlayerListGUI(wxWindow* parent) +{ + const int space5 = FromDIP(5); - wxStaticBoxSizer* const player_szr = new wxStaticBoxSizer(wxVERTICAL, panel, _("Players")); + wxStaticBoxSizer* const player_szr = new wxStaticBoxSizer(wxVERTICAL, parent, _("Players")); + // Static box is a widget, new widgets should be children instead of siblings to avoid various + // flickering problems. + parent = player_szr->GetStaticBox(); + + m_player_lbox = new wxListBox(parent, wxID_ANY, wxDefaultPosition, FromDIP(wxSize(256, -1)), 0, + nullptr, wxLB_HSCROLL); - // player list if (m_is_hosting && g_TraversalClient) { - wxBoxSizer* const host_szr = new wxBoxSizer(wxHORIZONTAL); - m_host_type_choice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(76, -1)); + m_host_type_choice = new wxChoice(parent, wxID_ANY, wxDefaultPosition, FromDIP(wxSize(76, -1))); m_host_type_choice->Bind(wxEVT_CHOICE, &NetPlayDialog::OnChoice, this); m_host_type_choice->Append(_("Room ID:")); - host_szr->Add(m_host_type_choice); - - m_host_label = new wxStaticText(panel, wxID_ANY, "555.555.555.555:55555", wxDefaultPosition, - wxDefaultSize, wxST_NO_AUTORESIZE | wxALIGN_LEFT); - // Update() should fix this immediately. - m_host_label->SetLabel(""); - host_szr->Add(m_host_label, 1, wxLEFT | wxCENTER, 5); - - m_host_copy_btn = new wxButton(panel, wxID_ANY, _("Copy")); - m_host_copy_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnCopyIP, this); - m_host_copy_btn->Disable(); - host_szr->Add(m_host_copy_btn, 0, wxLEFT | wxCENTER, 5); - player_szr->Add(host_szr, 0, wxEXPAND | wxBOTTOM, 5); m_host_type_choice->Select(0); + m_host_label = new wxStaticText(parent, wxID_ANY, "555.555.555.555:55555", wxDefaultPosition, + wxDefaultSize, wxST_NO_AUTORESIZE); + // Update() should fix this immediately. + m_host_label->SetLabel(""); + + m_host_copy_btn = new wxButton(parent, wxID_ANY, _("Copy")); + m_host_copy_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnCopyIP, this); + m_host_copy_btn->Disable(); + UpdateHostLabel(); + + wxBoxSizer* const host_szr = new wxBoxSizer(wxHORIZONTAL); + host_szr->Add(m_host_type_choice); + host_szr->Add(m_host_label, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + host_szr->Add(m_host_copy_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + player_szr->Add(host_szr, 0, wxEXPAND, space5); } player_szr->Add(m_player_lbox, 1, wxEXPAND); @@ -152,59 +224,54 @@ NetPlayDialog::NetPlayDialog(wxWindow* const parent, const CGameListCtrl* const if (m_is_hosting) { m_player_lbox->Bind(wxEVT_LISTBOX, &NetPlayDialog::OnPlayerSelect, this); - m_kick_btn = new wxButton(panel, wxID_ANY, _("Kick Player")); + m_kick_btn = new wxButton(parent, wxID_ANY, _("Kick Player")); m_kick_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnKick, this); - player_szr->Add(m_kick_btn, 0, wxEXPAND | wxTOP, 5); m_kick_btn->Disable(); - m_player_config_btn = new wxButton(panel, wxID_ANY, _("Assign Controller Ports")); + m_player_config_btn = new wxButton(parent, wxID_ANY, _("Assign Controller Ports")); m_player_config_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnAssignPads, this); - player_szr->Add(m_player_config_btn, 0, wxEXPAND | wxTOP, 5); + + player_szr->Add(m_kick_btn, 0, wxEXPAND | wxTOP, space5); + player_szr->Add(m_player_config_btn, 0, wxEXPAND | wxTOP, space5); } + return player_szr; +} - wxBoxSizer* const mid_szr = new wxBoxSizer(wxHORIZONTAL); - mid_szr->Add(chat_szr, 1, wxEXPAND | wxRIGHT, 5); - mid_szr->Add(player_szr, 0, wxEXPAND); - - // bottom crap - wxButton* const quit_btn = new wxButton(panel, wxID_ANY, _("Quit Netplay")); - quit_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnQuit, this); +wxSizer* NetPlayDialog::CreateBottomGUI(wxWindow* parent) +{ + const int space5 = FromDIP(5); wxBoxSizer* const bottom_szr = new wxBoxSizer(wxHORIZONTAL); - if (is_hosting) + if (m_is_hosting) { - m_start_btn = new wxButton(panel, wxID_ANY, _("Start")); + m_start_btn = new wxButton(parent, wxID_ANY, _("Start")); m_start_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnStart, this); - bottom_szr->Add(m_start_btn); - bottom_szr->Add(new wxStaticText(panel, wxID_ANY, _("Buffer:")), 0, wxLEFT | wxCENTER, 5); + wxStaticText* buffer_lbl = new wxStaticText(parent, wxID_ANY, _("Buffer:")); wxSpinCtrl* const padbuf_spin = - new wxSpinCtrl(panel, wxID_ANY, std::to_string(INITIAL_PAD_BUFFER_SIZE), wxDefaultPosition, - wxSize(64, -1), wxSP_ARROW_KEYS, 0, 200, INITIAL_PAD_BUFFER_SIZE); + new wxSpinCtrl(parent, wxID_ANY, std::to_string(INITIAL_PAD_BUFFER_SIZE), wxDefaultPosition, + wxDefaultSize, wxSP_ARROW_KEYS, 0, 200, INITIAL_PAD_BUFFER_SIZE); padbuf_spin->Bind(wxEVT_SPINCTRL, &NetPlayDialog::OnAdjustBuffer, this); - bottom_szr->AddSpacer(3); - bottom_szr->Add(padbuf_spin, 0, wxCENTER); - bottom_szr->AddSpacer(5); - m_memcard_write = new wxCheckBox(panel, wxID_ANY, _("Write to memcards/SD")); - bottom_szr->Add(m_memcard_write, 0, wxCENTER); + padbuf_spin->SetMinSize(WxUtils::GetTextWidgetMinSize(padbuf_spin)); + + m_memcard_write = new wxCheckBox(parent, wxID_ANY, _("Write to memcards/SD")); + + bottom_szr->Add(m_start_btn, 0, wxALIGN_CENTER_VERTICAL); + bottom_szr->Add(buffer_lbl, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + bottom_szr->Add(padbuf_spin, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + bottom_szr->Add(m_memcard_write, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, space5); + bottom_szr->AddSpacer(space5); } - bottom_szr->AddSpacer(5); - m_record_chkbox = new wxCheckBox(panel, wxID_ANY, _("Record inputs")); - bottom_szr->Add(m_record_chkbox, 0, wxCENTER); + m_record_chkbox = new wxCheckBox(parent, wxID_ANY, _("Record inputs")); - bottom_szr->AddStretchSpacer(1); + wxButton* quit_btn = new wxButton(parent, wxID_ANY, _("Quit Netplay")); + quit_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnQuit, this); + + bottom_szr->Add(m_record_chkbox, 0, wxALIGN_CENTER_VERTICAL); + bottom_szr->AddStretchSpacer(); bottom_szr->Add(quit_btn); - - // main sizer - wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); - main_szr->Add(top_szr, 0, wxEXPAND | wxALL, 5); - main_szr->Add(mid_szr, 1, wxEXPAND | wxLEFT | wxRIGHT, 5); - main_szr->Add(bottom_szr, 0, wxEXPAND | wxALL, 5); - - panel->SetSizerAndFit(main_szr); - - main_szr->SetSizeHints(this); + return bottom_szr; } NetPlayDialog::~NetPlayDialog() diff --git a/Source/Core/DolphinWX/NetPlay/NetWindow.h b/Source/Core/DolphinWX/NetPlay/NetWindow.h index f6623a8a1c..1dd36c52e4 100644 --- a/Source/Core/DolphinWX/NetPlay/NetWindow.h +++ b/Source/Core/DolphinWX/NetPlay/NetWindow.h @@ -19,6 +19,7 @@ class wxButton; class wxCheckBox; class wxChoice; class wxListBox; +class wxSizer; class wxStaticText; class wxString; class wxTextCtrl; @@ -101,6 +102,13 @@ public: bool IsRecording() override; private: + void CreateGUI(); + wxSizer* CreateTopGUI(wxWindow* parent); + wxSizer* CreateMiddleGUI(wxWindow* parent); + wxSizer* CreateChatGUI(wxWindow* parent); + wxSizer* CreatePlayerListGUI(wxWindow* parent); + wxSizer* CreateBottomGUI(wxWindow* parent); + void OnChat(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); void OnThread(wxThreadEvent& event); @@ -133,7 +141,7 @@ private: wxStaticText* m_host_label; wxChoice* m_host_type_choice; wxButton* m_host_copy_btn; - wxChoice* m_MD5_choice; + wxChoice* m_MD5_choice = nullptr; MD5Dialog* m_MD5_dialog = nullptr; bool m_host_copy_btn_is_retry; bool m_is_hosting; diff --git a/Source/Core/DolphinWX/NetPlay/PadMapDialog.cpp b/Source/Core/DolphinWX/NetPlay/PadMapDialog.cpp index b5e5badc7c..d2bef9a687 100644 --- a/Source/Core/DolphinWX/NetPlay/PadMapDialog.cpp +++ b/Source/Core/DolphinWX/NetPlay/PadMapDialog.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include @@ -10,79 +11,63 @@ #include "Core/NetPlayProto.h" #include "Core/NetPlayServer.h" #include "DolphinWX/NetPlay/PadMapDialog.h" +#include "DolphinWX/WxUtils.h" PadMapDialog::PadMapDialog(wxWindow* parent, NetPlayServer* server, NetPlayClient* client) : wxDialog(parent, wxID_ANY, _("Controller Ports")), m_pad_mapping(server->GetPadMapping()), m_wii_mapping(server->GetWiimoteMapping()), m_player_list(client->GetPlayers()) { - wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL); - h_szr->AddSpacer(10); + const int space5 = FromDIP(5); + const int space10 = FromDIP(10); + + wxGridBagSizer* pad_sizer = new wxGridBagSizer(space5, space10); wxArrayString player_names; player_names.Add(_("None")); - for (auto& player : m_player_list) - player_names.Add(player->name); + for (const auto& player : m_player_list) + player_names.Add(StrToWxStr(player->name)); - for (unsigned int i = 0; i < 4; ++i) - { - wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL); - v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("GC Port ")) + (wxChar)('1' + i))), 1, - wxALIGN_CENTER_HORIZONTAL); + auto build_choice = [&](unsigned int base_idx, unsigned int idx, const PadMappingArray& mapping, + const wxString& port_name) { + pad_sizer->Add(new wxStaticText(this, wxID_ANY, wxString::Format("%s %d", port_name, idx + 1)), + wxGBPosition(0, base_idx + idx), wxDefaultSpan, wxALIGN_CENTER); - m_map_cbox[i] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names); - m_map_cbox[i]->Bind(wxEVT_CHOICE, &PadMapDialog::OnAdjust, this); - if (m_pad_mapping[i] == -1) - { - m_map_cbox[i]->Select(0); - } - else - { - for (unsigned int j = 0; j < m_player_list.size(); j++) - { - if (m_pad_mapping[i] == m_player_list[j]->pid) - m_map_cbox[i]->Select(j + 1); - } - } - - v_szr->Add(m_map_cbox[i], 1); - - h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20); - h_szr->AddSpacer(10); - } - - for (unsigned int i = 0; i < 4; ++i) - { - wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL); - v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Wiimote ")) + (wxChar)('1' + i))), 1, - wxALIGN_CENTER_HORIZONTAL); - - m_map_cbox[i + 4] = + m_map_cbox[base_idx + idx] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names); - m_map_cbox[i + 4]->Bind(wxEVT_CHOICE, &PadMapDialog::OnAdjust, this); - if (m_wii_mapping[i] == -1) - { - m_map_cbox[i + 4]->Select(0); - } - else + m_map_cbox[base_idx + idx]->Select(0); + m_map_cbox[base_idx + idx]->Bind(wxEVT_CHOICE, &PadMapDialog::OnAdjust, this); + if (mapping[idx] != -1) { for (unsigned int j = 0; j < m_player_list.size(); j++) { - if (m_wii_mapping[i] == m_player_list[j]->pid) - m_map_cbox[i + 4]->Select(j + 1); + if (m_pad_mapping[idx] == m_player_list[j]->pid) + { + m_map_cbox[base_idx + idx]->Select(j + 1); + break; + } } } + // Combo boxes break on Windows when wxEXPAND-ed vertically but you can't control the + // direction of expansion in a grid sizer. Solution is to wrap in a box sizer. + wxBoxSizer* wrapper = new wxBoxSizer(wxHORIZONTAL); + wrapper->Add(m_map_cbox[base_idx + idx], 1, wxALIGN_CENTER_VERTICAL); + pad_sizer->Add(wrapper, wxGBPosition(1, base_idx + idx), wxDefaultSpan, wxEXPAND); + }; - v_szr->Add(m_map_cbox[i + 4], 1); - - h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20); - h_szr->AddSpacer(10); + for (unsigned int i = 0; i < 4; ++i) + { + // This looks a little weird but it's fine because we're using a grid bag sizer; + // we can add columns in any order. + build_choice(0, i, m_pad_mapping, _("GC Port")); + build_choice(4, i, m_wii_mapping, _("Wiimote")); } wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); - main_szr->Add(h_szr); - main_szr->AddSpacer(5); - main_szr->Add(CreateButtonSizer(wxOK), 0, wxEXPAND | wxLEFT | wxRIGHT, 20); - main_szr->AddSpacer(5); + main_szr->AddSpacer(space10); + main_szr->Add(pad_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, space10); + main_szr->AddSpacer(space10); + main_szr->Add(CreateButtonSizer(wxOK), 0, wxEXPAND | wxLEFT | wxRIGHT, space10); + main_szr->AddSpacer(space5); SetSizerAndFit(main_szr); SetFocus(); } diff --git a/Source/Core/DolphinWX/NetPlay/PadMapDialog.h b/Source/Core/DolphinWX/NetPlay/PadMapDialog.h index 30d0266555..d8f4167eb6 100644 --- a/Source/Core/DolphinWX/NetPlay/PadMapDialog.h +++ b/Source/Core/DolphinWX/NetPlay/PadMapDialog.h @@ -12,7 +12,9 @@ class NetPlayClient; class NetPlayServer; class Player; +class wxArrayString; class wxChoice; +class wxSizer; class PadMapDialog final : public wxDialog {