1 //
2 // This file is part of Gambit
3 // Copyright (c) 1994-2016, The Gambit Project (http://www.gambit-project.org)
4 //
5 // FILE: src/gui/dlefglayout.cc
6 // Declaration of dialog to set tree layout parameters
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 //
22
23 #include <wx/wxprec.h>
24 #ifndef WX_PRECOMP
25 #include <wx/wx.h>
26 #endif // WX_PRECOMP
27 #include <wx/spinctrl.h>
28 #include "dlefglayout.h"
29
30 //==========================================================================
31 // class gbtLayoutDialog: Implementation
32 //==========================================================================
33
34 class gbtLayoutNodesPanel : public wxPanel {
35 private:
36 wxChoice *m_chanceToken, *m_playerToken, *m_terminalToken;
37 wxSpinCtrl *m_nodeSize, *m_terminalSpacing;
38
39 public:
40 gbtLayoutNodesPanel(wxWindow *p_parent, const gbtStyle &p_settings);
41
NodeSize(void) const42 int NodeSize(void) const { return m_nodeSize->GetValue(); }
TerminalSpacing(void) const43 int TerminalSpacing(void) const { return m_terminalSpacing->GetValue(); }
44
ChanceToken(void) const45 int ChanceToken(void) const { return m_chanceToken->GetSelection(); }
PlayerToken(void) const46 int PlayerToken(void) const { return m_playerToken->GetSelection(); }
TerminalToken(void) const47 int TerminalToken(void) const { return m_terminalToken->GetSelection(); }
48 };
49
50
gbtLayoutNodesPanel(wxWindow * p_parent,const gbtStyle & p_settings)51 gbtLayoutNodesPanel::gbtLayoutNodesPanel(wxWindow *p_parent,
52 const gbtStyle &p_settings)
53 : wxPanel(p_parent, -1)
54 {
55 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
56
57 wxStaticBoxSizer *nodeSizer = new wxStaticBoxSizer(wxVERTICAL, this,
58 _T("Drawing nodes"));
59
60 wxFlexGridSizer *tokenSizer = new wxFlexGridSizer(2);
61
62 wxString tokenChoices[] = { _("a line"),
63 _("a box"),
64 _("an unfilled circle"),
65 _("a diamond"),
66 _("a filled circle") };
67
68 tokenSizer->Add(new wxStaticText(this, wxID_STATIC,
69 _("Indicate chance nodes with")),
70 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
71 m_chanceToken = new wxChoice(this, -1,
72 wxDefaultPosition, wxDefaultSize,
73 5, tokenChoices);
74 m_chanceToken->SetSelection(p_settings.ChanceToken());
75 tokenSizer->Add(m_chanceToken, 1, wxALL | wxEXPAND | wxALIGN_CENTER, 5);
76
77 tokenSizer->Add(new wxStaticText(this, wxID_STATIC,
78 _("Indicate player nodes with")),
79 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
80 m_playerToken = new wxChoice(this, -1,
81 wxDefaultPosition, wxDefaultSize,
82 5, tokenChoices);
83 m_playerToken->SetSelection(p_settings.PlayerToken());
84 tokenSizer->Add(m_playerToken, 1, wxALL | wxEXPAND | wxALIGN_CENTER, 5);
85
86 tokenSizer->Add(new wxStaticText(this, wxID_STATIC,
87 _("Indicate terminal nodes with")),
88 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
89 m_terminalToken = new wxChoice(this, -1,
90 wxDefaultPosition, wxDefaultSize,
91 5, tokenChoices);
92 m_terminalToken->SetSelection(p_settings.TerminalToken());
93 tokenSizer->Add(m_terminalToken, 1, wxALL | wxEXPAND | wxALIGN_CENTER, 5);
94
95 nodeSizer->Add(tokenSizer, 1, wxALL | wxEXPAND, 5);
96 topSizer->Add(nodeSizer, 0, wxALL | wxALIGN_CENTER, 5);
97
98
99 wxStaticBoxSizer *sizeSizer = new wxStaticBoxSizer(wxVERTICAL, this,
100 _("Layout sizing"));
101
102 wxFlexGridSizer *gridSizer = new wxFlexGridSizer(2);
103 gridSizer->AddGrowableCol(1);
104
105 gridSizer->Add(new wxStaticText(this, -1, _("Horizontal size of nodes")),
106 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
107
108 const int NODE_LENGTH_MIN = 5;
109 const int NODE_LENGTH_MAX = 100;
110
111 m_nodeSize = new wxSpinCtrl(this, -1,
112 wxString::Format(_T("%d"),
113 p_settings.NodeSize()),
114 wxDefaultPosition, wxDefaultSize,
115 wxSP_ARROW_KEYS,
116 NODE_LENGTH_MIN, NODE_LENGTH_MAX);
117 gridSizer->Add(m_nodeSize, 1, wxEXPAND | wxALL, 5);
118
119 gridSizer->Add(new wxStaticText(this, -1,
120 _("Vertical spacing between terminal nodes")),
121 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
122
123 const int Y_SPACING_MIN = 15;
124 const int Y_SPACING_MAX = 60;
125
126 m_terminalSpacing =
127 new wxSpinCtrl(this, -1,
128 wxString::Format(_T("%d"), p_settings.TerminalSpacing()),
129 wxDefaultPosition, wxDefaultSize,
130 wxSP_ARROW_KEYS, Y_SPACING_MIN, Y_SPACING_MAX);
131 gridSizer->Add(m_terminalSpacing, 1, wxEXPAND | wxALL, 5);
132
133 sizeSizer->Add(gridSizer, 1, wxALL | wxEXPAND, 5);
134 topSizer->Add(sizeSizer, 0, wxALL | wxALIGN_CENTER, 5);
135
136 SetSizer(topSizer);
137 topSizer->Fit(this);
138 topSizer->SetSizeHints(this);
139 Layout();
140 }
141
142 class gbtLayoutBranchesPanel : public wxPanel {
143 private:
144 wxChoice *m_branchStyle, *m_branchLabels;
145 wxSpinCtrl *m_branchLength, *m_tineLength;
146
147 public:
148 gbtLayoutBranchesPanel(wxWindow *p_parent, const gbtStyle &);
149
BranchLength(void) const150 int BranchLength(void) const { return m_branchLength->GetValue(); }
TineLength(void) const151 int TineLength(void) const { return m_tineLength->GetValue(); }
152
BranchStyle(void) const153 int BranchStyle(void) const { return m_branchStyle->GetSelection(); }
BranchLabels(void) const154 int BranchLabels(void) const { return m_branchLabels->GetSelection(); }
155 };
156
gbtLayoutBranchesPanel(wxWindow * p_parent,const gbtStyle & p_settings)157 gbtLayoutBranchesPanel::gbtLayoutBranchesPanel(wxWindow *p_parent,
158 const gbtStyle &p_settings)
159 : wxPanel(p_parent, -1)
160 {
161 const int BRANCH_LENGTH_MIN = 0;
162 const int BRANCH_LENGTH_MAX = 100;
163
164 const int TINE_LENGTH_MIN = 20;
165 const int TINE_LENGTH_MAX = 100;
166
167 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
168
169 wxStaticBoxSizer *styleBoxSizer =
170 new wxStaticBoxSizer(wxHORIZONTAL, this, _("Drawing branches"));
171
172 wxFlexGridSizer *styleSizer = new wxFlexGridSizer(2);
173
174 styleSizer->Add(new wxStaticText(this, wxID_STATIC, _("Draw branches")),
175 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
176 wxString styleChoices[] = { _("using straight lines between nodes"),
177 _("with a tine for branch labels") };
178 m_branchStyle = new wxChoice(this, -1,
179 wxDefaultPosition, wxDefaultSize,
180 2, styleChoices);
181 m_branchStyle->SetSelection(p_settings.BranchStyle());
182 styleSizer->Add(m_branchStyle, 1, wxALL | wxEXPAND, 5);
183
184 styleSizer->Add(new wxStaticText(this, wxID_STATIC, _("Draw labels")),
185 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
186 wxString labelChoices[] = { _("horizontally"),
187 _("rotated parallel to the branch") };
188 m_branchLabels = new wxChoice(this, -1,
189 wxDefaultPosition, wxDefaultSize,
190 2, labelChoices);
191 m_branchLabels->SetSelection(p_settings.BranchLabels());
192 styleSizer->Add(m_branchLabels, 1, wxALL | wxEXPAND, 5);
193
194 styleBoxSizer->Add(styleSizer, 1, wxALL | wxEXPAND, 5);
195 topSizer->Add(styleBoxSizer, 0, wxALL | wxALIGN_CENTER, 5);
196
197 wxStaticBoxSizer *lengthSizer =
198 new wxStaticBoxSizer(wxHORIZONTAL, this, _T("Length of branches"));
199
200 wxFlexGridSizer *gridSizer = new wxFlexGridSizer(2);
201 gridSizer->AddGrowableCol(1);
202
203 gridSizer->Add(new wxStaticText(this, -1, _("Length of branch fork")),
204 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
205 m_branchLength = new wxSpinCtrl(this, -1,
206 wxString::Format(_T("%d"),
207 p_settings.BranchLength()),
208 wxDefaultPosition, wxDefaultSize,
209 wxSP_ARROW_KEYS,
210 BRANCH_LENGTH_MIN, BRANCH_LENGTH_MAX);
211 gridSizer->Add(m_branchLength, 1, wxALL | wxEXPAND, 5);
212
213 gridSizer->Add(new wxStaticText(this, -1, _("Length of branch tine")),
214 1, wxALIGN_CENTER_VERTICAL | wxALL, 5);
215 m_tineLength = new wxSpinCtrl(this, -1,
216 wxString::Format(_T("%d"),
217 p_settings.TineLength()),
218 wxDefaultPosition, wxDefaultSize,
219 wxSP_ARROW_KEYS,
220 TINE_LENGTH_MIN, TINE_LENGTH_MAX);
221 gridSizer->Add(m_tineLength, 1, wxALL | wxEXPAND, 5);
222
223 lengthSizer->Add(gridSizer, 1, wxALL | wxEXPAND, 5);
224 topSizer->Add(lengthSizer, 0, wxALL | wxALIGN_CENTER, 5);
225
226 SetSizer(topSizer);
227 topSizer->Fit(this);
228 topSizer->SetSizeHints(this);
229 Layout();
230 }
231
232 class gbtLayoutInfosetsPanel : public wxPanel {
233 private:
234 wxChoice *m_infosetConnect, *m_infosetJoin;
235
236 public:
237 gbtLayoutInfosetsPanel(wxWindow *p_parent, const gbtStyle &);
238
InfosetConnect(void) const239 int InfosetConnect(void) const { return m_infosetConnect->GetSelection(); }
InfosetJoin(void) const240 int InfosetJoin(void) const { return m_infosetJoin->GetSelection(); }
241 };
242
gbtLayoutInfosetsPanel(wxWindow * p_parent,const gbtStyle & p_settings)243 gbtLayoutInfosetsPanel::gbtLayoutInfosetsPanel(wxWindow *p_parent,
244 const gbtStyle &p_settings)
245 : wxPanel(p_parent, -1)
246 {
247 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
248
249 wxStaticBoxSizer *infosetSizer =
250 new wxStaticBoxSizer(wxVERTICAL, this, _("Drawing information sets"));
251
252 wxFlexGridSizer *styleSizer = new wxFlexGridSizer(2);
253
254 styleSizer->Add(new wxStaticText(this, wxID_STATIC,
255 _("Connect members of information sets")),
256 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
257 wxString connectChoices[] = { _("invisibly (don't draw indicators)"),
258 _("only when on the same level"),
259 _("regardless of level") };
260 m_infosetConnect = new wxChoice(this, -1,
261 wxDefaultPosition, wxDefaultSize,
262 3, connectChoices);
263 m_infosetConnect->SetSelection(p_settings.InfosetConnect());
264 styleSizer->Add(m_infosetConnect, 0, wxALL, 5);
265
266 styleSizer->Add(new wxStaticText(this, wxID_STATIC,
267 _("Draw information set connections")),
268 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
269 wxString joinChoices[] = { _("using lines"),
270 _("using bubbles") };
271 m_infosetJoin = new wxChoice(this, -1,
272 wxDefaultPosition, wxDefaultSize,
273 2, joinChoices);
274 m_infosetJoin->SetSelection(p_settings.InfosetJoin());
275 styleSizer->Add(m_infosetJoin, 0, wxALL | wxEXPAND, 5);
276 infosetSizer->Add(styleSizer, 0, wxALL | wxALIGN_CENTER, 5);
277 topSizer->Add(infosetSizer, 0, wxALL, 5);
278
279 SetSizer(topSizer);
280 topSizer->Fit(this);
281 topSizer->SetSizeHints(this);
282 Layout();
283 }
284
gbtLayoutDialog(wxWindow * p_parent,const gbtStyle & p_settings)285 gbtLayoutDialog::gbtLayoutDialog(wxWindow *p_parent,
286 const gbtStyle &p_settings)
287 : wxDialog(p_parent, -1, _("Layout options"), wxDefaultPosition),
288 m_toDefaults(false)
289 {
290 m_notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize);
291 m_notebook->AddPage(new gbtLayoutNodesPanel(m_notebook, p_settings), _("Nodes"));
292 m_notebook->AddPage(new gbtLayoutBranchesPanel(m_notebook, p_settings), _("Branches"));
293 m_notebook->AddPage(new gbtLayoutInfosetsPanel(m_notebook, p_settings),
294 _("Information sets"));
295
296 wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
297 wxButton *defaultsButton = new wxButton(this, -1, _("Set to defaults"));
298 Connect(defaultsButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
299 wxCommandEventHandler(gbtLayoutDialog::OnSetDefaults));
300 buttonSizer->Add(defaultsButton, 0, wxALL, 5);
301 buttonSizer->Add(new wxButton(this, wxID_CANCEL, _("Cancel")), 0, wxALL, 5);
302 wxButton *okButton = new wxButton(this, wxID_OK, _("OK"));
303 okButton->SetDefault();
304 buttonSizer->Add(okButton, 0, wxALL, 5);
305
306 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
307 topSizer->Add(m_notebook, 0, wxEXPAND | wxALL, 5);
308 topSizer->Add(buttonSizer, 0, wxALL | wxALIGN_RIGHT, 5);
309
310 SetSizer(topSizer);
311 topSizer->Fit(this);
312 topSizer->SetSizeHints(this);
313
314 Layout();
315 CenterOnParent();
316 }
317
GetSettings(gbtStyle & p_settings)318 void gbtLayoutDialog::GetSettings(gbtStyle &p_settings)
319 {
320 if (m_toDefaults) {
321 p_settings.SetDefaults();
322 return;
323 }
324
325 gbtLayoutNodesPanel *nodes = (gbtLayoutNodesPanel *) m_notebook->GetPage(0);
326 p_settings.SetNodeSize(nodes->NodeSize());
327 p_settings.SetTerminalSpacing(nodes->TerminalSpacing());
328 p_settings.SetChanceToken(nodes->ChanceToken());
329 p_settings.SetPlayerToken(nodes->PlayerToken());
330 p_settings.SetTerminalToken(nodes->TerminalToken());
331
332 gbtLayoutBranchesPanel *branches = (gbtLayoutBranchesPanel *) m_notebook->GetPage(1);
333 p_settings.SetBranchLength(branches->BranchLength());
334 p_settings.SetTineLength(branches->TineLength());
335 p_settings.SetBranchStyle(branches->BranchStyle());
336 p_settings.SetBranchLabels(branches->BranchLabels());
337
338 gbtLayoutInfosetsPanel *infosets = (gbtLayoutInfosetsPanel *) m_notebook->GetPage(2);
339 p_settings.SetInfosetConnect(infosets->InfosetConnect());
340 p_settings.SetInfosetJoin(infosets->InfosetJoin());
341 }
342
OnSetDefaults(wxCommandEvent &)343 void gbtLayoutDialog::OnSetDefaults(wxCommandEvent &)
344 {
345 m_toDefaults = true;
346 EndModal(wxID_OK);
347 }
348