Browse Source

Semi-working create of new elements in GUI

Yentl Van Tendeloo 8 years ago
parent
commit
95f559e5af

+ 169 - 79
classes/canvas/canvas.xml

@@ -31,10 +31,18 @@
             self.connecting_lines = {}
             self.connecting_lines = {}
             self.lines = set()
             self.lines = set()
             self.layers = []
             self.layers = []
+            print("RESET CANVAS")
+            self.to_move = {}
+
+            self.elems = []
+
+            self.currently_selected = None
+            self.loading = [tk.PhotoImage(file="icons/loading.gif", format="gif -index %i" % i) for i in range(8)]
         </body>
         </body>
     </constructor>
     </constructor>
     <destructor>
     <destructor>
         <body>
         <body>
+            print("CANVAS DESTROYED")
             self.destroy()
             self.destroy()
         </body>
         </body>
     </destructor>
     </destructor>
@@ -48,91 +56,173 @@
             </transition>
             </transition>
         </state>
         </state>
 
 
-        <state id="ready">
-            <transition event="clear_canvas" target=".">
-                <raise event="delete_instance" scope="cd">
-                    <parameter expr="'elements'"/>
-                </raise>
-                <raise event="delete_instance" scope="cd">
-                    <parameter expr="'connecting_lines'"/>
-                </raise>
-                <script>
-                    self.group_location = {}
-                    self.layers = []
-                </script>
-            </transition>
+        <parallel id="ready">
+            <state id="process_events" initial="ready">
+                <state id="ready">
+                    <transition event="clear_canvas" target=".">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'elements'"/>
+                        </raise>
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'connecting_lines'"/>
+                        </raise>
+                        <script>
+                            self.group_location = {}
+                            self.layers = []
+                        </script>
+                    </transition>
 
 
-            <transition event="define_group" target="../creating_group">
-                <parameter name="element"/>
-                <script>
-                    self.creating_id = element["id"]
-                    self.group_location[element['id']] = (element['x'], element['y'])
-                </script>
-                <raise event="create_instance" scope="cd">
-                    <parameter expr="'elements'"/>
-                    <parameter expr="'CanvasElement'"/>
-                    <parameter expr="self"/>
-                    <parameter expr="(element['x'], element['y'])"/>
-                    <parameter expr="element['id']"/>
-                    <parameter expr="element['__asid']"/>
-                </raise>
-            </transition>
+                    <transition event="select_for_creation" target=".">
+                        <parameter name="element_name"/>
+                        <script>
+                            self.currently_selected = element_name
+                        </script>
+                    </transition>
 
 
-            <transition event="define_contains" target=".">
-                <parameter name="element"/>
-                <script>
-                    self.element_group[element["__target"]] = element["__source"]
-                </script>
-            </transition>
+                    <transition event="right-click" cond="self.currently_selected is not None" target="../creating_element">
+                        <script>
+                            self.create_location = (self.last_x, self.last_y)
+                        </script>
+                    </transition>
 
 
-            <transition event="draw_canvas" cond="element['type'] != 'ConnectingLine'" target=".">
-                <parameter name="element"/>
-                <raise event="draw_element" scope="narrow" target="self.assoc_links[self.element_group[element['id']]]">
-                    <parameter expr="element"/>
-                </raise>
-            </transition>
+                    <transition event="define_group" target="../creating_group">
+                        <parameter name="element"/>
+                        <script>
+                            self.creating_id = element["id"]
+                            self.group_location[element['id']] = (element['x'], element['y'])
+                        </script>
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'elements'"/>
+                            <parameter expr="'CanvasElement'"/>
+                            <parameter expr="self"/>
+                            <parameter expr="(element['x'], element['y'])"/>
+                            <parameter expr="element['id']"/>
+                            <parameter expr="element['__asid']"/>
+                        </raise>
+                    </transition>
 
 
-            <transition event="draw_canvas" cond="element['type'] == 'ConnectingLine'" target=".">
-                <parameter name="element"/>
-                <raise event="create_instance" scope="cd">
-                    <parameter expr="'connecting_lines'"/>
-                    <parameter expr="'ConnectingLine'"/>
-                    <parameter expr="self"/>
-                    <parameter expr="element"/>
-                </raise>
-            </transition>
+                    <transition event="define_contains" target=".">
+                        <parameter name="element"/>
+                        <script>
+                            self.element_group[element["__target"]] = element["__source"]
+                        </script>
+                    </transition>
 
 
-            <transition event="instance_created" target=".">
-                <parameter name="result"/>
-                <raise event="start_instance" scope="cd">
-                    <parameter expr="result"/>
-                </raise>
-            </transition>
+                    <transition event="draw_canvas" cond="element['type'] != 'ConnectingLine'" target=".">
+                        <parameter name="element"/>
+                        <raise event="draw_element" scope="narrow" target="self.assoc_links[self.element_group[element['id']]]">
+                            <parameter expr="element"/>
+                        </raise>
+                    </transition>
 
 
-            <transition event="moved_group" target=".">
-                <parameter name="group_element"/>
-                <parameter name="new_location"/>
-                <script>
-                    self.group_location[group_element] = new_location
-                </script>
-                <raise event="moved_element" scope="narrow" target="'connecting_lines'">
-                    <parameter expr="group_element"/>
-                    <parameter expr="new_location"/>
-                </raise>
-            </transition>
-        </state>
+                    <transition event="draw_canvas" cond="element['type'] == 'ConnectingLine'" target=".">
+                        <parameter name="element"/>
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'connecting_lines'"/>
+                            <parameter expr="'ConnectingLine'"/>
+                            <parameter expr="self"/>
+                            <parameter expr="element"/>
+                        </raise>
+                    </transition>
 
 
-        <state id="creating_group">
-            <transition event="instance_created" target="../ready">
-                <parameter name="assoc_name"/>
-                <raise event="start_instance" scope="cd">
-                    <parameter expr="assoc_name"/>
-                </raise>
-                <script>
-                    self.assoc_links[self.creating_id] = assoc_name
-                </script>
-                <raise event="group_ready" scope="narrow" target="'parent'"/>
-            </transition>
-        </state>
+                    <transition event="instance_created" target=".">
+                        <parameter name="result"/>
+                        <raise event="start_instance" scope="cd">
+                            <parameter expr="result"/>
+                        </raise>
+                    </transition>
+
+                    <transition event="moved_group" target=".">
+                        <parameter name="group_element"/>
+                        <parameter name="new_location"/>
+                        <script>
+                            self.group_location[group_element] = new_location
+                        </script>
+                        <raise event="moved_element" scope="narrow" target="'connecting_lines'">
+                            <parameter expr="group_element"/>
+                            <parameter expr="new_location"/>
+                        </raise>
+                    </transition>
+                </state>
+
+                <state id="creating_group">
+                    <transition event="instance_created" target="../wait_canvas_element_ready">
+                        <parameter name="assoc_name"/>
+                        <raise event="start_instance" scope="cd">
+                            <parameter expr="assoc_name"/>
+                        </raise>
+                        <script>
+                            self.assoc_links[self.creating_id] = assoc_name
+                        </script>
+                    </transition>
+                </state>
+
+                <state id="wait_canvas_element_ready">
+                    <transition event="moved_group" target=".">
+                        <parameter name="group_element"/>
+                        <parameter name="new_location"/>
+                        <script>
+                            self.group_location[group_element] = new_location
+                        </script>
+                        <raise event="moved_element" scope="narrow" target="'connecting_lines'">
+                            <parameter expr="group_element"/>
+                            <parameter expr="new_location"/>
+                        </raise>
+                    </transition>
+
+                    <transition event="canvas_element_ready" target="../ready">
+                        <raise event="group_ready" scope="narrow" target="'parent'"/>
+                    </transition>
+                </state>
+
+                <state id="creating_element">
+                    <onentry>
+                        <raise event="mv_request" scope="broad">
+                            <parameter expr="'instantiate'"/>
+                            <parameter expr="[current_model, self.currently_selected, None, '']"/>
+                        </raise>
+
+                        <script>
+                            self.elems.append([0, self.create_image(self.last_x, self.last_y, image=self.loading[0])])
+                        </script>
+                    </onentry>
+
+                    <transition event="mv_response" target="../waiting_for_clear">
+                        <parameter name="ID"/>
+                        <script>
+                            self.to_move[ID] = self.create_location
+                        </script>
+                        <raise event="rerender_model" scope="narrow" target="'parent'"/>
+                    </transition>
+                </state>
+
+                <state id="waiting_for_clear">
+                    <transition event="clear_canvas" target="../ready">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'elements'"/>
+                        </raise>
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'connecting_lines'"/>
+                        </raise>
+                        <script>
+                            self.group_location = {}
+                            self.layers = []
+                        </script>
+                    </transition>
+                </state>
+            </state>
+
+            <state id="update_loading">
+                <state id="updating">
+                    <transition after="self.sccd_yield() + 0.1" target=".">
+                        <script>
+                            for i in self.elems:
+                                self.itemconfigure(i[1], image=self.loading[i[0]])
+                                i[0] = (i[0] + 1) % 8
+                        </script>
+                    </transition>
+                </state>
+            </state>
+        </parallel>
     </scxml>
     </scxml>
 </class>
 </class>

+ 73 - 27
classes/canvas/canvas_element.xml

@@ -44,7 +44,72 @@
         </body>
         </body>
     </method>
     </method>
 
 
-    <scxml initial="main">
+    <method name="move_group">
+        <parameter name="new_location"/>
+        <body>
+            for f in self.elements:
+                old_coords = self.containing_canvas.coords(f)
+
+                new_x = new_location[0] + self.elements[f]['x']
+                new_y = new_location[1] + self.elements[f]['y']
+
+                if len(old_coords) == 2:
+                    self.containing_canvas.coords(f, (new_x, new_y))
+                elif len(old_coords) == 4:
+                    height = old_coords[3] - old_coords[1]
+                    width = old_coords[2] - old_coords[0]
+                    self.containing_canvas.coords(f, (new_x, new_y, new_x + width, new_y + height))
+        </body>
+    </method>
+
+    <scxml initial="init">
+        <state id="init" initial="init">
+            <onexit>
+                <raise event="canvas_element_ready" target="'parent'"/>
+            </onexit>
+
+            <state id="init">
+                <transition cond="self.as_element not in self.containing_canvas.to_move" target="../../main">
+                    <script>
+                        print("Not found: %s in %s" % (self.as_element, self.containing_canvas.to_move))
+                    </script>
+                </transition>
+
+                <transition cond="self.as_element in self.containing_canvas.to_move" target="../update_mv">
+                    <script>
+                        self.coordinates = self.containing_canvas.to_move.pop(self.as_element)
+                        self.move_group(self.coordinates)
+                        
+                        self.containing_canvas.delete(self.containing_canvas.elems.pop(0)[1])
+                    </script>
+                </transition>
+            </state>
+
+            <state id="update_mv" initial="x">
+                <state id="x">
+                    <onentry>
+                        <raise event="mv_request" scope="broad">
+                            <parameter expr="'attr_assign'"/>
+                            <parameter expr="[current_rendered_model, self.cs_element, 'x', self.coordinates[0]]"/>
+                        </raise>
+                    </onentry>
+
+                    <transition event="mv_response" target="../y"/>
+                </state>
+
+                <state id="y">
+                    <onentry>
+                        <raise event="mv_request" scope="broad">
+                            <parameter expr="'attr_assign'"/>
+                            <parameter expr="[current_rendered_model, self.cs_element, 'y', self.coordinates[1]]"/>
+                        </raise>
+                    </onentry>
+
+                    <transition event="mv_response" target="../../../main"/>
+                </state>
+            </state>
+        </state>
+
         <state id="main">
         <state id="main">
             <transition event="draw_element" target=".">
             <transition event="draw_element" target=".">
                 <parameter name="element"/>
                 <parameter name="element"/>
@@ -58,11 +123,11 @@
                     elif element["type"] == "Line":
                     elif element["type"] == "Line":
                         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)
                         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)
                     else:
                     else:
-                        print("Undefined render format: " + str(element))
+                        raise Exception("Undefined render format: " + str(element))
                         result = None
                         result = None
 
 
                     if result is not None:
                     if result is not None:
-                        self.elements[result] = element["id"]
+                        self.elements[result] = element
                         self.set_bindable_and_tagorid(self.containing_canvas, result)
                         self.set_bindable_and_tagorid(self.containing_canvas, result)
                         self.add_to_layer(element["layer"], result)
                         self.add_to_layer(element["layer"], result)
                 </script>
                 </script>
@@ -72,44 +137,26 @@
                 <parameter name="ID"/>
                 <parameter name="ID"/>
                 <script>
                 <script>
                     self.original_coords = self.last_x, self.last_y
                     self.original_coords = self.last_x, self.last_y
-                    self.prev_x = self.last_x
-                    self.prev_y = self.last_y
                 </script>
                 </script>
             </transition>
             </transition>
 
 
             <transition event="middle-click" cond="id(self) == ID" target="../update_attrs">
             <transition event="middle-click" cond="id(self) == ID" target="../update_attrs">
                 <parameter name="ID"/>
                 <parameter name="ID"/>
             </transition>
             </transition>
+
         </state>
         </state>
 
 
         <state id="dragging">
         <state id="dragging">
             <transition event="motion" cond="id(self) == ID" target=".">
             <transition event="motion" cond="id(self) == ID" target=".">
                 <parameter name="ID"/>
                 <parameter name="ID"/>
                 <script>
                 <script>
-                    delta_x = self.prev_x - self.last_x
-                    delta_y = self.prev_y - self.last_y
-
-                    for f in self.elements:
-                        old_coords = self.containing_canvas.coords(f)
-                        new_x = old_coords[0] - delta_x
-                        new_y = old_coords[1] - delta_y
-
-                        if len(old_coords) == 2:
-                            self.containing_canvas.coords(f, (new_x, new_y))
-                        elif len(old_coords) == 4:
-                            height = old_coords[3] - old_coords[1]
-                            width = old_coords[2] - old_coords[0]
-                            self.containing_canvas.coords(f, (new_x, new_y, new_x + width, new_y + height))
-
-                    self.prev_x = self.last_x
-                    self.prev_y = self.last_y
-
-                    delta_x = self.original_coords[0] - self.last_x
-                    delta_y = self.original_coords[1] - self.last_y
+                    new_x = self.coordinates[0] + (self.last_x - self.original_coords[0])
+                    new_y = self.coordinates[1] + (self.last_y - self.original_coords[1])
+                    self.move_group((new_x, new_y))
                 </script>
                 </script>
                 <raise event="moved_group" scope="narrow" target="'parent'">
                 <raise event="moved_group" scope="narrow" target="'parent'">
                     <parameter expr="self.cs_element"/>
                     <parameter expr="self.cs_element"/>
-                    <parameter expr="(self.coordinates[0] - delta_x, self.coordinates[1] - delta_y)"/>
+                    <parameter expr="(new_x, new_y)"/>
                 </raise>
                 </raise>
             </transition>
             </transition>
 
 
@@ -118,7 +165,6 @@
                 <script>
                 <script>
                     delta_x = self.original_coords[0] - self.last_x
                     delta_x = self.original_coords[0] - self.last_x
                     delta_y = self.original_coords[1] - self.last_y
                     delta_y = self.original_coords[1] - self.last_y
-
                     self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
                     self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
                 </script>
                 </script>
             </transition>
             </transition>

+ 3 - 0
classes/modelverse/http_client.xml

@@ -70,6 +70,9 @@
 
 
             <transition after="self.timeout" target="../waiting">
             <transition after="self.timeout" target="../waiting">
                 <raise scope="broad" event="http_client_timeout"/>
                 <raise scope="broad" event="http_client_timeout"/>
+                <script>
+                    print("Raise timeout after %ss" % self.timeout)
+                </script>
             </transition>
             </transition>
         </state>
         </state>
 
 

+ 5 - 4
classes/modelverse/modelverse.xml

@@ -217,6 +217,7 @@
 
 
                             <script>
                             <script>
                                 self.i += 1
                                 self.i += 1
+                                print("READY")
                             </script>
                             </script>
                         </transition>
                         </transition>
 
 
@@ -1092,13 +1093,13 @@
                     <state id="types">
                     <state id="types">
                         <onentry>
                         <onentry>
                             <raise event="request">
                             <raise event="request">
-                                <parameter expr="['types', self.parameters[1]]"/>
+                                <parameter expr="['types']"/>
                             </raise>
                             </raise>
                         </onentry>
                         </onentry>
 
 
                         <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
                         <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
                             <raise event="result">
                             <raise event="result">
-                                <parameter expr="set(self.split_response(self.responses.pop(0)))"/>
+                                <parameter expr="set([tuple(entry.strip().split(' : ')) for entry in self.split_response(self.responses.pop(0))])"/>
                             </raise>
                             </raise>
                         </transition>
                         </transition>
                     </state>
                     </state>
@@ -1106,13 +1107,13 @@
                     <state id="types_full">
                     <state id="types_full">
                         <onentry>
                         <onentry>
                             <raise event="request">
                             <raise event="request">
-                                <parameter expr="['types_full', self.parameters[1]]"/>
+                                <parameter expr="['types_full']"/>
                             </raise>
                             </raise>
                         </onentry>
                         </onentry>
 
 
                         <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
                         <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
                             <raise event="result">
                             <raise event="result">
-                                <parameter expr="set(self.split_response(self.responses.pop(0)))"/>
+                                <parameter expr="set([tuple(entry.strip().split(' : ')) for entry in self.split_response(self.responses.pop(0))])"/>
                             </raise>
                             </raise>
                         </transition>
                         </transition>
                     </state>
                     </state>

+ 17 - 10
classes/toolbar/dsl_toolbar.xml

@@ -7,14 +7,17 @@
 
 
     <constructor>
     <constructor>
         <parameter name="parent"/>
         <parameter name="parent"/>
+        <parameter name="elements"/>
         <super class="Toolbar">
         <super class="Toolbar">
             <parameter expr="parent"/>
             <parameter expr="parent"/>
         </super>
         </super>
         <body>
         <body>
-            self.to_create = ["todo"]
-            self.button_info = {"todo": "REMOVE"}
+            print("Got elements: " + str(elements))
+            self.to_create = [i[0] for i in elements if i[1] == "Class"]
+            self.button_info = {i: "Instantiate element %s" % i for i in self.to_create}
             self.buttons = {}
             self.buttons = {}
             tk.Label(self, text="Domain-Specific").pack(side=tk.LEFT)
             tk.Label(self, text="Domain-Specific").pack(side=tk.LEFT)
+            self.currently_active = None
         </body>
         </body>
     </constructor>
     </constructor>
 
 
@@ -35,7 +38,7 @@
                     <raise event="create_instance" scope="cd">
                     <raise event="create_instance" scope="cd">
                         <parameter expr="'buttons'"/>
                         <parameter expr="'buttons'"/>
                         <parameter expr="'Button'"/>
                         <parameter expr="'Button'"/>
-                        <parameter expr="{'parent': self, 'visual': ImageVisual('icons/%s.png' % self.to_create[0]), 'tooltip_text': self.button_info[self.to_create[0]], 'event_parameters': self.to_create[0]}"/>
+                        <parameter expr="{'parent': self, 'visual': TextVisual(self.to_create[0]), 'tooltip_text': self.button_info[self.to_create[0]], 'event_parameters': self.to_create[0]}"/>
                     </raise>
                     </raise>
                 </onentry>
                 </onentry>
 
 
@@ -68,14 +71,18 @@
         </state>
         </state>
 
 
         <state id="root">
         <state id="root">
-            <transition event="button_pressed" cond="event_name == 'new'" target=".">
+            <transition event="button_pressed" cond="event_name != self.currently_active" target=".">
                 <parameter name="event_name"/>
                 <parameter name="event_name"/>
-                <raise event="create_new_model" scope="narrow" target="'parent'"/>
-            </transition>
-
-            <transition event="button_pressed" cond="event_name == 'open'" target=".">
-                <parameter name="event_name"/>
-                <raise event="open_model" scope="narrow" target="'parent'"/>
+                <!-- Fake conditional raise: if no button pressed, we don't want to raise an event, but we have to :(
+                     As such, we send the event to the parent, which we HOPE doesn't catch this event. -->
+                <raise event="deactivate" scope="narrow" target="self.buttons[self.currently_active] if self.currently_active is not None else 'parent'"/>
+                <raise event="activate" scope="narrow" target="self.buttons[event_name]"/>
+                <raise event="select_for_creation" scope="narrow" target="'parent'">
+                    <parameter expr="event_name"/>
+                </raise>
+                <script>
+                    self.currently_active = event_name
+                </script>
             </transition>
             </transition>
 
 
             <transition event="close" target="../closing"/>
             <transition event="close" target="../closing"/>

+ 13 - 0
classes/widgets/button.xml

@@ -55,6 +55,19 @@
                         self.tooltip.hidetip()
                         self.tooltip.hidetip()
                     </script>
                     </script>
                 </transition>
                 </transition>
+
+                <transition event="activate" target=".">
+                    <script>
+                        self.configure(state=tk.ACTIVE, relief=tk.SUNKEN)
+                        print("Activate " + str(self.event_parameters))
+                    </script>
+                </transition>
+                <transition event="deactivate" target=".">
+                    <script>
+                        self.configure(state=tk.NORMAL, relief=tk.RAISED)
+                        print("Deactivate " + str(self.event_parameters))
+                    </script>
+                </transition>
             </state>
             </state>
         </state>
         </state>
     </scxml>
     </scxml>

+ 21 - 4
classes/window/main_window.xml

@@ -134,6 +134,12 @@
                         current_rendered_model = new_rendered
                         current_rendered_model = new_rendered
                     </script>
                     </script>
                 </transition>
                 </transition>
+                <transition event="select_for_creation" target=".">
+                    <parameter name="element_name"/>
+                    <raise event="select_for_creation" scope="narrow" target="'canvas'">
+                        <parameter expr="element_name"/>
+                    </raise>
+                </transition>
             </state>
             </state>
 
 
             <state id="add_object_diagrams" initial="init">
             <state id="add_object_diagrams" initial="init">
@@ -405,7 +411,7 @@
                             <parameter expr="'subwindow'"/>
                             <parameter expr="'subwindow'"/>
                             <parameter expr="'Browser'"/>
                             <parameter expr="'Browser'"/>
                             <parameter expr="'Select model to open'"/>
                             <parameter expr="'Select model to open'"/>
-                            <parameter expr="['formalisms/SimpleClassDiagrams']"/>
+                            <parameter expr="[]"/>
                         </raise>
                         </raise>
                         <raise event="update_status" scope="narrow" target="'progress_bar'">
                         <raise event="update_status" scope="narrow" target="'progress_bar'">
                             <parameter expr="0"/>
                             <parameter expr="0"/>
@@ -808,7 +814,7 @@
                     </state>
                     </state>
 
 
                     <state id="pack_cs_toolbar">
                     <state id="pack_cs_toolbar">
-                        <transition event="tk_widget" target="../dsl_toolbar">
+                        <transition event="tk_widget" target="../fetch_types">
                             <parameter name="tk_elem"/>
                             <parameter name="tk_elem"/>
                             <script>
                             <script>
                                 tk_elem.pack(anchor=tk.W)
                                 tk_elem.pack(anchor=tk.W)
@@ -816,15 +822,26 @@
                         </transition>
                         </transition>
                     </state>
                     </state>
 
 
-                    <state id="dsl_toolbar">
+                    <state id="fetch_types">
                         <onentry>
                         <onentry>
+                            <raise event="mv_request" scope="broad">
+                                <parameter expr="'types'"/>
+                                <parameter expr="[current_model]"/>
+                            </raise>
+                        </onentry>
+
+                        <transition event="mv_response" target="../dsl_toolbar">
+                            <parameter name="result"/>
                             <raise event="create_instance" scope="cd">
                             <raise event="create_instance" scope="cd">
                                 <parameter expr="'model_toolbars'"/>
                                 <parameter expr="'model_toolbars'"/>
                                 <parameter expr="'DSLToolbar'"/>
                                 <parameter expr="'DSLToolbar'"/>
                                 <parameter expr="self.toolbar_frame"/>
                                 <parameter expr="self.toolbar_frame"/>
+                                <parameter expr="result"/>
                             </raise>
                             </raise>
-                        </onentry>
+                        </transition>
+                    </state>
 
 
+                    <state id="dsl_toolbar">
                         <transition event="instance_created" target="../pack_dsl_toolbar">
                         <transition event="instance_created" target="../pack_dsl_toolbar">
                             <parameter name="association_name"/>
                             <parameter name="association_name"/>
                             <raise event="start_instance" scope="cd">
                             <raise event="start_instance" scope="cd">

+ 354 - 133
frontend.py

@@ -1,7 +1,7 @@
 """
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
 
-Date:   Fri Oct  6 10:19:43 2017
+Date:   Mon Oct  9 13:35:39 2017
 
 
 Model author: Yentl Van Tendeloo
 Model author: Yentl Van Tendeloo
 Model name:   Modelverse Visual Editor - Tkinter Version 
 Model name:   Modelverse Visual Editor - Tkinter Version 
@@ -2369,10 +2369,10 @@ class Modelverse(RuntimeClassBase):
         self.raiseInternalEvent(Event("request", None, [['JSON']]))
         self.raiseInternalEvent(Event("request", None, [['JSON']]))
     
     
     def _initialized_behaviour_operations_types_enter(self):
     def _initialized_behaviour_operations_types_enter(self):
-        self.raiseInternalEvent(Event("request", None, [['types', self.parameters[1]]]))
+        self.raiseInternalEvent(Event("request", None, [['types']]))
     
     
     def _initialized_behaviour_operations_types_full_enter(self):
     def _initialized_behaviour_operations_types_full_enter(self):
-        self.raiseInternalEvent(Event("request", None, [['types_full', self.parameters[1]]]))
+        self.raiseInternalEvent(Event("request", None, [['types_full']]))
     
     
     def _initialized_behaviour_operations_read_info_enter(self):
     def _initialized_behaviour_operations_read_info_enter(self):
         self.raiseInternalEvent(Event("request", None, [['read_info', self.parameters[1]]]))
         self.raiseInternalEvent(Event("request", None, [['read_info', self.parameters[1]]]))
@@ -2647,6 +2647,7 @@ class Modelverse(RuntimeClassBase):
     def _initialized_behaviour_init_waiting_http_client_0_exec(self, parameters):
     def _initialized_behaviour_init_waiting_http_client_0_exec(self, parameters):
         self.raiseInternalEvent(Event("request_raw", None, [self.taskname, 'task_manager', self.i]))
         self.raiseInternalEvent(Event("request_raw", None, [self.taskname, 'task_manager', self.i]))
         self.i += 1
         self.i += 1
+        print("READY")
     
     
     def _initialized_behaviour_init_waiting_http_client_1_exec(self, parameters):
     def _initialized_behaviour_init_waiting_http_client_1_exec(self, parameters):
         self.raiseInternalEvent(Event("exception", None, ['NetworkException', 'Connection timeout']))
         self.raiseInternalEvent(Event("exception", None, ['NetworkException', 'Connection timeout']))
@@ -3039,13 +3040,13 @@ class Modelverse(RuntimeClassBase):
         return self.expect_response_partial('Success: ', pop=False)
         return self.expect_response_partial('Success: ', pop=False)
     
     
     def _initialized_behaviour_operations_types_0_exec(self, parameters):
     def _initialized_behaviour_operations_types_0_exec(self, parameters):
-        self.raiseInternalEvent(Event("result", None, [set(self.split_response(self.responses.pop(0)))]))
+        self.raiseInternalEvent(Event("result", None, [set([tuple(entry.strip().split(' : ')) for entry in self.split_response(self.responses.pop(0))])]))
     
     
     def _initialized_behaviour_operations_types_0_guard(self, parameters):
     def _initialized_behaviour_operations_types_0_guard(self, parameters):
         return self.expect_response_partial('Success: ', pop=False)
         return self.expect_response_partial('Success: ', pop=False)
     
     
     def _initialized_behaviour_operations_types_full_0_exec(self, parameters):
     def _initialized_behaviour_operations_types_full_0_exec(self, parameters):
-        self.raiseInternalEvent(Event("result", None, [set(self.split_response(self.responses.pop(0)))]))
+        self.raiseInternalEvent(Event("result", None, [set([tuple(entry.strip().split(' : ')) for entry in self.split_response(self.responses.pop(0))])]))
     
     
     def _initialized_behaviour_operations_types_full_0_guard(self, parameters):
     def _initialized_behaviour_operations_types_full_0_guard(self, parameters):
         return self.expect_response_partial('Success: ', pop=False)
         return self.expect_response_partial('Success: ', pop=False)
@@ -3690,6 +3691,7 @@ class HTTPClient(RuntimeClassBase):
     
     
     def _connecting_0_exec(self, parameters):
     def _connecting_0_exec(self, parameters):
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("http_client_timeout", None, [])]))
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("http_client_timeout", None, [])]))
+        print("Raise timeout after %ss" % self.timeout)
     
     
     def _init_0_exec(self, parameters):
     def _init_0_exec(self, parameters):
         socket = parameters[0]
         socket = parameters[0]
@@ -4193,35 +4195,38 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         # state /running/rerender_model/model_toolbars/pack_cs_toolbar
         # state /running/rerender_model/model_toolbars/pack_cs_toolbar
         self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"] = State(59, "/running/rerender_model/model_toolbars/pack_cs_toolbar", self)
         self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"] = State(59, "/running/rerender_model/model_toolbars/pack_cs_toolbar", self)
         
         
+        # state /running/rerender_model/model_toolbars/fetch_types
+        self.states["/running/rerender_model/model_toolbars/fetch_types"] = State(60, "/running/rerender_model/model_toolbars/fetch_types", self)
+        self.states["/running/rerender_model/model_toolbars/fetch_types"].setEnter(self._running_rerender_model_model_toolbars_fetch_types_enter)
+        
         # state /running/rerender_model/model_toolbars/dsl_toolbar
         # state /running/rerender_model/model_toolbars/dsl_toolbar
-        self.states["/running/rerender_model/model_toolbars/dsl_toolbar"] = State(60, "/running/rerender_model/model_toolbars/dsl_toolbar", self)
-        self.states["/running/rerender_model/model_toolbars/dsl_toolbar"].setEnter(self._running_rerender_model_model_toolbars_dsl_toolbar_enter)
+        self.states["/running/rerender_model/model_toolbars/dsl_toolbar"] = State(61, "/running/rerender_model/model_toolbars/dsl_toolbar", self)
         
         
         # state /running/rerender_model/model_toolbars/pack_dsl_toolbar
         # state /running/rerender_model/model_toolbars/pack_dsl_toolbar
-        self.states["/running/rerender_model/model_toolbars/pack_dsl_toolbar"] = State(61, "/running/rerender_model/model_toolbars/pack_dsl_toolbar", self)
+        self.states["/running/rerender_model/model_toolbars/pack_dsl_toolbar"] = State(62, "/running/rerender_model/model_toolbars/pack_dsl_toolbar", self)
         
         
         # state /running/rerender_model/request_render
         # state /running/rerender_model/request_render
-        self.states["/running/rerender_model/request_render"] = State(62, "/running/rerender_model/request_render", self)
+        self.states["/running/rerender_model/request_render"] = State(63, "/running/rerender_model/request_render", self)
         self.states["/running/rerender_model/request_render"].setEnter(self._running_rerender_model_request_render_enter)
         self.states["/running/rerender_model/request_render"].setEnter(self._running_rerender_model_request_render_enter)
         
         
         # state /running/rerender_model/render_model
         # state /running/rerender_model/render_model
-        self.states["/running/rerender_model/render_model"] = State(63, "/running/rerender_model/render_model", self)
+        self.states["/running/rerender_model/render_model"] = State(64, "/running/rerender_model/render_model", self)
         self.states["/running/rerender_model/render_model"].setEnter(self._running_rerender_model_render_model_enter)
         self.states["/running/rerender_model/render_model"].setEnter(self._running_rerender_model_render_model_enter)
         
         
         # state /running/rerender_model/render_model/allocate_groups
         # state /running/rerender_model/render_model/allocate_groups
-        self.states["/running/rerender_model/render_model/allocate_groups"] = State(64, "/running/rerender_model/render_model/allocate_groups", self)
+        self.states["/running/rerender_model/render_model/allocate_groups"] = State(65, "/running/rerender_model/render_model/allocate_groups", self)
         
         
         # state /running/rerender_model/render_model/allocating_group
         # state /running/rerender_model/render_model/allocating_group
-        self.states["/running/rerender_model/render_model/allocating_group"] = State(65, "/running/rerender_model/render_model/allocating_group", self)
+        self.states["/running/rerender_model/render_model/allocating_group"] = State(66, "/running/rerender_model/render_model/allocating_group", self)
         
         
         # state /running/rerender_model/render_model/allocate_contains
         # state /running/rerender_model/render_model/allocate_contains
-        self.states["/running/rerender_model/render_model/allocate_contains"] = State(66, "/running/rerender_model/render_model/allocate_contains", self)
+        self.states["/running/rerender_model/render_model/allocate_contains"] = State(67, "/running/rerender_model/render_model/allocate_contains", self)
         
         
         # state /running/rerender_model/render_model/render_elements
         # state /running/rerender_model/render_model/render_elements
-        self.states["/running/rerender_model/render_model/render_elements"] = State(67, "/running/rerender_model/render_model/render_elements", self)
+        self.states["/running/rerender_model/render_model/render_elements"] = State(68, "/running/rerender_model/render_model/render_elements", self)
         
         
         # state /close
         # state /close
-        self.states["/close"] = State(68, "/close", self)
+        self.states["/close"] = State(69, "/close", self)
         self.states["/close"].setEnter(self._close_enter)
         self.states["/close"].setEnter(self._close_enter)
         
         
         # add children
         # add children
@@ -4287,6 +4292,7 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/pack_mm_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/pack_mm_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/cs_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/cs_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"])
+        self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/fetch_types"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/dsl_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/dsl_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/pack_dsl_toolbar"])
         self.states["/running/rerender_model/model_toolbars"].addChild(self.states["/running/rerender_model/model_toolbars/pack_dsl_toolbar"])
         self.states["/running/rerender_model/render_model"].addChild(self.states["/running/rerender_model/render_model/allocate_groups"])
         self.states["/running/rerender_model/render_model"].addChild(self.states["/running/rerender_model/render_model/allocate_groups"])
@@ -4376,6 +4382,10 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         _running_idle_11.setAction(self._running_idle_11_exec)
         _running_idle_11.setAction(self._running_idle_11_exec)
         _running_idle_11.setTrigger(Event("change_rendered", None))
         _running_idle_11.setTrigger(Event("change_rendered", None))
         self.states["/running/idle"].addTransition(_running_idle_11)
         self.states["/running/idle"].addTransition(_running_idle_11)
+        _running_idle_12 = Transition(self, self.states["/running/idle"], [self.states["/running/idle"]])
+        _running_idle_12.setAction(self._running_idle_12_exec)
+        _running_idle_12.setTrigger(Event("select_for_creation", None))
+        self.states["/running/idle"].addTransition(_running_idle_12)
         
         
         # transition /running/add_object_diagrams/init
         # transition /running/add_object_diagrams/init
         _running_add_object_diagrams_init_0 = Transition(self, self.states["/running/add_object_diagrams/init"], [self.states["/running/add_object_diagrams/modify_render_OD"]])
         _running_add_object_diagrams_init_0 = Transition(self, self.states["/running/add_object_diagrams/init"], [self.states["/running/add_object_diagrams/modify_render_OD"]])
@@ -4658,11 +4668,17 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         self.states["/running/rerender_model/model_toolbars/cs_toolbar"].addTransition(_running_rerender_model_model_toolbars_cs_toolbar_0)
         self.states["/running/rerender_model/model_toolbars/cs_toolbar"].addTransition(_running_rerender_model_model_toolbars_cs_toolbar_0)
         
         
         # transition /running/rerender_model/model_toolbars/pack_cs_toolbar
         # transition /running/rerender_model/model_toolbars/pack_cs_toolbar
-        _running_rerender_model_model_toolbars_pack_cs_toolbar_0 = Transition(self, self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"], [self.states["/running/rerender_model/model_toolbars/dsl_toolbar"]])
+        _running_rerender_model_model_toolbars_pack_cs_toolbar_0 = Transition(self, self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"], [self.states["/running/rerender_model/model_toolbars/fetch_types"]])
         _running_rerender_model_model_toolbars_pack_cs_toolbar_0.setAction(self._running_rerender_model_model_toolbars_pack_cs_toolbar_0_exec)
         _running_rerender_model_model_toolbars_pack_cs_toolbar_0.setAction(self._running_rerender_model_model_toolbars_pack_cs_toolbar_0_exec)
         _running_rerender_model_model_toolbars_pack_cs_toolbar_0.setTrigger(Event("tk_widget", None))
         _running_rerender_model_model_toolbars_pack_cs_toolbar_0.setTrigger(Event("tk_widget", None))
         self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"].addTransition(_running_rerender_model_model_toolbars_pack_cs_toolbar_0)
         self.states["/running/rerender_model/model_toolbars/pack_cs_toolbar"].addTransition(_running_rerender_model_model_toolbars_pack_cs_toolbar_0)
         
         
+        # transition /running/rerender_model/model_toolbars/fetch_types
+        _running_rerender_model_model_toolbars_fetch_types_0 = Transition(self, self.states["/running/rerender_model/model_toolbars/fetch_types"], [self.states["/running/rerender_model/model_toolbars/dsl_toolbar"]])
+        _running_rerender_model_model_toolbars_fetch_types_0.setAction(self._running_rerender_model_model_toolbars_fetch_types_0_exec)
+        _running_rerender_model_model_toolbars_fetch_types_0.setTrigger(Event("mv_response", None))
+        self.states["/running/rerender_model/model_toolbars/fetch_types"].addTransition(_running_rerender_model_model_toolbars_fetch_types_0)
+        
         # transition /running/rerender_model/model_toolbars/dsl_toolbar
         # transition /running/rerender_model/model_toolbars/dsl_toolbar
         _running_rerender_model_model_toolbars_dsl_toolbar_0 = Transition(self, self.states["/running/rerender_model/model_toolbars/dsl_toolbar"], [self.states["/running/rerender_model/model_toolbars/pack_dsl_toolbar"]])
         _running_rerender_model_model_toolbars_dsl_toolbar_0 = Transition(self, self.states["/running/rerender_model/model_toolbars/dsl_toolbar"], [self.states["/running/rerender_model/model_toolbars/pack_dsl_toolbar"]])
         _running_rerender_model_model_toolbars_dsl_toolbar_0.setAction(self._running_rerender_model_model_toolbars_dsl_toolbar_0_exec)
         _running_rerender_model_model_toolbars_dsl_toolbar_0.setAction(self._running_rerender_model_model_toolbars_dsl_toolbar_0_exec)
@@ -4793,7 +4809,7 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['verify', [current_model, current_metamodel]])]))
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['verify', [current_model, current_metamodel]])]))
     
     
     def _running_open_model_query_model_enter(self):
     def _running_open_model_query_model_enter(self):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, 'subwindow', 'Browser', 'Select model to open', ['formalisms/SimpleClassDiagrams']]))
+        self.big_step.outputEventOM(Event("create_instance", None, [self, 'subwindow', 'Browser', 'Select model to open', []]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'progress_bar', Event("update_status", None, [0, 'Browsing for model...'])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'progress_bar', Event("update_status", None, [0, 'Browsing for model...'])]))
     
     
     def _running_open_model_search_metamodels_enter(self):
     def _running_open_model_search_metamodels_enter(self):
@@ -4836,8 +4852,8 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
     def _running_rerender_model_model_toolbars_cs_toolbar_enter(self):
     def _running_rerender_model_model_toolbars_cs_toolbar_enter(self):
         self.big_step.outputEventOM(Event("create_instance", None, [self, 'model_toolbars', 'ConcreteSyntaxToolbar', self.toolbar_frame, self.allowed_mappers, self.allowed_rendered]))
         self.big_step.outputEventOM(Event("create_instance", None, [self, 'model_toolbars', 'ConcreteSyntaxToolbar', self.toolbar_frame, self.allowed_mappers, self.allowed_rendered]))
     
     
-    def _running_rerender_model_model_toolbars_dsl_toolbar_enter(self):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, 'model_toolbars', 'DSLToolbar', self.toolbar_frame]))
+    def _running_rerender_model_model_toolbars_fetch_types_enter(self):
+        self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['types', [current_model]])]))
     
     
     def _running_rerender_model_request_render_enter(self):
     def _running_rerender_model_request_render_enter(self):
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['model_render', [current_model, current_mapper, current_rendered_model]])]))
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['model_render', [current_model, current_mapper, current_rendered_model]])]))
@@ -4885,6 +4901,10 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         global current_rendered_model
         global current_rendered_model
         current_rendered_model = new_rendered
         current_rendered_model = new_rendered
     
     
+    def _running_idle_12_exec(self, parameters):
+        element_name = parameters[0]
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'canvas', Event("select_for_creation", None, [element_name])]))
+    
     def _running_add_object_diagrams_init_0_exec(self, parameters):
     def _running_add_object_diagrams_init_0_exec(self, parameters):
         context = parameters[0]
         context = parameters[0]
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'progress_bar', Event("update_status", None, [25, 'Switching contexts...'])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'progress_bar', Event("update_status", None, [25, 'Switching contexts...'])]))
@@ -5104,6 +5124,10 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         tk_elem = parameters[0]
         tk_elem = parameters[0]
         tk_elem.pack(anchor=tk.W)
         tk_elem.pack(anchor=tk.W)
     
     
+    def _running_rerender_model_model_toolbars_fetch_types_0_exec(self, parameters):
+        result = parameters[0]
+        self.big_step.outputEventOM(Event("create_instance", None, [self, 'model_toolbars', 'DSLToolbar', self.toolbar_frame, result]))
+    
     def _running_rerender_model_model_toolbars_dsl_toolbar_0_exec(self, parameters):
     def _running_rerender_model_model_toolbars_dsl_toolbar_0_exec(self, parameters):
         association_name = parameters[0]
         association_name = parameters[0]
         self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
         self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
@@ -6144,7 +6168,7 @@ class GenericToolbar(Toolbar):
         RuntimeClassBase.initializeStatechart(self)
         RuntimeClassBase.initializeStatechart(self)
 
 
 class DSLToolbar(Toolbar):
 class DSLToolbar(Toolbar):
-    def __init__(self, controller, parent):
+    def __init__(self, controller, parent, elements):
         RuntimeClassBase.__init__(self, controller)
         RuntimeClassBase.__init__(self, controller)
         
         
         self.semantics.big_step_maximality = StatechartSemantics.TakeMany
         self.semantics.big_step_maximality = StatechartSemantics.TakeMany
@@ -6157,14 +6181,16 @@ class DSLToolbar(Toolbar):
         self.build_statechart_structure()
         self.build_statechart_structure()
         
         
         # call user defined constructor
         # call user defined constructor
-        DSLToolbar.user_defined_constructor(self, parent)
+        DSLToolbar.user_defined_constructor(self, parent, elements)
     
     
-    def user_defined_constructor(self, parent):
+    def user_defined_constructor(self, parent, elements):
         Toolbar.user_defined_constructor(self, parent)
         Toolbar.user_defined_constructor(self, parent)
-        self.to_create = ["todo"]
-        self.button_info = {"todo": "REMOVE"}
+        print("Got elements: " + str(elements))
+        self.to_create = [i[0] for i in elements if i[1] == "Class"]
+        self.button_info = {i: "Instantiate element %s" % i for i in self.to_create}
         self.buttons = {}
         self.buttons = {}
         tk.Label(self, text="Domain-Specific").pack(side=tk.LEFT)
         tk.Label(self, text="Domain-Specific").pack(side=tk.LEFT)
+        self.currently_active = None
     
     
     def user_defined_destructor(self):
     def user_defined_destructor(self):
         # call super class destructors
         # call super class destructors
@@ -6242,14 +6268,9 @@ class DSLToolbar(Toolbar):
         _root_0.setTrigger(Event("button_pressed", None))
         _root_0.setTrigger(Event("button_pressed", None))
         _root_0.setGuard(self._root_0_guard)
         _root_0.setGuard(self._root_0_guard)
         self.states["/root"].addTransition(_root_0)
         self.states["/root"].addTransition(_root_0)
-        _root_1 = Transition(self, self.states["/root"], [self.states["/root"]])
-        _root_1.setAction(self._root_1_exec)
-        _root_1.setTrigger(Event("button_pressed", None))
-        _root_1.setGuard(self._root_1_guard)
+        _root_1 = Transition(self, self.states["/root"], [self.states["/closing"]])
+        _root_1.setTrigger(Event("close", None))
         self.states["/root"].addTransition(_root_1)
         self.states["/root"].addTransition(_root_1)
-        _root_2 = Transition(self, self.states["/root"], [self.states["/closing"]])
-        _root_2.setTrigger(Event("close", None))
-        self.states["/root"].addTransition(_root_2)
         
         
         # transition /closing
         # transition /closing
         _closing_0 = Transition(self, self.states["/closing"], [self.states["/closing"]])
         _closing_0 = Transition(self, self.states["/closing"], [self.states["/closing"]])
@@ -6265,7 +6286,7 @@ class DSLToolbar(Toolbar):
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("tk_widget", None, [self])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("tk_widget", None, [self])]))
     
     
     def _init_init_buttons_enter(self):
     def _init_init_buttons_enter(self):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, 'buttons', 'Button', {'parent': self, 'visual': ImageVisual('icons/%s.png' % self.to_create[0]), 'tooltip_text': self.button_info[self.to_create[0]], 'event_parameters': self.to_create[0]}]))
+        self.big_step.outputEventOM(Event("create_instance", None, [self, 'buttons', 'Button', {'parent': self, 'visual': TextVisual(self.to_create[0]), 'tooltip_text': self.button_info[self.to_create[0]], 'event_parameters': self.to_create[0]}]))
     
     
     def _closing_enter(self):
     def _closing_enter(self):
         self.big_step.outputEventOM(Event("delete_instance", None, [self, self.buttons.popitem()[1]]))
         self.big_step.outputEventOM(Event("delete_instance", None, [self, self.buttons.popitem()[1]]))
@@ -6291,19 +6312,14 @@ class DSLToolbar(Toolbar):
     
     
     def _root_0_exec(self, parameters):
     def _root_0_exec(self, parameters):
         event_name = parameters[0]
         event_name = parameters[0]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("create_new_model", None, [])]))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.buttons[self.currently_active] if self.currently_active is not None else 'parent', Event("deactivate", None, [])]))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.buttons[event_name], Event("activate", None, [])]))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("select_for_creation", None, [event_name])]))
+        self.currently_active = event_name
     
     
     def _root_0_guard(self, parameters):
     def _root_0_guard(self, parameters):
         event_name = parameters[0]
         event_name = parameters[0]
-        return event_name == 'new'
-    
-    def _root_1_exec(self, parameters):
-        event_name = parameters[0]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("open_model", None, [])]))
-    
-    def _root_1_guard(self, parameters):
-        event_name = parameters[0]
-        return event_name == 'open'
+        return event_name != self.currently_active
     
     
     def _closing_0_guard(self, parameters):
     def _closing_0_guard(self, parameters):
         return len(self.buttons) > 0
         return len(self.buttons) > 0
@@ -6860,6 +6876,14 @@ class Button(RuntimeClassBase, tk.Button, SCCDWidget):
         _main_ready_2.setTrigger(Event("leave", "input"))
         _main_ready_2.setTrigger(Event("leave", "input"))
         _main_ready_2.setGuard(self._main_ready_2_guard)
         _main_ready_2.setGuard(self._main_ready_2_guard)
         self.states["/main/ready"].addTransition(_main_ready_2)
         self.states["/main/ready"].addTransition(_main_ready_2)
+        _main_ready_3 = Transition(self, self.states["/main/ready"], [self.states["/main/ready"]])
+        _main_ready_3.setAction(self._main_ready_3_exec)
+        _main_ready_3.setTrigger(Event("activate", None))
+        self.states["/main/ready"].addTransition(_main_ready_3)
+        _main_ready_4 = Transition(self, self.states["/main/ready"], [self.states["/main/ready"]])
+        _main_ready_4.setAction(self._main_ready_4_exec)
+        _main_ready_4.setTrigger(Event("deactivate", None))
+        self.states["/main/ready"].addTransition(_main_ready_4)
     
     
     def _main_initializing_0_exec(self, parameters):
     def _main_initializing_0_exec(self, parameters):
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("tk_widget", None, [self])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("tk_widget", None, [self])]))
@@ -6888,6 +6912,14 @@ class Button(RuntimeClassBase, tk.Button, SCCDWidget):
         tagorid = parameters[0]
         tagorid = parameters[0]
         return tagorid == id(self) and self.tooltip is not None
         return tagorid == id(self) and self.tooltip is not None
     
     
+    def _main_ready_3_exec(self, parameters):
+        self.configure(state=tk.ACTIVE, relief=tk.SUNKEN)
+        print("Activate " + str(self.event_parameters))
+    
+    def _main_ready_4_exec(self, parameters):
+        self.configure(state=tk.NORMAL, relief=tk.RAISED)
+        print("Deactivate " + str(self.event_parameters))
+    
     def initializeStatechart(self):
     def initializeStatechart(self):
         # enter default state
         # enter default state
         self.default_targets = self.states["/main"].getEffectiveTargetStates()
         self.default_targets = self.states["/main"].getEffectiveTargetStates()
@@ -7112,8 +7144,16 @@ class Canvas(RuntimeClassBase, tk.Canvas, SCCDWidget):
         self.connecting_lines = {}
         self.connecting_lines = {}
         self.lines = set()
         self.lines = set()
         self.layers = []
         self.layers = []
+        print("RESET CANVAS")
+        self.to_move = {}
+        
+        self.elems = []
+        
+        self.currently_selected = None
+        self.loading = [tk.PhotoImage(file="icons/loading.gif", format="gif -index %i" % i) for i in range(8)]
     
     
     def user_defined_destructor(self):
     def user_defined_destructor(self):
+        print("CANVAS DESTROYED")
         self.destroy()
         self.destroy()
         # call super class destructors
         # call super class destructors
         if hasattr(tk.Canvas, "__del__"):
         if hasattr(tk.Canvas, "__del__"):
@@ -7132,17 +7172,50 @@ class Canvas(RuntimeClassBase, tk.Canvas, SCCDWidget):
         self.states["/main"] = State(1, "/main", self)
         self.states["/main"] = State(1, "/main", self)
         
         
         # state /ready
         # state /ready
-        self.states["/ready"] = State(2, "/ready", self)
+        self.states["/ready"] = ParallelState(2, "/ready", self)
+        
+        # state /ready/process_events
+        self.states["/ready/process_events"] = State(3, "/ready/process_events", self)
+        
+        # state /ready/process_events/ready
+        self.states["/ready/process_events/ready"] = State(4, "/ready/process_events/ready", self)
+        
+        # state /ready/process_events/creating_group
+        self.states["/ready/process_events/creating_group"] = State(5, "/ready/process_events/creating_group", self)
+        
+        # state /ready/process_events/wait_canvas_element_ready
+        self.states["/ready/process_events/wait_canvas_element_ready"] = State(6, "/ready/process_events/wait_canvas_element_ready", self)
+        
+        # state /ready/process_events/creating_element
+        self.states["/ready/process_events/creating_element"] = State(7, "/ready/process_events/creating_element", self)
+        self.states["/ready/process_events/creating_element"].setEnter(self._ready_process_events_creating_element_enter)
+        
+        # state /ready/process_events/waiting_for_clear
+        self.states["/ready/process_events/waiting_for_clear"] = State(8, "/ready/process_events/waiting_for_clear", self)
         
         
-        # state /creating_group
-        self.states["/creating_group"] = State(3, "/creating_group", self)
+        # state /ready/update_loading
+        self.states["/ready/update_loading"] = State(9, "/ready/update_loading", self)
+        
+        # state /ready/update_loading/updating
+        self.states["/ready/update_loading/updating"] = State(10, "/ready/update_loading/updating", self)
+        self.states["/ready/update_loading/updating"].setEnter(self._ready_update_loading_updating_enter)
+        self.states["/ready/update_loading/updating"].setExit(self._ready_update_loading_updating_exit)
         
         
         # add children
         # add children
         self.states[""].addChild(self.states["/main"])
         self.states[""].addChild(self.states["/main"])
         self.states[""].addChild(self.states["/ready"])
         self.states[""].addChild(self.states["/ready"])
-        self.states[""].addChild(self.states["/creating_group"])
+        self.states["/ready"].addChild(self.states["/ready/process_events"])
+        self.states["/ready"].addChild(self.states["/ready/update_loading"])
+        self.states["/ready/process_events"].addChild(self.states["/ready/process_events/ready"])
+        self.states["/ready/process_events"].addChild(self.states["/ready/process_events/creating_group"])
+        self.states["/ready/process_events"].addChild(self.states["/ready/process_events/wait_canvas_element_ready"])
+        self.states["/ready/process_events"].addChild(self.states["/ready/process_events/creating_element"])
+        self.states["/ready/process_events"].addChild(self.states["/ready/process_events/waiting_for_clear"])
+        self.states["/ready/update_loading"].addChild(self.states["/ready/update_loading/updating"])
         self.states[""].fixTree()
         self.states[""].fixTree()
         self.states[""].default_state = self.states["/main"]
         self.states[""].default_state = self.states["/main"]
+        self.states["/ready/process_events"].default_state = self.states["/ready/process_events/ready"]
+        self.states["/ready/update_loading"].default_state = self.states["/ready/update_loading/updating"]
         
         
         # transition /main
         # transition /main
         _main_0 = Transition(self, self.states["/main"], [self.states["/ready"]])
         _main_0 = Transition(self, self.states["/main"], [self.states["/ready"]])
@@ -7150,95 +7223,176 @@ class Canvas(RuntimeClassBase, tk.Canvas, SCCDWidget):
         _main_0.setTrigger(None)
         _main_0.setTrigger(None)
         self.states["/main"].addTransition(_main_0)
         self.states["/main"].addTransition(_main_0)
         
         
-        # transition /ready
-        _ready_0 = Transition(self, self.states["/ready"], [self.states["/ready"]])
-        _ready_0.setAction(self._ready_0_exec)
-        _ready_0.setTrigger(Event("clear_canvas", None))
-        self.states["/ready"].addTransition(_ready_0)
-        _ready_1 = Transition(self, self.states["/ready"], [self.states["/creating_group"]])
-        _ready_1.setAction(self._ready_1_exec)
-        _ready_1.setTrigger(Event("define_group", None))
-        self.states["/ready"].addTransition(_ready_1)
-        _ready_2 = Transition(self, self.states["/ready"], [self.states["/ready"]])
-        _ready_2.setAction(self._ready_2_exec)
-        _ready_2.setTrigger(Event("define_contains", None))
-        self.states["/ready"].addTransition(_ready_2)
-        _ready_3 = Transition(self, self.states["/ready"], [self.states["/ready"]])
-        _ready_3.setAction(self._ready_3_exec)
-        _ready_3.setTrigger(Event("draw_canvas", None))
-        _ready_3.setGuard(self._ready_3_guard)
-        self.states["/ready"].addTransition(_ready_3)
-        _ready_4 = Transition(self, self.states["/ready"], [self.states["/ready"]])
-        _ready_4.setAction(self._ready_4_exec)
-        _ready_4.setTrigger(Event("draw_canvas", None))
-        _ready_4.setGuard(self._ready_4_guard)
-        self.states["/ready"].addTransition(_ready_4)
-        _ready_5 = Transition(self, self.states["/ready"], [self.states["/ready"]])
-        _ready_5.setAction(self._ready_5_exec)
-        _ready_5.setTrigger(Event("instance_created", None))
-        self.states["/ready"].addTransition(_ready_5)
-        _ready_6 = Transition(self, self.states["/ready"], [self.states["/ready"]])
-        _ready_6.setAction(self._ready_6_exec)
-        _ready_6.setTrigger(Event("moved_group", None))
-        self.states["/ready"].addTransition(_ready_6)
-        
-        # transition /creating_group
-        _creating_group_0 = Transition(self, self.states["/creating_group"], [self.states["/ready"]])
-        _creating_group_0.setAction(self._creating_group_0_exec)
-        _creating_group_0.setTrigger(Event("instance_created", None))
-        self.states["/creating_group"].addTransition(_creating_group_0)
+        # transition /ready/process_events/ready
+        _ready_process_events_ready_0 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_ready_0.setAction(self._ready_process_events_ready_0_exec)
+        _ready_process_events_ready_0.setTrigger(Event("clear_canvas", None))
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_0)
+        _ready_process_events_ready_1 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_ready_1.setAction(self._ready_process_events_ready_1_exec)
+        _ready_process_events_ready_1.setTrigger(Event("select_for_creation", None))
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_1)
+        _ready_process_events_ready_2 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/creating_element"]])
+        _ready_process_events_ready_2.setAction(self._ready_process_events_ready_2_exec)
+        _ready_process_events_ready_2.setTrigger(Event("right-click", None))
+        _ready_process_events_ready_2.setGuard(self._ready_process_events_ready_2_guard)
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_2)
+        _ready_process_events_ready_3 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/creating_group"]])
+        _ready_process_events_ready_3.setAction(self._ready_process_events_ready_3_exec)
+        _ready_process_events_ready_3.setTrigger(Event("define_group", None))
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_3)
+        _ready_process_events_ready_4 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_ready_4.setAction(self._ready_process_events_ready_4_exec)
+        _ready_process_events_ready_4.setTrigger(Event("define_contains", None))
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_4)
+        _ready_process_events_ready_5 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_ready_5.setAction(self._ready_process_events_ready_5_exec)
+        _ready_process_events_ready_5.setTrigger(Event("draw_canvas", None))
+        _ready_process_events_ready_5.setGuard(self._ready_process_events_ready_5_guard)
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_5)
+        _ready_process_events_ready_6 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_ready_6.setAction(self._ready_process_events_ready_6_exec)
+        _ready_process_events_ready_6.setTrigger(Event("draw_canvas", None))
+        _ready_process_events_ready_6.setGuard(self._ready_process_events_ready_6_guard)
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_6)
+        _ready_process_events_ready_7 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_ready_7.setAction(self._ready_process_events_ready_7_exec)
+        _ready_process_events_ready_7.setTrigger(Event("instance_created", None))
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_7)
+        _ready_process_events_ready_8 = Transition(self, self.states["/ready/process_events/ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_ready_8.setAction(self._ready_process_events_ready_8_exec)
+        _ready_process_events_ready_8.setTrigger(Event("moved_group", None))
+        self.states["/ready/process_events/ready"].addTransition(_ready_process_events_ready_8)
+        
+        # transition /ready/process_events/creating_group
+        _ready_process_events_creating_group_0 = Transition(self, self.states["/ready/process_events/creating_group"], [self.states["/ready/process_events/wait_canvas_element_ready"]])
+        _ready_process_events_creating_group_0.setAction(self._ready_process_events_creating_group_0_exec)
+        _ready_process_events_creating_group_0.setTrigger(Event("instance_created", None))
+        self.states["/ready/process_events/creating_group"].addTransition(_ready_process_events_creating_group_0)
+        
+        # transition /ready/process_events/wait_canvas_element_ready
+        _ready_process_events_wait_canvas_element_ready_0 = Transition(self, self.states["/ready/process_events/wait_canvas_element_ready"], [self.states["/ready/process_events/wait_canvas_element_ready"]])
+        _ready_process_events_wait_canvas_element_ready_0.setAction(self._ready_process_events_wait_canvas_element_ready_0_exec)
+        _ready_process_events_wait_canvas_element_ready_0.setTrigger(Event("moved_group", None))
+        self.states["/ready/process_events/wait_canvas_element_ready"].addTransition(_ready_process_events_wait_canvas_element_ready_0)
+        _ready_process_events_wait_canvas_element_ready_1 = Transition(self, self.states["/ready/process_events/wait_canvas_element_ready"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_wait_canvas_element_ready_1.setAction(self._ready_process_events_wait_canvas_element_ready_1_exec)
+        _ready_process_events_wait_canvas_element_ready_1.setTrigger(Event("canvas_element_ready", None))
+        self.states["/ready/process_events/wait_canvas_element_ready"].addTransition(_ready_process_events_wait_canvas_element_ready_1)
+        
+        # transition /ready/process_events/creating_element
+        _ready_process_events_creating_element_0 = Transition(self, self.states["/ready/process_events/creating_element"], [self.states["/ready/process_events/waiting_for_clear"]])
+        _ready_process_events_creating_element_0.setAction(self._ready_process_events_creating_element_0_exec)
+        _ready_process_events_creating_element_0.setTrigger(Event("mv_response", None))
+        self.states["/ready/process_events/creating_element"].addTransition(_ready_process_events_creating_element_0)
+        
+        # transition /ready/process_events/waiting_for_clear
+        _ready_process_events_waiting_for_clear_0 = Transition(self, self.states["/ready/process_events/waiting_for_clear"], [self.states["/ready/process_events/ready"]])
+        _ready_process_events_waiting_for_clear_0.setAction(self._ready_process_events_waiting_for_clear_0_exec)
+        _ready_process_events_waiting_for_clear_0.setTrigger(Event("clear_canvas", None))
+        self.states["/ready/process_events/waiting_for_clear"].addTransition(_ready_process_events_waiting_for_clear_0)
+        
+        # transition /ready/update_loading/updating
+        _ready_update_loading_updating_0 = Transition(self, self.states["/ready/update_loading/updating"], [self.states["/ready/update_loading/updating"]])
+        _ready_update_loading_updating_0.setAction(self._ready_update_loading_updating_0_exec)
+        _ready_update_loading_updating_0.setTrigger(Event("_0after"))
+        self.states["/ready/update_loading/updating"].addTransition(_ready_update_loading_updating_0)
+    
+    def _ready_process_events_creating_element_enter(self):
+        self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['instantiate', [current_model, self.currently_selected, None, '']])]))
+        self.elems.append([0, self.create_image(self.last_x, self.last_y, image=self.loading[0])])
+    
+    def _ready_update_loading_updating_enter(self):
+        self.addTimer(0, self.sccd_yield() + 0.1)
+    
+    def _ready_update_loading_updating_exit(self):
+        self.removeTimer(0)
     
     
     def _main_0_exec(self, parameters):
     def _main_0_exec(self, parameters):
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("tk_widget", None, [self])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("tk_widget", None, [self])]))
     
     
-    def _ready_0_exec(self, parameters):
+    def _ready_process_events_ready_0_exec(self, parameters):
         self.big_step.outputEventOM(Event("delete_instance", None, [self, 'elements']))
         self.big_step.outputEventOM(Event("delete_instance", None, [self, 'elements']))
         self.big_step.outputEventOM(Event("delete_instance", None, [self, 'connecting_lines']))
         self.big_step.outputEventOM(Event("delete_instance", None, [self, 'connecting_lines']))
         self.group_location = {}
         self.group_location = {}
         self.layers = []
         self.layers = []
     
     
-    def _ready_1_exec(self, parameters):
+    def _ready_process_events_ready_1_exec(self, parameters):
+        element_name = parameters[0]
+        self.currently_selected = element_name
+    
+    def _ready_process_events_ready_2_exec(self, parameters):
+        self.create_location = (self.last_x, self.last_y)
+    
+    def _ready_process_events_ready_2_guard(self, parameters):
+        return self.currently_selected is not None
+    
+    def _ready_process_events_ready_3_exec(self, parameters):
         element = parameters[0]
         element = parameters[0]
         self.creating_id = element["id"]
         self.creating_id = element["id"]
         self.group_location[element['id']] = (element['x'], element['y'])
         self.group_location[element['id']] = (element['x'], element['y'])
         self.big_step.outputEventOM(Event("create_instance", None, [self, 'elements', 'CanvasElement', self, (element['x'], element['y']), element['id'], element['__asid']]))
         self.big_step.outputEventOM(Event("create_instance", None, [self, 'elements', 'CanvasElement', self, (element['x'], element['y']), element['id'], element['__asid']]))
     
     
-    def _ready_2_exec(self, parameters):
+    def _ready_process_events_ready_4_exec(self, parameters):
         element = parameters[0]
         element = parameters[0]
         self.element_group[element["__target"]] = element["__source"]
         self.element_group[element["__target"]] = element["__source"]
     
     
-    def _ready_3_exec(self, parameters):
+    def _ready_process_events_ready_5_exec(self, parameters):
         element = parameters[0]
         element = parameters[0]
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.assoc_links[self.element_group[element['id']]], Event("draw_element", None, [element])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.assoc_links[self.element_group[element['id']]], Event("draw_element", None, [element])]))
     
     
-    def _ready_3_guard(self, parameters):
+    def _ready_process_events_ready_5_guard(self, parameters):
         element = parameters[0]
         element = parameters[0]
         return element['type'] != 'ConnectingLine'
         return element['type'] != 'ConnectingLine'
     
     
-    def _ready_4_exec(self, parameters):
+    def _ready_process_events_ready_6_exec(self, parameters):
         element = parameters[0]
         element = parameters[0]
         self.big_step.outputEventOM(Event("create_instance", None, [self, 'connecting_lines', 'ConnectingLine', self, element]))
         self.big_step.outputEventOM(Event("create_instance", None, [self, 'connecting_lines', 'ConnectingLine', self, element]))
     
     
-    def _ready_4_guard(self, parameters):
+    def _ready_process_events_ready_6_guard(self, parameters):
         element = parameters[0]
         element = parameters[0]
         return element['type'] == 'ConnectingLine'
         return element['type'] == 'ConnectingLine'
     
     
-    def _ready_5_exec(self, parameters):
+    def _ready_process_events_ready_7_exec(self, parameters):
         result = parameters[0]
         result = parameters[0]
         self.big_step.outputEventOM(Event("start_instance", None, [self, result]))
         self.big_step.outputEventOM(Event("start_instance", None, [self, result]))
     
     
-    def _ready_6_exec(self, parameters):
+    def _ready_process_events_ready_8_exec(self, parameters):
         group_element = parameters[0]
         group_element = parameters[0]
         new_location = parameters[1]
         new_location = parameters[1]
         self.group_location[group_element] = new_location
         self.group_location[group_element] = new_location
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'connecting_lines', Event("moved_element", None, [group_element, new_location])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'connecting_lines', Event("moved_element", None, [group_element, new_location])]))
     
     
-    def _creating_group_0_exec(self, parameters):
+    def _ready_process_events_creating_group_0_exec(self, parameters):
         assoc_name = parameters[0]
         assoc_name = parameters[0]
         self.big_step.outputEventOM(Event("start_instance", None, [self, assoc_name]))
         self.big_step.outputEventOM(Event("start_instance", None, [self, assoc_name]))
         self.assoc_links[self.creating_id] = assoc_name
         self.assoc_links[self.creating_id] = assoc_name
+    
+    def _ready_process_events_wait_canvas_element_ready_0_exec(self, parameters):
+        group_element = parameters[0]
+        new_location = parameters[1]
+        self.group_location[group_element] = new_location
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'connecting_lines', Event("moved_element", None, [group_element, new_location])]))
+    
+    def _ready_process_events_wait_canvas_element_ready_1_exec(self, parameters):
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("group_ready", None, [])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("group_ready", None, [])]))
     
     
+    def _ready_process_events_creating_element_0_exec(self, parameters):
+        ID = parameters[0]
+        self.to_move[ID] = self.create_location
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("rerender_model", None, [])]))
+    
+    def _ready_process_events_waiting_for_clear_0_exec(self, parameters):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'elements']))
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'connecting_lines']))
+        self.group_location = {}
+        self.layers = []
+    
+    def _ready_update_loading_updating_0_exec(self, parameters):
+        for i in self.elems:
+            self.itemconfigure(i[1], image=self.loading[i[0]])
+            i[0] = (i[0] + 1) % 8
+    
     def initializeStatechart(self):
     def initializeStatechart(self):
         # enter default state
         # enter default state
         self.default_targets = self.states["/main"].getEffectiveTargetStates()
         self.default_targets = self.states["/main"].getEffectiveTargetStates()
@@ -7564,55 +7718,94 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
             self.containing_canvas.lift(layer)
             self.containing_canvas.lift(layer)
     
     
     
     
+    # user defined method
+    def move_group(self, new_location):
+        for f in self.elements:
+            old_coords = self.containing_canvas.coords(f)
+        
+            new_x = new_location[0] + self.elements[f]['x']
+            new_y = new_location[1] + self.elements[f]['y']
+        
+            if len(old_coords) == 2:
+                self.containing_canvas.coords(f, (new_x, new_y))
+            elif len(old_coords) == 4:
+                height = old_coords[3] - old_coords[1]
+                width = old_coords[2] - old_coords[0]
+                self.containing_canvas.coords(f, (new_x, new_y, new_x + width, new_y + height))
+    
+    
     # builds Statechart structure
     # builds Statechart structure
     def build_statechart_structure(self):
     def build_statechart_structure(self):
         
         
         # state <root>
         # state <root>
         self.states[""] = State(0, "", self)
         self.states[""] = State(0, "", self)
         
         
+        # state /init
+        self.states["/init"] = State(1, "/init", self)
+        self.states["/init"].setExit(self._init_exit)
+        
+        # state /init/init
+        self.states["/init/init"] = State(2, "/init/init", self)
+        
+        # state /init/update_mv
+        self.states["/init/update_mv"] = State(3, "/init/update_mv", self)
+        
+        # state /init/update_mv/x
+        self.states["/init/update_mv/x"] = State(4, "/init/update_mv/x", self)
+        self.states["/init/update_mv/x"].setEnter(self._init_update_mv_x_enter)
+        
+        # state /init/update_mv/y
+        self.states["/init/update_mv/y"] = State(5, "/init/update_mv/y", self)
+        self.states["/init/update_mv/y"].setEnter(self._init_update_mv_y_enter)
+        
         # state /main
         # state /main
-        self.states["/main"] = State(1, "/main", self)
+        self.states["/main"] = State(6, "/main", self)
         
         
         # state /dragging
         # state /dragging
-        self.states["/dragging"] = State(2, "/dragging", self)
+        self.states["/dragging"] = State(7, "/dragging", self)
         
         
         # state /update_attrs
         # state /update_attrs
-        self.states["/update_attrs"] = State(3, "/update_attrs", self)
+        self.states["/update_attrs"] = State(8, "/update_attrs", self)
         
         
         # state /update_attrs/query
         # state /update_attrs/query
-        self.states["/update_attrs/query"] = State(4, "/update_attrs/query", self)
+        self.states["/update_attrs/query"] = State(9, "/update_attrs/query", self)
         self.states["/update_attrs/query"].setEnter(self._update_attrs_query_enter)
         self.states["/update_attrs/query"].setEnter(self._update_attrs_query_enter)
         
         
         # state /update_attrs/prompt
         # state /update_attrs/prompt
-        self.states["/update_attrs/prompt"] = State(5, "/update_attrs/prompt", self)
+        self.states["/update_attrs/prompt"] = State(10, "/update_attrs/prompt", self)
         self.states["/update_attrs/prompt"].setEnter(self._update_attrs_prompt_enter)
         self.states["/update_attrs/prompt"].setEnter(self._update_attrs_prompt_enter)
         
         
         # state /update_attrs/wait_for_results
         # state /update_attrs/wait_for_results
-        self.states["/update_attrs/wait_for_results"] = State(6, "/update_attrs/wait_for_results", self)
+        self.states["/update_attrs/wait_for_results"] = State(11, "/update_attrs/wait_for_results", self)
         
         
         # state /update_attrs/process_results
         # state /update_attrs/process_results
-        self.states["/update_attrs/process_results"] = State(7, "/update_attrs/process_results", self)
+        self.states["/update_attrs/process_results"] = State(12, "/update_attrs/process_results", self)
         
         
         # state /update_attrs/mark_dirty
         # state /update_attrs/mark_dirty
-        self.states["/update_attrs/mark_dirty"] = State(8, "/update_attrs/mark_dirty", self)
+        self.states["/update_attrs/mark_dirty"] = State(13, "/update_attrs/mark_dirty", self)
         self.states["/update_attrs/mark_dirty"].setEnter(self._update_attrs_mark_dirty_enter)
         self.states["/update_attrs/mark_dirty"].setEnter(self._update_attrs_mark_dirty_enter)
         
         
         # state /update_mv
         # state /update_mv
-        self.states["/update_mv"] = State(9, "/update_mv", self)
+        self.states["/update_mv"] = State(14, "/update_mv", self)
         
         
         # state /update_mv/x
         # state /update_mv/x
-        self.states["/update_mv/x"] = State(10, "/update_mv/x", self)
+        self.states["/update_mv/x"] = State(15, "/update_mv/x", self)
         self.states["/update_mv/x"].setEnter(self._update_mv_x_enter)
         self.states["/update_mv/x"].setEnter(self._update_mv_x_enter)
         
         
         # state /update_mv/y
         # state /update_mv/y
-        self.states["/update_mv/y"] = State(11, "/update_mv/y", self)
+        self.states["/update_mv/y"] = State(16, "/update_mv/y", self)
         self.states["/update_mv/y"].setEnter(self._update_mv_y_enter)
         self.states["/update_mv/y"].setEnter(self._update_mv_y_enter)
         
         
         # add children
         # add children
+        self.states[""].addChild(self.states["/init"])
         self.states[""].addChild(self.states["/main"])
         self.states[""].addChild(self.states["/main"])
         self.states[""].addChild(self.states["/dragging"])
         self.states[""].addChild(self.states["/dragging"])
         self.states[""].addChild(self.states["/update_attrs"])
         self.states[""].addChild(self.states["/update_attrs"])
         self.states[""].addChild(self.states["/update_mv"])
         self.states[""].addChild(self.states["/update_mv"])
+        self.states["/init"].addChild(self.states["/init/init"])
+        self.states["/init"].addChild(self.states["/init/update_mv"])
+        self.states["/init/update_mv"].addChild(self.states["/init/update_mv/x"])
+        self.states["/init/update_mv"].addChild(self.states["/init/update_mv/y"])
         self.states["/update_attrs"].addChild(self.states["/update_attrs/query"])
         self.states["/update_attrs"].addChild(self.states["/update_attrs/query"])
         self.states["/update_attrs"].addChild(self.states["/update_attrs/prompt"])
         self.states["/update_attrs"].addChild(self.states["/update_attrs/prompt"])
         self.states["/update_attrs"].addChild(self.states["/update_attrs/wait_for_results"])
         self.states["/update_attrs"].addChild(self.states["/update_attrs/wait_for_results"])
@@ -7621,10 +7814,34 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
         self.states["/update_mv"].addChild(self.states["/update_mv/x"])
         self.states["/update_mv"].addChild(self.states["/update_mv/x"])
         self.states["/update_mv"].addChild(self.states["/update_mv/y"])
         self.states["/update_mv"].addChild(self.states["/update_mv/y"])
         self.states[""].fixTree()
         self.states[""].fixTree()
-        self.states[""].default_state = self.states["/main"]
+        self.states[""].default_state = self.states["/init"]
+        self.states["/init"].default_state = self.states["/init/init"]
+        self.states["/init/update_mv"].default_state = self.states["/init/update_mv/x"]
         self.states["/update_attrs"].default_state = self.states["/update_attrs/query"]
         self.states["/update_attrs"].default_state = self.states["/update_attrs/query"]
         self.states["/update_mv"].default_state = self.states["/update_mv/x"]
         self.states["/update_mv"].default_state = self.states["/update_mv/x"]
         
         
+        # transition /init/init
+        _init_init_0 = Transition(self, self.states["/init/init"], [self.states["/main"]])
+        _init_init_0.setAction(self._init_init_0_exec)
+        _init_init_0.setTrigger(None)
+        _init_init_0.setGuard(self._init_init_0_guard)
+        self.states["/init/init"].addTransition(_init_init_0)
+        _init_init_1 = Transition(self, self.states["/init/init"], [self.states["/init/update_mv"]])
+        _init_init_1.setAction(self._init_init_1_exec)
+        _init_init_1.setTrigger(None)
+        _init_init_1.setGuard(self._init_init_1_guard)
+        self.states["/init/init"].addTransition(_init_init_1)
+        
+        # transition /init/update_mv/x
+        _init_update_mv_x_0 = Transition(self, self.states["/init/update_mv/x"], [self.states["/init/update_mv/y"]])
+        _init_update_mv_x_0.setTrigger(Event("mv_response", None))
+        self.states["/init/update_mv/x"].addTransition(_init_update_mv_x_0)
+        
+        # transition /init/update_mv/y
+        _init_update_mv_y_0 = Transition(self, self.states["/init/update_mv/y"], [self.states["/main"]])
+        _init_update_mv_y_0.setTrigger(Event("mv_response", None))
+        self.states["/init/update_mv/y"].addTransition(_init_update_mv_y_0)
+        
         # transition /main
         # transition /main
         _main_0 = Transition(self, self.states["/main"], [self.states["/main"]])
         _main_0 = Transition(self, self.states["/main"], [self.states["/main"]])
         _main_0.setAction(self._main_0_exec)
         _main_0.setAction(self._main_0_exec)
@@ -7711,6 +7928,15 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
         _update_mv_y_0.setTrigger(Event("mv_response", None))
         _update_mv_y_0.setTrigger(Event("mv_response", None))
         self.states["/update_mv/y"].addTransition(_update_mv_y_0)
         self.states["/update_mv/y"].addTransition(_update_mv_y_0)
     
     
+    def _init_exit(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("canvas_element_ready", None, [])]))
+    
+    def _init_update_mv_x_enter(self):
+        self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['attr_assign', [current_rendered_model, self.cs_element, 'x', self.coordinates[0]]])]))
+    
+    def _init_update_mv_y_enter(self):
+        self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['attr_assign', [current_rendered_model, self.cs_element, 'y', self.coordinates[1]]])]))
+    
     def _update_attrs_query_enter(self):
     def _update_attrs_query_enter(self):
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['read_attrs', [current_model, self.as_element]])]))
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['read_attrs', [current_model, self.as_element]])]))
     
     
@@ -7726,6 +7952,21 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
     def _update_mv_y_enter(self):
     def _update_mv_y_enter(self):
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['attr_assign', [current_rendered_model, self.cs_element, 'y', self.coordinates[1]]])]))
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['attr_assign', [current_rendered_model, self.cs_element, 'y', self.coordinates[1]]])]))
     
     
+    def _init_init_0_exec(self, parameters):
+        print("Not found: %s in %s" % (self.as_element, self.containing_canvas.to_move))
+    
+    def _init_init_0_guard(self, parameters):
+        return self.as_element not in self.containing_canvas.to_move
+    
+    def _init_init_1_exec(self, parameters):
+        self.coordinates = self.containing_canvas.to_move.pop(self.as_element)
+        self.move_group(self.coordinates)
+        
+        self.containing_canvas.delete(self.containing_canvas.elems.pop(0)[1])
+    
+    def _init_init_1_guard(self, parameters):
+        return self.as_element in self.containing_canvas.to_move
+    
     def _main_0_exec(self, parameters):
     def _main_0_exec(self, parameters):
         element = parameters[0]
         element = parameters[0]
         elem_x = self.coordinates[0] + element["x"]
         elem_x = self.coordinates[0] + element["x"]
@@ -7737,19 +7978,17 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
         elif element["type"] == "Line":
         elif element["type"] == "Line":
             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)
             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)
         else:
         else:
-            print("Undefined render format: " + str(element))
+            raise Exception("Undefined render format: " + str(element))
             result = None
             result = None
         
         
         if result is not None:
         if result is not None:
-            self.elements[result] = element["id"]
+            self.elements[result] = element
             self.set_bindable_and_tagorid(self.containing_canvas, result)
             self.set_bindable_and_tagorid(self.containing_canvas, result)
             self.add_to_layer(element["layer"], result)
             self.add_to_layer(element["layer"], result)
     
     
     def _main_1_exec(self, parameters):
     def _main_1_exec(self, parameters):
         ID = parameters[0]
         ID = parameters[0]
         self.original_coords = self.last_x, self.last_y
         self.original_coords = self.last_x, self.last_y
-        self.prev_x = self.last_x
-        self.prev_y = self.last_y
     
     
     def _main_1_guard(self, parameters):
     def _main_1_guard(self, parameters):
         ID = parameters[0]
         ID = parameters[0]
@@ -7761,27 +8000,10 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
     
     
     def _dragging_0_exec(self, parameters):
     def _dragging_0_exec(self, parameters):
         ID = parameters[0]
         ID = parameters[0]
-        delta_x = self.prev_x - self.last_x
-        delta_y = self.prev_y - self.last_y
-        
-        for f in self.elements:
-            old_coords = self.containing_canvas.coords(f)
-            new_x = old_coords[0] - delta_x
-            new_y = old_coords[1] - delta_y
-        
-            if len(old_coords) == 2:
-                self.containing_canvas.coords(f, (new_x, new_y))
-            elif len(old_coords) == 4:
-                height = old_coords[3] - old_coords[1]
-                width = old_coords[2] - old_coords[0]
-                self.containing_canvas.coords(f, (new_x, new_y, new_x + width, new_y + height))
-        
-        self.prev_x = self.last_x
-        self.prev_y = self.last_y
-        
-        delta_x = self.original_coords[0] - self.last_x
-        delta_y = self.original_coords[1] - self.last_y
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("moved_group", None, [self.cs_element, (self.coordinates[0] - delta_x, self.coordinates[1] - delta_y)])]))
+        new_x = self.coordinates[0] + (self.last_x - self.original_coords[0])
+        new_y = self.coordinates[1] + (self.last_y - self.original_coords[1])
+        self.move_group((new_x, new_y))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("moved_group", None, [self.cs_element, (new_x, new_y)])]))
     
     
     def _dragging_0_guard(self, parameters):
     def _dragging_0_guard(self, parameters):
         ID = parameters[0]
         ID = parameters[0]
@@ -7791,7 +8013,6 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
         ID = parameters[0]
         ID = parameters[0]
         delta_x = self.original_coords[0] - self.last_x
         delta_x = self.original_coords[0] - self.last_x
         delta_y = self.original_coords[1] - self.last_y
         delta_y = self.original_coords[1] - self.last_y
-        
         self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
         self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
     
     
     def _dragging_1_guard(self, parameters):
     def _dragging_1_guard(self, parameters):
@@ -7844,7 +8065,7 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
     
     
     def initializeStatechart(self):
     def initializeStatechart(self):
         # enter default state
         # enter default state
-        self.default_targets = self.states["/main"].getEffectiveTargetStates()
+        self.default_targets = self.states["/init"].getEffectiveTargetStates()
         RuntimeClassBase.initializeStatechart(self)
         RuntimeClassBase.initializeStatechart(self)
 
 
 class ObjectManager(ObjectManagerBase):
 class ObjectManager(ObjectManagerBase):
@@ -7904,7 +8125,7 @@ class ObjectManager(ObjectManagerBase):
             instance.associations["buttons"] = Association("Button", 0, -1)
             instance.associations["buttons"] = Association("Button", 0, -1)
             instance.associations["parent"] = Association("A", 0, -1)
             instance.associations["parent"] = Association("A", 0, -1)
         elif class_name == "DSLToolbar":
         elif class_name == "DSLToolbar":
-            instance = DSLToolbar(self.controller, construct_params[0])
+            instance = DSLToolbar(self.controller, construct_params[0], construct_params[1])
             instance.associations = {}
             instance.associations = {}
             instance.associations["buttons"] = Association("Button", 0, -1)
             instance.associations["buttons"] = Association("Button", 0, -1)
             instance.associations["parent"] = Association("A", 0, -1)
             instance.associations["parent"] = Association("A", 0, -1)

+ 6 - 3
models/render_OD.alc

@@ -153,17 +153,20 @@ Boolean function main(model : Element):
 	// Rerender associations
 	// Rerender associations
 	Element to_render
 	Element to_render
 	to_render = set_create()
 	to_render = set_create()
-	class_types = allInstances(metamodel, "Class")
+	class_types = allInstances(metamodel, "Association")
 	while (set_len(class_types) > 0):
 	while (set_len(class_types) > 0):
 		class_type = set_pop(class_types)
 		class_type = set_pop(class_types)
+		log("Checking type " + class_type)
 
 
 		if (string_startswith(class_type, "abstract/")):
 		if (string_startswith(class_type, "abstract/")):
 			elements = allInstances(model, class_type)
 			elements = allInstances(model, class_type)
+			log("    Checking instance " + class)
 			while (set_len(elements) > 0):
 			while (set_len(elements) > 0):
 				class = set_pop(elements)
 				class = set_pop(elements)
 				if (is_edge(model["model"][class])):
 				if (is_edge(model["model"][class])):
 					if (bool_not(set_in(to_render, class))):
 					if (bool_not(set_in(to_render, class))):
 						set_add(to_render, class)
 						set_add(to_render, class)
+						log("Added!")
 
 
 	to_render = set_to_list(to_render)
 	to_render = set_to_list(to_render)
 	Element delayed_elements
 	Element delayed_elements
@@ -186,13 +189,13 @@ Boolean function main(model : Element):
 				instantiate_attribute(model, elem, "offsetSourceY", 0)
 				instantiate_attribute(model, elem, "offsetSourceY", 0)
 			else:
 			else:
 				instantiate_attribute(model, elem, "offsetSourceX", 100)
 				instantiate_attribute(model, elem, "offsetSourceX", 100)
-				instantiate_attribute(model, elem, "offsetSourceY", 50)
+				instantiate_attribute(model, elem, "offsetSourceY", 30)
 			if (is_edge(model["model"][readAssociationDestination(model, class)])):
 			if (is_edge(model["model"][readAssociationDestination(model, class)])):
 				instantiate_attribute(model, elem, "offsetTargetX", 0)
 				instantiate_attribute(model, elem, "offsetTargetX", 0)
 				instantiate_attribute(model, elem, "offsetTargetY", 0)
 				instantiate_attribute(model, elem, "offsetTargetY", 0)
 			else:
 			else:
 				instantiate_attribute(model, elem, "offsetTargetX", 100)
 				instantiate_attribute(model, elem, "offsetTargetX", 100)
-				instantiate_attribute(model, elem, "offsetTargetY", 50)
+				instantiate_attribute(model, elem, "offsetTargetY", 30)
 			instantiate_attribute(model, elem, "lineWidth", 3)
 			instantiate_attribute(model, elem, "lineWidth", 3)
 			instantiate_attribute(model, elem, "lineColour", "black")
 			instantiate_attribute(model, elem, "lineColour", "black")
 			instantiate_attribute(model, elem, "arrow", True)
 			instantiate_attribute(model, elem, "arrow", True)