import matplotlib matplotlib.use("TkAgg") from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure from Tkinter import * import tkSimpleDialog import urllib import urllib2 JUMP = 40 MAX_WIDTH = 20 * JUMP MAX_HEIGHT = 20 * JUMP address = "http://127.0.0.1:8001" root = Tk() canvas = Canvas(root, width=MAX_WIDTH, height=MAX_HEIGHT, bg="white") canvas.pack() name = 0 class FakeLayer(): def __init__(self, address): self.types = {} self.sources = {} self.targets = {} self.attrs = {} def read_available_attributes(self, name): if self.types[name] == "const": return ["value"] else: return [] def read_attribute(self, name, attr): return self.attr.get(name, {}).get(attr, None) def set_attribute(self, name, attr, value): self.attrs[name][attr] = value def instantiate_block(self, name, block_type): self.types[name] = block_type def instantiate_link(self, name, link_type, source, target): self.types[name] = link_type self.sources[name] = source self.targets[name] = target self.attrs[name] = {} def simulate(self): pass def step(self): pass def pause(self): pass attribute = [] available_attrs = [] simulation = [] def poll(address): working_attribute = [] working_available_attrs = [] working_simulation = [] while 1: returnvalue = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": "CBD_env"}))).read() if returnvalue.startswith("AVAILABLE:"): working_available_attrs.append(returnvalue.split(":", 1)[1]) elif returnvalue.startswith("ATTRIBUTE:"): working_attribute.append(returnvalue.split(":", 1)[1]) elif returnvalue.startswith("SIMULATION:"): working_simulation.append(returnvalue.split(":", 1)[1]) elif returnvalue.startswith("FINISH_AVAILABLE"): available_attrs.append(working_available_attrs) working_available_attrs = [] elif returnvalue.startswith("FINISH_ATTRIBUTE"): attributes.append(working_attributes) working_attributes = [] elif returnvalue.startswith("FINISH_SIMULATION"): simulation.append(working_simulation) working_simulation = [] class MvLayer(): def __init__(self, address): import threading self.address = address urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"CBD_env"', "username": "user_manager"}))).read() threading.Thread(target=poll, args=[address]) def read_available_attributes(self, name): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"read_available_attributes"', "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": "CBD_env"}))).read() while not available_attrs: time.sleep(0.1) return available_attrs.pop(0) def read_attribute(self, name, attr): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"read_attribute"', "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % attr, "username": "CBD_env"}))).read() while not attribute: time.sleep(0.1) return attribute.pop(0) def set_attribute(self, name, attr, value): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"set_attribute"', "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % attr, "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % value, "username": "CBD_env"}))).read() def instantiate_block(self, name, block_type): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"instantiate"', "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (block_type), "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (name), "username": "CBD_env"}))).read() def instantiate_link(self, name, link_type, source, target): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"instantiate"', "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (link_type), "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (name), "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (source), "username": "CBD_env"}))).read() urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (target), "username": "CBD_env"}))).read() def simulate(self): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"simulate"', "username": "CBD_env"}))).read() def step(self): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"step"', "username": "CBD_env"}))).read() def pause(self): urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"pause"', "username": "CBD_env"}))).read() def lower(value): return value / JUMP * JUMP def upper(value): return (value / JUMP + 1) * JUMP def avg(a, b): return float(a + b) / 2 class InterfaceCore(): mode = "" drawn = set() refs = dict() mappings = {"+": "AdditionBlock", "-": "NegationBlock", } #mv = MvLayer(address) mv = FakeLayer(address) def set_mode(self, mode): self.mode = mode def clicked(self, event): if self.mode not in ["+", "-"]: print("Cannot create something not guaranteed to be block type!") else: if self.find((event.x, event.y)): # Something already there, so don't add, but modify lname = self.find((event.x, event.y)) attrs = self.mv.read_available_attributes(lname) if not attrs: print("No attrs to manage!") for attr in attrs: old_value = self.mv.read_attribute(lname, attr) new_value = tkSimpleDialog.askstring("Attribute modification", attr, initialvalue=old_value) self.mv.set_attribute(lname, attr, new_value) else: global name x = event.x y = event.y self.mv.instantiate_block(str(name), self.mappings[self.mode]) r = canvas.create_rectangle(lower(x), lower(y), upper(x), upper(y), fill="white") t = canvas.create_text(avg(lower(x), upper(x)), avg(lower(y), upper(y)), text=self.mode, fill="black") b = (lower(x), lower(y), upper(x), upper(y), str(name)) self.drawn.add(b) self.refs[str(name)] = [r, t] name += 1 def find(self, location): x, y = location for e in self.drawn: if (e[0] <= x and e[1] <= y and e[2] >= x and e[3] >= y): return e[4] print("Found nothing at that location!") return [] def draw(self, start, end): source = self.find(start) target = self.find(end) print("Connect from %s to %s" % (source, target)) if source and target: if self.mode not in ["Link", "IC"]: print("Cannot create something not guaranteed to be link type!") else: global name self.mv.instantiate_link(str(name), self.mode, source, target) self.refs[str(name)] = [canvas.create_line(start[0], start[1], end[0], end[1], fill="black", arrow=LAST)] name += 1 core = InterfaceCore() def addition(): core.set_mode("+") def negation(): core.set_mode("-") def link(): core.set_mode("Link") def clicked(event): core.clicked(event) def draw(event): global start_location start_location = (event.x, event.y) def release(event): core.draw(start_location, (event.x, event.y)) def simulate(): core.mv.simulate() def step(): core.mv.step() def pause(): core.mv.pause() Button(root, text="+", command=addition).pack() Button(root, text="-", command=negation).pack() Button(root, text="Link", command=link).pack() Button(root, text="SIM", command=simulate).pack() Button(root, text="STEP", command=step).pack() Button(root, text="PAUSE", command=pause).pack() core.canvas = canvas for i in range(JUMP, MAX_HEIGHT, JUMP): canvas.create_line(0, i, MAX_HEIGHT, i, fill="grey") for i in range(JUMP, MAX_WIDTH, JUMP): canvas.create_line(i, 0, i, MAX_WIDTH, fill="grey") canvas.bind("", clicked) canvas.bind("", draw) canvas.bind("", release) visual = Toplevel(root) # TODO: https://pythonprogramming.net/how-to-embed-matplotlib-graph-tkinter-gui/ f = Figure(figsize=(5,5), dpi=100) a = f.add_subplot(111) a.plot(range(5), [1, 43, 5, 3, 2]) fcanvas = FigureCanvasTkAgg(f, visual) fcanvas.show() fcanvas.get_tk_widget().pack() root.mainloop()