canvas_element.xml 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <class name="CanvasElement">
  2. <relationships>
  3. <association name="parent" class="A" min="1" max="1" />
  4. <inheritance class="SCCDWidget" priority='0'/>
  5. <association name="elements" class="CanvasElement"/>
  6. <association name="prompt" class="PromptWindow"/>
  7. </relationships>
  8. <constructor>
  9. <parameter name="parent"/>
  10. <parameter name="coordinates"/>
  11. <parameter name="cs_element"/>
  12. <parameter name="as_element"/>
  13. <super class="SCCDWidget">
  14. <parameter expr="True"/>
  15. </super>
  16. <body>
  17. self.containing_canvas = parent
  18. self.coordinates = coordinates
  19. self.elements = {}
  20. self.tmp = {}
  21. self.cs_element = cs_element
  22. self.as_element = as_element
  23. self.diff_results = {}
  24. </body>
  25. </constructor>
  26. <destructor>
  27. for f in self.elements:
  28. self.containing_canvas.delete(f)
  29. </destructor>
  30. <scxml initial="main">
  31. <state id="main">
  32. <transition event="draw_element" target=".">
  33. <parameter name="element"/>
  34. <script>
  35. elem_x = self.coordinates[0] + element["x"]
  36. elem_y = self.coordinates[1] + element["y"]
  37. if element["type"] == "Rectangle":
  38. result = self.containing_canvas.create_rectangle(elem_x, elem_y, elem_x + element["width"], elem_y + element["height"], fill=element["fillColour"], outline=element["lineColour"])
  39. elif element["type"] == "Text":
  40. result = self.containing_canvas.create_text(elem_x, elem_y, fill=element["lineColour"], text=element["text"], anchor=tk.NW)
  41. elif element["type"] == "Line":
  42. result = self.containing_canvas.create_line(elem_x, elem_y, self.coordinates[0] + element["targetX"], self.coordinates[1] + element["targetY"], fill=element["lineColour"], width=element["lineWidth"], arrow=tk.LAST if element["arrow"] else tk.NONE)
  43. else:
  44. print("Undefined render format: " + str(element))
  45. result = None
  46. if result is not None:
  47. self.elements[result] = element["id"]
  48. self.set_bindable_and_tagorid(self.containing_canvas, result)
  49. </script>
  50. </transition>
  51. <transition event="left-click" cond="id(self) == ID" target="../dragging">
  52. <parameter name="ID"/>
  53. <script>
  54. self.original_coords = self.last_x, self.last_y
  55. self.prev_x = self.last_x
  56. self.prev_y = self.last_y
  57. </script>
  58. </transition>
  59. <transition event="middle-click" cond="id(self) == ID" target="../update_attrs">
  60. <parameter name="ID"/>
  61. </transition>
  62. </state>
  63. <state id="dragging">
  64. <transition event="motion" cond="id(self) == ID" target=".">
  65. <parameter name="ID"/>
  66. <script>
  67. delta_x = self.prev_x - self.last_x
  68. delta_y = self.prev_y - self.last_y
  69. for f in self.elements:
  70. old_coords = self.containing_canvas.coords(f)
  71. new_x = old_coords[0] - delta_x
  72. new_y = old_coords[1] - delta_y
  73. if len(old_coords) == 2:
  74. self.containing_canvas.coords(f, (new_x, new_y))
  75. elif len(old_coords) == 4:
  76. height = old_coords[3] - old_coords[1]
  77. width = old_coords[2] - old_coords[0]
  78. self.containing_canvas.coords(f, (new_x, new_y, new_x + width, new_y + height))
  79. self.prev_x = self.last_x
  80. self.prev_y = self.last_y
  81. delta_x = self.original_coords[0] - self.last_x
  82. delta_y = self.original_coords[1] - self.last_y
  83. </script>
  84. <raise event="moved_group" scope="narrow" target="'parent'">
  85. <parameter expr="self.cs_element"/>
  86. <parameter expr="(self.coordinates[0] - delta_x, self.coordinates[1] - delta_y)"/>
  87. </raise>
  88. </transition>
  89. <transition event="left-release" cond="id(self) == ID" target="../update_mv">
  90. <parameter name="ID"/>
  91. <script>
  92. delta_x = self.original_coords[0] - self.last_x
  93. delta_y = self.original_coords[1] - self.last_y
  94. self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
  95. </script>
  96. </transition>
  97. </state>
  98. <state id="update_attrs" initial="query">
  99. <state id="query">
  100. <onentry>
  101. <raise event="mv_request" scope="broad">
  102. <parameter expr="'read_attrs'"/>
  103. <parameter expr="[current_model, self.as_element]"/>
  104. </raise>
  105. </onentry>
  106. <transition event="mv_response" target="../prompt">
  107. <parameter name="result"/>
  108. <script>
  109. self.prev_results = result
  110. </script>
  111. </transition>
  112. </state>
  113. <state id="prompt">
  114. <onentry>
  115. <raise event="create_instance" scope="cd">
  116. <parameter expr="'prompt'"/>
  117. <parameter expr="'PromptWindow'"/>
  118. <parameter expr="self.prev_results"/>
  119. <parameter expr="{}"/>
  120. </raise>
  121. </onentry>
  122. <transition event="instance_created" target="../wait_for_results">
  123. <parameter name="name"/>
  124. <raise event="start_instance" scope="cd">
  125. <parameter expr="name"/>
  126. </raise>
  127. </transition>
  128. </state>
  129. <state id="wait_for_results">
  130. <transition event="prompt_results" target=".">
  131. <parameter name="results"/>
  132. <script>
  133. for k in results:
  134. if results[k] != self.prev_results[k]:
  135. self.diff_results[k] = json.loads(results[k])
  136. self.remaining_responses = len(self.diff_results)
  137. </script>
  138. </transition>
  139. <transition event="close_window" target="../process_results">
  140. <raise event="delete_instance" scope="cd">
  141. <parameter expr="'prompt'"/>
  142. </raise>
  143. </transition>
  144. </state>
  145. <state id="process_results">
  146. <transition cond="len(self.diff_results) > 0" target=".">
  147. <script>
  148. k, v = self.diff_results.popitem()
  149. </script>
  150. <raise event="mv_request" scope="broad">
  151. <parameter expr="'attr_assign'"/>
  152. <parameter expr="[current_model, self.as_element, k, v]"/>
  153. </raise>
  154. </transition>
  155. <transition cond="self.remaining_responses == 0" target="../mark_dirty"/>
  156. <transition event="mv_response" target=".">
  157. <script>
  158. self.remaining_responses -= 1
  159. </script>
  160. </transition>
  161. </state>
  162. <state id="mark_dirty">
  163. <onentry>
  164. <raise event="mv_request" scope="broad">
  165. <parameter expr="'attr_assign'"/>
  166. <parameter expr="[current_rendered_model, self.cs_element, 'dirty', True]"/>
  167. </raise>
  168. </onentry>
  169. <transition target="../../main"/>
  170. </state>
  171. </state>
  172. <state id="update_mv" initial="mark_dirty">
  173. <state id="mark_dirty">
  174. <onentry>
  175. <raise event="mv_request" scope="broad">
  176. <parameter expr="'attr_assign'"/>
  177. <parameter expr="[current_rendered_model, self.cs_element, 'dirty', True]"/>
  178. </raise>
  179. </onentry>
  180. <transition event="mv_response" target="../x"/>
  181. </state>
  182. <state id="x">
  183. <onentry>
  184. <raise event="mv_request" scope="broad">
  185. <parameter expr="'attr_assign'"/>
  186. <parameter expr="[current_rendered_model, self.cs_element, 'x', self.coordinates[0]]"/>
  187. </raise>
  188. </onentry>
  189. <transition event="mv_response" target="../y"/>
  190. </state>
  191. <state id="y">
  192. <onentry>
  193. <raise event="mv_request" scope="broad">
  194. <parameter expr="'attr_assign'"/>
  195. <parameter expr="[current_rendered_model, self.cs_element, 'y', self.coordinates[1]]"/>
  196. </raise>
  197. </onentry>
  198. <transition event="mv_response" target="../../main"/>
  199. </state>
  200. </state>
  201. </scxml>
  202. </class>