rev |
line source |
is_rusinov@64
|
1 import math |
is_rusinov@69
|
2 import random |
is_rusinov@70
|
3 import pickle |
is_rusinov@64
|
4 import tkColorChooser |
is_rusinov@70
|
5 import tkFileDialog |
Ilia@6
|
6 from Tkinter import * |
Ilia@2
|
7 |
is_rusinov@18
|
8 from State import * |
is_rusinov@18
|
9 from Automata import * |
is_rusinov@18
|
10 |
is_rusinov@18
|
11 |
Ilia@2
|
12 class Handlers(object): |
is_rusinov@5
|
13 |
is_rusinov@54
|
14 def __init__(self, cell_size=8, line_width=1 ,delay=10, offset_x=0, offset_y=0):# cell_size is size of cell, including line width, if there is it |
is_rusinov@7
|
15 self.cell_size = cell_size |
is_rusinov@18
|
16 self.line_width = line_width |
is_rusinov@7
|
17 self.delay = delay |
Ilia@6
|
18 self.offset_x = offset_x |
Ilia@6
|
19 self.offset_y = offset_y |
is_rusinov@5
|
20 self.after_id = 0 |
is_rusinov@51
|
21 self.mouse_offset_x = 0 |
is_rusinov@51
|
22 self.mouse_offset_y = 0 |
is_rusinov@18
|
23 self.mouse_zoom = 0 |
is_rusinov@54
|
24 self.zoom_divisor = 1 |
is_rusinov@64
|
25 self.selected_state = None |
is_rusinov@7
|
26 self.is_started = False |
is_rusinov@54
|
27 self.char = None |
is_rusinov@70
|
28 self.keys = {} |
is_rusinov@70
|
29 for index, state in enumerate(automata.states): |
is_rusinov@70
|
30 self.keys[state.key] = index |
is_rusinov@29
|
31 self.draw() |
is_rusinov@5
|
32 def start(self): |
is_rusinov@8
|
33 if not self.is_started: |
is_rusinov@7
|
34 self.is_started = True |
is_rusinov@43
|
35 self.repeat() |
is_rusinov@43
|
36 def repeat(self): |
is_rusinov@43
|
37 self.next_step() |
is_rusinov@43
|
38 self.after_id = canvas.after(self.delay, self.repeat) |
is_rusinov@5
|
39 |
is_rusinov@5
|
40 def stop(self): |
is_rusinov@29
|
41 canvas.after_cancel(self.after_id) |
is_rusinov@7
|
42 self.is_started = False |
is_rusinov@5
|
43 |
is_rusinov@5
|
44 def next_step(self): |
is_rusinov@53
|
45 self.draw_cell(automata.next_step()) |
is_rusinov@5
|
46 |
is_rusinov@18
|
47 def save_file(self): |
is_rusinov@70
|
48 file = tkFileDialog.asksaveasfile(title="Save automata as", filetypes=[('Cyclic cell Automata File', '*.caf')]) |
is_rusinov@70
|
49 print file |
is_rusinov@70
|
50 pickle.dump([automata.field, automata.states], file) |
is_rusinov@5
|
51 |
is_rusinov@18
|
52 def open_file(self): |
is_rusinov@70
|
53 file = tkFileDialog.askopenfile(title="Open file", filetypes=[('Cyclic cell Automata File', '*.caf')]) |
is_rusinov@70
|
54 if file != None: |
is_rusinov@70
|
55 from_file = pickle.load(file) |
is_rusinov@70
|
56 automata.field = from_file[0] |
is_rusinov@70
|
57 automata.height = len(automata.field) |
is_rusinov@70
|
58 automata.width = len(automata.field[0]) |
is_rusinov@70
|
59 automata.states = from_file[1] |
is_rusinov@70
|
60 self.selected_state = None |
is_rusinov@70
|
61 self.refresh_dicts() |
is_rusinov@70
|
62 self.refresh_list() |
is_rusinov@70
|
63 self.hide_automata_window() |
is_rusinov@70
|
64 self.draw() |
is_rusinov@5
|
65 |
is_rusinov@29
|
66 def show_help_window(self): |
Ilia@2
|
67 pass |
is_rusinov@5
|
68 |
is_rusinov@29
|
69 def hide_help_window(self): |
is_rusinov@8
|
70 pass |
is_rusinov@8
|
71 |
is_rusinov@8
|
72 def zoom_in(self, zoom_rate=1): |
is_rusinov@7
|
73 if self.cell_size < 50: |
is_rusinov@8
|
74 self.cell_size = self.cell_size + zoom_rate |
is_rusinov@7
|
75 self.draw() |
is_rusinov@5
|
76 |
is_rusinov@8
|
77 def zoom_out(self, zoom_rate=1): |
is_rusinov@7
|
78 if self.cell_size > 1: |
is_rusinov@8
|
79 self.cell_size = self.cell_size - zoom_rate |
is_rusinov@7
|
80 self.draw() |
is_rusinov@5
|
81 |
is_rusinov@8
|
82 def slower(self, speed_rate=1): |
is_rusinov@7
|
83 self.delay = self.delay + speed_rate |
is_rusinov@5
|
84 |
is_rusinov@8
|
85 def faster(self, speed_rate=1): |
is_rusinov@29
|
86 if self.delay > speed_rate: |
is_rusinov@7
|
87 self.delay = self.delay - speed_rate |
is_rusinov@7
|
88 else: |
is_rusinov@7
|
89 self.delay = 0 |
is_rusinov@5
|
90 |
is_rusinov@70
|
91 def change_size(self): |
is_rusinov@70
|
92 try: |
is_rusinov@70
|
93 dx = int(size_x.get()) - automata.width |
is_rusinov@70
|
94 dy = int(size_y.get()) - automata.height |
is_rusinov@70
|
95 position = side.get() |
is_rusinov@8
|
96 if position == 0 or position == 3 or position == 6: |
is_rusinov@8
|
97 automata.change_size(dx, 3) |
is_rusinov@8
|
98 elif position == 1 or position == 4 or position == 7: |
is_rusinov@8
|
99 automata.change_size(dx / 2, 3) |
is_rusinov@8
|
100 automata.change_size(dx - dx / 2, 1) |
is_rusinov@18
|
101 else: |
is_rusinov@8
|
102 automata.change_size(dx, 1) |
is_rusinov@8
|
103 if position == 0 or position == 1 or position == 2: |
is_rusinov@8
|
104 automata.change_size(dy, 0) |
is_rusinov@8
|
105 elif position == 3 or position == 4 or position == 5: |
is_rusinov@8
|
106 automata.change_size(dy / 2, 0) |
is_rusinov@8
|
107 automata.change_size(dy - dy / 2, 2) |
is_rusinov@18
|
108 else: |
is_rusinov@8
|
109 automata.change_size(dy, 2) |
is_rusinov@8
|
110 self.draw() |
is_rusinov@70
|
111 self.hide_size_window() |
is_rusinov@70
|
112 except Exception: |
is_rusinov@70
|
113 message.config(text="Operation is refused") |
is_rusinov@70
|
114 message.after(2000, self.clear_message) |
darkhan@50
|
115 def draw_cell(self, cells): |
darkhan@50
|
116 for row, col in cells: |
darkhan@42
|
117 index = automata.symbols[automata.field[row][col]] |
darkhan@42
|
118 color = automata.states[index].color |
darkhan@42
|
119 canvas.itemconfig(self.cells[row][col], fill=color) |
darkhan@42
|
120 |
darkhan@32
|
121 def draw(self): |
darkhan@31
|
122 canvas.delete("all") |
darkhan@42
|
123 self.cells = [] |
darkhan@31
|
124 shift = self.cell_size + self.line_width |
darkhan@42
|
125 left = -self.offset_x + self.line_width |
darkhan@42
|
126 top = -self.offset_y + self.line_width |
darkhan@31
|
127 for row in range(automata.height): |
darkhan@42
|
128 self.cells.append([]) |
darkhan@31
|
129 for col in range(automata.width): |
darkhan@31
|
130 index = automata.symbols[automata.field[row][col]] |
darkhan@31
|
131 color = automata.states[index].color |
darkhan@42
|
132 cell = canvas.create_rectangle(left + col * shift, |
darkhan@31
|
133 top + row * shift, |
darkhan@31
|
134 left + col * shift + self.cell_size, |
darkhan@31
|
135 top + row * shift + self.cell_size, |
darkhan@50
|
136 fill=color, outline="", tag="cell") |
darkhan@42
|
137 self.cells[row].append(cell) |
is_rusinov@5
|
138 |
is_rusinov@64
|
139 def draw_line(self, x1, y1, x2, y2, order=1): |
is_rusinov@64
|
140 answer = [] |
is_rusinov@64
|
141 if abs(x1 - x2) > abs(y1 - y2): |
is_rusinov@64
|
142 dx = x2 - x1 |
is_rusinov@64
|
143 abs_dx = abs(dx) |
is_rusinov@64
|
144 dy = float(y2 - y1) |
is_rusinov@64
|
145 while x1 != x2: |
is_rusinov@64
|
146 x1 = x1 + dx / abs_dx |
is_rusinov@64
|
147 y1 = y1 + dy / abs_dx |
is_rusinov@64
|
148 answer.append((self.rounding(y1), x1)) |
is_rusinov@64
|
149 else: |
is_rusinov@64
|
150 dx = float(x2 - x1) |
is_rusinov@64
|
151 dy = y2 - y1 |
is_rusinov@64
|
152 abs_dy = abs(dy) |
is_rusinov@64
|
153 while y1 != y2: |
is_rusinov@64
|
154 x1 = x1 + dx / abs_dy |
is_rusinov@64
|
155 y1 = y1 + dy / abs_dy |
is_rusinov@64
|
156 answer.append((y1, self.rounding(x1))) |
is_rusinov@64
|
157 self.new_state(answer, order) |
is_rusinov@64
|
158 |
is_rusinov@64
|
159 def rounding(self, num): |
is_rusinov@64
|
160 return int(num + math.copysign(0.5, num)) |
is_rusinov@64
|
161 |
is_rusinov@64
|
162 def new_state(self, cells, order=1): |
is_rusinov@64
|
163 num_states = len(automata.states) |
is_rusinov@64
|
164 changed_cells = [] |
is_rusinov@64
|
165 for row, col in cells: |
is_rusinov@64
|
166 if col >= 0 and row >= 0: |
is_rusinov@64
|
167 try: |
is_rusinov@64
|
168 index = (automata.symbols[automata.field[row][col]] + num_states + order) % num_states |
is_rusinov@69
|
169 if self.char != None and self.char in self.keys: |
is_rusinov@64
|
170 index = self.keys[self.char] |
is_rusinov@64
|
171 automata.field[row][col] = automata.states[index].symbol |
is_rusinov@64
|
172 changed_cells.append((row, col)) |
is_rusinov@64
|
173 except: |
is_rusinov@64
|
174 pass |
is_rusinov@64
|
175 self.draw_cell(changed_cells) |
is_rusinov@64
|
176 |
is_rusinov@7
|
177 def press1(self, event):# drawer |
is_rusinov@64
|
178 self.col1 = event.x / (self.cell_size + self.line_width) - self.offset_x |
is_rusinov@64
|
179 self.row1 = event.y / (self.cell_size + self.line_width) - self.offset_y |
is_rusinov@64
|
180 if self.col1 >= 0 and self.row1 >= 0: |
is_rusinov@64
|
181 self.new_state([(self.row1, self.col1)]) |
is_rusinov@69
|
182 |
is_rusinov@64
|
183 def motion1(self, event):# drawer |
is_rusinov@64
|
184 col = (event.x - self.offset_x * (self.cell_size + self.line_width)) / (self.cell_size + self.line_width) |
is_rusinov@26
|
185 row = (event.y - self.offset_y * (self.cell_size + self.line_width)) / (self.cell_size + self.line_width) |
is_rusinov@64
|
186 if not (self.col1 == col and self.row1 == row): |
is_rusinov@64
|
187 if abs(self.col1 - col) <= 1 and abs(self.row1 - row) <= 1: |
is_rusinov@64
|
188 self.new_state([(row, col)]) |
is_rusinov@64
|
189 else: |
is_rusinov@64
|
190 self.draw_line(self.col1, self.row1, col, row) |
is_rusinov@64
|
191 self.col1 = col |
is_rusinov@64
|
192 self.row1 = row |
is_rusinov@5
|
193 |
is_rusinov@7
|
194 def press3(self, event):# drawer |
is_rusinov@64
|
195 self.col3 = event.x / (self.cell_size + self.line_width) - self.offset_x |
is_rusinov@64
|
196 self.row3 = event.y / (self.cell_size + self.line_width) - self.offset_y |
is_rusinov@64
|
197 if self.col1 >= 0 and self.row1 >= 0: |
is_rusinov@64
|
198 self.new_state([(self.row3, self.col3)], -1) |
is_rusinov@54
|
199 |
is_rusinov@64
|
200 def motion3(self, event):# drawer |
is_rusinov@64
|
201 col = (event.x - self.offset_x * (self.cell_size + self.line_width)) / (self.cell_size + self.line_width) |
is_rusinov@26
|
202 row = (event.y - self.offset_y * (self.cell_size + self.line_width)) / (self.cell_size + self.line_width) |
is_rusinov@64
|
203 if not (self.col3 == col and self.row3 == row): |
is_rusinov@64
|
204 if abs(self.col3 - col) <= 1 and abs(self.row3 - row) <= 1: |
is_rusinov@64
|
205 self.new_state([(row, col)], -1) |
is_rusinov@64
|
206 else: |
is_rusinov@64
|
207 self.draw_line(self.col3, self.row3, col, row, -1) |
is_rusinov@64
|
208 self.col3 = col |
is_rusinov@64
|
209 self.row3 = row |
is_rusinov@5
|
210 |
is_rusinov@54
|
211 def press_key(self, event):# drawer |
is_rusinov@54
|
212 self.char = event.char |
is_rusinov@5
|
213 |
is_rusinov@54
|
214 def release_key(self, event):# drawer |
is_rusinov@54
|
215 self.char = None |
is_rusinov@18
|
216 |
is_rusinov@43
|
217 def press1_ctrl(self, event):# change_offset (B1+ctrl) |
is_rusinov@54
|
218 canvas.focus_set() |
is_rusinov@51
|
219 self.mouse_offset_x = event.x |
is_rusinov@51
|
220 self.mouse_offset_y = event.y |
is_rusinov@18
|
221 |
is_rusinov@43
|
222 def motion1_ctrl(self, event):# change_offset (B1+ctrl) |
is_rusinov@51
|
223 self.offset_x = (event.x - self.mouse_offset_x) / (self.cell_size + self.line_width) |
is_rusinov@51
|
224 self.offset_y = (event.y - self.mouse_offset_y) / (self.cell_size + self.line_width) |
is_rusinov@51
|
225 self.mouse_offset_x = event.x |
is_rusinov@51
|
226 self.mouse_offset_y = event.y |
is_rusinov@18
|
227 self.draw() |
is_rusinov@5
|
228 |
is_rusinov@43
|
229 def press13(self, event):# zoom |
is_rusinov@54
|
230 canvas.focus_set() |
is_rusinov@18
|
231 self.mouse_zoom = event.y |
is_rusinov@5
|
232 |
is_rusinov@43
|
233 def motion13(self, event):# zoom |
is_rusinov@18
|
234 delta = (event.y - self.mouse_zoom) / self.zoom_divisor |
is_rusinov@18
|
235 self.cell_size = self.cell_size + delta |
is_rusinov@18
|
236 if self.cell_size > 50: |
is_rusinov@18
|
237 self.cell_size = 50 |
is_rusinov@18
|
238 if self.cell_size < 1: |
is_rusinov@18
|
239 self.cell_size = 1 |
is_rusinov@18
|
240 self.mouse_zoom = event.y |
is_rusinov@18
|
241 self.draw() |
is_rusinov@5
|
242 |
is_rusinov@8
|
243 def to_top(self):# replace choosen state to top |
is_rusinov@64
|
244 selected = self.selected_state |
is_rusinov@64
|
245 if selected != None: |
is_rusinov@64
|
246 index = selected |
is_rusinov@58
|
247 state = automata.states[index] |
is_rusinov@58
|
248 del automata.states[index] |
is_rusinov@58
|
249 automata.states.insert(0, state) |
is_rusinov@64
|
250 self.selected_state = 0 |
is_rusinov@69
|
251 self.refresh_dicts() |
is_rusinov@58
|
252 self.refresh_list() |
is_rusinov@7
|
253 |
is_rusinov@8
|
254 def to_bottom(self):# replace choosen state to botton |
is_rusinov@64
|
255 selected = self.selected_state |
is_rusinov@64
|
256 if selected != None: |
is_rusinov@64
|
257 index = selected |
is_rusinov@58
|
258 state = automata.states[index] |
is_rusinov@58
|
259 del automata.states[index] |
is_rusinov@58
|
260 automata.states.append(state) |
is_rusinov@64
|
261 self.selected_state = len(automata.states) - 1 |
is_rusinov@69
|
262 self.refresh_dicts() |
is_rusinov@58
|
263 self.refresh_list() |
is_rusinov@7
|
264 |
is_rusinov@8
|
265 def upwards(self): |
is_rusinov@64
|
266 selected = self.selected_state |
is_rusinov@64
|
267 if selected != None: |
is_rusinov@64
|
268 index = selected |
is_rusinov@58
|
269 if index > 0: |
is_rusinov@58
|
270 state = automata.states[index] |
is_rusinov@58
|
271 del automata.states[index] |
is_rusinov@58
|
272 automata.states.insert(index - 1, state) |
is_rusinov@64
|
273 self.selected_state = index - 1 |
is_rusinov@69
|
274 self.refresh_dicts() |
is_rusinov@58
|
275 self.refresh_list() |
is_rusinov@7
|
276 |
is_rusinov@8
|
277 def downwards(self): |
is_rusinov@64
|
278 selected = self.selected_state |
is_rusinov@64
|
279 if selected != None: |
is_rusinov@64
|
280 index = selected |
is_rusinov@58
|
281 if index < state_list.size() - 1: |
is_rusinov@58
|
282 state = automata.states[index] |
is_rusinov@58
|
283 del automata.states[index] |
is_rusinov@58
|
284 automata.states.insert(index + 1, state) |
is_rusinov@64
|
285 self.selected_state = index + 1 |
is_rusinov@69
|
286 self.refresh_dicts() |
is_rusinov@58
|
287 self.refresh_list() |
is_rusinov@7
|
288 |
is_rusinov@8
|
289 def delete_state(self):# delete choosen state |
is_rusinov@64
|
290 selected = self.selected_state |
is_rusinov@69
|
291 if selected != None and len(automata.states) != 1: |
is_rusinov@64
|
292 index = selected |
is_rusinov@69
|
293 symbol = automata.states[index].symbol |
is_rusinov@65
|
294 del automata.states[index] |
is_rusinov@69
|
295 self.refresh_dicts() |
is_rusinov@65
|
296 if index in automata.states: |
is_rusinov@65
|
297 self.selected_state = index |
is_rusinov@69
|
298 else: |
is_rusinov@65
|
299 self.selected_state = len(automata.states) - 1 |
is_rusinov@58
|
300 self.refresh_list() |
is_rusinov@65
|
301 self.select_item(self.selected_state) |
is_rusinov@69
|
302 self.draw_changed_state(symbol, automata.states[0].symbol) |
is_rusinov@69
|
303 else: |
is_rusinov@69
|
304 error.config(text="Operation is refused") |
is_rusinov@69
|
305 error.after(2000, self.clear_error) |
is_rusinov@7
|
306 |
is_rusinov@18
|
307 def add(self):# add new state |
is_rusinov@29
|
308 name = state_name.get() |
is_rusinov@48
|
309 symbol = state_symbol.get() |
is_rusinov@54
|
310 key = state_key.get().lower() |
is_rusinov@64
|
311 color = state_color.cget("bg") |
is_rusinov@29
|
312 nums = [] |
is_rusinov@29
|
313 for i, value in enumerate(ckeckbox_nums): |
is_rusinov@65
|
314 if value.get() == 1: |
is_rusinov@65
|
315 nums.append(i) |
is_rusinov@54
|
316 if self.keys.has_key(key): |
is_rusinov@29
|
317 error.config(text="State with such key has already existed") |
is_rusinov@69
|
318 error.after(2000, self.clear_error) |
is_rusinov@29
|
319 state_key.focus() |
is_rusinov@29
|
320 elif len(key) != 1: |
is_rusinov@29
|
321 error.config(text="Bad key for state") |
is_rusinov@69
|
322 error.after(2000, self.clear_error) |
is_rusinov@29
|
323 state_key.focus() |
is_rusinov@29
|
324 elif automata.symbols.has_key(symbol): |
is_rusinov@29
|
325 error.config(text="State with such symbol has already existed") |
is_rusinov@69
|
326 error.after(2000, self.clear_error) |
is_rusinov@29
|
327 state_symbol.focus() |
is_rusinov@29
|
328 elif len(symbol) != 1: |
is_rusinov@29
|
329 error.config(text="Bad symbol for state") |
is_rusinov@69
|
330 error.after(2000, self.clear_error) |
is_rusinov@29
|
331 state_symbol.focus() |
is_rusinov@29
|
332 else: |
is_rusinov@69
|
333 state = State(name, symbol, color, key, nums) |
is_rusinov@29
|
334 automata.states.append(state) |
is_rusinov@34
|
335 automata.symbols[symbol] = len(automata.states) - 1 |
is_rusinov@34
|
336 self.keys[key] = len(automata.states) - 1 |
is_rusinov@58
|
337 error.config(text="") |
is_rusinov@65
|
338 self.selected_state = len(automata.states) - 1 |
is_rusinov@58
|
339 self.refresh_list() |
is_rusinov@65
|
340 self.select_item(self.selected_state) |
is_rusinov@66
|
341 automata.st_sym[symbol] = state |
is_rusinov@5
|
342 |
is_rusinov@18
|
343 def change(self):# change chosen state |
is_rusinov@64
|
344 selected = self.selected_state |
is_rusinov@64
|
345 if selected != None: |
is_rusinov@64
|
346 index = selected |
is_rusinov@58
|
347 name = state_name.get() |
is_rusinov@58
|
348 symbol = state_symbol.get() |
is_rusinov@58
|
349 key = state_key.get().lower() |
is_rusinov@64
|
350 color = state_color.cget("bg") |
is_rusinov@58
|
351 nums = [] |
is_rusinov@58
|
352 for i, value in enumerate(ckeckbox_nums): |
is_rusinov@58
|
353 if value.get() == 1: |
is_rusinov@58
|
354 nums.append(i) |
is_rusinov@58
|
355 if self.keys.has_key(key) and self.keys[key] != index: |
is_rusinov@58
|
356 error.config(text="State with such key has already existed") |
is_rusinov@69
|
357 error.after(2000, self.clear_error) |
is_rusinov@58
|
358 state_key.focus() |
is_rusinov@58
|
359 elif len(key) != 1: |
is_rusinov@58
|
360 error.config(text="Bad key for state") |
is_rusinov@69
|
361 error.after(2000, self.clear_error) |
is_rusinov@58
|
362 state_key.focus() |
is_rusinov@58
|
363 elif automata.symbols.has_key(symbol) and automata.symbols[symbol] != index: |
is_rusinov@58
|
364 error.config(text="State with such symbol has already existed") |
is_rusinov@69
|
365 error.after(2000, self.clear_error) |
is_rusinov@58
|
366 state_symbol.focus() |
is_rusinov@58
|
367 elif len(symbol) != 1: |
is_rusinov@58
|
368 error.config(text="Bad symbol for state") |
is_rusinov@69
|
369 error.after(2000, self.clear_error) |
is_rusinov@58
|
370 state_symbol.focus() |
is_rusinov@58
|
371 else: |
is_rusinov@69
|
372 state = State(name, symbol, color, key, nums) |
is_rusinov@69
|
373 self.draw_changed_state(automata.states[index].symbol, symbol) |
is_rusinov@66
|
374 automata.states[index] = state |
is_rusinov@69
|
375 self.refresh_dicts() |
is_rusinov@58
|
376 self.refresh_list() |
is_rusinov@54
|
377 |
is_rusinov@69
|
378 def draw_changed_state(self, symbol_old, symbol_new): |
is_rusinov@69
|
379 cells = [] |
is_rusinov@69
|
380 for row in range(automata.height): |
is_rusinov@69
|
381 for col in range(automata.width): |
is_rusinov@69
|
382 if automata.field[row][col] == symbol_old: |
is_rusinov@69
|
383 automata.field[row][col] = symbol_new |
is_rusinov@69
|
384 cells.append((row, col)) |
is_rusinov@69
|
385 |
is_rusinov@69
|
386 self.draw_cell(cells) |
is_rusinov@69
|
387 |
is_rusinov@18
|
388 def show_size_window(self): |
is_rusinov@18
|
389 size_window.deiconify() |
Ilia@55
|
390 |
is_rusinov@18
|
391 def hide_size_window(self): |
is_rusinov@18
|
392 size_window.withdraw() |
Ilia@55
|
393 |
Ilia@55
|
394 def show_automata_window(self): |
is_rusinov@70
|
395 self.select_item(self.selected_state) |
is_rusinov@70
|
396 self.refresh_list |
Ilia@55
|
397 automata_window.deiconify() |
Ilia@55
|
398 |
Ilia@55
|
399 def hide_automata_window(self): |
Ilia@55
|
400 automata_window.withdraw() |
is_rusinov@65
|
401 |
is_rusinov@58
|
402 def refresh_list(self): |
is_rusinov@58
|
403 state_list.delete(0, "end") |
is_rusinov@58
|
404 for state in automata.states: |
is_rusinov@58
|
405 state_list.insert("end", state) |
is_rusinov@64
|
406 if self.selected_state != None: |
is_rusinov@64
|
407 state_list.selection_set(self.selected_state) |
is_rusinov@65
|
408 |
is_rusinov@65
|
409 def select_item(self, index): |
is_rusinov@65
|
410 if index != None: |
is_rusinov@58
|
411 state = automata.states[index] |
is_rusinov@58
|
412 state_name.delete(0, "end") |
is_rusinov@58
|
413 state_name.insert(0, state.name) |
is_rusinov@58
|
414 state_symbol.delete(0, "end") |
is_rusinov@58
|
415 state_symbol.insert(0, state.symbol) |
is_rusinov@58
|
416 for key in self.keys.keys(): |
is_rusinov@58
|
417 if self.keys[key] == index: |
is_rusinov@58
|
418 state_key.delete(0, "end") |
is_rusinov@58
|
419 state_key.insert(0, key) |
is_rusinov@64
|
420 state_color.config(bg=state.color) |
is_rusinov@58
|
421 for i in range(9): |
is_rusinov@58
|
422 ckeckbox_nums[i].set(i in state.nums) |
is_rusinov@65
|
423 else: |
is_rusinov@65
|
424 state_name.delete(0, "end") |
is_rusinov@65
|
425 state_symbol.delete(0, "end") |
is_rusinov@65
|
426 state_key.delete(0, "end") |
is_rusinov@65
|
427 state_color.config(bg="white") |
is_rusinov@65
|
428 for i in range(9): |
is_rusinov@65
|
429 ckeckbox_nums[i].set(False) |
is_rusinov@64
|
430 |
is_rusinov@65
|
431 def list_mouse_release(self, event): |
is_rusinov@65
|
432 selected = state_list.curselection() |
is_rusinov@65
|
433 self.selected_state = int(selected[0]) |
is_rusinov@65
|
434 if len(selected): |
is_rusinov@65
|
435 self.select_item(self.selected_state) |
is_rusinov@69
|
436 |
is_rusinov@64
|
437 def choose_color(self, event): |
is_rusinov@64
|
438 state_color.config(bg=tkColorChooser.askcolor()[1]) |
is_rusinov@69
|
439 |
is_rusinov@69
|
440 def clear_error(self): |
is_rusinov@69
|
441 error.config(text="") |
is_rusinov@69
|
442 |
is_rusinov@70
|
443 def clear_message(self): |
is_rusinov@70
|
444 message.config(text="") |
is_rusinov@70
|
445 |
is_rusinov@69
|
446 def clean_field(self): |
is_rusinov@69
|
447 symbol = automata.states[0].symbol |
is_rusinov@69
|
448 cells = [] |
is_rusinov@69
|
449 for row in range(automata.height): |
is_rusinov@69
|
450 for col in range(automata.width): |
is_rusinov@69
|
451 if automata.field[row][col] != symbol: |
is_rusinov@69
|
452 automata.field[row][col] = symbol |
is_rusinov@69
|
453 cells.append((row, col)) |
is_rusinov@69
|
454 self.draw_cell(cells) |
is_rusinov@69
|
455 |
is_rusinov@69
|
456 def fill_randomly(self): |
is_rusinov@69
|
457 cells = [] |
is_rusinov@69
|
458 for row in range(automata.height): |
is_rusinov@69
|
459 for col in range(automata.width): |
is_rusinov@69
|
460 automata.field[row][col] = automata.states[random.randint(0, len(automata.states) - 1)].symbol |
is_rusinov@69
|
461 cells.append((row, col)) |
is_rusinov@69
|
462 self.draw_cell(cells) |
is_rusinov@69
|
463 |
is_rusinov@69
|
464 def refresh_dicts(self): |
is_rusinov@69
|
465 automata.symbols = {} |
is_rusinov@69
|
466 automata.st_sym = {} |
is_rusinov@69
|
467 self.keys = {} |
is_rusinov@69
|
468 for index, state in enumerate(automata.states): |
is_rusinov@69
|
469 automata.symbols[state.symbol] = index |
is_rusinov@69
|
470 automata.st_sym[state.symbol] = state |
is_rusinov@69
|
471 self.keys[state.key] = index |
is_rusinov@69
|
472 |
Ilia@55
|
473 |
Ilia@6
|
474 |
Ilia@6
|
475 root = Tk() |
Ilia@36
|
476 root.title("Cyclic Cellular Automata") |
Ilia@6
|
477 |
darkhan@42
|
478 canvas = Canvas(root, background="grey") |
Ilia@6
|
479 canvas.config(width=500, height=400) |
Ilia@6
|
480 |
is_rusinov@54
|
481 automata = Automata() |
Ilia@36
|
482 handlers = Handlers() |
Ilia@36
|
483 |
is_rusinov@54
|
484 canvas.tag_bind("cell", "<1>", handlers.press1) |
is_rusinov@64
|
485 canvas.tag_bind("cell", "<B1-Motion>", handlers.motion1) |
is_rusinov@54
|
486 canvas.tag_bind("cell", "<3>", handlers.press3) |
is_rusinov@64
|
487 canvas.tag_bind("cell", "<B3-Motion>", handlers.motion3) |
is_rusinov@54
|
488 canvas.bind_all("<KeyPress>", handlers.press_key) |
is_rusinov@54
|
489 canvas.bind_all("<KeyRelease>", handlers.release_key) |
is_rusinov@54
|
490 #canvas.bind("<Control-ButtonPress-1>", handlers.press1_ctrl) |
is_rusinov@54
|
491 #canvas.bind("<Control-B1-Motion>", handlers.motion1_ctrl) |
is_rusinov@54
|
492 #canvas.bind("<Shift-ButtonPress-1>", handlers.press13) |
is_rusinov@54
|
493 #canvas.bind("<Shift-ButtonPress-1>", handlers.motion13) |
Ilia@36
|
494 |
Ilia@36
|
495 canvas.pack(fill="both", expand="yes") |
Ilia@6
|
496 |
Ilia@6
|
497 #infoPanel=Frame |
Ilia@55
|
498 automata_window = Toplevel(root) |
Ilia@55
|
499 automata_window.title("Automata") |
Ilia@55
|
500 automata_window.withdraw() |
Ilia@55
|
501 automata_window.resizable(False, False) |
Ilia@55
|
502 automata_window.protocol("WM_DELETE_WINDOW", handlers.hide_automata_window) |
Ilia@9
|
503 |
Ilia@55
|
504 headline = Label(automata_window, text= "Automata Panel", font=16) |
Ilia@55
|
505 headline.pack(side="top",fill="both", expand="no") |
Ilia@9
|
506 |
Ilia@55
|
507 Label(automata_window, text= "State Box:").pack(side="top", fill="x") |
Ilia@56
|
508 |
Ilia@56
|
509 list_frame=Frame(automata_window) |
Ilia@56
|
510 scrollbar = Scrollbar(list_frame) |
Ilia@57
|
511 scrollbar.pack(side="right", fill="y") |
is_rusinov@58
|
512 state_list=Listbox(list_frame, yscrollcommand=scrollbar.set, activestyle="none", selectmode="single") |
is_rusinov@58
|
513 handlers.refresh_list() |
is_rusinov@58
|
514 state_list.bind("<ButtonRelease-1>", handlers.list_mouse_release) |
is_rusinov@7
|
515 state_list.pack(side="top", fill="y") |
Ilia@56
|
516 scrollbar.config(command=state_list.yview) |
Ilia@56
|
517 list_frame.pack(side="top") |
Ilia@56
|
518 |
Ilia@59
|
519 manip_frame1 = Frame(automata_window, padx=10, pady=5) |
Ilia@59
|
520 up = Button(manip_frame1, text="Up", command=handlers.upwards, width=10) |
Ilia@59
|
521 to_top = Button(manip_frame1, text="To Top", command=handlers.to_top, width=10) |
Ilia@59
|
522 up.pack(side="left", fill="x") |
Ilia@59
|
523 to_top.pack(side="right", fill="x") |
Ilia@59
|
524 manip_frame1.pack(side="top", fill="x") |
Ilia@59
|
525 |
Ilia@59
|
526 manip_frame2 = Frame(automata_window, padx=10, pady=5) |
Ilia@59
|
527 down = Button(manip_frame2, text="Down", command=handlers.downwards, width=10) |
Ilia@59
|
528 to_bottom = Button(manip_frame2, text="To Bottom", command=handlers.to_bottom, width=10) |
Ilia@59
|
529 down.pack(side="left", fill="x") |
Ilia@59
|
530 to_bottom.pack(side="right", fill="x") |
Ilia@59
|
531 manip_frame2.pack(side="top", fill="x") |
Ilia@59
|
532 |
Ilia@59
|
533 delete = Button(automata_window, text="Delete", command=handlers.delete_state, width=10) |
Ilia@59
|
534 delete.pack(side="top") |
Ilia@6
|
535 |
Ilia@6
|
536 |
Ilia@55
|
537 information = Label(automata_window, text= "Information of State") |
Ilia@9
|
538 information.pack(side="top", fill="x") |
Ilia@55
|
539 info_frame=Frame(automata_window) |
Ilia@9
|
540 Label(info_frame, text="Name").grid(row=0, column=0) |
Ilia@9
|
541 state_name = Entry(info_frame) |
Ilia@9
|
542 state_name.grid(row=0, column=1) |
Ilia@9
|
543 Label(info_frame, text="Symbol").grid(row=1, column=0) |
Ilia@9
|
544 state_symbol = Entry(info_frame) |
Ilia@9
|
545 state_symbol.grid(row=1, column=1) |
Ilia@60
|
546 Label(info_frame, text="Key").grid(row=2, column=0) |
Ilia@9
|
547 state_key = Entry(info_frame) |
Ilia@60
|
548 state_key.grid(row=2, column=1) |
Ilia@60
|
549 Label(info_frame, text="Color").grid(row=3, column=0) |
Ilia@60
|
550 state_color = Label(info_frame, background="white", cursor="plus") |
Ilia@60
|
551 state_color.grid(row=3, column=1, sticky="ew") |
is_rusinov@64
|
552 state_color.bind('<1>', handlers.choose_color) |
Ilia@9
|
553 info_frame.pack(side="top") |
Ilia@9
|
554 |
Ilia@9
|
555 |
Ilia@36
|
556 ckeckbox_nums = [IntVar(), IntVar(), IntVar(), IntVar(), IntVar(), |
Ilia@36
|
557 IntVar(), IntVar(), IntVar(), IntVar()] |
Ilia@33
|
558 |
Ilia@55
|
559 condition = Label(automata_window, text= "Condition of conversion") |
Ilia@9
|
560 condition.pack(side="top", fill="x") |
Ilia@55
|
561 condition_frame=Frame(automata_window) |
Ilia@9
|
562 Label(condition_frame, text="0: ").grid(row=0, column=0) |
Ilia@39
|
563 c_button_0 = Checkbutton(condition_frame, variable=ckeckbox_nums[0]) |
Ilia@36
|
564 c_button_0.grid(row=0, column=1) |
Ilia@9
|
565 Label(condition_frame, text="1: ").grid(row=0, column=2) |
Ilia@39
|
566 c_button_1 = Checkbutton(condition_frame, variable=ckeckbox_nums[1]) |
Ilia@36
|
567 c_button_1.grid(row=0, column=3) |
Ilia@9
|
568 Label(condition_frame, text="2: ").grid(row=0, column=4) |
Ilia@39
|
569 c_button_2 = Checkbutton(condition_frame, variable=ckeckbox_nums[2]) |
Ilia@36
|
570 c_button_2.grid(row=0, column=5) |
Ilia@9
|
571 Label(condition_frame, text="3: ").grid(row=1, column=0) |
Ilia@39
|
572 c_button_3 = Checkbutton(condition_frame, variable=ckeckbox_nums[3]) |
Ilia@36
|
573 c_button_3.grid(row=1, column=1) |
Ilia@9
|
574 Label(condition_frame, text="4: ").grid(row=1, column=2) |
Ilia@39
|
575 c_button_4 = Checkbutton(condition_frame, variable=ckeckbox_nums[4]) |
Ilia@36
|
576 c_button_4.grid(row=1, column=3) |
Ilia@9
|
577 Label(condition_frame, text="5: ").grid(row=1, column=4) |
Ilia@39
|
578 c_button_5 = Checkbutton(condition_frame, variable=ckeckbox_nums[5]) |
Ilia@36
|
579 c_button_5.grid(row=1, column=5) |
Ilia@9
|
580 Label(condition_frame, text="6: ").grid(row=2, column=0) |
Ilia@39
|
581 c_button_6 = Checkbutton(condition_frame, variable=ckeckbox_nums[6]) |
Ilia@36
|
582 c_button_6.grid(row=2, column=1) |
Ilia@9
|
583 Label(condition_frame, text="7: ").grid(row=2, column=2) |
Ilia@39
|
584 c_button_7 = Checkbutton(condition_frame, variable=ckeckbox_nums[7]) |
Ilia@36
|
585 c_button_7.grid(row=2, column=3) |
Ilia@9
|
586 Label(condition_frame, text="8: ").grid(row=2, column=4) |
Ilia@39
|
587 c_button_8 = Checkbutton(condition_frame, variable=ckeckbox_nums[8]) |
Ilia@36
|
588 c_button_8.grid(row=2, column=5) |
Ilia@9
|
589 condition_frame.pack(side="top") |
Ilia@9
|
590 |
Ilia@9
|
591 |
Ilia@59
|
592 add_frame = Frame(automata_window, padx=10, pady=5) |
Ilia@59
|
593 add_state = Button(add_frame, text="Add", command=handlers.add, width=10) |
Ilia@59
|
594 change_state = Button(add_frame, text="Change", command=handlers.change, width=10) |
Ilia@59
|
595 add_state.pack(side="left", fill="x") |
Ilia@59
|
596 change_state.pack(side="right", fill="x") |
Ilia@59
|
597 add_frame.pack(side="top", fill="x") |
Ilia@9
|
598 |
Ilia@55
|
599 error=Label(automata_window) |
Ilia@9
|
600 error.pack(side="top", fill="x") |
is_rusinov@8
|
601 |
is_rusinov@8
|
602 |
is_rusinov@70
|
603 side = IntVar() |
Ilia@12
|
604 |
Ilia@12
|
605 size_window = Toplevel(root) |
Ilia@12
|
606 size_window.title("") |
Ilia@13
|
607 size_window.withdraw() |
Ilia@55
|
608 size_window.resizable(False, False) |
Ilia@12
|
609 size_window.protocol("WM_DELETE_WINDOW", handlers.hide_size_window) |
Ilia@12
|
610 Label(size_window, text= "Current size of window:").pack(side="top", fill="x") |
Ilia@19
|
611 size = Label(size_window, text= str(len(automata.field)) + " x " + str(len(automata.field[0]))) |
Ilia@19
|
612 size.pack(side="top", fill="x") |
Ilia@12
|
613 Label(size_window, text= "New size:").pack(side="top", fill="x") |
Ilia@12
|
614 new_size = Frame(size_window) |
Ilia@12
|
615 size_x = Entry(new_size, width=5) |
Ilia@12
|
616 size_x.grid(row=0, column=0) |
Ilia@12
|
617 Label(new_size, text=" x ").grid(row=0, column=1) |
Ilia@12
|
618 size_y = Entry(new_size, width=5) |
Ilia@12
|
619 size_y.grid(row=0, column=2) |
Ilia@12
|
620 new_size.pack(side="top") |
Ilia@12
|
621 Label(size_window, text= "Expansion of window:").pack(side="top", fill="x") |
Ilia@12
|
622 expansion = Frame(size_window) |
Ilia@12
|
623 r0 = Radiobutton(expansion, variable=side, value = 0, indicatoron=0, width=2, height=1) |
Ilia@12
|
624 r0.select() |
Ilia@12
|
625 r0.grid(row=0, column=0) |
Ilia@12
|
626 r1 = Radiobutton(expansion, variable=side, value = 1, indicatoron=0, width=2, height=1) |
Ilia@12
|
627 r1.grid(row=0, column=1) |
Ilia@12
|
628 r2 = Radiobutton(expansion, variable=side, value = 2, indicatoron=0, width=2, height=1) |
Ilia@12
|
629 r2.grid(row=0, column=2) |
Ilia@12
|
630 r3 = Radiobutton(expansion, variable=side, value = 3, indicatoron=0, width=2, height=1) |
Ilia@12
|
631 r3.grid(row=1, column=0) |
Ilia@12
|
632 r4 = Radiobutton(expansion, variable=side, value = 4, indicatoron=0, width=2, height=1) |
Ilia@12
|
633 r4.grid(row=1, column=1) |
Ilia@12
|
634 r5 = Radiobutton(expansion, variable=side, value = 5, indicatoron=0, width=2, height=1) |
Ilia@12
|
635 r5.grid(row=1, column=2) |
Ilia@12
|
636 r6 = Radiobutton(expansion, variable=side, value = 6, indicatoron=0, width=2, height=1) |
Ilia@12
|
637 r6.grid(row=2, column=0) |
Ilia@12
|
638 r7 = Radiobutton(expansion, variable=side, value = 7, indicatoron=0, width=2, height=1) |
Ilia@12
|
639 r7.grid(row=2, column=1) |
Ilia@12
|
640 r8 = Radiobutton(expansion, variable=side, value = 8, indicatoron=0, width=2, height=1) |
Ilia@12
|
641 r8.grid(row=2, column=2) |
Ilia@12
|
642 expansion.pack(side="top") |
Ilia@12
|
643 Label(size_window).pack(side="top", fill="x") |
Ilia@12
|
644 apply_frame = Frame(size_window, padx=10, pady=5) |
is_rusinov@70
|
645 apply_size = Button(apply_frame, text="Apply", width=6, command=handlers.change_size) |
Ilia@12
|
646 apply_size.pack(side="left", fill="x") |
Ilia@59
|
647 close_size = Button(apply_frame, text="Close", command=handlers.hide_size_window, width=6) |
Ilia@12
|
648 close_size.pack(side="right", fill="x") |
Ilia@12
|
649 apply_frame.pack(side="top", fill="x") |
is_rusinov@70
|
650 message = Label(size_window, text="") |
is_rusinov@70
|
651 message.pack(side="top", fill="x") |
Ilia@6
|
652 menubar = Menu(root) |
Ilia@6
|
653 root.config(menu=menubar) |
Ilia@6
|
654 |
Ilia@6
|
655 menu_file = Menu(menubar) |
Ilia@6
|
656 menu_file.add_command(label="New") |
Ilia@9
|
657 menu_file.add_command(label="Open...", command=handlers.open_file) |
Ilia@9
|
658 menu_file.add_command(label="Save...", command=handlers.save_file) |
Ilia@6
|
659 menu_file.add_separator() |
Ilia@9
|
660 menu_file.add_command(label="Exit", command=root.destroy) |
Ilia@6
|
661 menubar.add_cascade(label="File", menu=menu_file) |
Ilia@6
|
662 |
Ilia@6
|
663 menu_action = Menu(menubar) |
Ilia@9
|
664 menu_action.add_command(label="Start", command=handlers.start) |
Ilia@9
|
665 menu_action.add_command(label="Stop", command=handlers.stop) |
Ilia@9
|
666 menu_action.add_command(label="Next Step", command=handlers.next_step) |
Ilia@12
|
667 menu_action.add_separator() |
Ilia@9
|
668 menu_action.add_command(label="Increase speed", command=handlers.faster) |
Ilia@9
|
669 menu_action.add_command(label="Decrease speed", command=handlers.slower) |
Ilia@12
|
670 menu_action.add_separator() |
Ilia@9
|
671 menu_action.add_command(label="Zoom In", command=handlers.zoom_in) |
Ilia@9
|
672 menu_action.add_command(label="Zoom Out", command=handlers.zoom_out) |
Ilia@12
|
673 menu_action.add_separator() |
is_rusinov@69
|
674 menu_action.add_command(label="Clean field", command=handlers.clean_field) |
is_rusinov@69
|
675 menu_action.add_command(label="Fill randomly", command=handlers.fill_randomly) |
Ilia@13
|
676 menu_action.add_separator() |
Ilia@12
|
677 menu_action.add_command(label="Change size",command=handlers.show_size_window) |
Ilia@6
|
678 menubar.add_cascade(label="Action", menu=menu_action) |
Ilia@6
|
679 |
Ilia@55
|
680 menubar.add_command(label="Automata", command=handlers.show_automata_window) |
Ilia@6
|
681 |
is_rusinov@43
|
682 menubar.add_command(label="Help", command=handlers.show_help_window) |
Ilia@6
|
683 |
Ilia@6
|
684 root.mainloop() |
Ilia@6
|
685
|