Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/gui/dlnashmon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
203 changes: 102 additions & 101 deletions src/gui/efgprofile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<wxEventFunction>(wxStaticCastEvent(
wxSheetEventFunction,
static_cast<wxSheetEventFunction>(&BehaviorProfileList::OnLabelClick))));

Connect(GetId(), wxEVT_SHEET_CELL_LEFT_DOWN,
(wxObjectEventFunction) reinterpret_cast<wxEventFunction>(wxStaticCastEvent(
wxSheetEventFunction,
static_cast<wxSheetEventFunction>(&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);
Expand All @@ -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)
Expand All @@ -98,94 +89,104 @@ 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;
}

const AnalysisOutput &profiles = m_doc->GetProfiles();
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();
}
Expand Down
34 changes: 12 additions & 22 deletions src/gui/efgprofile.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,27 @@
#ifndef GAMBIT_GUI_EFGPROFILE_H
#define GAMBIT_GUI_EFGPROFILE_H

#include "wx/sheet/sheet.h"
#include <wx/grid.h>

#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

Expand Down
4 changes: 2 additions & 2 deletions src/gui/gameframe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ 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);
}
else {
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);

Expand Down
Loading
Loading