瀏覽代碼

Semi-working create of new elements in GUI

Yentl Van Tendeloo 7 年之前
父節點
當前提交
95f559e5af

+ 169 - 79
classes/canvas/canvas.xml

@@ -31,10 +31,18 @@
             self.connecting_lines = {}
             self.lines = set()
             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>
     </constructor>
     <destructor>
         <body>
+            print("CANVAS DESTROYED")
             self.destroy()
         </body>
     </destructor>
@@ -48,91 +56,173 @@
             </transition>
         </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>
 </class>

+ 73 - 27
classes/canvas/canvas_element.xml

@@ -44,7 +44,72 @@
         </body>
     </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">
             <transition event="draw_element" target=".">
                 <parameter name="element"/>
@@ -58,11 +123,11 @@
                     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)
                     else:
-                        print("Undefined render format: " + str(element))
+                        raise Exception("Undefined render format: " + str(element))
                         result = 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.add_to_layer(element["layer"], result)
                 </script>
@@ -72,44 +137,26 @@
                 <parameter name="ID"/>
                 <script>
                     self.original_coords = self.last_x, self.last_y
-                    self.prev_x = self.last_x
-                    self.prev_y = self.last_y
                 </script>
             </transition>
 
             <transition event="middle-click" cond="id(self) == ID" target="../update_attrs">
                 <parameter name="ID"/>
             </transition>
+
         </state>
 
         <state id="dragging">
             <transition event="motion" cond="id(self) == ID" target=".">
                 <parameter name="ID"/>
                 <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>
                 <raise event="moved_group" scope="narrow" target="'parent'">
                     <parameter expr="self.cs_element"/>
-                    <parameter expr="(self.coordinates[0] - delta_x, self.coordinates[1] - delta_y)"/>
+                    <parameter expr="(new_x, new_y)"/>
                 </raise>
             </transition>
 
@@ -118,7 +165,6 @@
                 <script>
                     delta_x = self.original_coords[0] - self.last_x
                     delta_y = self.original_coords[1] - self.last_y
-
                     self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
                 </script>
             </transition>

+ 3 - 0
classes/modelverse/http_client.xml

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

+ 5 - 4
classes/modelverse/modelverse.xml

@@ -217,6 +217,7 @@
 
                             <script>
                                 self.i += 1
+                                print("READY")
                             </script>
                         </transition>
 
@@ -1092,13 +1093,13 @@
                     <state id="types">
                         <onentry>
                             <raise event="request">
-                                <parameter expr="['types', self.parameters[1]]"/>
+                                <parameter expr="['types']"/>
                             </raise>
                         </onentry>
 
                         <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
                             <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>
                         </transition>
                     </state>
@@ -1106,13 +1107,13 @@
                     <state id="types_full">
                         <onentry>
                             <raise event="request">
-                                <parameter expr="['types_full', self.parameters[1]]"/>
+                                <parameter expr="['types_full']"/>
                             </raise>
                         </onentry>
 
                         <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
                             <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>
                         </transition>
                     </state>

+ 17 - 10
classes/toolbar/dsl_toolbar.xml

@@ -7,14 +7,17 @@
 
     <constructor>
         <parameter name="parent"/>
+        <parameter name="elements"/>
         <super class="Toolbar">
             <parameter expr="parent"/>
         </super>
         <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 = {}
             tk.Label(self, text="Domain-Specific").pack(side=tk.LEFT)
+            self.currently_active = None
         </body>
     </constructor>
 
@@ -35,7 +38,7 @@
                     <raise event="create_instance" scope="cd">
                         <parameter expr="'buttons'"/>
                         <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>
                 </onentry>
 
@@ -68,14 +71,18 @@
         </state>
 
         <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"/>
-                <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 event="close" target="../closing"/>

+ 13 - 0
classes/widgets/button.xml

@@ -55,6 +55,19 @@
                         self.tooltip.hidetip()
                     </script>
                 </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>
     </scxml>

+ 21 - 4
classes/window/main_window.xml

@@ -134,6 +134,12 @@
                         current_rendered_model = new_rendered
                     </script>
                 </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 id="add_object_diagrams" initial="init">
@@ -405,7 +411,7 @@
                             <parameter expr="'subwindow'"/>
                             <parameter expr="'Browser'"/>
                             <parameter expr="'Select model to open'"/>
-                            <parameter expr="['formalisms/SimpleClassDiagrams']"/>
+                            <parameter expr="[]"/>
                         </raise>
                         <raise event="update_status" scope="narrow" target="'progress_bar'">
                             <parameter expr="0"/>
@@ -808,7 +814,7 @@
                     </state>
 
                     <state id="pack_cs_toolbar">
-                        <transition event="tk_widget" target="../dsl_toolbar">
+                        <transition event="tk_widget" target="../fetch_types">
                             <parameter name="tk_elem"/>
                             <script>
                                 tk_elem.pack(anchor=tk.W)
@@ -816,15 +822,26 @@
                         </transition>
                     </state>
 
-                    <state id="dsl_toolbar">
+                    <state id="fetch_types">
                         <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">
                                 <parameter expr="'model_toolbars'"/>
                                 <parameter expr="'DSLToolbar'"/>
                                 <parameter expr="self.toolbar_frame"/>
+                                <parameter expr="result"/>
                             </raise>
-                        </onentry>
+                        </transition>
+                    </state>
 
+                    <state id="dsl_toolbar">
                         <transition event="instance_created" target="../pack_dsl_toolbar">
                             <parameter name="association_name"/>
                             <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)
 
-Date:   Fri Oct  6 10:19:43 2017
+Date:   Mon Oct  9 13:35:39 2017
 
 Model author: Yentl Van Tendeloo
 Model name:   Modelverse Visual Editor - Tkinter Version 
@@ -2369,10 +2369,10 @@ class Modelverse(RuntimeClassBase):
         self.raiseInternalEvent(Event("request", None, [['JSON']]))
     
     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):
-        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):
         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):
         self.raiseInternalEvent(Event("request_raw", None, [self.taskname, 'task_manager', self.i]))
         self.i += 1
+        print("READY")
     
     def _initialized_behaviour_init_waiting_http_client_1_exec(self, parameters):
         self.raiseInternalEvent(Event("exception", None, ['NetworkException', 'Connection timeout']))
@@ -3039,13 +3040,13 @@ class Modelverse(RuntimeClassBase):
         return self.expect_response_partial('Success: ', pop=False)
     
     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):
         return self.expect_response_partial('Success: ', pop=False)
     
     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):
         return self.expect_response_partial('Success: ', pop=False)
@@ -3690,6 +3691,7 @@ class HTTPClient(RuntimeClassBase):
     
     def _connecting_0_exec(self, parameters):
         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):
         socket = parameters[0]
@@ -4193,35 +4195,38 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         # 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)
         
+        # 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
-        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
-        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
-        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)
         
         # 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)
         
         # 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
-        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
-        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
-        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
-        self.states["/close"] = State(68, "/close", self)
+        self.states["/close"] = State(69, "/close", self)
         self.states["/close"].setEnter(self._close_enter)
         
         # 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/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/pack_dsl_toolbar"])
         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.setTrigger(Event("change_rendered", None))
         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
         _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)
         
         # 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.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)
         
+        # 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
         _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)
@@ -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]])]))
     
     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...'])]))
     
     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):
         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):
         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
         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):
         context = parameters[0]
         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.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):
         association_name = parameters[0]
         self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
@@ -6144,7 +6168,7 @@ class GenericToolbar(Toolbar):
         RuntimeClassBase.initializeStatechart(self)
 
 class DSLToolbar(Toolbar):
-    def __init__(self, controller, parent):
+    def __init__(self, controller, parent, elements):
         RuntimeClassBase.__init__(self, controller)
         
         self.semantics.big_step_maximality = StatechartSemantics.TakeMany
@@ -6157,14 +6181,16 @@ class DSLToolbar(Toolbar):
         self.build_statechart_structure()
         
         # 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)
-        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 = {}
         tk.Label(self, text="Domain-Specific").pack(side=tk.LEFT)
+        self.currently_active = None
     
     def user_defined_destructor(self):
         # call super class destructors
@@ -6242,14 +6268,9 @@ class DSLToolbar(Toolbar):
         _root_0.setTrigger(Event("button_pressed", None))
         _root_0.setGuard(self._root_0_guard)
         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)
-        _root_2 = Transition(self, self.states["/root"], [self.states["/closing"]])
-        _root_2.setTrigger(Event("close", None))
-        self.states["/root"].addTransition(_root_2)
         
         # transition /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])]))
     
     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):
         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):
         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):
         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):
         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.setGuard(self._main_ready_2_guard)
         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):
         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]
         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):
         # enter default state
         self.default_targets = self.states["/main"].getEffectiveTargetStates()
@@ -7112,8 +7144,16 @@ class Canvas(RuntimeClassBase, tk.Canvas, SCCDWidget):
         self.connecting_lines = {}
         self.lines = set()
         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):
+        print("CANVAS DESTROYED")
         self.destroy()
         # call super class destructors
         if hasattr(tk.Canvas, "__del__"):
@@ -7132,17 +7172,50 @@ class Canvas(RuntimeClassBase, tk.Canvas, SCCDWidget):
         self.states["/main"] = State(1, "/main", self)
         
         # 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
         self.states[""].addChild(self.states["/main"])
         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[""].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
         _main_0 = Transition(self, self.states["/main"], [self.states["/ready"]])
@@ -7150,95 +7223,176 @@ class Canvas(RuntimeClassBase, tk.Canvas, SCCDWidget):
         _main_0.setTrigger(None)
         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):
         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, 'connecting_lines']))
         self.group_location = {}
         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]
         self.creating_id = element["id"]
         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']]))
     
-    def _ready_2_exec(self, parameters):
+    def _ready_process_events_ready_4_exec(self, parameters):
         element = parameters[0]
         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]
         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]
         return element['type'] != 'ConnectingLine'
     
-    def _ready_4_exec(self, parameters):
+    def _ready_process_events_ready_6_exec(self, parameters):
         element = parameters[0]
         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]
         return element['type'] == 'ConnectingLine'
     
-    def _ready_5_exec(self, parameters):
+    def _ready_process_events_ready_7_exec(self, parameters):
         result = parameters[0]
         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]
         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 _creating_group_0_exec(self, parameters):
+    def _ready_process_events_creating_group_0_exec(self, parameters):
         assoc_name = parameters[0]
         self.big_step.outputEventOM(Event("start_instance", None, [self, 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, [])]))
     
+    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):
         # enter default state
         self.default_targets = self.states["/main"].getEffectiveTargetStates()
@@ -7564,55 +7718,94 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
             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
     def build_statechart_structure(self):
         
         # state <root>
         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
-        self.states["/main"] = State(1, "/main", self)
+        self.states["/main"] = State(6, "/main", self)
         
         # state /dragging
-        self.states["/dragging"] = State(2, "/dragging", self)
+        self.states["/dragging"] = State(7, "/dragging", self)
         
         # 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
-        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)
         
         # 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)
         
         # 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
-        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
-        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)
         
         # 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
-        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)
         
         # 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)
         
         # add children
+        self.states[""].addChild(self.states["/init"])
         self.states[""].addChild(self.states["/main"])
         self.states[""].addChild(self.states["/dragging"])
         self.states[""].addChild(self.states["/update_attrs"])
         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/prompt"])
         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/y"])
         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_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
         _main_0 = Transition(self, self.states["/main"], [self.states["/main"]])
         _main_0.setAction(self._main_0_exec)
@@ -7711,6 +7928,15 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
         _update_mv_y_0.setTrigger(Event("mv_response", None))
         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):
         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):
         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):
         element = parameters[0]
         elem_x = self.coordinates[0] + element["x"]
@@ -7737,19 +7978,17 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
         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)
         else:
-            print("Undefined render format: " + str(element))
+            raise Exception("Undefined render format: " + str(element))
             result = 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.add_to_layer(element["layer"], result)
     
     def _main_1_exec(self, parameters):
         ID = parameters[0]
         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):
         ID = parameters[0]
@@ -7761,27 +8000,10 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
     
     def _dragging_0_exec(self, parameters):
         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):
         ID = parameters[0]
@@ -7791,7 +8013,6 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
         ID = parameters[0]
         delta_x = self.original_coords[0] - self.last_x
         delta_y = self.original_coords[1] - self.last_y
-        
         self.coordinates = self.coordinates[0] - delta_x, self.coordinates[1] - delta_y
     
     def _dragging_1_guard(self, parameters):
@@ -7844,7 +8065,7 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
     
     def initializeStatechart(self):
         # enter default state
-        self.default_targets = self.states["/main"].getEffectiveTargetStates()
+        self.default_targets = self.states["/init"].getEffectiveTargetStates()
         RuntimeClassBase.initializeStatechart(self)
 
 class ObjectManager(ObjectManagerBase):
@@ -7904,7 +8125,7 @@ class ObjectManager(ObjectManagerBase):
             instance.associations["buttons"] = Association("Button", 0, -1)
             instance.associations["parent"] = Association("A", 0, -1)
         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["buttons"] = Association("Button", 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
 	Element to_render
 	to_render = set_create()
-	class_types = allInstances(metamodel, "Class")
+	class_types = allInstances(metamodel, "Association")
 	while (set_len(class_types) > 0):
 		class_type = set_pop(class_types)
+		log("Checking type " + class_type)
 
 		if (string_startswith(class_type, "abstract/")):
 			elements = allInstances(model, class_type)
+			log("    Checking instance " + class)
 			while (set_len(elements) > 0):
 				class = set_pop(elements)
 				if (is_edge(model["model"][class])):
 					if (bool_not(set_in(to_render, class))):
 						set_add(to_render, class)
+						log("Added!")
 
 	to_render = set_to_list(to_render)
 	Element delayed_elements
@@ -186,13 +189,13 @@ Boolean function main(model : Element):
 				instantiate_attribute(model, elem, "offsetSourceY", 0)
 			else:
 				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)])):
 				instantiate_attribute(model, elem, "offsetTargetX", 0)
 				instantiate_attribute(model, elem, "offsetTargetY", 0)
 			else:
 				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, "lineColour", "black")
 			instantiate_attribute(model, elem, "arrow", True)