canvas_element.xml 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. </relationships>
  7. <constructor>
  8. <parameter name="parent"/>
  9. <parameter name="coordinates"/>
  10. <parameter name="group_element"/>
  11. <super class="SCCDWidget">
  12. <parameter expr="True"/>
  13. </super>
  14. <body>
  15. self.containing_canvas = parent
  16. self.coordinates = coordinates
  17. self.elements = {}
  18. self.tmp = {}
  19. self.group_element = group_element
  20. </body>
  21. </constructor>
  22. <destructor>
  23. for f in self.elements:
  24. self.containing_canvas.delete(f)
  25. </destructor>
  26. <scxml initial="main">
  27. <state id="main">
  28. <transition event="draw_element" target=".">
  29. <parameter name="element"/>
  30. <script>
  31. elem_x = self.coordinates[0] + element["x"]
  32. elem_y = self.coordinates[1] + element["y"]
  33. if element["type"] == "Rectangle":
  34. result = self.containing_canvas.create_rectangle(elem_x, elem_y, elem_x + element["width"], elem_y + element["height"], fill=element["fillColour"], outline=element["lineColour"])
  35. elif element["type"] == "Text":
  36. result = self.containing_canvas.create_text(elem_x, elem_y, fill=element["lineColour"], text=element["text"], anchor=tk.NW)
  37. elif element["type"] == "Line":
  38. 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)
  39. else:
  40. print("Undefined render format: " + str(element))
  41. result = None
  42. if result is not None:
  43. self.elements[result] = element["id"]
  44. self.set_bindable_and_tagorid(self.containing_canvas, result)
  45. </script>
  46. </transition>
  47. <transition event="left-click" cond="id(self) == ID" target="../dragging">
  48. <parameter name="ID"/>
  49. <script>
  50. self.original_coords = self.last_x, self.last_y
  51. self.prev_x = self.last_x
  52. self.prev_y = self.last_y
  53. </script>
  54. </transition>
  55. </state>
  56. <state id="dragging">
  57. <transition event="motion" cond="id(self) == ID" target=".">
  58. <parameter name="ID"/>
  59. <script>
  60. delta_x = self.prev_x - self.last_x
  61. delta_y = self.prev_y - self.last_y
  62. for f in self.elements:
  63. old_coords = self.containing_canvas.coords(f)
  64. new_x = old_coords[0] - delta_x
  65. new_y = old_coords[1] - delta_y
  66. if len(old_coords) == 2:
  67. self.containing_canvas.coords(f, (new_x, new_y))
  68. elif len(old_coords) == 4:
  69. height = old_coords[3] - old_coords[1]
  70. width = old_coords[2] - old_coords[0]
  71. self.containing_canvas.coords(f, (new_x, new_y, new_x + width, new_y + height))
  72. self.prev_x = self.last_x
  73. self.prev_y = self.last_y
  74. delta_x = self.original_coords[0] - self.last_x
  75. delta_y = self.original_coords[1] - self.last_y
  76. </script>
  77. <raise event="moved_group" scope="narrow" target="'parent'">
  78. <parameter expr="self.group_element"/>
  79. <parameter expr="(self.coordinates[0] - delta_x, self.coordinates[1] - delta_y)"/>
  80. </raise>
  81. </transition>
  82. <transition event="left-release" cond="id(self) == ID" target="../update_mv">
  83. <parameter name="ID"/>
  84. <script>
  85. delta_x = self.original_coords[0] - self.last_x
  86. delta_y = self.original_coords[1] - self.last_y
  87. self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
  88. self.to_update = dict(self.elements)
  89. </script>
  90. </transition>
  91. </state>
  92. <state id="update_mv" initial="init">
  93. <state id="init">
  94. <transition cond="len(self.to_update) > 0" target="../x">
  95. <script>
  96. tk_id, self.tmp["mv_id"] = self.to_update.popitem()
  97. self.tmp['x'], self.tmp['y'] = self.containing_canvas.coords(tk_id)[:2]
  98. </script>
  99. </transition>
  100. <transition cond="len(self.to_update) == 0" target="../../main"/>
  101. </state>
  102. <state id="x">
  103. <onentry>
  104. <raise event="mv_request" scope="broad">
  105. <parameter expr="'attr_assign'"/>
  106. <parameter expr="[current_rendered_model, self.tmp['mv_id'], 'x', self.tmp['x']]"/>
  107. </raise>
  108. </onentry>
  109. <transition event="mv_response" target="../y"/>
  110. </state>
  111. <state id="y">
  112. <onentry>
  113. <raise event="mv_request" scope="broad">
  114. <parameter expr="'attr_assign'"/>
  115. <parameter expr="[current_rendered_model, self.tmp['mv_id'], 'y', self.tmp['y']]"/>
  116. </raise>
  117. </onentry>
  118. <transition event="mv_response" target="../init"/>
  119. </state>
  120. </state>
  121. </scxml>
  122. </class>