|
20 | 20 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 | 21 | // |
22 | 22 |
|
| 23 | +#include <optional> |
| 24 | + |
23 | 25 | #include <wx/wxprec.h> |
24 | 26 | #ifndef WX_PRECOMP |
25 | 27 | #include <wx/wx.h> |
26 | 28 | #endif // WX_PRECOMP |
27 | 29 |
|
28 | 30 | #include "gambit.h" |
29 | | -#include "dlefgreveal.h" |
| 31 | +#include "gamedoc.h" |
30 | 32 |
|
31 | | -namespace Gambit::GUI { |
32 | | -//========================================================================= |
33 | | -// RevealMoveDialog: Member functions |
34 | | -//========================================================================= |
| 33 | +namespace { |
| 34 | + |
| 35 | +using namespace Gambit; |
| 36 | +using namespace Gambit::GUI; |
| 37 | + |
| 38 | +class RevealMoveDialog final : public wxDialog { |
| 39 | + struct PlayerEntry { |
| 40 | + GamePlayer player; |
| 41 | + wxCheckBox *checkbox; |
| 42 | + }; |
| 43 | + std::vector<PlayerEntry> m_entries; |
| 44 | + |
| 45 | + void OnCheckbox(wxCommandEvent &) { UpdateButtonState(); } |
| 46 | + void UpdateButtonState(); |
35 | 47 |
|
36 | | -RevealMoveDialog::RevealMoveDialog(wxWindow *p_parent, GameDocument *p_doc) |
37 | | - : wxDialog(p_parent, wxID_ANY, _("Reveal this move to players"), wxDefaultPosition), m_doc(p_doc) |
| 48 | +public: |
| 49 | + RevealMoveDialog(wxWindow *p_parent, const Game &p_game); |
| 50 | + std::vector<GamePlayer> GetPlayers() const; |
| 51 | +}; |
| 52 | + |
| 53 | +RevealMoveDialog::RevealMoveDialog(wxWindow *p_parent, const Game &p_game) |
| 54 | + : wxDialog(p_parent, wxID_ANY, _("Reveal this move to players"), wxDefaultPosition, |
| 55 | + wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) |
38 | 56 | { |
39 | 57 | auto *topSizer = new wxBoxSizer(wxVERTICAL); |
40 | 58 |
|
41 | | - auto *playerBox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Reveal the move to players")); |
| 59 | + auto *groupLabel = new wxStaticText(this, wxID_ANY, _("Reveal this move to players")); |
| 60 | + auto f = groupLabel->GetFont(); |
| 61 | + f.SetWeight(wxFONTWEIGHT_BOLD); |
| 62 | + groupLabel->SetFont(f); |
| 63 | + topSizer->Add(groupLabel, wxSizerFlags().Border(wxLEFT | wxTOP | wxRIGHT, 10)); |
| 64 | + |
| 65 | + auto *playerBox = new wxBoxSizer(wxVERTICAL); |
| 66 | + playerBox->AddSpacer(3); |
42 | 67 |
|
43 | | - auto *boxSizer = new wxBoxSizer(wxVERTICAL); |
| 68 | + const auto &players = p_game->GetPlayers(); |
| 69 | + m_entries.reserve(players.size()); |
44 | 70 |
|
45 | | - for (size_t pl = 1; pl <= m_doc->NumPlayers(); pl++) { |
46 | | - auto player = m_doc->GetGame()->GetPlayer(pl); |
47 | | - if (player->GetLabel().empty()) { |
48 | | - m_players.push_back( |
49 | | - new wxCheckBox(this, wxID_ANY, wxString(player->GetLabel().c_str(), *wxConvCurrent))); |
| 71 | + for (const auto &player : players) { |
| 72 | + wxString label; |
| 73 | + if (!player->GetLabel().empty()) { |
| 74 | + label = wxString::FromUTF8(player->GetLabel()); |
50 | 75 | } |
51 | 76 | else { |
52 | | - m_players.push_back(new wxCheckBox(this, wxID_ANY, wxString::Format(_T("Player %d"), pl))); |
| 77 | + label = wxString::Format("Player %u", player->GetNumber()); |
53 | 78 | } |
54 | | - m_players[pl]->SetValue(true); |
55 | | - m_players[pl]->SetForegroundColour(m_doc->GetStyle().GetPlayerColor(player)); |
56 | | - boxSizer->Add(m_players[pl], 1, wxALL | wxEXPAND, 0); |
| 79 | + auto *cb = new wxCheckBox(this, wxID_ANY, label); |
| 80 | + cb->SetValue(true); |
| 81 | + cb->Bind(wxEVT_CHECKBOX, &RevealMoveDialog::OnCheckbox, this); |
| 82 | + m_entries.push_back({player, cb}); |
| 83 | + playerBox->Add(cb, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT | wxTOP, 4)); |
57 | 84 | } |
58 | | - playerBox->Add(boxSizer, 1, wxALL | wxEXPAND, 5); |
59 | | - topSizer->Add(playerBox, 1, wxALL | wxEXPAND, 5); |
60 | | - |
61 | | - auto *buttonSizer = new wxBoxSizer(wxHORIZONTAL); |
62 | | - buttonSizer->Add(new wxButton(this, wxID_CANCEL, _("Cancel")), 0, wxALL, 5); |
63 | | - auto *okButton = new wxButton(this, wxID_OK, _("OK")); |
64 | | - okButton->SetDefault(); |
65 | | - buttonSizer->Add(okButton, 0, wxALL, 5); |
66 | | - topSizer->Add(buttonSizer, 0, wxALL | wxALIGN_RIGHT, 5); |
67 | | - |
68 | | - SetSizer(topSizer); |
69 | | - topSizer->Fit(this); |
70 | | - topSizer->SetSizeHints(this); |
71 | | - wxTopLevelWindowBase::Layout(); |
| 85 | + |
| 86 | + topSizer->Add(playerBox, wxSizerFlags(1).Expand().Border(wxALL, 5)); |
| 87 | + |
| 88 | + auto *buttonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL); |
| 89 | + buttonSizer->Realize(); |
| 90 | + topSizer->Add(buttonSizer, wxSizerFlags().Right().Border(wxALL, 10)); |
| 91 | + |
| 92 | + SetSizerAndFit(topSizer); |
72 | 93 | CenterOnParent(); |
| 94 | + UpdateButtonState(); |
73 | 95 | } |
74 | 96 |
|
75 | | -Array<GamePlayer> RevealMoveDialog::GetPlayers() const |
| 97 | +void RevealMoveDialog::UpdateButtonState() |
76 | 98 | { |
77 | | - Array<GamePlayer> players; |
| 99 | + const bool anyChecked = |
| 100 | + std::any_of(m_entries.begin(), m_entries.end(), |
| 101 | + [](const PlayerEntry &entry) { return entry.checkbox->IsChecked(); }); |
| 102 | + FindWindow(wxID_OK)->Enable(anyChecked); |
| 103 | +} |
78 | 104 |
|
79 | | - for (size_t pl = 1; pl <= m_doc->NumPlayers(); pl++) { |
80 | | - if (m_players[pl]->GetValue()) { |
81 | | - players.push_back(m_doc->GetGame()->GetPlayer(pl)); |
| 105 | +std::vector<GamePlayer> RevealMoveDialog::GetPlayers() const |
| 106 | +{ |
| 107 | + std::vector<GamePlayer> result; |
| 108 | + result.reserve(m_entries.size()); |
| 109 | + for (const auto &[player, checkbox] : m_entries) { |
| 110 | + if (checkbox->GetValue()) { |
| 111 | + result.push_back(player); |
82 | 112 | } |
83 | 113 | } |
| 114 | + return result; |
| 115 | +} |
| 116 | +} // anonymous namespace |
84 | 117 |
|
85 | | - return players; |
| 118 | +namespace Gambit::GUI { |
| 119 | + |
| 120 | +std::optional<std::vector<GamePlayer>> RevealMove(wxWindow *p_parent, const Game &p_game) |
| 121 | +{ |
| 122 | + if (RevealMoveDialog dialog(p_parent, p_game); dialog.ShowModal() == wxID_OK) { |
| 123 | + return dialog.GetPlayers(); |
| 124 | + } |
| 125 | + return std::nullopt; |
86 | 126 | } |
87 | 127 |
|
88 | 128 | } // namespace Gambit::GUI |
0 commit comments