diff --git a/src/gui/dlnashmon.cc b/src/gui/dlnashmon.cc index a07ab5a16..7a17b0fed 100644 --- a/src/gui/dlnashmon.cc +++ b/src/gui/dlnashmon.cc @@ -72,10 +72,10 @@ NashMonitorDialog::NashMonitorDialog(wxWindow *p_parent, GameDocument *p_doc, sizer->Add(startSizer, 0, wxALL | wxALIGN_CENTER, 5); if (p_command->IsBehavior()) { - m_profileList = new BehaviorProfileList(this, m_doc); + m_profileList = new MixedBehaviorProfileList(this, m_doc); } else { - m_profileList = new MixedProfileList(this, m_doc); + m_profileList = new MixedStrategyProfileList(this, m_doc); } m_profileList->SetSizeHints(wxSize(500, 300)); sizer->Add(m_profileList, 1, wxALL | wxEXPAND, 5); diff --git a/src/gui/efgprofile.cc b/src/gui/efgprofile.cc index 73ba19805..484ec2531 100644 --- a/src/gui/efgprofile.cc +++ b/src/gui/efgprofile.cc @@ -26,34 +26,37 @@ #endif // WX_PRECOMP #include "efgprofile.h" -#include "renratio.h" // for rational number rendering namespace Gambit::GUI { //------------------------------------------------------------------------- // class BehaviorProfileList: Member functions //------------------------------------------------------------------------- -BehaviorProfileList::BehaviorProfileList(wxWindow *p_parent, GameDocument *p_doc) - : wxSheet(p_parent, wxID_ANY), GameView(p_doc) +MixedBehaviorProfileList::MixedBehaviorProfileList(wxWindow *p_parent, GameDocument *p_doc) + : wxGrid(p_parent, wxID_ANY), GameView(p_doc) { CreateGrid(0, 0); - SetRowLabelWidth(40); - SetColLabelHeight(25); - - Connect(GetId(), wxEVT_SHEET_LABEL_LEFT_DOWN, - (wxObjectEventFunction) reinterpret_cast(wxStaticCastEvent( - wxSheetEventFunction, - static_cast(&BehaviorProfileList::OnLabelClick)))); - - Connect(GetId(), wxEVT_SHEET_CELL_LEFT_DOWN, - (wxObjectEventFunction) reinterpret_cast(wxStaticCastEvent( - wxSheetEventFunction, - static_cast(&BehaviorProfileList::OnCellClick)))); + + SetRowLabelSize(40); + SetColLabelSize(25); + SetCornerLabelValue(wxT("#")); + + EnableEditing(false); + EnableDragGridSize(false); + EnableDragRowSize(false); + EnableDragColSize(false); + + SetCellHighlightPenWidth(0); + SetCellHighlightROPenWidth(0); + + Bind(wxEVT_GRID_LABEL_LEFT_CLICK, &MixedBehaviorProfileList::OnLabelClick, this); + Bind(wxEVT_GRID_CELL_LEFT_CLICK, &MixedBehaviorProfileList::OnCellClick, this); + Bind(wxEVT_GRID_SELECT_CELL, &MixedBehaviorProfileList::OnSelectCell, this); } -BehaviorProfileList::~BehaviorProfileList() = default; +MixedBehaviorProfileList::~MixedBehaviorProfileList() = default; -void BehaviorProfileList::OnLabelClick(wxSheetEvent &p_event) +void MixedBehaviorProfileList::OnLabelClick(wxGridEvent &p_event) { if (p_event.GetCol() == -1) { m_doc->SetCurrentProfile(p_event.GetRow() + 1); @@ -64,32 +67,20 @@ void BehaviorProfileList::OnLabelClick(wxSheetEvent &p_event) const GameAction action = m_doc->GetAction(p_event.GetCol() + 1); m_doc->SetSelectNode(action->GetInfoset()->GetMember(1)); } + + ClearSelection(); } -void BehaviorProfileList::OnCellClick(wxSheetEvent &p_event) +void MixedBehaviorProfileList::OnCellClick(wxGridEvent &p_event) { m_doc->SetCurrentProfile(p_event.GetRow() + 1); + ClearSelection(); } -wxString BehaviorProfileList::GetCellValue(const wxSheetCoords &p_coords) +void MixedBehaviorProfileList::OnSelectCell(wxGridEvent &p_event) { - if (IsRowLabelCell(p_coords)) { - wxString label; - label << (p_coords.GetRow() + 1); - return label; - } - if (IsColLabelCell(p_coords)) { - const GameAction action = m_doc->GetAction(p_coords.GetCol() + 1); - wxString label; - label << action->GetInfoset()->GetNumber() << ": " << action->GetLabel(); - return label; - } - if (IsCornerLabelCell(p_coords)) { - return wxT("#"); - } - - return {m_doc->GetProfiles().GetActionProb(p_coords.GetCol() + 1, p_coords.GetRow() + 1).c_str(), - *wxConvCurrent}; + p_event.Veto(); + ClearSelection(); } static wxColour GetPlayerColor(const GameDocument *p_doc, int p_index) @@ -98,71 +89,88 @@ static wxColour GetPlayerColor(const GameDocument *p_doc, int p_index) return p_doc->GetStyle().GetPlayerColor(action->GetInfoset()->GetPlayer()); } -wxSheetCellAttr BehaviorProfileList::GetAttr(const wxSheetCoords &p_coords, wxSheetAttr_Type) const +void MixedBehaviorProfileList::ResizeGrid(int p_rows, int p_cols) { - const int currentProfile = m_doc->GetCurrentProfile(); - - if (IsRowLabelCell(p_coords)) { - wxSheetCellAttr attr(GetSheetRefData()->m_defaultRowLabelAttr); - if (p_coords.GetRow() + 1 == currentProfile) { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); - } - else { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); - } - attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); - attr.SetOrientation(wxHORIZONTAL); - attr.SetReadOnly(true); - return attr; + if (GetNumberRows() > p_rows) { + DeleteRows(p_rows, GetNumberRows() - p_rows); } - if (IsColLabelCell(p_coords)) { - wxSheetCellAttr attr(GetSheetRefData()->m_defaultColLabelAttr); - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); - attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); - attr.SetOrientation(wxHORIZONTAL); - attr.SetReadOnly(true); - if (p_coords.GetRow() > 0) { - attr.SetForegroundColour(GetPlayerColor(m_doc, p_coords.GetCol())); - } - return attr; + else if (GetNumberRows() < p_rows) { + AppendRows(p_rows - GetNumberRows()); + } + + if (GetNumberCols() > p_cols) { + DeleteCols(p_cols, GetNumberCols() - p_cols); } - if (IsCornerLabelCell(p_coords)) { - return GetSheetRefData()->m_defaultCornerLabelAttr; + else if (GetNumberCols() < p_cols) { + AppendCols(p_cols - GetNumberCols()); } +} - wxSheetCellAttr attr(GetSheetRefData()->m_defaultGridCellAttr); - if (p_coords.GetRow() + 1 == currentProfile) { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); +void MixedBehaviorProfileList::UpdateLabels() +{ + for (int row = 0; row < GetNumberRows(); ++row) { + wxString label; + label << (row + 1); + SetRowLabelValue(row, label); } - else { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); + + for (int col = 0; col < GetNumberCols(); ++col) { + const GameAction action = m_doc->GetAction(col + 1); + + wxString label; + label << action->GetInfoset()->GetNumber() << ": " << action->GetLabel(); + SetColLabelValue(col, label); } - attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); - attr.SetOrientation(wxHORIZONTAL); - attr.SetRenderer(wxSheetCellRenderer(new RationalRendererRefData())); - - try { - const GameAction action = m_doc->GetAction(p_coords.GetCol() + 1); - attr.SetForegroundColour(m_doc->GetStyle().GetPlayerColor(action->GetInfoset()->GetPlayer())); - if (action->GetInfoset()->GetNumber() % 2 == 0) { - attr.SetBackgroundColour(wxColour(250, 250, 250)); - } - else { - attr.SetBackgroundColour(wxColour(225, 225, 225)); +} + +void MixedBehaviorProfileList::UpdateCells() +{ + const int currentProfile = m_doc->GetCurrentProfile(); + + const wxFont normalFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + const wxFont boldFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD); + + for (int row = 0; row < GetNumberRows(); ++row) { + for (int col = 0; col < GetNumberCols(); ++col) { + SetCellValue( + row, col, + wxString(m_doc->GetProfiles().GetActionProb(col + 1, row + 1).c_str(), *wxConvCurrent)); + + wxGridCellAttr *attr = new wxGridCellAttr; + attr->SetFont(row + 1 == currentProfile ? boldFont : normalFont); + attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); + attr->SetReadOnly(true); + + try { + const GameAction action = m_doc->GetAction(col + 1); + attr->SetTextColour(m_doc->GetStyle().GetPlayerColor(action->GetInfoset()->GetPlayer())); + + if (action->GetInfoset()->GetNumber() % 2 == 0) { + attr->SetBackgroundColour(wxColour(250, 250, 250)); + } + else { + attr->SetBackgroundColour(wxColour(225, 225, 225)); + } + } + catch (std::out_of_range &) { + // If GetAction() throws this, just handle it silently; can occur + // when solving a trivial game via the strategic form + } + + SetAttr(row, col, attr); } } - catch (std::out_of_range &) { - // If GetAction() throws this, just handle it silently; can occur - // when solving a trivial game via the strategic form - } - attr.SetReadOnly(true); - return attr; } -void BehaviorProfileList::OnUpdate() +void MixedBehaviorProfileList::OnUpdate() { if (!m_doc->GetGame() || m_doc->NumProfileLists() == 0) { - DeleteRows(0, GetNumberRows()); + if (GetNumberRows() > 0) { + DeleteRows(0, GetNumberRows()); + } + if (GetNumberCols() > 0) { + DeleteCols(0, GetNumberCols()); + } return; } @@ -170,22 +178,15 @@ void BehaviorProfileList::OnUpdate() const int profileLength = m_doc->GetGame()->BehavProfileLength(); BeginBatch(); - if (GetNumberRows() > profiles.NumProfiles()) { - DeleteRows(0, GetNumberRows() - profiles.NumProfiles()); - } - else if (GetNumberRows() < profiles.NumProfiles()) { - InsertRows(0, profiles.NumProfiles() - GetNumberRows()); - } - if (GetNumberCols() > profileLength) { - DeleteCols(0, GetNumberCols() - profileLength); - } - else if (GetNumberCols() < profileLength) { - InsertCols(0, profileLength - GetNumberCols()); - } + ResizeGrid(profiles.NumProfiles(), profileLength); + UpdateLabels(); + UpdateCells(); AutoSizeRows(); - AutoSizeCols(); + AutoSizeColumns(); + + ClearSelection(); EndBatch(); } diff --git a/src/gui/efgprofile.h b/src/gui/efgprofile.h index e70f52ed1..ca492469c 100644 --- a/src/gui/efgprofile.h +++ b/src/gui/efgprofile.h @@ -23,37 +23,27 @@ #ifndef GAMBIT_GUI_EFGPROFILE_H #define GAMBIT_GUI_EFGPROFILE_H -#include "wx/sheet/sheet.h" +#include + #include "gamedoc.h" namespace Gambit::GUI { -class BehaviorProfileList final : public wxSheet, public GameView { - // Overriding wxSheet members for data access - wxString GetCellValue(const wxSheetCoords &) override; - wxSheetCellAttr GetAttr(const wxSheetCoords &p_coords, wxSheetAttr_Type) const override; - - // Overriding wxSheet members to disable selection behavior - bool SelectRow(int, bool = false, bool = false) override { return false; } - bool SelectRows(int, int, bool = false, bool = false) override { return false; } - bool SelectCol(int, bool = false, bool = false) override { return false; } - bool SelectCols(int, int, bool = false, bool = false) override { return false; } - bool SelectCell(const wxSheetCoords &, bool = false, bool = false) override { return false; } - bool SelectBlock(const wxSheetBlock &, bool = false, bool = false) override { return false; } - bool SelectAll(bool = false) override { return false; } - - // Overriding wxSheet member to suppress drawing of cursor - void DrawCursorCellHighlight(wxDC &, const wxSheetCellAttr &) override {} - +class MixedBehaviorProfileList final : public wxGrid, public GameView { // Event handlers - void OnLabelClick(wxSheetEvent &); - void OnCellClick(wxSheetEvent &); + void OnLabelClick(wxGridEvent &); + void OnCellClick(wxGridEvent &); + void OnSelectCell(wxGridEvent &); + + void ResizeGrid(int p_rows, int p_cols); + void UpdateLabels(); + void UpdateCells(); // Overriding GameView members void OnUpdate() override; public: - BehaviorProfileList(wxWindow *p_parent, GameDocument *p_doc); - ~BehaviorProfileList() override; + MixedBehaviorProfileList(wxWindow *p_parent, GameDocument *p_doc); + ~MixedBehaviorProfileList() override; }; } // namespace Gambit::GUI diff --git a/src/gui/gameframe.cc b/src/gui/gameframe.cc index 260030245..75ad3aaf3 100644 --- a/src/gui/gameframe.cc +++ b/src/gui/gameframe.cc @@ -85,7 +85,7 @@ ProfileListPanel::ProfileListPanel(wxWindow *p_parent, GameDocument *p_doc) auto *topSizer = new wxBoxSizer(wxHORIZONTAL); if (p_doc->IsTree()) { - m_behavProfiles = new BehaviorProfileList(this, p_doc); + m_behavProfiles = new MixedBehaviorProfileList(this, p_doc); m_behavProfiles->Show(false); topSizer->Add(m_behavProfiles, 1, wxEXPAND, 0); } @@ -93,7 +93,7 @@ ProfileListPanel::ProfileListPanel(wxWindow *p_parent, GameDocument *p_doc) m_behavProfiles = nullptr; } - m_mixedProfiles = new MixedProfileList(this, p_doc); + m_mixedProfiles = new MixedStrategyProfileList(this, p_doc); m_mixedProfiles->Show(false); topSizer->Add(m_mixedProfiles, 1, wxEXPAND, 0); diff --git a/src/gui/nfgprofile.cc b/src/gui/nfgprofile.cc index 71f125afd..ead4b9e7f 100644 --- a/src/gui/nfgprofile.cc +++ b/src/gui/nfgprofile.cc @@ -26,43 +26,55 @@ #endif // WX_PRECOMP #include "nfgprofile.h" -#include "renratio.h" // for rational number rendering namespace Gambit::GUI { //------------------------------------------------------------------------- // class MixedProfileList: Member functions //------------------------------------------------------------------------- -MixedProfileList::MixedProfileList(wxWindow *p_parent, GameDocument *p_doc) - : wxSheet(p_parent, wxID_ANY), GameView(p_doc), m_showProbs(1), m_showPayoff(0) +MixedStrategyProfileList::MixedStrategyProfileList(wxWindow *p_parent, GameDocument *p_doc) + : wxGrid(p_parent, wxID_ANY), GameView(p_doc) { CreateGrid(0, 0); - SetRowLabelWidth(40); - SetColLabelHeight(25); - - Connect(GetId(), wxEVT_SHEET_LABEL_LEFT_DOWN, - (wxObjectEventFunction) reinterpret_cast(wxStaticCastEvent( - wxSheetEventFunction, - static_cast(&MixedProfileList::OnLabelClick)))); - - Connect(GetId(), wxEVT_SHEET_CELL_LEFT_DOWN, - (wxObjectEventFunction) reinterpret_cast(wxStaticCastEvent( - wxSheetEventFunction, - static_cast(&MixedProfileList::OnCellClick)))); + + SetRowLabelSize(40); + SetColLabelSize(25); + SetCornerLabelValue(wxT("#")); + + EnableEditing(false); + EnableDragGridSize(false); + EnableDragRowSize(false); + EnableDragColSize(false); + + SetCellHighlightPenWidth(0); + SetCellHighlightROPenWidth(0); + + Bind(wxEVT_GRID_LABEL_LEFT_CLICK, &MixedStrategyProfileList::OnLabelClick, this); + Bind(wxEVT_GRID_CELL_LEFT_CLICK, &MixedStrategyProfileList::OnCellClick, this); + Bind(wxEVT_GRID_SELECT_CELL, &MixedStrategyProfileList::OnSelectCell, this); } -MixedProfileList::~MixedProfileList() = default; +MixedStrategyProfileList::~MixedStrategyProfileList() = default; -void MixedProfileList::OnLabelClick(wxSheetEvent &p_event) +void MixedStrategyProfileList::OnLabelClick(wxGridEvent &p_event) { if (p_event.GetCol() == -1) { - m_doc->SetCurrentProfile(RowToProfile(p_event.GetRow())); + m_doc->SetCurrentProfile(p_event.GetRow() + 1); } + + ClearSelection(); +} + +void MixedStrategyProfileList::OnCellClick(wxGridEvent &p_event) +{ + m_doc->SetCurrentProfile(p_event.GetRow() + 1); + ClearSelection(); } -void MixedProfileList::OnCellClick(wxSheetEvent &p_event) +void MixedStrategyProfileList::OnSelectCell(wxGridEvent &p_event) { - m_doc->SetCurrentProfile(RowToProfile(p_event.GetRow())); + p_event.Veto(); + ClearSelection(); } #ifdef UNUSED @@ -81,105 +93,89 @@ static Gambit::GameStrategy GetStrategy(GameDocument *p_doc, int p_index) } #endif -wxString MixedProfileList::GetCellValue(const wxSheetCoords &p_coords) +static wxColour GetPlayerColor(const GameDocument *p_doc, int p_index) { - if (IsRowLabelCell(p_coords)) { - wxString label; - label << RowToProfile(p_coords.GetRow()); - return label; - } - if (IsColLabelCell(p_coords)) { - int index = 0; - for (const auto &player : m_doc->GetGame()->GetPlayers()) { - for (const auto &strategy : player->GetStrategies()) { - if (index++ == p_coords.GetCol()) { - wxString label; - label << player->GetNumber() << ": " << strategy->GetLabel(); - return label; - } + int index = 0; + for (const auto &player : p_doc->GetGame()->GetPlayers()) { + for (const auto &strategy : player->GetStrategies()) { + if (index++ == p_index) { + return p_doc->GetStyle().GetPlayerColor(player); } } - return wxT(""); - } - if (IsCornerLabelCell(p_coords)) { - return wxT("#"); } + return *wxBLACK; +} - const int profile = RowToProfile(p_coords.GetRow()); +void MixedStrategyProfileList::ResizeGrid(int p_rows, int p_cols) +{ + if (GetNumberRows() > p_rows) { + DeleteRows(p_rows, GetNumberRows() - p_rows); + } + else if (GetNumberRows() < p_rows) { + AppendRows(p_rows - GetNumberRows()); + } - if (IsProbabilityRow(p_coords.GetRow())) { - return {m_doc->GetProfiles().GetStrategyProb(p_coords.GetCol() + 1, profile).c_str(), - *wxConvCurrent}; + if (GetNumberCols() > p_cols) { + DeleteCols(p_cols, GetNumberCols() - p_cols); } - else { - return {m_doc->GetProfiles().GetStrategyValue(p_coords.GetCol() + 1, profile).c_str(), - *wxConvCurrent}; + else if (GetNumberCols() < p_cols) { + AppendCols(p_cols - GetNumberCols()); } } -static wxColour GetPlayerColor(const GameDocument *p_doc, int p_index) +void MixedStrategyProfileList::UpdateLabels() { + for (int row = 0; row < GetNumberRows(); ++row) { + wxString label; + label << (row + 1); + SetRowLabelValue(row, label); + } + int index = 0; - for (const auto &player : p_doc->GetGame()->GetPlayers()) { + for (const auto &player : m_doc->GetGame()->GetPlayers()) { for (const auto &strategy : player->GetStrategies()) { - if (index++ == p_index) { - return p_doc->GetStyle().GetPlayerColor(player); - } + wxString label; + label << player->GetNumber() << ": " << strategy->GetLabel(); + SetColLabelValue(index++, label); } } - return *wxBLACK; } -wxSheetCellAttr MixedProfileList::GetAttr(const wxSheetCoords &p_coords, wxSheetAttr_Type) const +void MixedStrategyProfileList::UpdateCells() { const int currentProfile = m_doc->GetCurrentProfile(); - if (IsRowLabelCell(p_coords)) { - wxSheetCellAttr attr(GetSheetRefData()->m_defaultRowLabelAttr); - if (RowToProfile(p_coords.GetRow()) == currentProfile) { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); - } - else { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); - } - attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); - attr.SetOrientation(wxHORIZONTAL); - attr.SetReadOnly(true); - return attr; - } - else if (IsColLabelCell(p_coords)) { - wxSheetCellAttr attr(GetSheetRefData()->m_defaultColLabelAttr); - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); - attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); - attr.SetOrientation(wxHORIZONTAL); - attr.SetReadOnly(true); - attr.SetForegroundColour(GetPlayerColor(m_doc, p_coords.GetCol())); - return attr; - } - else if (IsCornerLabelCell(p_coords)) { - return GetSheetRefData()->m_defaultCornerLabelAttr; - } + const wxFont normalFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + const wxFont boldFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD); - wxSheetCellAttr attr(GetSheetRefData()->m_defaultGridCellAttr); - if (RowToProfile(p_coords.GetRow()) == currentProfile) { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); - } - else { - attr.SetFont(wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); - } - attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); - attr.SetOrientation(wxHORIZONTAL); - attr.SetRenderer(wxSheetCellRenderer(new RationalRendererRefData())); - attr.SetForegroundColour(GetPlayerColor(m_doc, p_coords.GetCol())); + for (int row = 0; row < GetNumberRows(); ++row) { + const int profile = row + 1; + + for (int col = 0; col < GetNumberCols(); ++col) { + SetCellValue(row, col, + wxString(m_doc->GetProfiles().GetStrategyProb(col + 1, profile).c_str(), + *wxConvCurrent)); - attr.SetReadOnly(true); - return attr; + wxGridCellAttr *attr = new wxGridCellAttr; + attr->SetFont(profile == currentProfile ? boldFont : normalFont); + attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER); + attr->SetTextColour(GetPlayerColor(m_doc, col)); + attr->SetReadOnly(true); + + SetAttr(row, col, attr); + } + } } -void MixedProfileList::OnUpdate() +void MixedStrategyProfileList::OnUpdate() { if (m_doc->NumProfileLists() == 0) { - DeleteRows(0, GetNumberRows()); + if (GetNumberRows() > 0) { + DeleteRows(0, GetNumberRows()); + } + if (GetNumberCols() > 0) { + DeleteCols(0, GetNumberCols()); + } return; } @@ -187,31 +183,28 @@ void MixedProfileList::OnUpdate() BeginBatch(); - const int newRows = profiles.NumProfiles() * (m_showProbs + m_showPayoff); - DeleteRows(0, GetNumberRows()); - InsertRows(0, newRows); - - const int profileLength = m_doc->GetGame()->GetStrategies().size(); - const int newCols = profileLength; - DeleteCols(0, GetNumberCols()); - InsertCols(0, newCols); + const int newRows = profiles.NumProfiles(); + const int newCols = m_doc->GetGame()->GetStrategies().size(); - for (int row = 0; row < GetNumberRows(); row += m_showProbs + m_showPayoff) { - SetCellSpan(wxSheetCoords(row, -1), wxSheetCoords(m_showProbs + m_showPayoff, 1)); - } + ResizeGrid(newRows, newCols); + UpdateLabels(); + UpdateCells(); AutoSizeRows(); - AutoSizeCols(); + AutoSizeColumns(); - int colSize = GetColWidth(0); - for (int col = 1; col < GetNumberCols(); col++) { - if (GetColWidth(col) > colSize) { - colSize = GetColWidth(col); + int colSize = 0; + for (int col = 0; col < GetNumberCols(); ++col) { + if (GetColSize(col) > colSize) { + colSize = GetColSize(col); } } - for (int col = 0; col < GetNumberCols(); SetColWidth(col++, colSize)) - ; + for (int col = 0; col < GetNumberCols(); ++col) { + SetColSize(col, colSize); + } + + ClearSelection(); EndBatch(); } diff --git a/src/gui/nfgprofile.h b/src/gui/nfgprofile.h index e8f26ba86..c9029460c 100644 --- a/src/gui/nfgprofile.h +++ b/src/gui/nfgprofile.h @@ -23,44 +23,27 @@ #ifndef GAMBIT_GUI_NFGPROFILE_H #define GAMBIT_GUI_NFGPROFILE_H -#include "wx/sheet/sheet.h" +#include + #include "gamedoc.h" namespace Gambit::GUI { -class MixedProfileList final : public wxSheet, public GameView { - int m_showProbs, m_showPayoff; - - // Overriding wxSheet members for data access - wxString GetCellValue(const wxSheetCoords &) override; - wxSheetCellAttr GetAttr(const wxSheetCoords &p_coords, wxSheetAttr_Type) const override; - - // Overriding wxSheet members to disable selection behavior - bool SelectRow(int, bool = false, bool = false) override { return false; } - bool SelectRows(int, int, bool = false, bool = false) override { return false; } - bool SelectCol(int, bool = false, bool = false) override { return false; } - bool SelectCols(int, int, bool = false, bool = false) override { return false; } - bool SelectCell(const wxSheetCoords &, bool = false, bool = false) override { return false; } - bool SelectBlock(const wxSheetBlock &, bool = false, bool = false) override { return false; } - bool SelectAll(bool = false) override { return false; } - - // Overriding wxSheet member to suppress drawing of cursor - void DrawCursorCellHighlight(wxDC &, const wxSheetCellAttr &) override {} - +class MixedStrategyProfileList final : public wxGrid, public GameView { // Event handlers - void OnLabelClick(wxSheetEvent &); - void OnCellClick(wxSheetEvent &); + void OnLabelClick(wxGridEvent &); + void OnCellClick(wxGridEvent &); + void OnSelectCell(wxGridEvent &); + + void ResizeGrid(int p_rows, int p_cols); + void UpdateLabels(); + void UpdateCells(); // Overriding GameView members void OnUpdate() override; - // Which profile index corresponds to a sheet row - int RowToProfile(int row) const { return row / (m_showProbs + m_showPayoff) + 1; } - bool IsProbabilityRow(int row) const { return (m_showPayoff == 0 || row % 2 == 0); } - bool IsPayoffRow(int row) const { return (m_showProbs == 0 || row % 2 == 1); } - public: - MixedProfileList(wxWindow *p_parent, GameDocument *p_doc); - ~MixedProfileList() override; + MixedStrategyProfileList(wxWindow *p_parent, GameDocument *p_doc); + ~MixedStrategyProfileList() override; }; } // namespace Gambit::GUI