|
@@ -20,6 +20,7 @@ address = "http://127.0.0.1:8001"
|
|
|
username = "test"
|
|
|
|
|
|
root = Tk()
|
|
|
+event_entry = StringVar()
|
|
|
|
|
|
canvas = Canvas(root, width=MAX_WIDTH, height=MAX_HEIGHT, bg="white")
|
|
|
|
|
@@ -172,16 +173,12 @@ def avg(a, b):
|
|
|
return float(a + b) / 2
|
|
|
|
|
|
class InterfaceCore():
|
|
|
- mode = ""
|
|
|
drawn = set()
|
|
|
refs = dict()
|
|
|
|
|
|
#mv = MvLayer(address)
|
|
|
mv = FakeLayer(address)
|
|
|
|
|
|
- def set_mode(self, mode):
|
|
|
- self.mode = mode
|
|
|
-
|
|
|
def delete(self, x, y):
|
|
|
lname = self.find((x, y))
|
|
|
self.mv.delete(lname)
|
|
@@ -216,18 +213,15 @@ class InterfaceCore():
|
|
|
print("Got unknown type: " + str(t))
|
|
|
self.mv.set_attribute(lname, attr, new_value)
|
|
|
|
|
|
- elif self.mode not in ["AdditionBlock", "NegatorBlock", "ConstantBlock", "MultiplyBlock", "ConstantBlock", "InverseBlock", "DelayBlock", "IntegratorBlock", "DerivatorBlock", "ProbeBlock"]:
|
|
|
- print("Cannot create something not guaranteed to be block type!")
|
|
|
else:
|
|
|
global name
|
|
|
x = event.x
|
|
|
y = event.y
|
|
|
- self.mv.instantiate_block(str(name), self.mode)
|
|
|
- r = canvas.create_rectangle(lower(x), lower(y), upper(x), upper(y), fill="white")
|
|
|
- t = canvas.create_image(avg(lower(x), upper(x)), avg(lower(y), upper(y)), image=photos[self.mode])
|
|
|
+ self.mv.instantiate_block(str(name), "State")
|
|
|
+ r = canvas.create_oval(lower(x), lower(y), upper(x), upper(y), fill="white")
|
|
|
b = (lower(x), lower(y), upper(x), upper(y), str(name))
|
|
|
self.drawn.add(b)
|
|
|
- self.refs[str(name)] = [r, t]
|
|
|
+ self.refs[str(name)] = [r]
|
|
|
name += 1
|
|
|
|
|
|
def find(self, location):
|
|
@@ -249,15 +243,10 @@ class InterfaceCore():
|
|
|
print("Connect from %s to %s" % (source, target))
|
|
|
|
|
|
if source and target:
|
|
|
- if self.mode not in ["Link", "InitialCondition"]:
|
|
|
- print("Cannot create something not guaranteed to be link type!")
|
|
|
- elif source == target:
|
|
|
- print("Cannot create link to self")
|
|
|
- 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" if self.mode == "Link" else "red", arrow=LAST)]
|
|
|
- name += 1
|
|
|
+ global name
|
|
|
+ self.mv.instantiate_link(str(name), "Transition", 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()
|
|
|
|
|
@@ -274,91 +263,21 @@ def release(event):
|
|
|
def simulate():
|
|
|
core.mv.simulate()
|
|
|
|
|
|
-def step():
|
|
|
- core.mv.step()
|
|
|
-
|
|
|
def pause():
|
|
|
core.mv.pause()
|
|
|
|
|
|
-def addition():
|
|
|
- core.set_mode("AdditionBlock")
|
|
|
-
|
|
|
-def negation():
|
|
|
- core.set_mode("NegatorBlock")
|
|
|
-
|
|
|
-def link():
|
|
|
- core.set_mode("Link")
|
|
|
-
|
|
|
-def multiply():
|
|
|
- core.set_mode("MultiplyBlock")
|
|
|
-
|
|
|
-def constant():
|
|
|
- core.set_mode("ConstantBlock")
|
|
|
-
|
|
|
-def inverse():
|
|
|
- core.set_mode("InverseBlock")
|
|
|
-
|
|
|
-def ic():
|
|
|
- core.set_mode("InitialCondition")
|
|
|
-
|
|
|
-def delay():
|
|
|
- core.set_mode("DelayBlock")
|
|
|
-
|
|
|
-def derivator():
|
|
|
- core.set_mode("DerivatorBlock")
|
|
|
-
|
|
|
-def integrator():
|
|
|
- core.set_mode("IntegratorBlock")
|
|
|
-
|
|
|
def delete(event):
|
|
|
core.delete(event.x, event.y)
|
|
|
|
|
|
-def probe():
|
|
|
- core.set_mode("ProbeBlock")
|
|
|
-
|
|
|
-images = {
|
|
|
- "ConstantBlock": Image.open("figures/constant.png"),
|
|
|
- "AdditionBlock": Image.open("figures/summation.png"),
|
|
|
- "NegatorBlock": Image.open("figures/negation.png"),
|
|
|
- "MultiplyBlock": Image.open("figures/multiply.png"),
|
|
|
- "InverseBlock": Image.open("figures/inverse.png"),
|
|
|
- "DerivatorBlock": Image.open("figures/derivative.png"),
|
|
|
- "IntegratorBlock": Image.open("figures/integrator.png"),
|
|
|
- "DelayBlock": Image.open("figures/delay.png"),
|
|
|
- "ProbeBlock": Image.open("figures/probe.png"),
|
|
|
- }
|
|
|
-
|
|
|
-hsize = 20
|
|
|
-for k, v in images.items():
|
|
|
- old_vsize, old_hsize = v.size
|
|
|
- vsize = int(old_vsize * hsize / float(old_hsize))
|
|
|
- images[k] = v.resize((vsize, hsize), Image.ANTIALIAS)
|
|
|
-
|
|
|
-photos = {k: ImageTk.PhotoImage(v) for k, v in images.items()}
|
|
|
-
|
|
|
-bound_functions = {
|
|
|
- "ConstantBlock": constant,
|
|
|
- "AdditionBlock": addition,
|
|
|
- "MultiplyBlock": multiply,
|
|
|
- "NegatorBlock": negation,
|
|
|
- "InverseBlock": inverse,
|
|
|
- "DerivatorBlock": derivator,
|
|
|
- "IntegratorBlock": integrator,
|
|
|
- "DelayBlock": delay,
|
|
|
- "ProbeBlock": probe,
|
|
|
-}
|
|
|
-
|
|
|
-buttons = []
|
|
|
-for k, v in bound_functions.items():
|
|
|
- buttons.append(Button(root, image=photos[k], command=v))
|
|
|
-
|
|
|
-buttons.extend([
|
|
|
- Button(root, text="Link", command=link, bg="blue"),
|
|
|
- Button(root, text="InitialCondition", command=ic, bg="blue"),
|
|
|
- Button(root, text="SIM", command=simulate, bg="green"),
|
|
|
- Button(root, text="STEP", command=step, bg="green"),
|
|
|
- Button(root, text="PAUSE", command=pause, bg="green"),
|
|
|
- ])
|
|
|
+def add_event():
|
|
|
+ core.add_event(event_entry.get())
|
|
|
+
|
|
|
+buttons = [
|
|
|
+ Button(root, text="START", command=simulate),
|
|
|
+ Button(root, text="PAUSE", command=pause),
|
|
|
+ Entry(root, textvariable=event_entry),
|
|
|
+ Button(root, text="EVENT", command=add_event),
|
|
|
+ ]
|
|
|
|
|
|
for i, b in enumerate(buttons):
|
|
|
b.grid(row=0, column=i)
|
|
@@ -385,52 +304,7 @@ values = {}
|
|
|
# Example:
|
|
|
# simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
|
|
|
|
|
|
-# Class from StackOverflow
|
|
|
-class VerticalScrolledFrame(Frame):
|
|
|
- """A pure Tkinter scrollable frame that actually works!
|
|
|
- * Use the 'interior' attribute to place widgets inside the scrollable frame
|
|
|
- * Construct and pack/place/grid normally
|
|
|
- * This frame only allows vertical scrolling
|
|
|
-
|
|
|
- """
|
|
|
- def __init__(self, parent, *args, **kw):
|
|
|
- Frame.__init__(self, parent, *args, **kw)
|
|
|
-
|
|
|
- # create a canvas object and a vertical scrollbar for scrolling it
|
|
|
- vscrollbar = Scrollbar(self, orient=VERTICAL)
|
|
|
- vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
|
|
|
- canvas = Canvas(self, bd=0, highlightthickness=0,
|
|
|
- yscrollcommand=vscrollbar.set)
|
|
|
- canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
|
|
|
- vscrollbar.config(command=canvas.yview)
|
|
|
-
|
|
|
- # reset the view
|
|
|
- canvas.xview_moveto(0)
|
|
|
- canvas.yview_moveto(0)
|
|
|
-
|
|
|
- # create a frame inside the canvas which will be scrolled with it
|
|
|
- self.interior = interior = Frame(canvas)
|
|
|
- interior_id = canvas.create_window(0, 0, window=interior,
|
|
|
- anchor=NW)
|
|
|
-
|
|
|
- # track changes to the canvas and frame width and sync them,
|
|
|
- # also updating the scrollbar
|
|
|
- def _configure_interior(event):
|
|
|
- # update the scrollbars to match the size of the inner frame
|
|
|
- size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
|
|
|
- canvas.config(scrollregion="0 0 %s %s" % size)
|
|
|
- if interior.winfo_reqwidth() != canvas.winfo_width():
|
|
|
- # update the canvas's width to fit the inner frame
|
|
|
- canvas.config(width=interior.winfo_reqwidth())
|
|
|
- interior.bind('<Configure>', _configure_interior)
|
|
|
-
|
|
|
- def _configure_canvas(event):
|
|
|
- if interior.winfo_reqwidth() != canvas.winfo_width():
|
|
|
- # update the inner frame's width to fill the canvas
|
|
|
- canvas.itemconfigure(interior_id, width=canvas.winfo_width())
|
|
|
- canvas.bind('<Configure>', _configure_canvas)
|
|
|
-
|
|
|
-frame = VerticalScrolledFrame(visual)
|
|
|
+frame = Frame(visual)
|
|
|
frame.pack(fill=BOTH,expand=True)
|
|
|
|
|
|
def update_graphs():
|