Implement graph visualization

This commit is contained in:
Nedko Arnaudov 2009-08-12 18:04:29 +03:00
parent a93b867caf
commit 6bf15d3be1
4 changed files with 316 additions and 41 deletions

View File

@ -788,34 +788,6 @@ Patchage::disconnect(
}
}
/** Destroy all JACK (canvas) ports.
*/
void
Patchage::clear_canvas()
{
ItemList modules = _canvas->items(); // copy
for (ItemList::iterator m = modules.begin(); m != modules.end(); ++m) {
shared_ptr<Module> module = dynamic_pointer_cast<Module>(*m);
if (!module)
continue;
PortVector ports = module->ports(); // copy
for (PortVector::iterator p = ports.begin(); p != ports.end(); ++p) {
boost::shared_ptr<PatchagePort> port = boost::dynamic_pointer_cast<PatchagePort>(*p);
if (port)
{
module->remove_port(port);
port->hide();
}
}
if (module->ports().empty())
_canvas->remove_item(module);
else
module->resize();
}
}
bool
Patchage::is_canvas_empty()
{

View File

@ -2,7 +2,8 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2008, 2009 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2007 Dave Robillard <http://drobilla.net>
*
**************************************************************************
* This file contains implements the canvas functionality through flowcanvas
@ -32,7 +33,7 @@
struct canvas
{
FlowCanvas::Canvas * flowcanvas_ptr;
boost::shared_ptr<FlowCanvas::Canvas> * flowcanvas;
};
bool
@ -44,7 +45,7 @@ canvas_create(
struct canvas * canvas_ptr;
canvas_ptr = new canvas;
canvas_ptr->flowcanvas_ptr = new FlowCanvas::Canvas(width, height);
canvas_ptr->flowcanvas = new boost::shared_ptr<FlowCanvas::Canvas>(new FlowCanvas::Canvas(width, height));
*canvas_handle_ptr = (canvas_handle)canvas_ptr;
@ -57,14 +58,14 @@ GtkWidget *
canvas_get_widget(
canvas_handle canvas)
{
return ((Gtk::Widget *)canvas_ptr->flowcanvas_ptr)->gobj();
return ((Gtk::Widget *)canvas_ptr->flowcanvas->get())->gobj();
}
void
canvas_destroy(
canvas_handle canvas)
{
delete canvas_ptr->flowcanvas_ptr;
delete canvas_ptr->flowcanvas;
delete canvas_ptr;
}
@ -72,6 +73,25 @@ void
canvas_clear(
canvas_handle canvas)
{
FlowCanvas::ItemList modules = canvas_ptr->flowcanvas->get()->items(); // copy
for (FlowCanvas::ItemList::iterator m = modules.begin(); m != modules.end(); ++m)
{
boost::shared_ptr<FlowCanvas::Module> module = boost::dynamic_pointer_cast<FlowCanvas::Module>(*m);
if (!module)
continue;
FlowCanvas::PortVector ports = module->ports(); // copy
for (FlowCanvas::PortVector::iterator p = ports.begin(); p != ports.end(); ++p)
{
boost::shared_ptr<FlowCanvas::Port> port = boost::dynamic_pointer_cast<FlowCanvas::Port>(*p);
assert(port != NULL);
module->remove_port(port);
port->hide();
}
assert(module->ports().empty());
canvas_ptr->flowcanvas->get()->remove_item(module);
}
}
void
@ -79,12 +99,14 @@ canvas_set_zoom(
canvas_handle canvas,
double pix_per_unit)
{
canvas_ptr->flowcanvas->get()->set_zoom(pix_per_unit);
}
void
canvas_arrange(
canvas_handle canvas)
{
canvas_ptr->flowcanvas->get()->arrange();
}
bool
@ -97,15 +119,27 @@ canvas_create_module(
bool show_port_labels,
canvas_module_handle * module_handle_ptr)
{
return false;
boost::shared_ptr<FlowCanvas::Module> * module;
module = new boost::shared_ptr<FlowCanvas::Module>(new FlowCanvas::Module(*canvas_ptr->flowcanvas, name, x, y, show_title, show_port_labels));
canvas_ptr->flowcanvas->get()->add_item(*module);
module->get()->resize();
*module_handle_ptr = (canvas_module_handle)module;
return true;
}
#define module_ptr ((boost::shared_ptr<FlowCanvas::Module> *)module)
bool
canvas_destroy_module(
canvas_handle canvas,
canvas_module_handle module)
{
return false;
canvas_ptr->flowcanvas->get()->remove_item(*module_ptr);
delete module_ptr;
return true;
}
bool
@ -114,19 +148,46 @@ canvas_create_port(
canvas_module_handle module,
const char * name,
bool is_input,
int color)
int color,
canvas_port_handle * port_handle_ptr)
{
return false;
boost::shared_ptr<FlowCanvas::Port> * port;
port = new boost::shared_ptr<FlowCanvas::Port>(new FlowCanvas::Port(*module_ptr, name, is_input, color));
module_ptr->get()->add_port(*port);
module_ptr->get()->resize();
*port_handle_ptr = (canvas_port_handle)port;
return true;
}
#undef module_ptr
#define port_ptr ((boost::shared_ptr<FlowCanvas::Port> *)port)
bool
canvas_destroy_port(
canvas_handle canvas,
canvas_port_handle port)
{
return false;
boost::shared_ptr<FlowCanvas::Module> module = port_ptr->get()->module().lock();
module->remove_port(*port_ptr);
delete port_ptr;
module->resize();
return true;
}
int
canvas_get_port_color(
canvas_port_handle port)
{
return port_ptr->get()->color();
}
#undef port_ptr
#define port1_ptr ((boost::shared_ptr<FlowCanvas::Port> *)port1)
#define port2_ptr ((boost::shared_ptr<FlowCanvas::Port> *)port2)
bool
canvas_add_connection(
canvas_handle canvas,
@ -134,7 +195,8 @@ canvas_add_connection(
canvas_port_handle port2,
uint32_t color)
{
return false;
canvas_ptr->flowcanvas->get()->add_connection(*port1_ptr, *port2_ptr, color);
return true;
}
bool
@ -143,9 +205,13 @@ canvas_remove_connection(
canvas_port_handle port1,
canvas_port_handle port2)
{
return false;
canvas_ptr->flowcanvas->get()->remove_connection(*port1_ptr, *port2_ptr);
return true;
}
#undef port1_ptr
#undef port2_ptr
bool
canvas_enum_modules(
canvas_handle canvas,

View File

@ -89,13 +89,18 @@ canvas_create_port(
canvas_module_handle module,
const char * name,
bool is_input,
int color);
int color,
canvas_port_handle * port_handle_ptr);
bool
canvas_destroy_port(
canvas_handle canvas,
canvas_port_handle port);
int
canvas_get_port_color(
canvas_port_handle port);
bool
canvas_add_connection(
canvas_handle canvas,

View File

@ -29,13 +29,72 @@
#include "graph_canvas.h"
#include "../common/debug.h"
#include "../common/klist.h"
struct graph_canvas
{
graph_handle graph;
canvas_handle canvas;
struct list_head clients;
};
struct client
{
struct list_head siblings;
uint64_t id;
canvas_module_handle canvas_module;
struct list_head ports;
};
struct port
{
struct list_head siblings;
uint64_t id;
canvas_port_handle canvas_port;
};
static
struct client *
find_client(
struct graph_canvas * graph_canvas_ptr,
uint64_t id)
{
struct list_head * node_ptr;
struct client * client_ptr;
list_for_each(node_ptr, &graph_canvas_ptr->clients)
{
client_ptr = list_entry(node_ptr, struct client, siblings);
if (client_ptr->id == id)
{
return client_ptr;
}
}
return NULL;
}
static
struct port *
find_port(
struct client * client_ptr,
uint64_t id)
{
struct list_head * node_ptr;
struct port * port_ptr;
list_for_each(node_ptr, &client_ptr->ports)
{
port_ptr = list_entry(node_ptr, struct port, siblings);
if (port_ptr->id == id)
{
return port_ptr;
}
}
return NULL;
}
bool
graph_canvas_create(
int width,
@ -57,6 +116,7 @@ graph_canvas_create(
}
graph_canvas_ptr->graph = NULL;
INIT_LIST_HEAD(&graph_canvas_ptr->clients);
*graph_canvas_handle_ptr = (graph_canvas_handle)graph_canvas_ptr;
@ -71,6 +131,7 @@ clear(
void * graph_canvas)
{
lash_info("canvas::clear()");
canvas_clear(graph_canvas_ptr->canvas);
}
static
@ -80,7 +141,28 @@ client_appeared(
uint64_t id,
const char * name)
{
struct client * client_ptr;
lash_info("canvas::client_appeared(%"PRIu64", \"%s\")", id, name);
client_ptr = malloc(sizeof(struct client));
if (client_ptr == NULL)
{
lash_error("allocation of memory for struct client failed");
return;
}
client_ptr->id = id;
INIT_LIST_HEAD(&client_ptr->ports);
if (!canvas_create_module(graph_canvas_ptr->canvas, name, 0, 0, true, true, &client_ptr->canvas_module))
{
lash_error("canvas_create_module(\"%s\") failed", name);
free(client_ptr);
return;
}
list_add_tail(&client_ptr->siblings, &graph_canvas_ptr->clients);
}
static
@ -89,7 +171,20 @@ client_disappeared(
void * graph_canvas,
uint64_t id)
{
struct client * client_ptr;
lash_info("canvas::client_disappeared(%"PRIu64")", id);
client_ptr = find_client(graph_canvas_ptr, id);
if (client_ptr == NULL)
{
lash_error("cannot find disappearing client %"PRIu64"", id);
return;
}
list_del(&client_ptr->siblings);
canvas_destroy_module(graph_canvas_ptr->canvas, client_ptr->canvas_module);
free(client_ptr);
}
static
@ -103,7 +198,46 @@ port_appeared(
bool is_terminal,
bool is_midi)
{
int color;
struct client * client_ptr;
struct port * port_ptr;
lash_info("canvas::port_appeared(%"PRIu64", %"PRIu64", \"%s\")", client_id, port_id, port_name);
client_ptr = find_client(graph_canvas_ptr, client_id);
if (client_ptr == NULL)
{
lash_error("cannot find client %"PRIu64" of appearing port %"PRIu64" \"%s\"", client_id, port_id, port_name);
return;
}
port_ptr = malloc(sizeof(struct port));
if (port_ptr == NULL)
{
lash_error("allocation of memory for struct port failed");
return;
}
port_ptr->id = port_id;
// Darkest tango palette colour, with S -= 6, V -= 6, w/ transparency
if (is_midi)
{
color = 0x960909C0;
}
else
{
color = 0x244678C0;
}
if (!canvas_create_port(graph_canvas_ptr->canvas, client_ptr->canvas_module, port_name, is_input, color, &port_ptr->canvas_port))
{
lash_error("canvas_create_port(\"%s\") failed", port_name);
free(client_ptr);
return;
}
list_add_tail(&port_ptr->siblings, &client_ptr->ports);
}
static
@ -113,7 +247,28 @@ port_disappeared(
uint64_t client_id,
uint64_t port_id)
{
struct client * client_ptr;
struct port * port_ptr;
lash_info("canvas::port_disappeared(%"PRIu64", %"PRIu64")", client_id, port_id);
client_ptr = find_client(graph_canvas_ptr, client_id);
if (client_ptr == NULL)
{
lash_error("cannot find client %"PRIu64" of disappearing port %"PRIu64"", client_id, port_id);
return;
}
port_ptr = find_port(client_ptr, port_id);
if (client_ptr == NULL)
{
lash_error("cannot find disappearing port %"PRIu64" of client %"PRIu64"", port_id, client_id);
return;
}
list_del(&port_ptr->siblings);
canvas_destroy_port(graph_canvas_ptr->canvas, port_ptr->canvas_port);
free(port_ptr);
}
static
@ -125,7 +280,46 @@ ports_connected(
uint64_t client2_id,
uint64_t port2_id)
{
struct client * client1_ptr;
struct port * port1_ptr;
struct client * client2_ptr;
struct port * port2_ptr;
lash_info("canvas::ports_connected(%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64")", client1_id, port1_id, client2_id, port2_id);
client1_ptr = find_client(graph_canvas_ptr, client1_id);
if (client1_ptr == NULL)
{
lash_error("cannot find client %"PRIu64" of connected port %"PRIu64"", client1_id, port1_id);
return;
}
port1_ptr = find_port(client1_ptr, port1_id);
if (client1_ptr == NULL)
{
lash_error("cannot find connected port %"PRIu64" of client %"PRIu64"", port1_id, client1_id);
return;
}
client2_ptr = find_client(graph_canvas_ptr, client2_id);
if (client2_ptr == NULL)
{
lash_error("cannot find client %"PRIu64" of connected port %"PRIu64"", client2_id, port2_id);
return;
}
port2_ptr = find_port(client2_ptr, port2_id);
if (client2_ptr == NULL)
{
lash_error("cannot find connected port %"PRIu64" of client %"PRIu64"", port2_id, client2_id);
return;
}
canvas_add_connection(
graph_canvas_ptr->canvas,
port1_ptr->canvas_port,
port2_ptr->canvas_port,
canvas_get_port_color(port1_ptr->canvas_port) + 0x22222200);
}
static
@ -137,7 +331,45 @@ ports_disconnected(
uint64_t client2_id,
uint64_t port2_id)
{
struct client * client1_ptr;
struct port * port1_ptr;
struct client * client2_ptr;
struct port * port2_ptr;
lash_info("canvas::ports_disconnected(%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64")", client1_id, port1_id, client2_id, port2_id);
client1_ptr = find_client(graph_canvas_ptr, client1_id);
if (client1_ptr == NULL)
{
lash_error("cannot find client %"PRIu64" of disconnected port %"PRIu64"", client1_id, port1_id);
return;
}
port1_ptr = find_port(client1_ptr, port1_id);
if (client1_ptr == NULL)
{
lash_error("cannot find disconnected port %"PRIu64" of client %"PRIu64"", port1_id, client1_id);
return;
}
client2_ptr = find_client(graph_canvas_ptr, client2_id);
if (client2_ptr == NULL)
{
lash_error("cannot find client %"PRIu64" of disconnected port %"PRIu64"", client2_id, port2_id);
return;
}
port2_ptr = find_port(client2_ptr, port2_id);
if (client2_ptr == NULL)
{
lash_error("cannot find disconnected port %"PRIu64" of client %"PRIu64"", port2_id, client2_id);
return;
}
canvas_remove_connection(
graph_canvas_ptr->canvas,
port1_ptr->canvas_port,
port2_ptr->canvas_port);
}
void