Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/cca/annotate/3d86906e79fa/interface.py
Дата изменения: Unknown
Дата индексирования: Fri Feb 28 23:47:57 2014
Кодировка:
cca: interface.py annotate

cca

annotate interface.py @ 91:3d86906e79fa

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