Implement graph visualization
This commit is contained in:
parent
a93b867caf
commit
6bf15d3be1
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue