-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.vala
More file actions
161 lines (147 loc) · 4.73 KB
/
main.vala
File metadata and controls
161 lines (147 loc) · 4.73 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
public class Main : Gtk.Application {
enum State {
ARG1,
ARG2,
RESULT,
}
const int MAX_DIGITS = 8;
State state = ARG1;
int arg1 = 0;
int arg2 = 0;
Operation? operation = null;
Gtk.Label display_label = null;
enum Operation {
ADD,
SUB,
MUL,
DIV,
}
int count_digits(int number) {
if (number == 0) return 1;
var count = 0;
while (number.abs() > 0) {
count += 1;
number /= 10;
}
return count;
}
string big_markup(string text) {
return "<span font='Monospace 28'>%s</span>".printf(text);
}
Gtk.Label make_big_label(string text) {
var label = new Gtk.Label(null);
label.set_markup(big_markup(text));
return label;
}
Gtk.Button make_big_button(string text) {
var button = new Gtk.Button();
button.child = make_big_label(text);
return button;
}
Gtk.Button make_digit_button(int digit) {
assert(0 <= digit && digit < 10);
var button = make_big_button(digit.to_string());
button.clicked.connect(() => {
switch (state) {
case ARG1:
if (count_digits(arg1) < MAX_DIGITS) {
arg1 = arg1*10 + digit;
display_label.set_markup(big_markup(arg1.to_string()));
}
break;
case ARG2:
if (count_digits(arg2) < MAX_DIGITS) {
arg2 = arg2*10 + digit;
display_label.set_markup(big_markup(arg2.to_string()));
}
break;
case RESULT:
arg1 = 0;
state = ARG1;
if (count_digits(arg1) < MAX_DIGITS) {
arg1 = arg1*10 + digit;
display_label.set_markup(big_markup(arg1.to_string()));
}
break;
}
});
return button;
}
Gtk.Button make_reset_button() {
var button = make_big_button("C");
button.clicked.connect(() => {
arg1 = 0;
arg2 = 0;
state = ARG1;
operation = null;
display_label.set_markup(big_markup("0"));
});
return button;
}
Gtk.Button make_op_button(string text, Operation op) {
var button = make_big_button(text);
button.clicked.connect(() => {
switch (state) {
case ARG1:
arg2 = 0;
state = ARG2;
operation = op;
break;
case RESULT:
case ARG2:
operation = op;
break;
}
});
return button;
}
Gtk.Button make_equals_button() {
var button = make_big_button("=");
button.clicked.connect(() => {
switch (state) {
case ARG1:
/* nothing */
break;
case ARG2:
case RESULT:
switch (operation) {
case ADD: arg1 = (arg1 + arg2)%100000000; break;
case SUB: arg1 = (arg1 - arg2)%100000000; break;
case MUL: arg1 = (arg1 * arg2)%100000000; break;
case DIV: arg1 = (arg1 / arg2)%100000000; break;
}
display_label.set_markup(big_markup(arg1.to_string()));
state = RESULT;
break;
}
});
return button;
}
public override void activate() {
var win = new Gtk.ApplicationWindow(this);
var grid = new Gtk.Grid();
display_label = make_big_label("0");
display_label.xalign = 1.0f;
grid.attach(display_label, 0, 0, 4);
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col) {
var digit = (3 - row - 1)*3 + col + 1;
grid.attach(make_digit_button(digit), col, row + 1);
}
}
grid.attach(make_reset_button(), 0, 4);
grid.attach(make_digit_button(0), 1, 4);
grid.attach(make_equals_button(), 2, 4);
grid.attach(make_op_button("/", DIV), 3, 1);
grid.attach(make_op_button("*", MUL), 3, 2);
grid.attach(make_op_button("-", SUB), 3, 3);
grid.attach(make_op_button("+", ADD), 3, 4);
win.set_title("Calculator");
win.child = grid;
win.present();
}
public static int main(string[] args) {
var app = new Main();
return app.run(args);
}
}