canvas_element.xml 9.3 KB

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