-
Notifications
You must be signed in to change notification settings - Fork 0
/
EditPollFrame.cpp
148 lines (122 loc) · 5.37 KB
/
EditPollFrame.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "EditPollFrame.h"
#include "ChoiceInput.h"
#include "DateInput.h"
#include "FloatInput.h"
#include "General.h"
#include "PartyCollection.h"
#include "PollsterCollection.h"
constexpr int ControlPadding = 4;
enum ControlId
{
Ok,
PollsterSelection,
Date,
Reported2pp,
Respondent2pp,
Calc2pp,
Primary, // this must be last as all the primary vote text boxes will follow ...
};
EditPollFrame::EditPollFrame(Function function, OkCallback callback, PartyCollection const& parties, PollsterCollection const& pollsters, Poll poll)
: wxDialog(NULL, 0, (function == Function::New ? "New Poll" : "Edit Poll"), wxDefaultPosition, wxSize(500, 400)),
poll(poll), callback(callback), parties(parties), pollsters(pollsters)
{
int currentY = ControlPadding;
createControls(currentY);
setFinalWindowHeight(currentY);
}
void EditPollFrame::createControls(int & y)
{
createPollsterInput(y);
createDateInput(y);
createReported2ppInput(y);
createRespondent2ppInput(y);
createPrimaryInputs(y);
createCalc2ppLabel(y);
createOkCancelButtons(y);
}
void EditPollFrame::createPollsterInput(int & y)
{
wxArrayString pollsterArray;
for (auto [key, pollster] : pollsters) {
pollsterArray.push_back(pollster.name);
}
int selectedPollster = pollsters.idToIndex(poll.pollster);
auto pollsterCallback = [this](int i) {poll.pollster = pollsters.indexToId(i); };
pollsterInput.reset(new ChoiceInput(this, ControlId::PollsterSelection, "Pollster: ", pollsterArray, selectedPollster,
wxPoint(2, y), pollsterCallback));
y += pollsterInput->Height + ControlPadding;
}
void EditPollFrame::createDateInput(int & y)
{
auto dateCallback = [this](wxDateTime d) {poll.date = d; };
dateInput.reset(new DateInput(this, ControlId::Date, "Date: ", poll.date,
wxPoint(2, y), dateCallback));
y += dateInput->Height + ControlPadding;
}
void EditPollFrame::createReported2ppInput(int & y)
{
auto reported2ppCallback = [this](float f) -> void {poll.reported2pp = f; };
auto reported2ppValidator = [](float f) {if (f == Poll::NullValue) return f; return std::clamp(f, 0.0f, 100.0f); };
reported2ppInput.reset(new FloatInput(this, ControlId::Reported2pp, "Reported 2PP:", poll.reported2pp,
wxPoint(2, y), reported2ppCallback, reported2ppValidator, Poll::NullValue));
y += reported2ppInput->Height + ControlPadding;
}
void EditPollFrame::createRespondent2ppInput(int & y)
{
auto respondent2ppCallback = [this](float f) -> void {poll.respondent2pp = f; };
auto respondent2ppValidator = [](float f) {if (f == Poll::NullValue) return f; return std::clamp(f, 0.0f, 100.0f); };
respondent2ppInput.reset(new FloatInput(this, ControlId::Respondent2pp, "Respondent-allocated 2PP:", poll.respondent2pp,
wxPoint(2, y), respondent2ppCallback, respondent2ppValidator, Poll::NullValue));
y += respondent2ppInput->Height + ControlPadding;
}
void EditPollFrame::createPrimaryInputs(int & y)
{
constexpr float labelWidth = 250;
constexpr float inputWidth = 100;
auto primaryValidator = [](float f) {if (f == Poll::NullValue) return f; return std::clamp(f, 0.0f, 100.0f); };
for (int i = 0; i < parties.count(); i++) {
std::string primaryString = poll.getPrimaryString(i);
std::string partyString = parties.viewByIndex(i).name + " primary vote:";
auto primaryCallback = [this, i](float f) -> void {poll.primary[i] = f; refreshCalculated2PP(); };
primaryVoteInput.emplace_back(std::make_unique<FloatInput>(this, ControlId::Primary + i, partyString, poll.primary[i],
wxPoint(2, y), primaryCallback, primaryValidator, Poll::NullValue, labelWidth, inputWidth));
y += respondent2ppInput->Height + ControlPadding;
}
auto othersCallback = [this](float f) -> void {poll.primary[PartyCollection::MaxParties] = f; refreshCalculated2PP(); };
primaryVoteInput.emplace_back(std::make_unique<FloatInput>(this, ControlId::Primary + PartyCollection::MaxParties,
"Others primary vote:", poll.primary[PartyCollection::MaxParties],
wxPoint(2, y), othersCallback, primaryValidator, Poll::NullValue, labelWidth, inputWidth));
y += respondent2ppInput->Height + ControlPadding;
}
void EditPollFrame::createCalc2ppLabel(int & y)
{
// *** need to replace this with a proper class for handling a double label.
// Create the controls for the estimated 2pp. This can't be edited by the user.
calc2ppStaticText = new wxStaticText(this, 0, "Calculated 2PP:", wxPoint(2, y + ControlPadding), wxSize(198, 23));
calc2ppNumberText = new wxStaticText(this, ControlId::Calc2pp, poll.getCalc2ppString(),
wxPoint(200, y + ControlPadding), wxSize(120, 23));
y += 27;
}
void EditPollFrame::createOkCancelButtons(int & y)
{
// Create the OK and cancel buttons.
okButton = new wxButton(this, ControlId::Ok, "OK", wxPoint(67, y), wxSize(100, FloatInput::Height));
cancelButton = new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(233, y), wxSize(100, FloatInput::Height));
// Bind events to the functions that should be carried out by them.
Bind(wxEVT_BUTTON, &EditPollFrame::OnOK, this, ControlId::Ok);
y += FloatInput::Height + ControlPadding;
}
void EditPollFrame::setFinalWindowHeight(int y)
{
SetClientSize(wxSize(GetClientSize().x, y));
}
void EditPollFrame::OnOK(wxCommandEvent& WXUNUSED(event)) {
callback(poll);
// Then close this dialog.
Close();
}
void EditPollFrame::refreshCalculated2PP() {
// *** need to figure out a way to recalculate poll 2pp without invoking the entire project
parties.recalculatePollCalc2PP(poll);
calc2ppNumberText->SetLabel(poll.getCalc2ppString());
}