|
@@ -21,7 +21,6 @@ username = "test"
|
|
|
root = Tk()
|
|
|
|
|
|
canvas = Canvas(root, width=MAX_WIDTH, height=MAX_HEIGHT, bg="white")
|
|
|
-canvas.pack()
|
|
|
|
|
|
name = 0
|
|
|
|
|
@@ -210,11 +209,13 @@ class InterfaceCore():
|
|
|
new_value = tkSimpleDialog.askstring("Attribute modification", attr, initialvalue=old_value)
|
|
|
if t == "Float":
|
|
|
new_value = float(new_value)
|
|
|
+ elif t == "String":
|
|
|
+ new_value = str(new_value)
|
|
|
else:
|
|
|
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"]:
|
|
|
+ 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
|
|
@@ -311,21 +312,30 @@ def integrator():
|
|
|
def delete(event):
|
|
|
core.delete(event.x, event.y)
|
|
|
|
|
|
-Button(root, text="+", command=addition).pack()
|
|
|
-Button(root, text="-x", command=negation).pack()
|
|
|
-Button(root, text="*", command=multiply).pack()
|
|
|
-Button(root, text="1/x", command=inverse).pack()
|
|
|
-Button(root, text="Constant", command=constant).pack()
|
|
|
-Button(root, text="Delay", command=delay).pack()
|
|
|
-Button(root, text="d/dx", command=derivator).pack()
|
|
|
-Button(root, text="integrator", command=integrator).pack()
|
|
|
-
|
|
|
-Button(root, text="Link", command=link).pack()
|
|
|
-Button(root, text="InitialCondition", command=ic).pack()
|
|
|
-
|
|
|
-Button(root, text="SIM", command=simulate).pack()
|
|
|
-Button(root, text="STEP", command=step).pack()
|
|
|
-Button(root, text="PAUSE", command=pause).pack()
|
|
|
+def make_probe():
|
|
|
+ core.set_mode("ProbeBlock")
|
|
|
+
|
|
|
+buttons = [
|
|
|
+ Button(root, text="+", command=addition),
|
|
|
+ Button(root, text="-x", command=negation),
|
|
|
+ Button(root, text="*", command=multiply),
|
|
|
+ Button(root, text="1/x", command=inverse),
|
|
|
+ Button(root, text="Constant", command=constant),
|
|
|
+ Button(root, text="Delay", command=delay),
|
|
|
+ Button(root, text="d/dx", command=derivator),
|
|
|
+ Button(root, text="integrator", command=integrator),
|
|
|
+ Button(root, text="Probe", command=make_probe),
|
|
|
+ Button(root, text="Link", command=link),
|
|
|
+ Button(root, text="InitialCondition", command=ic),
|
|
|
+ Button(root, text="SIM", command=simulate),
|
|
|
+ Button(root, text="STEP", command=step),
|
|
|
+ Button(root, text="PAUSE", command=pause),
|
|
|
+ ]
|
|
|
+
|
|
|
+for i, b in enumerate(buttons):
|
|
|
+ b.grid(row=0, column=i)
|
|
|
+
|
|
|
+canvas.grid(row=1,column=0,columnspan=len(buttons))
|
|
|
|
|
|
core.canvas = canvas
|
|
|
|
|
@@ -344,7 +354,56 @@ visual = Toplevel(root)
|
|
|
probes = {}
|
|
|
values = {}
|
|
|
|
|
|
-#simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
|
|
|
+# 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.pack(fill=BOTH,expand=True)
|
|
|
|
|
|
def update_graphs():
|
|
|
while simulation:
|
|
@@ -353,11 +412,13 @@ def update_graphs():
|
|
|
if k in probes:
|
|
|
fcanvas, a = probes[k]
|
|
|
else:
|
|
|
- f = Figure(figsize=(5,5), dpi=100)
|
|
|
+ f = Figure()
|
|
|
a = f.add_subplot(111)
|
|
|
a.plot([], [])
|
|
|
+ print(k)
|
|
|
+ f.suptitle(k)
|
|
|
|
|
|
- fcanvas = FigureCanvasTkAgg(f, visual)
|
|
|
+ fcanvas = FigureCanvasTkAgg(f, frame.interior)
|
|
|
fcanvas.show()
|
|
|
fcanvas.get_tk_widget().pack()
|
|
|
|
|
@@ -370,6 +431,7 @@ def update_graphs():
|
|
|
a.clear()
|
|
|
a.plot(values[k][0], values[k][1], linestyle="none", marker="o")
|
|
|
fcanvas.draw()
|
|
|
- root.after(50, update_graphs)
|
|
|
-root.after(50, update_graphs)
|
|
|
+ root.after(100, update_graphs)
|
|
|
+
|
|
|
+root.after(100, update_graphs)
|
|
|
root.mainloop()
|