[SCM] calf/master: More jackvis/conngraph - skeleton handlers for D-Bus signals and clean-ups.
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:40:17 UTC 2013
The following commit has been merged in the master branch:
commit 9aca7d8da97304cd5ceffc51e56f916848f62ad0
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Fri May 14 00:31:54 2010 +0100
More jackvis/conngraph - skeleton handlers for D-Bus signals and clean-ups.
* Clean up event handling in jackvis/conngraph
* Add Disconnect All menu option on ports
* Add a few dummy handling for some JACK D-Bus signals.
diff --git a/bigbull/calfgtkutils.py b/bigbull/calfgtkutils.py
index b62778f..bebee8a 100644
--- a/bigbull/calfgtkutils.py
+++ b/bigbull/calfgtkutils.py
@@ -2,8 +2,9 @@ import pygtk
pygtk.require('2.0')
import gtk
-def add_option(menu, option, handler, data = None):
+def add_option(menu, option, handler, data = None, enabled = True):
item = gtk.MenuItem(option)
+ item.set_sensitive(enabled)
item.connect_object("activate", handler, data)
menu.add(item)
diff --git a/bigbull/conndiagram.py b/bigbull/conndiagram.py
index f70d66d..9370487 100644
--- a/bigbull/conndiagram.py
+++ b/bigbull/conndiagram.py
@@ -62,7 +62,7 @@ class VisibleWire():
"""src is source PortView, dst is destination PortView"""
self.src = src
self.dest = dest
- self.mask = goocanvas.Path(parent = src.get_graph().get_root(), line_width=12, stroke_color_rgba = 0, pointer_events = goocanvas.EVENTS_STROKE)
+ self.mask = goocanvas.Path(parent = src.get_graph().get_root(), line_width=12, stroke_color_rgba = 0, pointer_events = goocanvas.EVENTS_ALL)
self.mask.type = "wire"
self.mask.object = self
self.wire = goocanvas.Path(parent = src.get_graph().get_root(), stroke_color_rgba = Colors.connectedWire, pointer_events = 0)
@@ -74,8 +74,8 @@ class VisibleWire():
if self.wire is not None:
self.wire.remove()
self.mask.remove()
- self.src.module.remove_wire(self)
- self.dest.module.remove_wire(self)
+ self.src.module.wires.remove(self)
+ self.dest.module.wires.remove(self)
self.wire = None
self.mask = None
@@ -88,8 +88,8 @@ class VisibleWire():
class Dragging():
- def __init__(self, module, port_view, x, y):
- self.module = module
+ def __init__(self, port_view, x, y):
+ self.module = port_view.module
self.port_view = port_view
self.x = x
self.y = y
@@ -110,8 +110,7 @@ class Dragging():
self.drag_wire.props.data = wireData(self.x, self.y, x2, y2)
def dragging(self, x2, y2):
- boundsGrp = self.module.group.get_bounds()
- self.update_drag_wire(x2 + boundsGrp.x1, y2 + boundsGrp.y1)
+ self.update_drag_wire(x2, y2)
def update_drag_wire(self, x2, y2):
items = self.get_graph().get_data_items_at(x2, y2)
@@ -146,7 +145,8 @@ class Dragging():
src, dst = self.port_view, self.connect_candidate
self.get_graph().dragging = None
src.update_style()
- self.remove_wire()
+ self.drag_wire.remove()
+ self.drag_wire = None
if dst is not None:
# print "Connect: " + tuple[1] + " with " + self.connect_candidate.get_id()
dst.update_style()
@@ -154,12 +154,8 @@ class Dragging():
src, dst = dst, src
self.get_graph().get_controller().connect(src.model, dst.model)
- def remove_wire(self):
- self.drag_wire.remove()
- self.drag_wire = None
-
class PortView():
- fontName = "DejaVu Sans 8"
+ fontName = "DejaVu Sans 11px"
type = "port"
def __init__(self, module, model):
self.module = module
@@ -219,10 +215,8 @@ class PortView():
def update_style(self):
color = self.model.get_port_color()
- 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
-
+ self.box.set_properties(fill_color_rgba = color.get_fill(self), stroke_color_rgba = color.get_stroke(self), line_width = 1, pointer_events = goocanvas.EVENTS_ALL)
+
def is_dragged(self):
dragging = self.get_graph().dragging
if dragging is not None and dragging.has_port_view(self):
@@ -238,6 +232,9 @@ class PortView():
y = (bounds.y1 + bounds.y2) / 2
return (x, y)
+ def get_connections(self):
+ return [wire for wire in self.module.wires if wire.src == self or wire.dest == self]
+
class ModuleView():
margin = 2
spacing = 4
@@ -250,82 +247,89 @@ class ModuleView():
self.connect_candidate = None
self.parent = parent
self.model = model
- self.group = goocanvas.Group(parent = self.parent)
+ self.group = goocanvas.Group(parent = self.parent, pointer_events = goocanvas.EVENTS_ALL)
+ self.group.type = "module"
+ self.group.object = self.group.module = self
+ self.group.raise_(None)
+ self.rect = None
+ self.titleItem = None
self.ports = []
self.wires = []
- self.create_items()
+ self.refresh()
def get_controller(self):
return self.controller
- def create_items(self):
- self.group.module = self
- while self.group.get_n_children() > 0:
- self.group.remove_child(0)
- ctx = self.group.get_canvas().create_cairo_context()
+ def refresh(self):
self.title = self.model.get_name()
+ self.ports = []
self.portDict = {}
- width = self.get_title_width(ctx)
for model in self.model.get_port_list():
- view = self.create_port(model)
- new_width = view.calc_width(ctx)
- if new_width > width:
- width = new_width
- self.width = width
+ self.add_port(model)
+ self.render()
+
+ def remove(self):
+ while self.group.get_n_children() > 0:
+ self.group.remove_child(0)
+ self.rect = None
+ self.titleItem = None
+
+ def render(self):
+ self.remove()
+ ctx = self.group.get_canvas().create_cairo_context()
+ self.width = max([self.get_title_width(ctx)] + [port_view.calc_width(ctx) for port_view in self.ports])
y = self.render_title(ctx, 0.5)
- for view in self.ports:
- y = self.render_port(ctx, view, 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)
+ for port_view in self.ports:
+ y = port_view.render(ctx, self.group, y)
+ self.rect = goocanvas.Rect(parent = self.group, x = 0.5, width = self.width, height = y)
+ self.update_style()
self.rect.lower(self.titleItem)
self.rect.type = "module"
- self.rect.object = self.rect.module = self
+ self.rect.object = self.group.module = self
self.group.ensure_updated()
- def create_port(self, model):
+ def add_port(self, model, pos = None):
+ if pos is None:
+ pos = len(self.ports)
view = PortView(self, model)
- self.ports.append(view)
+ self.ports.insert(pos, view)
self.portDict[model.get_id()] = view
return view
+ def del_port(self, pos):
+ del self.portDict[self.ports[pos].model.get_id()]
+ self.ports.pop(pos)
+
def get_title_width(self, ctx):
return calc_extents(ctx, self.fontName, self.title)[0] + 4 * self.margin
def render_title(self, ctx, y):
- self.titleItem = goocanvas.Text(parent = self.group, font = self.fontName, text = self.title, width = self.width, x = 0, y = y, alignment = "center", use_markup = True, fill_color_rgba = Colors.text, hint_metrics = cairo.HINT_METRICS_ON, antialias = cairo.ANTIALIAS_GRAY)
- y += self.titleItem.get_requested_height(ctx, self.width) + self.spacing
+ self.titleItem = goocanvas.Text(parent = self.group, font = self.fontName, text = self.title, width = self.width, x = 0, y = y, alignment = "center", use_markup = True, fill_color_rgba = Colors.text, hint_metrics = cairo.HINT_METRICS_ON, antialias = cairo.ANTIALIAS_GRAY, pointer_events = goocanvas.EVENTS_NONE)
+ y += self.titleItem.get_requested_height(ctx, self.width) + 2 * self.spacing
return y
def render_port(self, ctx, port_view, y):
- y = port_view.render(ctx, self.group, y)
- port_view.box.connect_object("button-press-event", self.port_button_press, port_view)
- port_view.title.connect_object("button-press-event", self.port_button_press, port_view)
- return y
+ return port_view.render(ctx, self.group, y)
+ #port_view.box.connect_object("button-press-event", self.port_button_press, port_view)
+ #port_view.title.connect_object("button-press-event", self.port_button_press, port_view)
def delete_items(self):
self.group.remove()
for w in list(self.wires):
w.remove()
-
- def port_button_press(self, port_view, box, event):
- if event.button == 1:
- (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 update_wires(self):
for wire in self.wires:
wire.update_shape()
- def remove_wire(self, wire):
- self.wires = [w for w in self.wires if w != wire]
-
def translate(self, dx, dy):
self.group.translate(dx, dy)
self.group.ensure_updated()
self.update_wires()
-
+
+ def update_style(self):
+ self.rect.set_properties(line_width = 1, stroke_color_rgba = Colors.frame, fill_color_rgba = Colors.box, antialias = cairo.ANTIALIAS_GRAY, pointer_events = goocanvas.EVENTS_ALL)
+
class ConnectionGraphEditor:
def __init__(self, app, controller):
self.app = app
@@ -351,8 +355,9 @@ class ConnectionGraphEditor:
self.canvas.props.background_color_rgb = 0
self.canvas.props.integer_layout = False
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)
+ self.canvas.connect("button-press-event", self.canvas_button_press_handler)
+ self.canvas.connect("motion-notify-event", self.canvas_motion_notify)
+ self.canvas.connect("button-release-event", self.canvas_button_release)
def get_canvas(self):
return self.canvas
@@ -361,11 +366,33 @@ class ConnectionGraphEditor:
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)
- items = set()
return self.canvas.get_items_at(x, y, True)
+ def get_module_map(self, model):
+ map = {}
+ for view in self.modules:
+ map[view.model] = view
+ return map
+
+ def get_module_view(self, model):
+ for view in self.modules:
+ if view.model == model:
+ return view
+ return None
+
+ def get_port_map(self):
+ map = {}
+ for mod in self.modules:
+ map.update(mod.portDict)
+ return map
+
+ def get_port_view(self, port_model):
+ for mod in self.modules:
+ for p in mod.ports:
+ if p.model == port_model:
+ return p
+ return None
+
def get_data_items_at(self, x, y):
items = self.get_items_at(x, y)
if items == None:
@@ -387,56 +414,52 @@ class ConnectionGraphEditor:
if x == None:
(x, y) = (int(random.uniform(bounds[0], bounds[2] - 100)), int(random.uniform(bounds[1], bounds[3] - 50)))
mbox.group.translate(x, y)
- 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)
module.delete_items()
- def get_port_map(self):
- map = {}
- for mod in self.modules:
- map.update(mod.portDict)
- return map
+ def canvas_button_press_handler(self, widget, event):
+ if event.button == 1:
+ for itype, iobject, item in self.get_data_items_at(event.x, event.y):
+ if itype == 'module':
+ group = iobject.group
+ group.raise_(None)
+ for w in group.module.wires:
+ w.wire.raise_(None)
+
+ self.moving = group.module
+ self.motion_x = event.x
+ self.motion_y = event.y
+ return True
+ if itype == 'port':
+ port_view = iobject
+ module = port_view.module
+ (x, y) = port_view.get_endpoint()
+ self.dragging = Dragging(port_view, x, y)
+ port_view.update_style()
+ print "Port URI is " + port_view.get_id()
+ return True
+ elif event.button == 3:
+ self.app.canvas_popup_menu(event.x, event.y, event.time)
+ return True
- def get_port_view(self, port_model):
- for mod in self.modules:
- for p in mod.ports:
- if p.model == port_model:
- return p
- return None
-
- def canvas_motion_notify(self, group, widget, event):
- if self.dragging != None:
+ def canvas_motion_notify(self, widget, event):
+ if self.dragging is not None:
self.dragging.dragging(event.x, event.y)
+ if self.moving is not None:
+ self.moving.translate(event.x - self.motion_x, event.y - self.motion_y)
+ self.moving.update_wires()
+ self.motion_x, self.motion_y = event.x, event.y
- def canvas_button_release(self, group, widget, event):
- if self.dragging != None and event.button == 1:
- self.dragging.end_drag(event.x, event.y)
-
- def box_button_press(self, group, widget, event):
- if event.button == 1:
- group.raise_(None)
- for w in group.module.wires:
- w.wire.raise_(None)
-
- self.moving = group
- self.motion_x = event.x
- self.motion_y = event.y
- return True
-
- def box_button_release(self, group, widget, event):
+ def canvas_button_release(self, widget, event):
if event.button == 1:
- self.moving = None
-
- def box_motion_notify(self, group, widget, event):
- if self.moving == group:
- self.moving.module.translate(event.x - self.motion_x, event.y - self.motion_y)
- group.module.update_wires()
-
+ if self.moving is not None:
+ self.moving = None
+ if self.dragging is not None:
+ self.dragging.end_drag(event.x, event.y)
+
# Connect elements visually (but not logically, that's what controller is for)
def connect(self, src, dest):
wire = VisibleWire(src, dest)
diff --git a/bigbull/jackvis.py b/bigbull/jackvis.py
index 7906969..939ba83 100755
--- a/bigbull/jackvis.py
+++ b/bigbull/jackvis.py
@@ -2,6 +2,7 @@
import pygtk
pygtk.require('2.0')
import dbus
+import dbus.mainloop.glib
import gtk
import conndiagram
from calfgtkutils import *
@@ -54,27 +55,37 @@ class JACKClientInfo(object):
def __init__(self, id, name, ports):
self.id = id
self.name = name
- self.ports = [JACKPortInfo("%s:%s" % (name, p[1]), *p) for p in ports]
+ self.ports = []
+ for p in ports:
+ self.add_port(*p)
def get_name(self):
return self.name
+ def add_port(self, port_id, name, flags, format):
+ model = JACKPortInfo("%s:%s" % (self.name, name), port_id, name, flags, format)
+ self.ports.append(model)
+ return model
class JACKGraphInfo(object):
version = 0
- clients = []
- client_map = {}
- connections_id = set()
- connections_name = set()
def __init__(self, version, clients, connections):
self.version = version
- self.clients = [JACKClientInfo(*c) for c in clients]
+ self.clients = []
self.client_map = {}
- for c in self.clients:
- self.client_map[c.name] = c
self.connections_id = set()
self.connections_name = set()
- for (cid1, cname1, pid1, pname1, cid2, cname2, pid2, pname2, something) in connections:
- self.connections_name.add(("%s:%s" % (cname1, pname1), "%s:%s" % (cname2, pname2)))
- self.connections_id.add(("%s:%s" % (cid1, pid1), "%s:%s" % (cid2, pid2)))
+ for c in clients:
+ self.add_client(*c)
+ for tuple in connections:
+ self.add_connection(*tuple)
+
+ def add_client(self, id, name, ports):
+ c = JACKClientInfo(id, name, ports)
+ self.clients.append(c)
+ self.client_map[name] = c
+
+ def add_connection(self, cid1, cname1, pid1, pname1, cid2, cname2, pid2, pname2, something):
+ self.connections_name.add(("%s:%s" % (cname1, pname1), "%s:%s" % (cname2, pname2)))
+ self.connections_id.add(("%s:%s" % (cid1, pid1), "%s:%s" % (cid2, pid2)))
class ClientModuleModel():
def __init__(self, client, checker):
@@ -86,12 +97,27 @@ class ClientModuleModel():
class JACKGraphController(object):
def __init__(self):
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
self.bus = dbus.SessionBus()
self.service = self.bus.get_object("org.jackaudio.service", "/org/jackaudio/Controller")
self.patchbay = dbus.Interface(self.service, "org.jackaudio.JackPatchbay")
self.graph = None
self.view = None
self.fetch_graph()
+ self.patchbay.connect_to_signal('PortAppeared', self.port_appeared)
+ self.patchbay.connect_to_signal('PortDisappeared', self.port_disappeared)
+ self.patchbay.connect_to_signal('PortsConnected', self.ports_connected)
+ self.patchbay.connect_to_signal('PortsDisconnected', self.ports_disconnected)
+ def port_appeared(self, seq_no, client_id, client_name, port_id, port_name, flags, format):
+ model = self.graph.client_map[str(client_name)].add_port(int(port_id), str(port_name), int(flags_format))
+ print "PortAppeared", model
+ def port_disappeared(self, seq_no, client_id, client_name, port_id, port_name):
+ print "PortDisappeared", str(client_name), str(port_name)
+ def ports_connected(self, *args):
+ print "PortsConnected", args
+ self.graph.add_connection(*args[1:])
+ def ports_disconnected(self, *args):
+ print "PortsDisconnected", args
def fetch_graph(self):
req_version = self.graph.version if self.graph is not None else 0
graphdata = self.patchbay.GetGraph(req_version)
@@ -132,8 +158,10 @@ class JACKGraphController(object):
self.view.connect(pmap[c], pmap[p])
else:
print "Connect %s to %s - not found" % (c, p)
+ for m in left_mods:
+ m.translate(width - m.width, 0)
for m in right_mods:
- m.translate(950 - width - 20 - width2, 0)
+ m.translate(950 - width - 30 - width2, 0)
def add_clients(self, x, y, checker):
margin = 10
mwidth = 0
@@ -156,28 +184,34 @@ class App:
self.canvas_popup_menu(0, 0, 0)
return True
- def canvas_button_press_handler(self, widget, event):
- if event.button == 3:
- self.canvas_popup_menu(event.x, event.y, event.time)
- return True
-
def canvas_popup_menu(self, x, y, time):
menu = gtk.Menu()
items = self.cgraph.get_data_items_at(x, y)
- types = set([di[0] for di in items])
- if 'wire' in types:
- for i in items:
- if i[0] == "wire":
- wire = i[1]
- add_option(menu, "Disconnect", self.disconnect, wire)
- else:
- return
- menu.show_all()
- menu.popup(None, None, None, 3, time)
+ found = False
+ for i in items:
+ if i[0] == "wire":
+ wire = i[1]
+ add_option(menu, "Disconnect", self.disconnect, wire)
+ found = True
+ break
+ elif i[0] == "port":
+ port = i[1]
+ add_option(menu, "Disconnect All", self.disconnect_all, port, enabled = len(port.get_connections()))
+ found = True
+ break
+ if found:
+ menu.show_all()
+ menu.popup(None, None, None, 3, time)
def disconnect(self, wire):
self.controller.disconnect(wire.src.model, wire.dest.model)
- wire.delete()
+ wire.remove()
+
+ def disconnect_all(self, port):
+ for wire in list(port.module.wires):
+ if wire.src == port or wire.dest == port:
+ self.controller.disconnect(wire.src.model, wire.dest.model)
+ wire.remove()
def create(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
@@ -192,7 +226,6 @@ class App:
self.window.add(self.main_vbox)
self.window.show_all()
self.main_vbox.connect("popup-menu", self.canvas_popup_menu_handler)
- self.cgraph.canvas.connect("button-press-event", self.canvas_button_press_handler)
self.controller.add_all()
self.cgraph.clear()
self.controller.add_all()
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list