浏览代码

Working visualization of SCD models

Yentl Van Tendeloo 8 年之前
父节点
当前提交
b527f89568
共有 4 个文件被更改,包括 5899 次插入8 次删除
  1. 90 0
      classes/canvas/canvas.xml
  2. 30 5
      classes/window/main_window.xml
  3. 5720 0
      frontend.py
  4. 59 3
      models/render_SCD.alc

+ 90 - 0
classes/canvas/canvas.xml

@@ -0,0 +1,90 @@
+<class name="Canvas">
+    <relationships>
+        <association name="parent" class="A" min="1" max="1" />
+        <inheritance class="SCCDWidget" priority='0'/>
+        <inheritance class="tk.Canvas" priority='1'/>
+    </relationships>
+    <constructor>
+        <parameter name="parent" />
+        <super class="SCCDWidget"/>
+        <super class="tk.Canvas">
+            <parameter expr="parent" />
+            <parameter expr="**{'scrollregion': (0, 0, parent.winfo_screenwidth()*2, parent.winfo_screenheight() * 2)}"/>
+        </super>
+        <body>
+            vbar = tk.Scrollbar(self, orient=tk.VERTICAL)
+            vbar.config(command=self.yview)
+            vbar.pack(side=tk.RIGHT, fill=tk.Y, pady=(0, 16))
+
+            hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL)
+            hbar.config(command=self.xview)
+            hbar.pack(side=tk.BOTTOM, fill=tk.X)
+
+            self.config(background='white', yscrollcommand=vbar.set, xscrollcommand=hbar.set)
+            self.focus_set()
+
+            self.elements = {}
+            self.shift = {}
+        </body>
+    </constructor>
+    <destructor>
+        <body>
+            self.delete("all")
+            self.destroy()
+        </body>
+    </destructor>
+
+    <scxml initial="main">
+        <state id="main">
+            <transition target="../ready">
+                <raise event="tk_widget" scope="narrow" target="'parent'">
+                    <parameter expr="self"/>
+                </raise>
+            </transition>
+        </state>
+
+        <state id="ready">
+            <transition event="clear_canvas" target=".">
+                <script>
+                    self.delete("all")
+                    self.elements = {}
+                    self.shift = {}
+                </script>
+            </transition>
+
+            <transition event="define_group" target=".">
+                <parameter name="element"/>
+                <script>
+                    self.elements[element["id"]] = element
+                    self.shift[element["id"]] = (element["x"], element["y"])
+                </script>
+            </transition>
+
+            <transition event="define_contains" target=".">
+                <parameter name="element"/>
+                <script>
+                    self.shift[element["__target"]] = self.shift[element["__source"]]
+                </script>
+            </transition>
+
+            <transition event="draw_canvas" target=".">
+                <parameter name="element"/>
+                <script>
+                    print("Render: " + str(element))
+                    self.elements[element["id"]] = element
+                    shift_x, shift_y = self.shift[element["id"]]
+                    elem_x = shift_x + element["x"]
+                    elem_y = shift_y + element["y"]
+                    if element["type"] == "Rectangle":
+                        self.create_rectangle(elem_x, elem_y, elem_x + element["width"], elem_y + element["height"], fill=element["fillColour"], outline=element["lineColour"])
+                    elif element["type"] == "Text":
+                        self.create_text(elem_x, elem_y, fill=element["lineColour"], text=element["text"], anchor=tk.NW)
+                    elif element["type"] == "Line":
+                        self.create_line(elem_x, elem_y, shift_x + element["targetX"], shift_y + element["targetY"], fill=element["lineColour"], width=element["lineWidth"])
+                    else:
+                        print("Undefined render format: " + str(element))
+                </script>
+            </transition>
+        </state>
+    </scxml>
+</class>

+ 30 - 5
classes/window/main_window.xml

@@ -408,19 +408,44 @@
                     <transition event="mv_exception" target="../../../close"/>
                 </state>
 
-                <state id="render_model">
+                <state id="render_model" initial="allocate_groups">
                     <onentry>
                         <raise event="update_status" scope="narrow" target="'progress_bar'">
                             <parameter expr="80"/>
                             <parameter expr="'Perceptualizing model... OK'"/>
                         </raise>
+                        <raise event="clear_canvas" scope="narrow" target="'canvas'"/>
+                        <script>
+                            self.groups = [i for i in self.rendered if i["type"] == "Group"]
+                            self.contains = [i for i in self.rendered if i["type"] == "contains"]
+                            self.rendered = [i for i in self.rendered if i["type"] not in ["Group", "contains"]]
+                            self.rendered.reverse()
+                        </script>
                     </onentry>
 
-                    <state id="render_first">
+                    <state id="allocate_groups">
+                        <transition cond="len(self.groups) > 0" target=".">
+                            <raise event="define_group" scope="narrow" target="'canvas'">
+                                <parameter expr="self.groups.pop()"/>
+                            </raise>
+                        </transition>
+                        <transition cond="len(self.groups) == 0" target="../allocate_contains"/>
+                    </state>
+
+                    <state id="allocate_contains">
+                        <transition cond="len(self.contains) > 0" target=".">
+                            <raise event="define_contains" scope="narrow" target="'canvas'">
+                                <parameter expr="self.contains.pop()"/>
+                            </raise>
+                        </transition>
+                        <transition cond="len(self.contains) == 0" target="../render_elements"/>
+                    </state>
+
+                    <state id="render_elements">
                         <transition cond="len(self.rendered) > 0" target=".">
-                            <script>
-                                to_render = self.rendered.pop()
-                            </script>
+                            <raise event="draw_canvas" scope="narrow" target="'canvas'">
+                                <parameter expr="self.rendered.pop()"/>
+                            </raise>
                         </transition>
 
                         <transition cond="len(self.rendered) == 0" target="../../../idle"/>

文件差异内容过多而无法显示
+ 5720 - 0
frontend.py


+ 59 - 3
models/render_SCD.alc

@@ -11,22 +11,78 @@ Boolean function main(model : Element):
 	Element attrs
 	Element attr_keys
 	String attr_key
+	String group
+	String elem
+	Integer loc
+	Integer text_loc
+	loc = 10
 
 	log("Classes:")
 	elements = allInstances(model, "abstract/Class")
+
 	while (set_len(elements) > 0):
 		class = set_pop(elements)
 		attr_keys = dict_keys(getAttributeList(model, class))
+		text_loc = 5
 
-		while (set_len(attr_keys) > 0):
-			attr_key = set_pop(attr_keys)
-			log((("  " + attr_key) + " = ") + cast_v2s(read_attribute(model, class, attr_key)))
+		group = instantiate_node(model, "rendered/Group", "")
+		instantiate_attribute(model, group, "x", loc)
+		instantiate_attribute(model, group, "y", 10)
+		loc = loc + 200
+
+		elem = instantiate_node(model, "rendered/Rectangle", "")
+		instantiate_attribute(model, elem, "x", 0)
+		instantiate_attribute(model, elem, "y", 0)
+		instantiate_attribute(model, elem, "height", 40 + set_len(getInstantiatableAttributes(model, class, "abstract/AttributeLink")) * 20)
+		instantiate_attribute(model, elem, "width", 150)
+		instantiate_attribute(model, elem, "lineWidth", 2) 
+		instantiate_attribute(model, elem, "lineColour", "black")
+		instantiate_attribute(model, elem, "fillColour", "white")
+		instantiate_link(model, "rendered/contains", "", group, elem)
+
+		String multiplicities
+		String lower_card
+		String upper_card
+		if (element_eq(read_attribute(model, class, "lower_cardinality"), read_root())):
+			lower_card = "*"
+		else:
+			lower_card = cast_v2s(read_attribute(model, class, "lower_cardinality"))
+		if (element_eq(read_attribute(model, class, "upper_cardinality"), read_root())):
+			upper_card = "*"
+		else:
+			upper_card = cast_v2s(read_attribute(model, class, "upper_cardinality"))
+		multiplicities = ((("[" + lower_card) + "..") + upper_card) + "]"
+
+		elem = instantiate_node(model, "rendered/Text", "")
+		instantiate_attribute(model, elem, "x", 5)
+		instantiate_attribute(model, elem, "y", 3)
+		instantiate_attribute(model, elem, "lineWidth", 1)
+		instantiate_attribute(model, elem, "lineColour", "black")
+		instantiate_attribute(model, elem, "text", string_join(list_read(string_split(class, "/"), 1), "  " + multiplicities))
+		instantiate_link(model, "rendered/contains", "", group, elem)
+
+		elem = instantiate_node(model, "rendered/Line", "")
+		instantiate_attribute(model, elem, "x", 0)
+		instantiate_attribute(model, elem, "y", 20)
+		instantiate_attribute(model, elem, "targetX", 150)
+		instantiate_attribute(model, elem, "targetY", 20)
+		instantiate_attribute(model, elem, "lineWidth", 1)
+		instantiate_attribute(model, elem, "lineColour", "black")
+		instantiate_link(model, "rendered/contains", "", group, elem)
 
 		attrs = getInstantiatableAttributes(model, class, "abstract/AttributeLink")
 		attr_keys = dict_keys(attrs)
 		while (dict_len(attr_keys) > 0):
 			attr_key = set_pop(attr_keys)
+			elem = instantiate_node(model, "rendered/Text", "")
 			log((("  " + attr_key) + " : ") + cast_v2s(list_read(string_split(attrs[attr_key], "/"), 1)))
+			instantiate_attribute(model, elem, "x", 5)
+			instantiate_attribute(model, elem, "y", text_loc + 20)
+			instantiate_attribute(model, elem, "lineWidth", 1)
+			instantiate_attribute(model, elem, "lineColour", "black")
+			instantiate_attribute(model, elem, "text", (attr_key + " : ") + cast_v2s(list_read(string_split(attrs[attr_key], "/"), 1)))
+			instantiate_link(model, "rendered/contains", "", group, elem)
+			text_loc = text_loc + 15
 
 		log("")