[SCM] calf/master: Clean up the connection graph module a lot.
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:40:15 UTC 2013
The following commit has been merged in the master branch:
commit a6fd8762a79cf1c93254c16bcc9a2920ba69cf0e
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Wed May 12 20:27:14 2010 +0100
Clean up the connection graph module a lot.
Not a proper MVC yet, but some things are closer to where they should be.
diff --git a/bigbull/conndiagram.py b/bigbull/conndiagram.py
index 2bf14a7..8b74a9e 100644
--- a/bigbull/conndiagram.py
+++ b/bigbull/conndiagram.py
@@ -14,25 +14,35 @@ def calc_extents(ctx, fontName, text):
layout.set_text(text)
return layout.get_pixel_size()
+class PortPalette(object):
+ def __init__(self, stroke, fill, activated_palette = None):
+ self.stroke = stroke
+ self.fill = fill
+ self.activated_palette = activated_palette
+ def get_stroke(self, port):
+ if self.activated_palette is not None and port.is_dragged():
+ return self.activated_palette.get_stroke(port)
+ return self.stroke
+ def get_fill(self, port):
+ if self.activated_palette is not None and port.is_dragged():
+ return self.activated_palette.get_fill(port)
+ return self.fill
+
class Colors:
frame = 0x4C4C4CFF
text = 0xE0E0E0FF
box = 0x242424FF
defPort = 0x404040FF
- audioPort = 0x204A87FF
- controlPort = 0x008000FF
- eventPort = 0xA40000FF
- audioPortIn = 0x183868FF
- controlPortIn = 0x00800080
- eventPortIn = 0x7C000080
- activePort = 0xF0F0F0FF
- activePortIn = 0x808080FF
+ activePort = PortPalette(0xF0F0F0FF, 0x808080FF)
+ audioPort = PortPalette(0x204A87FF, 0x183868FF, activePort)
+ controlPort = PortPalette(0x008000FF, 0x00800080, activePort)
+ eventPort = PortPalette(0xA40000FF, 0x7C000080, activePort)
draggedWire = 0xFFFFFFFF
connectedWire = 0x808080FF
class VisibleWire():
def __init__(self, src, dest, wire):
- """src is source ModulePort, dst is destination ModulePort, wire is a goocanvas.Path"""
+ """src is source PortView, dst is destination PortView, wire is a goocanvas.Path"""
self.src = src
self.dest = dest
self.wire = wire
@@ -42,27 +52,103 @@ class VisibleWire():
self.dest.module.remove_wire(self)
def path_move(x, y):
- return "M %s %s" % (x, y)
+ return "M %s %s " % (x, y)
+
def path_line(x, y):
- return "L %s %s" % (x, y)
+ return "L %s %s " % (x, y)
-class ModulePort():
+class Dragging():
+ def __init__(self, module, port_view, x, y):
+ self.module = module
+ self.port_view = port_view
+ self.x = x
+ self.y = y
+ self.drag_wire = goocanvas.Path(parent = self.get_graph().get_root(), stroke_color_rgba = Colors.draggedWire)
+ self.drag_wire.type = "tmp wire"
+ self.drag_wire.object = None
+ self.drag_wire.raise_(None)
+ self.connect_candidate = None
+ self.update_drag_wire(x, y)
+
+ def get_graph(self):
+ return self.module.graph
+
+ def update_shape(self, x2, y2):
+ (dx, dy) = (x2 - self.x, y2 - self.y)
+ self.drag_wire.props.data = path_move(self.x, self.y) + "C %0.0f,%0.0f %0.0f,%0.0f %0.0f,%0.0f" % (self.x+dx/2, self.y, self.x+dx/2, self.y+dy, self.x+dx, self.y+dy)
+
+ def dragging(self, x2, y2):
+ boundsGrp = self.module.group.get_bounds()
+ self.update_drag_wire(x2 + boundsGrp.x1, y2 + boundsGrp.y1)
+
+ def update_drag_wire(self, x2, y2):
+ items = self.get_graph().get_data_items_at(x2, y2)
+ found = None
+ for type, obj, item in items:
+ if type == 'port':
+ if item.module != self and self.get_graph().get_parser().can_connect(self.port_view.model, obj.model):
+ found = obj
+ self.set_connect_candidate(found)
+ if found is not None:
+ x2, y2 = found.get_endpoint()
+ self.update_shape(x2, y2)
+
+ def has_port_view(self, port_view):
+ if port_view == self.port_view:
+ return True
+ if port_view == self.connect_candidate:
+ return True
+ return False
+
+ def set_connect_candidate(self, item):
+ if self.connect_candidate != item:
+ old = self.connect_candidate
+ self.connect_candidate = item
+ if item is not None:
+ item.update_style()
+ if old is not None:
+ old.update_style()
+
+ def end_drag(self, x2, y2):
+ # self.update_drag_wire(tuple, x2, y2)
+ src, dst = self.port_view, self.connect_candidate
+ self.get_graph().dragging = None
+ src.update_style()
+ if dst is not None:
+ # print "Connect: " + tuple[1] + " with " + self.connect_candidate.get_id()
+ dst.update_style()
+ try:
+ self.get_graph().connect(src, dst, self.drag_wire)
+ except:
+ self.remove_wire()
+ raise
+ else:
+ self.remove_wire()
+
+ def remove_wire(self):
+ self.drag_wire.remove()
+ self.drag_wire = None
+
+class PortView():
fontName = "DejaVu Sans 8"
type = "port"
- def __init__(self, module, portData):
+ def __init__(self, module, model):
self.module = module
- self.portData = portData
- self.isInput = self.get_parser().is_port_input(portData)
+ self.model = model
+ self.isInput = model.is_port_input()
self.box = self.title = None
-
+
+ def get_graph(self):
+ return self.module.graph
+
def get_parser(self):
return self.module.get_parser()
def get_id(self):
- return self.get_parser().get_port_id(self.portData)
+ return self.get_parser().get_port_id(self.model)
def calc_width(self, ctx):
- return calc_extents(ctx, self.fontName, self.get_parser().get_port_name(self.portData))[0] + 4 * self.module.margin + 15
+ return calc_extents(ctx, self.fontName, self.get_parser().get_port_name(self.model))[0] + 4 * self.module.margin + 15
@staticmethod
def input_arrow(x, y, w, h):
@@ -76,7 +162,7 @@ class ModulePort():
module = self.module
(width, margin, spacing) = (module.width, module.margin, module.spacing)
al = "left"
- portName = self.get_parser().get_port_name(self.portData)
+ portName = self.get_parser().get_port_name(self.model)
title = goocanvas.Text(parent = parent, text = portName, font = self.fontName, width = width - 2 * margin, x = margin, y = y, alignment = al, fill_color_rgba = Colors.text, hint_metrics = cairo.HINT_METRICS_ON, pointer_events = False, wrap = False)
height = 1 + int(title.get_requested_height(ctx, width - 2 * margin))
title.ensure_updated()
@@ -84,24 +170,44 @@ class ModulePort():
bw = bnds.x2 - bnds.x1 + 2 * margin
if not self.isInput:
title.translate(width - bw, 0)
- color_in, color_out = self.get_parser().get_port_color(self.portData)
bw += 10
if self.isInput:
- box = goocanvas.Path(parent = parent, data = self.input_arrow(0.5, y - 0.5, bw, height + 1), line_width = 1, fill_color_rgba = color_in, stroke_color_rgba = color_out)
+ box = goocanvas.Path(parent = parent, data = self.input_arrow(0.5, y - 0.5, bw, height + 1))
else:
- box = goocanvas.Path(parent = parent, data = self.output_arrow(width - bw, y - 0.5, bw, height + 1), line_width = 1, fill_color_rgba = color_in, stroke_color_rgba = color_out)
+ box = goocanvas.Path(parent = parent, data = self.output_arrow(width - bw, y - 0.5, bw, height + 1))
box.lower(title)
y += height + spacing
box.type = "port"
- self.orig_color_in, self.orig_color_out = color_in, color_out
box.object = box.module = self
- box.portData = self.portData
- title.portData = self.portData
+ box.model = self.model
+ title.model = self.model
self.box = box
self.title = title
+ self.update_style()
return y
-
-class ModuleBox():
+
+ def update_style(self):
+ color = self.get_parser().get_port_color(self)
+ self.box.props.fill_color_rgba = color.get_fill(self)
+ self.box.props.stroke_color_rgba = color.get_stroke(self)
+ self.box.props.line_width = 1
+
+ def is_dragged(self):
+ dragging = self.get_graph().dragging
+ if dragging is not None and dragging.has_port_view(self):
+ return True
+ return False
+
+ def get_endpoint(self):
+ bounds = self.box.get_bounds()
+ if self.model.is_port_input():
+ x = bounds.x1
+ else:
+ x = bounds.x2
+ y = (bounds.y1 + bounds.y2) / 2
+ return (x, y)
+
+class ModuleView():
margin = 2
spacing = 4
fontName = "DejaVu Sans Bold 9"
@@ -128,14 +234,14 @@ class ModuleBox():
self.title = self.get_parser().get_module_name(self.moduleData)
self.portDict = {}
width = self.get_title_width(ctx)
- for (id, portData) in self.get_parser().get_module_port_list(self.moduleData):
- mport = self.create_port(id, portData)
+ for (id, model) in self.get_parser().get_module_port_list(self.moduleData):
+ mport = self.create_port(id, model)
new_width = mport.calc_width(ctx)
if new_width > width:
width = new_width
self.width = width
y = self.render_title(ctx, 0.5)
- for (id, portData) in self.get_parser().get_module_port_list(self.moduleData):
+ for (id, model) in self.get_parser().get_module_port_list(self.moduleData):
y = self.render_port(ctx, id, y)
self.rect = goocanvas.Rect(parent = self.group, x = 0.5, width = self.width, height = y, line_width = 1, stroke_color_rgba = Colors.frame, fill_color_rgba = Colors.box, antialias = cairo.ANTIALIAS_GRAY)
self.rect.lower(self.titleItem)
@@ -144,8 +250,8 @@ class ModuleBox():
self.group.ensure_updated()
self.wire = None
- def create_port(self, portId, portData):
- mport = ModulePort(self, portData)
+ def create_port(self, portId, model):
+ mport = PortView(self, model)
self.portDict[portId] = mport
return mport
@@ -167,68 +273,14 @@ class ModuleBox():
def delete_items(self):
self.group.remove()
- def port_button_press(self, mport, box, event):
+ def port_button_press(self, port_view, box, event):
if event.button == 1:
- port_id = mport.get_id()
- mport.box.props.fill_color_rgba = Colors.activePortIn
- mport.box.props.stroke_color_rgba = Colors.activePort
- (x, y) = self.graph.port_endpoint(mport)
- self.drag_wire = goocanvas.Path(parent = self.parent, stroke_color_rgba = Colors.draggedWire)
- self.drag_wire.type = "tmp wire"
- self.drag_wire.object = None
- self.drag_wire.raise_(None)
- self.graph.dragging = (self, port_id, self.drag_wire, x, y)
- self.set_connect_candidate(None)
- self.update_drag_wire(self.graph.dragging, x, y)
- print "Port URI is " + port_id
+ (x, y) = port_view.get_endpoint()
+ self.graph.dragging = Dragging(self, port_view, x, y)
+ port_view.update_style()
+ print "Port URI is " + port_view.get_id()
return True
- def dragging(self, tuple, x2, y2):
- boundsGrp = self.group.get_bounds()
- self.update_drag_wire(tuple, x2 + boundsGrp.x1, y2 + boundsGrp.y1)
-
- def dragged(self, tuple, x2, y2):
- # self.update_drag_wire(tuple, x2, y2)
- wireitem = tuple[2]
- port = self.portDict[tuple[1]]
- self.graph.dragging = None
- port.box.props.fill_color_rgba = port.orig_color_in
- port.box.props.stroke_color_rgba = port.orig_color_out
- if self.connect_candidate != None:
- # print "Connect: " + tuple[1] + " with " + self.connect_candidate.get_id()
- try:
- self.graph.connect(port, self.connect_candidate, wireitem)
- except:
- wireitem.remove()
- raise
- finally:
- self.set_connect_candidate(None)
- else:
- wireitem.remove()
-
- def set_connect_candidate(self, item):
- if self.connect_candidate != item:
- if self.connect_candidate != None:
- self.connect_candidate.box.props.fill_color_rgba = self.connect_candidate.orig_color_in
- self.connect_candidate.box.props.stroke_color_rgba = self.connect_candidate.orig_color_out
- self.connect_candidate = item
- if item != None:
- item.box.props.fill_color_rgba = Colors.activePortIn
- item.box.props.stroke_color_rgba = Colors.activePort
-
- def update_drag_wire(self, tuple, x2, y2):
- (uri, x, y, dx, dy, wireitem) = (tuple[1], tuple[3], tuple[4], x2 - tuple[3], y2 - tuple[4], tuple[2])
- wireitem.props.data = "M %0.0f,%0.0f C %0.0f,%0.0f %0.0f,%0.0f %0.0f,%0.0f" % (x, y, x+dx/2, y, x+dx/2, y+dy, x+dx, y+dy)
- items = self.graph.get_data_items_at(x+dx, y+dy)
- found = False
- for type, obj, item in items:
- if type == 'port':
- if item.module != self and self.get_parser().can_connect(self.portDict[uri].portData, obj.portData):
- found = True
- self.set_connect_candidate(obj)
- if not found and self.connect_candidate != None:
- self.set_connect_candidate(None)
-
def update_wires(self):
for wire in self.wires:
self.graph.update_wire(wire)
@@ -263,7 +315,13 @@ class ConnectionGraphEditor:
self.canvas.update()
self.canvas.get_root_item().connect("motion-notify-event", self.canvas_motion_notify)
self.canvas.get_root_item().connect("button-release-event", self.canvas_button_release)
-
+
+ def get_canvas(self):
+ return self.canvas
+
+ def get_root(self):
+ return self.canvas.get_root_item()
+
def get_items_at(self, x, y):
cr = self.canvas.create_cairo_context()
items = self.canvas.get_items_in_area(goocanvas.Bounds(x - 3, y - 3, x + 3, y + 3), True, True, False)
@@ -287,7 +345,7 @@ class ConnectionGraphEditor:
self.add_module(*params)
def add_module(self, moduleData, x, y):
- mbox = ModuleBox(self.parser, self.canvas.get_root_item(), moduleData, self)
+ mbox = ModuleView(self.parser, self.canvas.get_root_item(), moduleData, self)
self.modules.add(mbox)
bounds = self.canvas.get_bounds()
if x == None:
@@ -310,11 +368,11 @@ class ConnectionGraphEditor:
def canvas_motion_notify(self, group, widget, event):
if self.dragging != None:
- self.dragging[0].dragging(self.dragging, event.x, event.y)
+ self.dragging.dragging(event.x, event.y)
def canvas_button_release(self, group, widget, event):
if self.dragging != None and event.button == 1:
- self.dragging[0].dragged(self.dragging, event.x, event.y)
+ self.dragging.end_drag(event.x, event.y)
def box_button_press(self, group, widget, event):
if event.button == 1:
@@ -333,24 +391,14 @@ class ConnectionGraphEditor:
self.moving.translate(event.x - self.motion_x, event.y - self.motion_y)
group.module.update_wires()
- def port_endpoint(self, port):
- bounds = port.box.get_bounds()
- port = port.portData
- if self.get_parser().is_port_input(port):
- x = bounds.x1
- else:
- x = bounds.x2
- y = (bounds.y1 + bounds.y2) / 2
- return (x, y)
-
def update_wire(self, wire):
- (x1, y1) = self.port_endpoint(wire.src)
- (x2, y2) = self.port_endpoint(wire.dest)
+ (x1, y1) = wire.src.get_endpoint()
+ (x2, y2) = wire.dest.get_endpoint()
xm = (x1 + x2) / 2
wire.wire.props.data = "M %0.0f,%0.0f C %0.0f,%0.0f %0.0f,%0.0f %0.0f,%0.0f" % (x1, y1, xm, y1, xm, y2, x2, y2)
def connect(self, p1, p2, wireitem = None):
- # p1, p2 are ModulePort objects
+ # p1, p2 are PortView objects
# if wireitem is set, then this is manual connection, and parser.connect() is called
# if wireitem is None, then this is automatic connection, and parser.connect() is bypassed
if p2.isInput:
@@ -360,7 +408,7 @@ class ConnectionGraphEditor:
if wireitem == None:
wireitem = goocanvas.Path(parent = self.canvas.get_root_item())
else:
- self.get_parser().connect(src.portData, dest.portData)
+ self.get_parser().connect(src.model, dest.model)
wire = VisibleWire(src, dest, wireitem)
wireitem.type = "wire"
wireitem.object = wire
diff --git a/bigbull/jackvis.py b/bigbull/jackvis.py
index 1aa14b8..f18efc3 100755
--- a/bigbull/jackvis.py
+++ b/bigbull/jackvis.py
@@ -27,8 +27,11 @@ class JACKPortInfo(object):
def get_full_name(self):
return self.full_name
- def get_type(self):
- return self.format
+ def is_audio(self):
+ return self.format == 0
+
+ def is_midi(self):
+ return self.format == 1
def is_port_input(self):
return (self.flags & 1) != 0
@@ -70,13 +73,13 @@ class JACKGraphParser(object):
self.graph = None
self.fetch_graph()
def get_port_color(self, portData):
- if portData.get_type() == 0:
- return Colors.audioPortIn, Colors.audioPort
- elif portData.get_type() == 1:
- return Colors.eventPortIn, Colors.eventPort
+ if portData.model.is_audio():
+ return Colors.audioPort
+ elif portData.model.is_midi():
+ return Colors.eventPort
else:
- print "Unknown type %s" % portData.get_type()
- return color
+ print "Unknown type %s" % portData.model.format
+ return Colors.controlPort
def is_port_input(self, portData):
return portData.is_port_input()
def get_port_name(self, portData):
@@ -93,9 +96,11 @@ class JACKGraphParser(object):
def can_connect(self, first, second):
if self.is_port_input(first) == self.is_port_input(second):
return False
- if first.get_type() != second.get_type():
- return False
- return True
+ if first.is_audio() and second.is_audio():
+ return True
+ if first.is_midi() and second.is_midi():
+ return True
+ return False
def connect(self, first, second):
self.patchbay.ConnectPortsByName(first.client_name, first.name, second.client_name, second.name)
def disconnect(self, name_first, name_second):
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list