main.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. from Tkinter import *
  2. from PIL import Image, ImageTk
  3. import tkSimpleDialog
  4. import urllib
  5. import urllib2
  6. import json
  7. import time
  8. sys.path.append("interface/HUTN")
  9. sys.path.append("wrappers")
  10. from modelverse import *
  11. address = "http://127.0.0.1:8001"
  12. taskname = str(random.random())
  13. MAX_WIDTH = 500
  14. MAX_HEIGHT = 500
  15. MM_RENDERED = "MM_rendered_graphical"
  16. init()
  17. login("admin", "admin")
  18. root = Tk()
  19. canvas = Canvas(root, width=MAX_WIDTH, height=MAX_HEIGHT, bg="white")
  20. selected_model = StringVar(root)
  21. selected_mapper = StringVar(root)
  22. mm_buttons = []
  23. available_models = model_list()
  24. available_mappers = []
  25. model_options = OptionMenu(root, selected_model, *[i[0] for i in available_models])
  26. mapper_options = OptionMenu(root, selected_mapper, "", *available_mappers)
  27. def visualize(model):
  28. print("Visualizing model: " + str(model))
  29. cache = {}
  30. hierarchy = {}
  31. parent = {}
  32. def findXY(element_id):
  33. print(cache[element_id])
  34. x = cache[element_id]["x"]
  35. y = cache[element_id]["y"]
  36. while element_id in parent:
  37. # Has a parent (group), so increment the XY values and keep going
  38. element_id = parent[element_id]
  39. x += cache[element_id]["x"]
  40. y += cache[element_id]["y"]
  41. return x, y
  42. for element in model:
  43. # Determine type of element
  44. cache[element["id"]] = element
  45. t = element["type"]
  46. if t == "contains":
  47. # Cache the containment links as well
  48. parent[element["__target"]] = element["__source"]
  49. # Caches filled, so go over all elements, ignoring groups, and draw them relative to their enclosing groups
  50. for element in model:
  51. t = element["type"]
  52. if t in ["Rectangle", "Ellipse", "Line", "Text", "Figure"]:
  53. x, y = findXY(element["id"])
  54. if t == "Rectangle":
  55. fillColour = element["fillColour"]
  56. width = element["width"]
  57. height = element["height"]
  58. lineWidth = element["lineWidth"]
  59. lineColour = element["lineColour"]
  60. print("Coordinates: " + str((x, y, x+width, y+height)))
  61. canvas.create_rectangle(x, y, x+width, y+height, fill=fillColour, outline=lineColour)
  62. elif t == "Ellipse":
  63. fillColour = element["fillColour"]
  64. width = element["width"]
  65. height = element["height"]
  66. lineWidth = element["lineWidth"]
  67. lineColour = element["lineColour"]
  68. canvas.create_ellipse(x, y, x+width, y+height, fill=fillColour, outline=lineColour)
  69. elif t == "Line":
  70. targetX = element["targetX"]
  71. targetY = element["targetY"]
  72. lineWidth = element["lineWidth"]
  73. lineColour = element["lineColour"]
  74. canvas.create_line(x, y, targetX, targetY, fill=lineColour, width=lineWidth)
  75. elif t == "Text":
  76. lineWidth = element["lineWidth"]
  77. lineColour = element["lineColour"]
  78. text = element["text"]
  79. canvas.create_text(x, y, fill=lineColour, text=text)
  80. elif t == "Figure":
  81. # Fetch associated SVG figure
  82. raise NotImplementedError()
  83. def reset_optionmenu(optionmenu, options, var):
  84. menu = optionmenu.children["menu"]
  85. menu.delete(0, "end")
  86. var.set("")
  87. for option in options:
  88. menu.add_command(label=option, command=lambda value=option: var.set(value))
  89. reset_optionmenu(mapper_options, [], selected_mapper)
  90. def read_available_mappers(instance_model):
  91. # Get instance model's type first, as transformations are defined on the type
  92. models = dict(model_list())
  93. type_model = models[instance_model]
  94. print("Found type model: " + type_model)
  95. print("Found MM_Rendered model: " + MM_RENDERED)
  96. # Switch to the core to find all information on megamodel relations
  97. model_modify("core")
  98. all_elems = [n for n, t in element_list() if t in ["Model", "ModelTransformation"]]
  99. all_attrs = {i: read_attrs(i) for i in all_elems}
  100. model_map = {all_attrs[i]["name"]: i for i in all_attrs}
  101. print("Got model_map: " + str(model_map))
  102. a = set([read_association_source(i) for i in read_incoming(model_map[MM_RENDERED], "transformOutput")])
  103. b = set([read_association_source(i) for i in read_incoming(model_map[type_model], "transformInput")])
  104. model_exit()
  105. print("All mappers for this tool: " + str(a))
  106. print("All transformations for this model: " + str(b))
  107. mappers = [all_attrs[i]["name"] for i in a & b]
  108. print("Overlap: " + str(mappers))
  109. return mappers
  110. class PromptDialog(tkSimpleDialog.Dialog):
  111. def __init__(self, master, query):
  112. self.query = query
  113. tkSimpleDialog.Dialog.__init__(self, master)
  114. def body(self, master):
  115. self.entries = []
  116. for i, q in enumerate(self.query):
  117. Label(master, text=q).grid(row=i, column=0)
  118. self.entries.append(Entry(master))
  119. self.entries[-1].grid(row=i, column=1)
  120. return self.entries[0]
  121. def apply(self):
  122. self.result = {self.query[i]: self.entries[i].get() for i in range(len(self.entries))}
  123. def create_element(t):
  124. def create_elem():
  125. print("Create element of type " + str(t))
  126. return create_elem
  127. def render_model():
  128. try:
  129. model_exit()
  130. except InvalidMode:
  131. pass
  132. rendered = model_render(selected_model.get(), selected_mapper.get())
  133. #TODO visualize rendered model
  134. print("Rendering model: " + rendered)
  135. import json
  136. visualize(json.loads(rendered))
  137. def open_model():
  138. try:
  139. model_exit()
  140. except InvalidMode:
  141. pass
  142. print("Opening model: " + selected_model.get())
  143. available_mappers = read_available_mappers(selected_model.get())
  144. reset_optionmenu(mapper_options, available_mappers, selected_mapper)
  145. model_modify(selected_model.get())
  146. print(types_full())
  147. available_types = [i[0] for i in types_full() if i[1] == "Class"]
  148. global mm_buttons
  149. for button in mm_buttons:
  150. button.destroy()
  151. mm_buttons = []
  152. for i, t in enumerate(available_types):
  153. mm_buttons.append(Button(root, text=t, command=lambda : create_element(t)))
  154. mm_buttons[-1].grid(row=1, column=i)
  155. def instantiate_model():
  156. try:
  157. model_exit()
  158. except InvalidMode:
  159. pass
  160. d = PromptDialog(root, ["Name:"])
  161. if d.result is not None:
  162. name = str(d.result["Name:"])
  163. print("Creating new model named " + name)
  164. model_add(name, selected_model.get())
  165. reset_optionmenu(available_models, model_list())
  166. selected_model.set(name)
  167. open_model()
  168. def verify_model():
  169. try:
  170. # Exit if necessary
  171. model_exit()
  172. except InvalidMode:
  173. pass
  174. print(verify(selected_model.get()))
  175. bound_functions = {
  176. "open": open_model,
  177. "render": render_model,
  178. "instantiate": instantiate_model,
  179. "verify": verify_model,
  180. }
  181. buttons = []
  182. buttons.append(model_options)
  183. buttons.append(mapper_options)
  184. for k, v in bound_functions.items():
  185. buttons.append(Button(root, text=k, command=v))
  186. for i, b in enumerate(buttons):
  187. b.grid(row=0, column=i)
  188. canvas.grid(row=2,column=0,columnspan=len(buttons))
  189. def left_clicked():
  190. pass
  191. def middle_clicked():
  192. pass
  193. def right_clicked():
  194. pass
  195. canvas.bind("<Button-1>", left_clicked)
  196. canvas.bind("<Button-2>", middle_clicked)
  197. canvas.bind("<Button-3>", right_clicked)
  198. root.mainloop()