[SCM] calf/master: + Big Bull: make ConnDiagram style more FlowCanvas-like, add a dumb spring-based layout algorithm (used for initial layout in JackVis)

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:40 UTC 2013


The following commit has been merged in the master branch:
commit 1c604ced533dbfbc9b0b81f66eb4060499af7af3
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Sat Oct 4 00:15:59 2008 +0000

    + Big Bull: make ConnDiagram style more FlowCanvas-like, add a dumb spring-based layout algorithm (used for initial layout in JackVis)
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@315 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/bigbull/conndiagram.py b/bigbull/conndiagram.py
index 00ee84c..2c41d80 100644
--- a/bigbull/conndiagram.py
+++ b/bigbull/conndiagram.py
@@ -6,6 +6,7 @@ import pangocairo
 import pango
 import goocanvas
 import random
+import math
 
 def calc_extents(ctx, fontName, text):
     layout = pangocairo.CairoContext(ctx).create_layout()
@@ -14,11 +15,11 @@ def calc_extents(ctx, fontName, text):
     return layout.get_pixel_size()
 
 class Colors:
-    frame = 0xC0C0C0FF
-    text = 0xFFFFFFFF
-    box = 0x202020FF
+    frame = 0x808080FF
+    text = 0xE0E0E0FF
+    box = 0x303030FF
     defPort = 0x404040FF
-    audioPort = 0x000080FF
+    audioPort = 0x004060FF
     controlPort = 0x008000FF
     eventPort = 0x800000FF
     activePort = 0x808080FF
@@ -37,7 +38,7 @@ class VisibleWire():
         self.dest.module.remove_wire(self)
 
 class ModulePort():
-    fontName = "DejaVu Sans 10"
+    fontName = "DejaVu Sans 9"
     type = "port"
     def __init__(self, module, portData):
         self.module = module
@@ -68,9 +69,9 @@ class ModulePort():
             title.translate(width - bw, 0)
         color = self.get_parser().get_port_color(self.portData)
         if self.isInput:
-            box = goocanvas.Rect(parent = parent, x = 0.5, y = y - 0.5, width = bw, height = height + 1, line_width = 1, fill_color_rgba = color, stroke_color_rgba = Colors.frame)
+            box = goocanvas.Rect(parent = parent, x = 0.5, y = y - 0.5, width = bw, height = height + 1, line_width = 0, fill_color_rgba = color, stroke_color_rgba = Colors.frame)
         else:
-            box = goocanvas.Rect(parent = parent, x = width - bw - 0.5, y = y - 0.5, width = bw, height = height + 1, line_width = 1, fill_color_rgba = color, stroke_color_rgba = Colors.frame)
+            box = goocanvas.Rect(parent = parent, x = width - bw - 0.5, y = y - 0.5, width = bw, height = height + 1, line_width = 0, fill_color_rgba = color, stroke_color_rgba = Colors.frame)
         box.lower(title)
         y += height + spacing
         box.type = "port"
@@ -84,8 +85,8 @@ class ModulePort():
 
 class ModuleBox():
     margin = 2
-    spacing = 6
-    fontName = "DejaVu Sans Bold 10"
+    spacing = 3
+    fontName = "DejaVu Sans Bold 9"
 
     def __init__(self, parser, parent, moduleData, graph):
         self.parser = parser
@@ -118,7 +119,7 @@ class ModuleBox():
         y = self.render_title(ctx, 0)
         for (id, portData) in self.get_parser().get_module_port_list(self.moduleData):
             y = self.render_port(ctx, id, y)
-        self.rect = goocanvas.Rect(parent = self.group, width = self.width, height = y, line_width = 2, stroke_color_rgba = Colors.frame, fill_color_rgba = Colors.box)
+        self.rect = goocanvas.Rect(parent = self.group, width = self.width, height = y, line_width = 2, stroke_color_rgba = Colors.frame, fill_color_rgba = Colors.box, antialias = cairo.ANTIALIAS_GRAY)
         self.rect.lower(self.titleItem)
         self.rect.type = "module"
         self.rect.object = self.rect.module = self
@@ -273,6 +274,7 @@ class ConnectionGraphEditor:
         mbox.group.connect("button-press-event", self.box_button_press)
         mbox.group.connect("motion-notify-event", self.box_motion_notify)
         mbox.group.connect("button-release-event", self.box_button_release)
+        return mbox
         
     def delete_module(self, module):
         self.modules.remove(mbox)
@@ -344,4 +346,80 @@ class ConnectionGraphEditor:
         src.module.wires.append(wire)
         dest.module.wires.append(wire)
         self.update_wire(wire)
-
+        
+    def seg_distance(self, min1, max1, min2, max2):
+        if min1 > min2:
+            return self.seg_distance(min2, max2, min1, max1)
+        if min2 > max1 + 10:
+            return 0
+        return min2 - (max1 + 10)
+    
+    # Squared radius of the circle containing the box
+    def box_radius2(self, box):
+        return (box.x2 - box.x1) ** 2 + (box.y2 - box.y1) ** 2
+    
+    def repulsion(self, b1, b2):
+        minr2 = (self.box_radius2(b1) + self.box_radius2(b2)) 
+        b1x = (b1.x1 + b1.x2) / 2
+        b1y = (b1.y1 + b1.y2) / 2
+        b2x = (b2.x1 + b2.x2) / 2
+        b2y = (b2.y1 + b2.y2) / 2
+        r2 = (b2x - b1x) ** 2 + (b2y - b1y) ** 2
+        # Not repulsive ;)
+        #if r2 > minr2:
+        #    return 0
+        return (b1x - b2x + 1j * (b1y - b2y)) * 2 * minr2/ (2 * r2**1.5)
+        
+    def attraction(self, box, wire):
+        sign = +1
+        if box == wire.src.module:
+            sign = -1
+        b1 = wire.src.box.get_bounds();
+        b2 = wire.dest.box.get_bounds();
+        k = 0.003
+        if b1.x2 > b2.x1 - 40:
+            return k * 8 * sign * (b1.x2 - (b2.x1 - 40) + 1j * (b1.y1 - b2.y1))
+        return k * sign * (b1.x2 - b2.x1 + 1j * (b1.y1 - b2.y1))
+        
+    def blow_up(self):
+        for m in self.modules:
+            m.velocity = 0+0j
+            m.bounds = m.group.get_bounds()
+        damping = 0.5
+        step = 2.0
+        cr = self.canvas.create_cairo_context()
+        w, h = self.canvas.allocation.width, self.canvas.allocation.height
+        while True:
+            energy = 0.0
+            x = y = 0
+            for m1 in self.modules:
+                x += (m1.bounds.x1 + m1.bounds.x2) / 2
+                y += (m1.bounds.y1 + m1.bounds.y2) / 2
+            x /= len(self.modules)
+            y /= len(self.modules)
+            gforce = w / 2 - x + 1j * (h / 2 - y)
+            for m1 in self.modules:
+                force = gforce
+                for m2 in self.modules:
+                    if m1 == m2:
+                        continue
+                    force += self.repulsion(m1.bounds, m2.bounds)
+                for wi in m1.wires:
+                    force += self.attraction(m1, wi) 
+                if m1.bounds.x1 < 10: force -= m1.bounds.x1 - 10
+                if m1.bounds.y1 < 10: force -= m1.bounds.y1 * 1j - 10j
+                if m1.bounds.x2 > w: force -= (m1.bounds.x2 - w)
+                if m1.bounds.y2 > h: force -= (m1.bounds.y2 - h) * 1j
+                m1.velocity = (m1.velocity + force) * damping
+                energy += abs(m1.velocity) ** 2
+            for m1 in self.modules:
+                print "Velocity is (%s, %s)" % (m1.velocity.real, m1.velocity.imag)
+                m1.group.translate(step * m1.velocity.real, step * m1.velocity.imag)
+                m1.group.update(True, cr, m1.bounds)
+                m1.update_wires()
+            damping *= 0.99
+            self.canvas.draw(gtk.gdk.Rectangle(0, 0, w, h))
+            print "Energy is %s" % energy
+            if energy < 0.1:
+                break
+                
diff --git a/bigbull/jackvis.py b/bigbull/jackvis.py
index c8c6142..795e7cf 100755
--- a/bigbull/jackvis.py
+++ b/bigbull/jackvis.py
@@ -94,12 +94,13 @@ class App:
         self.add_clients(200, 0.0, calfpytools.JackPortIsInput)
         self.cgraph.canvas.update()
         self.add_wires()
+        self.cgraph.blow_up()
         
     def add_clients(self, x, y, flags):
         ports = self.parser.client.get_ports("", "", flags)
         clients = set([p.split(":")[0] for p in ports])
         for cl in clients:
-            self.cgraph.add_module(JACKClientData(cl, "", flags), x, y)
+            y += self.cgraph.add_module(JACKClientData(cl, "", flags), x, y).rect.props.height
         
     def add_wires(self):
         ports = self.parser.client.get_ports("", "", calfpytools.JackPortIsInput)
@@ -116,8 +117,12 @@ class App:
     def create_main_menu(self):
         self.menu_bar = gtk.MenuBar()
         self.file_menu = add_submenu(self.menu_bar, "_File")
+        add_option(self.file_menu, "_Blow-up", self.blow_up)
         add_option(self.file_menu, "_Exit", self.exit)
         
+    def blow_up(self, data):
+        self.cgraph.blow_up()
+    
     def exit(self, data):
         self.window.destroy()
         

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list