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

cca

annotate Interface.py @ 87:08600f868875

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