Split matrix widget code to separate file
git-svn-id: file:///home/vcs/svn/jsweeper/trunk@3 6611ac79-6612-48ef-a1e9-b906f853523emaster
parent
28ae767a35
commit
5249fa7d89
|
@ -19,6 +19,8 @@ SET(SOURCES
|
||||||
src/jack.cpp
|
src/jack.cpp
|
||||||
src/jack.h
|
src/jack.h
|
||||||
src/jsweeper.cpp
|
src/jsweeper.cpp
|
||||||
|
src/matrix.cpp
|
||||||
|
src/matrix.h
|
||||||
src/port.cpp
|
src/port.cpp
|
||||||
src/port.h
|
src/port.h
|
||||||
src/portmanager.cpp
|
src/portmanager.cpp
|
||||||
|
|
605
src/gui.cpp
605
src/gui.cpp
|
@ -6,611 +6,6 @@
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
const Rect Rect::None = Rect(0, 0, -1, -1);
|
|
||||||
|
|
||||||
Matrix::Matrix() :
|
|
||||||
m_client_width(0), m_client_height(0), m_port_width(0), m_port_height(0), m_separation(0), m_padding(cfg.CellPadding),
|
|
||||||
m_font_size(cfg.FontSize), m_typeface(cfg.FontFace)
|
|
||||||
{
|
|
||||||
set_size_request(0, 0);
|
|
||||||
show();
|
|
||||||
|
|
||||||
add_events(Gdk::BUTTON_PRESS_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix::~Matrix()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Matrix::Refresh()
|
|
||||||
{
|
|
||||||
Glib::RefPtr<Gdk::Window> window = get_window();
|
|
||||||
if (!window) return;
|
|
||||||
|
|
||||||
m_client_width = 0;
|
|
||||||
m_client_height = 0;
|
|
||||||
m_port_width = 0;
|
|
||||||
m_port_height = 0;
|
|
||||||
|
|
||||||
m_separation = 0;
|
|
||||||
|
|
||||||
pm.Sort();
|
|
||||||
|
|
||||||
int cols = 0;
|
|
||||||
int rows = 0;
|
|
||||||
|
|
||||||
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
|
|
||||||
cr->select_font_face(m_typeface, Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL);
|
|
||||||
cr->set_font_size(m_font_size);
|
|
||||||
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pm.m_ports.begin(); plit != pm.m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
p->rect = Rect::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientList::iterator clit;
|
|
||||||
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
|
||||||
Client *c = *clit;
|
|
||||||
|
|
||||||
cr->get_text_extents(c->m_name, c->extents);
|
|
||||||
|
|
||||||
int width = c->extents.width + m_padding * 2;
|
|
||||||
if (c->m_is_input) {
|
|
||||||
if (width > m_client_height) m_client_height = width;
|
|
||||||
} else {
|
|
||||||
if (width > m_client_width) m_client_width = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c->extents.height > m_separation) m_separation = c->extents.height;
|
|
||||||
|
|
||||||
if (!c->m_expanded) {
|
|
||||||
if (c->m_is_input) {
|
|
||||||
cols++;
|
|
||||||
} else {
|
|
||||||
rows++;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
pg->rect = Rect::None;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
|
|
||||||
cr->get_text_extents(pg->m_name, pg->extents);
|
|
||||||
if (pg->extents.height > m_separation) m_separation = pg->extents.height;
|
|
||||||
|
|
||||||
if (!pg->m_expanded && pg->m_name != "") {
|
|
||||||
int width = pg->extents.width + m_padding * 2;
|
|
||||||
if (c->m_is_input) {
|
|
||||||
if (width > m_port_height) m_port_height = width;
|
|
||||||
cols++;
|
|
||||||
} else {
|
|
||||||
if (width > m_port_width) m_port_width = width;
|
|
||||||
rows++;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
|
|
||||||
cr->get_text_extents(p->m_name, p->extents);
|
|
||||||
|
|
||||||
int width = pg->extents.width + p->extents.width + m_padding * (pg->extents.width > 0 ? 4 : 2);
|
|
||||||
if (p->m_flags & JackPortIsInput) {
|
|
||||||
if (width > m_port_height) m_port_height = width;
|
|
||||||
cols++;
|
|
||||||
} else {
|
|
||||||
if (width > m_port_width) m_port_width = width;
|
|
||||||
rows++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->extents.height > m_separation) m_separation = p->extents.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pm.m_ports.begin(); plit != pm.m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
|
|
||||||
cr->get_text_extents(p->m_name, p->extents);
|
|
||||||
|
|
||||||
if (p->m_flags & JackPortIsInput) {
|
|
||||||
if (p->extents.width > m_port_height) m_port_height = p->extents.width;
|
|
||||||
} else {
|
|
||||||
if (p->extents.width > m_port_width) m_port_width = p->extents.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->extents.height > m_separation) m_separation = p->extents.height;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
m_separation += m_padding * 2;
|
|
||||||
|
|
||||||
// if (m_port_width > m_separation * 5) m_port_width = m_separation * 5;
|
|
||||||
// if (m_port_height > m_separation * 5) m_port_height = m_separation * 5;
|
|
||||||
|
|
||||||
int y = m_client_height + m_port_height + m_padding;
|
|
||||||
int x = m_client_width + m_port_width + m_padding;
|
|
||||||
|
|
||||||
across.clear();
|
|
||||||
down.clear();
|
|
||||||
|
|
||||||
Rect r;
|
|
||||||
|
|
||||||
// ClientList::iterator clit;
|
|
||||||
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
|
||||||
Client *c = *clit;
|
|
||||||
|
|
||||||
if (c->m_is_input) {
|
|
||||||
r.left = x;
|
|
||||||
r.top = m_padding;
|
|
||||||
r.width = -1;
|
|
||||||
r.height = m_client_height;
|
|
||||||
c->rect = r;
|
|
||||||
|
|
||||||
if (!c->m_expanded) {
|
|
||||||
c->rect.width = m_separation;
|
|
||||||
c->rect.height = m_client_height + m_port_height;
|
|
||||||
across.push_back(c);
|
|
||||||
x += m_separation;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
|
|
||||||
if (pg->m_name != "") {
|
|
||||||
r.left = x;
|
|
||||||
r.top = m_padding + m_client_height;
|
|
||||||
r.width = pg->m_expanded ? m_separation * pg->m_ports.size() : m_separation;
|
|
||||||
r.height = pg->m_expanded ? pg->extents.width + m_padding * 2 : m_port_height;
|
|
||||||
pg->rect = r;
|
|
||||||
|
|
||||||
if (!pg->m_expanded) {
|
|
||||||
c->rect.width = pg->rect.left - c->rect.left + m_separation;
|
|
||||||
across.push_back(pg);
|
|
||||||
x += m_separation;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r.top += r.height;
|
|
||||||
r.width = m_separation;
|
|
||||||
r.height = m_port_height - r.height;
|
|
||||||
} else {
|
|
||||||
pg->rect = Rect::None;
|
|
||||||
|
|
||||||
r.top = m_padding + m_client_height;
|
|
||||||
r.width = m_separation;
|
|
||||||
r.height = m_port_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
|
|
||||||
r.left = x;
|
|
||||||
p->rect = r;
|
|
||||||
|
|
||||||
c->rect.width = p->rect.left - c->rect.left + m_separation;
|
|
||||||
if (pg->rect != Rect::None) {
|
|
||||||
pg->rect.width = p->rect.left - pg->rect.left + m_separation;
|
|
||||||
}
|
|
||||||
|
|
||||||
across.push_back(p);
|
|
||||||
x += m_separation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.left = m_padding;
|
|
||||||
r.top = y;
|
|
||||||
r.width = m_client_width;
|
|
||||||
r.height = -1;
|
|
||||||
c->rect = r;
|
|
||||||
|
|
||||||
if (!c->m_expanded) {
|
|
||||||
c->rect.width = m_client_width + m_port_width;
|
|
||||||
c->rect.height = m_separation;
|
|
||||||
down.push_back(c);
|
|
||||||
y += m_separation;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
|
|
||||||
if (pg->m_name != "") {
|
|
||||||
r.left = m_padding + m_client_width;
|
|
||||||
r.top = y;
|
|
||||||
r.width = pg->m_expanded ? pg->extents.width + m_padding * 2 : m_port_width;
|
|
||||||
r.height = pg->m_expanded ? m_separation * pg->m_ports.size() : m_separation;
|
|
||||||
pg->rect = r;
|
|
||||||
|
|
||||||
if (!pg->m_expanded) {
|
|
||||||
c->rect.height = pg->rect.top - c->rect.top + m_separation;
|
|
||||||
down.push_back(pg);
|
|
||||||
y += m_separation;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r.left += r.width;
|
|
||||||
r.width = m_port_width - r.width;
|
|
||||||
r.height = m_separation;
|
|
||||||
} else {
|
|
||||||
pg->rect = Rect::None;
|
|
||||||
|
|
||||||
r.left = m_padding + m_client_width;
|
|
||||||
r.width = m_port_width;
|
|
||||||
r.height = m_separation;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
|
|
||||||
r.top = y;
|
|
||||||
p->rect = r;
|
|
||||||
|
|
||||||
c->rect.height = p->rect.top - c->rect.top + m_separation;
|
|
||||||
if (pg->rect != Rect::None) {
|
|
||||||
pg->rect.height = p->rect.top - pg->rect.top + m_separation;
|
|
||||||
}
|
|
||||||
|
|
||||||
down.push_back(p);
|
|
||||||
y += m_separation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int w = m_padding * 2 + m_client_width + m_port_width;
|
|
||||||
int h = m_padding * 2 + m_client_height + m_port_height;
|
|
||||||
|
|
||||||
w += cols * m_separation;
|
|
||||||
h += rows * m_separation;
|
|
||||||
|
|
||||||
m_width = w;
|
|
||||||
m_height = h;
|
|
||||||
|
|
||||||
set_size_request(w, h);
|
|
||||||
parent->set_size_request(w + 20, h + 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Matrix::Box(Cairo::RefPtr<Cairo::Context> cr, float r, float g, float b, Rect &rect)
|
|
||||||
{
|
|
||||||
cr->set_source_rgb(r, g, b);
|
|
||||||
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
|
||||||
cr->fill();
|
|
||||||
|
|
||||||
cr->set_source_rgb(0.75, 0.75, 0.75);
|
|
||||||
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
|
||||||
cr->stroke();
|
|
||||||
|
|
||||||
cr->set_source_rgb(1, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Matrix::on_expose_event(GdkEventExpose *event)
|
|
||||||
{
|
|
||||||
Glib::RefPtr<Gdk::Window> window = get_window();
|
|
||||||
if (!window) return true;
|
|
||||||
|
|
||||||
if (m_client_width == 0) Refresh();
|
|
||||||
|
|
||||||
Gtk::Allocation allocation = get_allocation();
|
|
||||||
const int alloc_width = allocation.get_width();
|
|
||||||
const int alloc_height = allocation.get_height();
|
|
||||||
|
|
||||||
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
|
|
||||||
cr->set_line_width(1.0);
|
|
||||||
cr->set_antialias(Cairo::ANTIALIAS_NONE);
|
|
||||||
|
|
||||||
// Set clipping area
|
|
||||||
cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height);
|
|
||||||
cr->clip();
|
|
||||||
|
|
||||||
// Clear background
|
|
||||||
cr->set_source_rgb(0.25, 0.25, 0.25);
|
|
||||||
cr->rectangle(0, 0, alloc_width, alloc_height);
|
|
||||||
cr->fill();
|
|
||||||
|
|
||||||
cr->set_source_rgb(1, 1, 1);
|
|
||||||
cr->select_font_face(m_typeface, Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL);
|
|
||||||
cr->set_font_size(m_font_size);
|
|
||||||
|
|
||||||
Rect tr;
|
|
||||||
Rect &r = tr;
|
|
||||||
|
|
||||||
ClientList::iterator clit;
|
|
||||||
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
|
||||||
Client *c = *clit;
|
|
||||||
r = c->rect;
|
|
||||||
|
|
||||||
if (c->m_is_input) {
|
|
||||||
Box(cr, BACK_COLOUR, r);
|
|
||||||
|
|
||||||
cr->save();
|
|
||||||
cr->move_to(r.left + m_padding - c->extents.y_bearing, r.top + r.height - m_padding - c->extents.x_bearing);
|
|
||||||
cr->rotate(2 * M_PI * 0.75);
|
|
||||||
cr->show_text(c->m_name);
|
|
||||||
cr->restore();
|
|
||||||
|
|
||||||
if (!c->m_expanded) {
|
|
||||||
cr->set_source_rgb(GRID_CLIENT);
|
|
||||||
cr->move_to(r.left + r.width, r.top + r.height);
|
|
||||||
cr->line_to(r.left + r.width, m_height - m_padding);
|
|
||||||
cr->stroke();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroupList::iterator pglast = c->m_groups.end();
|
|
||||||
--pglast;
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
r = pg->rect;
|
|
||||||
|
|
||||||
if (pg->m_name != "") {
|
|
||||||
Box(cr, GROUP_COLOUR, r);
|
|
||||||
|
|
||||||
cr->save();
|
|
||||||
cr->move_to(r.left + m_padding - pg->extents.y_bearing, r.top + r.height - m_padding - pg->extents.x_bearing);
|
|
||||||
cr->rotate(2 * M_PI * 0.75);
|
|
||||||
cr->show_text(pg->m_name);
|
|
||||||
cr->restore();
|
|
||||||
|
|
||||||
if (!pg->m_expanded) {
|
|
||||||
if (pglit == pglast) {
|
|
||||||
cr->set_source_rgb(GRID_CLIENT);
|
|
||||||
} else {
|
|
||||||
cr->set_source_rgb(GRID_GROUP);
|
|
||||||
}
|
|
||||||
cr->move_to(r.left + r.width, r.top + r.height);
|
|
||||||
cr->line_to(r.left + r.width, m_height - m_padding);
|
|
||||||
cr->stroke();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PortList::iterator plast = pg->m_ports.end();
|
|
||||||
--plast;
|
|
||||||
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
r = p->rect;
|
|
||||||
|
|
||||||
if (p->m_is_midi) {
|
|
||||||
Box(cr, MIDI_COLOUR, r);
|
|
||||||
} else {
|
|
||||||
Box(cr, AUDIO_COLOUR, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
cr->save();
|
|
||||||
cr->move_to(r.left + m_padding - p->extents.y_bearing, r.top + r.height - m_padding - p->extents.x_bearing);
|
|
||||||
cr->rotate(2 * M_PI * 0.75);
|
|
||||||
cr->show_text(p->m_name);
|
|
||||||
cr->restore();
|
|
||||||
|
|
||||||
if (pglit == pglast && plit == plast) {
|
|
||||||
cr->set_source_rgb(GRID_CLIENT);
|
|
||||||
} else if (plit == plast) {
|
|
||||||
cr->set_source_rgb(GRID_GROUP);
|
|
||||||
} else {
|
|
||||||
cr->set_source_rgb(GRID_PORT);
|
|
||||||
}
|
|
||||||
cr->move_to(r.left + r.width, r.top + r.height);
|
|
||||||
cr->line_to(r.left + r.width, m_height - m_padding);
|
|
||||||
cr->stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Box(cr, BACK_COLOUR, r);
|
|
||||||
|
|
||||||
cr->move_to(r.left + m_padding - c->extents.x_bearing, r.top + m_padding - c->extents.y_bearing);
|
|
||||||
cr->show_text(c->m_name);
|
|
||||||
|
|
||||||
if (!c->m_expanded) {
|
|
||||||
cr->set_source_rgb(GRID_CLIENT);
|
|
||||||
cr->move_to(r.left + r.width, r.top + r.height);
|
|
||||||
cr->line_to(m_width - m_padding, r.top + r.height);
|
|
||||||
cr->stroke();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroupList::iterator pglast = c->m_groups.end();
|
|
||||||
--pglast;
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
r = pg->rect;
|
|
||||||
|
|
||||||
if (pg->m_name != "") {
|
|
||||||
Box(cr, GROUP_COLOUR, r);
|
|
||||||
cr->move_to(r.left + m_padding - pg->extents.x_bearing, r.top + m_padding - pg->extents.y_bearing);
|
|
||||||
cr->show_text(pg->m_name);
|
|
||||||
|
|
||||||
if (!pg->m_expanded) {
|
|
||||||
if (pglit == pglast) {
|
|
||||||
cr->set_source_rgb(GRID_CLIENT);
|
|
||||||
} else {
|
|
||||||
cr->set_source_rgb(GRID_GROUP);
|
|
||||||
}
|
|
||||||
cr->move_to(r.left + r.width, r.top + r.height);
|
|
||||||
cr->line_to(m_width - m_padding, r.top + r.height);
|
|
||||||
cr->stroke();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PortList::iterator plast = pg->m_ports.end();
|
|
||||||
--plast;
|
|
||||||
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
r = p->rect;
|
|
||||||
|
|
||||||
if (p->m_is_midi) {
|
|
||||||
Box(cr, MIDI_COLOUR, r);
|
|
||||||
} else {
|
|
||||||
Box(cr, AUDIO_COLOUR, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
cr->move_to(r.left + m_padding - p->extents.x_bearing, r.top + m_padding - p->extents.y_bearing);
|
|
||||||
cr->show_text(p->m_name);
|
|
||||||
|
|
||||||
if (pglit == pglast && plit == plast) {
|
|
||||||
cr->set_source_rgb(GRID_CLIENT);
|
|
||||||
} else if (plit == plast) {
|
|
||||||
cr->set_source_rgb(GRID_GROUP);
|
|
||||||
} else {
|
|
||||||
cr->set_source_rgb(GRID_PORT);
|
|
||||||
}
|
|
||||||
cr->move_to(r.left + r.width, r.top + r.height);
|
|
||||||
cr->line_to(m_width - m_padding, r.top + r.height);
|
|
||||||
cr->stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = m_client_width + m_port_width + m_padding;
|
|
||||||
BaseList::iterator bit1;
|
|
||||||
for (bit1 = across.begin(); bit1 != across.end(); ++bit1) {
|
|
||||||
BaseList::iterator bit2;
|
|
||||||
Base *b1 = *bit1;
|
|
||||||
|
|
||||||
int y = m_client_height + m_port_height + m_padding;
|
|
||||||
for (bit2 = down.begin(); bit2 != down.end(); ++bit2) {
|
|
||||||
Base *b2 = *bit2;
|
|
||||||
|
|
||||||
ConnectionMode cm = b1->ConnectedTo(b2);
|
|
||||||
|
|
||||||
if (cm != CM_NONE) {
|
|
||||||
// if (p1->m_is_midi) {
|
|
||||||
// cr->set_source_rgb(MIDI_COLOUR);
|
|
||||||
// } else {
|
|
||||||
cr->set_source_rgb(AUDIO_COLOUR);
|
|
||||||
// }
|
|
||||||
cr->rectangle(x + 1, y + 1, m_separation - 1, m_separation - 1);
|
|
||||||
cr->fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
y += m_separation;
|
|
||||||
}
|
|
||||||
|
|
||||||
x += m_separation;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
PortList::iterator plit1;
|
|
||||||
for (plit1 = pm.m_ports.begin(); plit1 != pm.m_ports.end(); ++plit1) {
|
|
||||||
Port *p1 = *plit1;
|
|
||||||
if (p1->pos == 0) continue;
|
|
||||||
PortList::iterator plit2;
|
|
||||||
for (plit2 = p1->m_connections.begin(); plit2 != p1->m_connections.end(); ++plit2) {
|
|
||||||
Port *p2 = *plit2;
|
|
||||||
if (p2->pos == 0) continue;
|
|
||||||
// cr->imove_to(p2->pos, p1->pos);
|
|
||||||
// cr->arc(p1->pos, p2->pos, (m_separation - m_padding * 2) / 2.0, 0, 2 * M_PI);
|
|
||||||
if (p1->m_is_midi) {
|
|
||||||
cr->set_source_rgb(MIDI_COLOUR);
|
|
||||||
} else {
|
|
||||||
cr->set_source_rgb(AUDIO_COLOUR);
|
|
||||||
}
|
|
||||||
cr->rectangle(p1->pos + 1, p2->pos + 1, m_separation - 1, m_separation - 1);
|
|
||||||
cr->fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Matrix::on_button_press_event(GdkEventButton *event)
|
|
||||||
{
|
|
||||||
// Check expandable boxes
|
|
||||||
ClientList::iterator clit;
|
|
||||||
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
|
||||||
Client *c = *clit;
|
|
||||||
if (c->rect.Hit(event->x, event->y)) {
|
|
||||||
c->m_expanded = !c->m_expanded;
|
|
||||||
Refresh();
|
|
||||||
queue_draw();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
if (pg->rect.Hit(event->x, event->y)) {
|
|
||||||
pg->m_expanded = !pg->m_expanded;
|
|
||||||
Refresh();
|
|
||||||
queue_draw();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Port *p1 = NULL;
|
|
||||||
Port *p2 = NULL;
|
|
||||||
|
|
||||||
// Check port hit
|
|
||||||
PortList::iterator plit;
|
|
||||||
for (plit = pm.m_ports.begin(); plit != pm.m_ports.end(); ++plit) {
|
|
||||||
Port *p = *plit;
|
|
||||||
|
|
||||||
if (p->rect.HitX(event->x)) p1 = p;
|
|
||||||
if (p->rect.HitY(event->y)) p2 = p;
|
|
||||||
|
|
||||||
if (p1 != NULL && p2 != NULL) {
|
|
||||||
pm.ToggleConnect(p1, p2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PortGroup *pg1 = NULL;
|
|
||||||
PortGroup *pg2 = NULL;
|
|
||||||
|
|
||||||
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
|
||||||
Client *c = *clit;
|
|
||||||
|
|
||||||
PortGroupList::iterator pglit;
|
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
|
||||||
PortGroup *pg = *pglit;
|
|
||||||
|
|
||||||
if (pg->rect.HitX(event->x)) pg1 = pg;
|
|
||||||
if (pg->rect.HitY(event->y)) pg2 = pg;
|
|
||||||
|
|
||||||
if (p1 != NULL && pg2 != NULL) {
|
|
||||||
pm.ToggleConnect(p1, pg2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (pg1 != NULL && p2 != NULL) {
|
|
||||||
pm.ToggleConnect(pg1, p2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (pg1 != NULL && pg2 != NULL) {
|
|
||||||
pm.ToggleConnect(pg1, pg2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << event->x << ", " << event->y << std::endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Gui::Gui()
|
Gui::Gui()
|
||||||
{
|
{
|
||||||
set_title("JACK Sweeper");
|
set_title("JACK Sweeper");
|
||||||
|
|
46
src/gui.h
46
src/gui.h
|
@ -2,51 +2,7 @@
|
||||||
#define GUI_H
|
#define GUI_H
|
||||||
|
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
#include <list>
|
#include "matrix.h"
|
||||||
#include "rect.h"
|
|
||||||
|
|
||||||
#define BACK_COLOUR 0.1020, 0.1059, 0.1059
|
|
||||||
#define MIDI_COLOUR 0.3098, 0.1882, 0.1882
|
|
||||||
#define AUDIO_COLOUR 0.1608, 0.2510, 0.3373
|
|
||||||
#define GROUP_COLOUR 0.1608, 0.3373, 0.1647
|
|
||||||
|
|
||||||
#define GRID_CLIENT 0.00, 0.00, 0.00
|
|
||||||
#define GRID_GROUP 0.10, 0.10, 0.10
|
|
||||||
#define GRID_PORT 0.20, 0.20, 0.20
|
|
||||||
|
|
||||||
typedef std::list<Base *> BaseList;
|
|
||||||
|
|
||||||
class Matrix : public Gtk::DrawingArea
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int m_client_width;
|
|
||||||
int m_client_height;
|
|
||||||
int m_port_width;
|
|
||||||
int m_port_height;
|
|
||||||
int m_separation;
|
|
||||||
int m_padding;
|
|
||||||
int m_width;
|
|
||||||
int m_height;
|
|
||||||
|
|
||||||
int m_font_size;
|
|
||||||
std::string m_typeface;
|
|
||||||
|
|
||||||
BaseList across;
|
|
||||||
BaseList down;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Matrix();
|
|
||||||
virtual ~Matrix();
|
|
||||||
|
|
||||||
void Refresh();
|
|
||||||
|
|
||||||
Gtk::Window *parent;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Box(Cairo::RefPtr<Cairo::Context> cr, float r, float g, float b, Rect &rect);
|
|
||||||
virtual bool on_expose_event(GdkEventExpose *event);
|
|
||||||
virtual bool on_button_press_event(GdkEventButton *event);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Gui : public Gtk::Window
|
class Gui : public Gtk::Window
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,612 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "jack.h"
|
||||||
|
#include "portmanager.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
const Rect Rect::None = Rect(0, 0, -1, -1);
|
||||||
|
|
||||||
|
Matrix::Matrix() :
|
||||||
|
m_client_width(0), m_client_height(0), m_port_width(0), m_port_height(0), m_separation(0), m_padding(cfg.CellPadding),
|
||||||
|
m_font_size(cfg.FontSize), m_typeface(cfg.FontFace)
|
||||||
|
{
|
||||||
|
set_size_request(0, 0);
|
||||||
|
show();
|
||||||
|
|
||||||
|
add_events(Gdk::BUTTON_PRESS_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix::~Matrix()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix::Refresh()
|
||||||
|
{
|
||||||
|
Glib::RefPtr<Gdk::Window> window = get_window();
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
m_client_width = 0;
|
||||||
|
m_client_height = 0;
|
||||||
|
m_port_width = 0;
|
||||||
|
m_port_height = 0;
|
||||||
|
|
||||||
|
m_separation = 0;
|
||||||
|
|
||||||
|
pm.Sort();
|
||||||
|
|
||||||
|
int cols = 0;
|
||||||
|
int rows = 0;
|
||||||
|
|
||||||
|
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
|
||||||
|
cr->select_font_face(m_typeface, Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL);
|
||||||
|
cr->set_font_size(m_font_size);
|
||||||
|
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pm.m_ports.begin(); plit != pm.m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
p->rect = Rect::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientList::iterator clit;
|
||||||
|
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
||||||
|
Client *c = *clit;
|
||||||
|
|
||||||
|
cr->get_text_extents(c->m_name, c->extents);
|
||||||
|
|
||||||
|
int width = c->extents.width + m_padding * 2;
|
||||||
|
if (c->m_is_input) {
|
||||||
|
if (width > m_client_height) m_client_height = width;
|
||||||
|
} else {
|
||||||
|
if (width > m_client_width) m_client_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->extents.height > m_separation) m_separation = c->extents.height;
|
||||||
|
|
||||||
|
if (!c->m_expanded) {
|
||||||
|
if (c->m_is_input) {
|
||||||
|
cols++;
|
||||||
|
} else {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
pg->rect = Rect::None;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
|
||||||
|
cr->get_text_extents(pg->m_name, pg->extents);
|
||||||
|
if (pg->extents.height > m_separation) m_separation = pg->extents.height;
|
||||||
|
|
||||||
|
if (!pg->m_expanded && pg->m_name != "") {
|
||||||
|
int width = pg->extents.width + m_padding * 2;
|
||||||
|
if (c->m_is_input) {
|
||||||
|
if (width > m_port_height) m_port_height = width;
|
||||||
|
cols++;
|
||||||
|
} else {
|
||||||
|
if (width > m_port_width) m_port_width = width;
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
|
||||||
|
cr->get_text_extents(p->m_name, p->extents);
|
||||||
|
|
||||||
|
int width = pg->extents.width + p->extents.width + m_padding * (pg->extents.width > 0 ? 4 : 2);
|
||||||
|
if (p->m_flags & JackPortIsInput) {
|
||||||
|
if (width > m_port_height) m_port_height = width;
|
||||||
|
cols++;
|
||||||
|
} else {
|
||||||
|
if (width > m_port_width) m_port_width = width;
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->extents.height > m_separation) m_separation = p->extents.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pm.m_ports.begin(); plit != pm.m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
|
||||||
|
cr->get_text_extents(p->m_name, p->extents);
|
||||||
|
|
||||||
|
if (p->m_flags & JackPortIsInput) {
|
||||||
|
if (p->extents.width > m_port_height) m_port_height = p->extents.width;
|
||||||
|
} else {
|
||||||
|
if (p->extents.width > m_port_width) m_port_width = p->extents.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->extents.height > m_separation) m_separation = p->extents.height;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
m_separation += m_padding * 2;
|
||||||
|
|
||||||
|
// if (m_port_width > m_separation * 5) m_port_width = m_separation * 5;
|
||||||
|
// if (m_port_height > m_separation * 5) m_port_height = m_separation * 5;
|
||||||
|
|
||||||
|
int y = m_client_height + m_port_height + m_padding;
|
||||||
|
int x = m_client_width + m_port_width + m_padding;
|
||||||
|
|
||||||
|
across.clear();
|
||||||
|
down.clear();
|
||||||
|
|
||||||
|
Rect r;
|
||||||
|
|
||||||
|
// ClientList::iterator clit;
|
||||||
|
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
||||||
|
Client *c = *clit;
|
||||||
|
|
||||||
|
if (c->m_is_input) {
|
||||||
|
r.left = x;
|
||||||
|
r.top = m_padding;
|
||||||
|
r.width = -1;
|
||||||
|
r.height = m_client_height;
|
||||||
|
c->rect = r;
|
||||||
|
|
||||||
|
if (!c->m_expanded) {
|
||||||
|
c->rect.width = m_separation;
|
||||||
|
c->rect.height = m_client_height + m_port_height;
|
||||||
|
across.push_back(c);
|
||||||
|
x += m_separation;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
|
||||||
|
if (pg->m_name != "") {
|
||||||
|
r.left = x;
|
||||||
|
r.top = m_padding + m_client_height;
|
||||||
|
r.width = pg->m_expanded ? m_separation * pg->m_ports.size() : m_separation;
|
||||||
|
r.height = pg->m_expanded ? pg->extents.width + m_padding * 2 : m_port_height;
|
||||||
|
pg->rect = r;
|
||||||
|
|
||||||
|
if (!pg->m_expanded) {
|
||||||
|
c->rect.width = pg->rect.left - c->rect.left + m_separation;
|
||||||
|
across.push_back(pg);
|
||||||
|
x += m_separation;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.top += r.height;
|
||||||
|
r.width = m_separation;
|
||||||
|
r.height = m_port_height - r.height;
|
||||||
|
} else {
|
||||||
|
pg->rect = Rect::None;
|
||||||
|
|
||||||
|
r.top = m_padding + m_client_height;
|
||||||
|
r.width = m_separation;
|
||||||
|
r.height = m_port_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
|
||||||
|
r.left = x;
|
||||||
|
p->rect = r;
|
||||||
|
|
||||||
|
c->rect.width = p->rect.left - c->rect.left + m_separation;
|
||||||
|
if (pg->rect != Rect::None) {
|
||||||
|
pg->rect.width = p->rect.left - pg->rect.left + m_separation;
|
||||||
|
}
|
||||||
|
|
||||||
|
across.push_back(p);
|
||||||
|
x += m_separation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r.left = m_padding;
|
||||||
|
r.top = y;
|
||||||
|
r.width = m_client_width;
|
||||||
|
r.height = -1;
|
||||||
|
c->rect = r;
|
||||||
|
|
||||||
|
if (!c->m_expanded) {
|
||||||
|
c->rect.width = m_client_width + m_port_width;
|
||||||
|
c->rect.height = m_separation;
|
||||||
|
down.push_back(c);
|
||||||
|
y += m_separation;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
|
||||||
|
if (pg->m_name != "") {
|
||||||
|
r.left = m_padding + m_client_width;
|
||||||
|
r.top = y;
|
||||||
|
r.width = pg->m_expanded ? pg->extents.width + m_padding * 2 : m_port_width;
|
||||||
|
r.height = pg->m_expanded ? m_separation * pg->m_ports.size() : m_separation;
|
||||||
|
pg->rect = r;
|
||||||
|
|
||||||
|
if (!pg->m_expanded) {
|
||||||
|
c->rect.height = pg->rect.top - c->rect.top + m_separation;
|
||||||
|
down.push_back(pg);
|
||||||
|
y += m_separation;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.left += r.width;
|
||||||
|
r.width = m_port_width - r.width;
|
||||||
|
r.height = m_separation;
|
||||||
|
} else {
|
||||||
|
pg->rect = Rect::None;
|
||||||
|
|
||||||
|
r.left = m_padding + m_client_width;
|
||||||
|
r.width = m_port_width;
|
||||||
|
r.height = m_separation;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
|
||||||
|
r.top = y;
|
||||||
|
p->rect = r;
|
||||||
|
|
||||||
|
c->rect.height = p->rect.top - c->rect.top + m_separation;
|
||||||
|
if (pg->rect != Rect::None) {
|
||||||
|
pg->rect.height = p->rect.top - pg->rect.top + m_separation;
|
||||||
|
}
|
||||||
|
|
||||||
|
down.push_back(p);
|
||||||
|
y += m_separation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = m_padding * 2 + m_client_width + m_port_width;
|
||||||
|
int h = m_padding * 2 + m_client_height + m_port_height;
|
||||||
|
|
||||||
|
w += cols * m_separation;
|
||||||
|
h += rows * m_separation;
|
||||||
|
|
||||||
|
m_width = w;
|
||||||
|
m_height = h;
|
||||||
|
|
||||||
|
set_size_request(w, h);
|
||||||
|
parent->set_size_request(w + 20, h + 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix::Box(Cairo::RefPtr<Cairo::Context> cr, float r, float g, float b, Rect &rect)
|
||||||
|
{
|
||||||
|
cr->set_source_rgb(r, g, b);
|
||||||
|
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
|
cr->set_source_rgb(0.75, 0.75, 0.75);
|
||||||
|
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
||||||
|
cr->stroke();
|
||||||
|
|
||||||
|
cr->set_source_rgb(1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
|
{
|
||||||
|
Glib::RefPtr<Gdk::Window> window = get_window();
|
||||||
|
if (!window) return true;
|
||||||
|
|
||||||
|
if (m_client_width == 0) Refresh();
|
||||||
|
|
||||||
|
Gtk::Allocation allocation = get_allocation();
|
||||||
|
const int alloc_width = allocation.get_width();
|
||||||
|
const int alloc_height = allocation.get_height();
|
||||||
|
|
||||||
|
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
|
||||||
|
cr->set_line_width(1.0);
|
||||||
|
cr->set_antialias(Cairo::ANTIALIAS_NONE);
|
||||||
|
|
||||||
|
// Set clipping area
|
||||||
|
cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height);
|
||||||
|
cr->clip();
|
||||||
|
|
||||||
|
// Clear background
|
||||||
|
cr->set_source_rgb(0.25, 0.25, 0.25);
|
||||||
|
cr->rectangle(0, 0, alloc_width, alloc_height);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
|
cr->set_source_rgb(1, 1, 1);
|
||||||
|
cr->select_font_face(m_typeface, Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL);
|
||||||
|
cr->set_font_size(m_font_size);
|
||||||
|
|
||||||
|
Rect tr;
|
||||||
|
Rect &r = tr;
|
||||||
|
|
||||||
|
ClientList::iterator clit;
|
||||||
|
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
||||||
|
Client *c = *clit;
|
||||||
|
r = c->rect;
|
||||||
|
|
||||||
|
if (c->m_is_input) {
|
||||||
|
Box(cr, BACK_COLOUR, r);
|
||||||
|
|
||||||
|
cr->save();
|
||||||
|
cr->move_to(r.left + m_padding - c->extents.y_bearing, r.top + r.height - m_padding - c->extents.x_bearing);
|
||||||
|
cr->rotate(2 * M_PI * 0.75);
|
||||||
|
cr->show_text(c->m_name);
|
||||||
|
cr->restore();
|
||||||
|
|
||||||
|
if (!c->m_expanded) {
|
||||||
|
cr->set_source_rgb(GRID_CLIENT);
|
||||||
|
cr->move_to(r.left + r.width, r.top + r.height);
|
||||||
|
cr->line_to(r.left + r.width, m_height - m_padding);
|
||||||
|
cr->stroke();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroupList::iterator pglast = c->m_groups.end();
|
||||||
|
--pglast;
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
r = pg->rect;
|
||||||
|
|
||||||
|
if (pg->m_name != "") {
|
||||||
|
Box(cr, GROUP_COLOUR, r);
|
||||||
|
|
||||||
|
cr->save();
|
||||||
|
cr->move_to(r.left + m_padding - pg->extents.y_bearing, r.top + r.height - m_padding - pg->extents.x_bearing);
|
||||||
|
cr->rotate(2 * M_PI * 0.75);
|
||||||
|
cr->show_text(pg->m_name);
|
||||||
|
cr->restore();
|
||||||
|
|
||||||
|
if (!pg->m_expanded) {
|
||||||
|
if (pglit == pglast) {
|
||||||
|
cr->set_source_rgb(GRID_CLIENT);
|
||||||
|
} else {
|
||||||
|
cr->set_source_rgb(GRID_GROUP);
|
||||||
|
}
|
||||||
|
cr->move_to(r.left + r.width, r.top + r.height);
|
||||||
|
cr->line_to(r.left + r.width, m_height - m_padding);
|
||||||
|
cr->stroke();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PortList::iterator plast = pg->m_ports.end();
|
||||||
|
--plast;
|
||||||
|
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
r = p->rect;
|
||||||
|
|
||||||
|
if (p->m_is_midi) {
|
||||||
|
Box(cr, MIDI_COLOUR, r);
|
||||||
|
} else {
|
||||||
|
Box(cr, AUDIO_COLOUR, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
cr->save();
|
||||||
|
cr->move_to(r.left + m_padding - p->extents.y_bearing, r.top + r.height - m_padding - p->extents.x_bearing);
|
||||||
|
cr->rotate(2 * M_PI * 0.75);
|
||||||
|
cr->show_text(p->m_name);
|
||||||
|
cr->restore();
|
||||||
|
|
||||||
|
if (pglit == pglast && plit == plast) {
|
||||||
|
cr->set_source_rgb(GRID_CLIENT);
|
||||||
|
} else if (plit == plast) {
|
||||||
|
cr->set_source_rgb(GRID_GROUP);
|
||||||
|
} else {
|
||||||
|
cr->set_source_rgb(GRID_PORT);
|
||||||
|
}
|
||||||
|
cr->move_to(r.left + r.width, r.top + r.height);
|
||||||
|
cr->line_to(r.left + r.width, m_height - m_padding);
|
||||||
|
cr->stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Box(cr, BACK_COLOUR, r);
|
||||||
|
|
||||||
|
cr->move_to(r.left + m_padding - c->extents.x_bearing, r.top + m_padding - c->extents.y_bearing);
|
||||||
|
cr->show_text(c->m_name);
|
||||||
|
|
||||||
|
if (!c->m_expanded) {
|
||||||
|
cr->set_source_rgb(GRID_CLIENT);
|
||||||
|
cr->move_to(r.left + r.width, r.top + r.height);
|
||||||
|
cr->line_to(m_width - m_padding, r.top + r.height);
|
||||||
|
cr->stroke();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroupList::iterator pglast = c->m_groups.end();
|
||||||
|
--pglast;
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
r = pg->rect;
|
||||||
|
|
||||||
|
if (pg->m_name != "") {
|
||||||
|
Box(cr, GROUP_COLOUR, r);
|
||||||
|
cr->move_to(r.left + m_padding - pg->extents.x_bearing, r.top + m_padding - pg->extents.y_bearing);
|
||||||
|
cr->show_text(pg->m_name);
|
||||||
|
|
||||||
|
if (!pg->m_expanded) {
|
||||||
|
if (pglit == pglast) {
|
||||||
|
cr->set_source_rgb(GRID_CLIENT);
|
||||||
|
} else {
|
||||||
|
cr->set_source_rgb(GRID_GROUP);
|
||||||
|
}
|
||||||
|
cr->move_to(r.left + r.width, r.top + r.height);
|
||||||
|
cr->line_to(m_width - m_padding, r.top + r.height);
|
||||||
|
cr->stroke();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PortList::iterator plast = pg->m_ports.end();
|
||||||
|
--plast;
|
||||||
|
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
r = p->rect;
|
||||||
|
|
||||||
|
if (p->m_is_midi) {
|
||||||
|
Box(cr, MIDI_COLOUR, r);
|
||||||
|
} else {
|
||||||
|
Box(cr, AUDIO_COLOUR, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
cr->move_to(r.left + m_padding - p->extents.x_bearing, r.top + m_padding - p->extents.y_bearing);
|
||||||
|
cr->show_text(p->m_name);
|
||||||
|
|
||||||
|
if (pglit == pglast && plit == plast) {
|
||||||
|
cr->set_source_rgb(GRID_CLIENT);
|
||||||
|
} else if (plit == plast) {
|
||||||
|
cr->set_source_rgb(GRID_GROUP);
|
||||||
|
} else {
|
||||||
|
cr->set_source_rgb(GRID_PORT);
|
||||||
|
}
|
||||||
|
cr->move_to(r.left + r.width, r.top + r.height);
|
||||||
|
cr->line_to(m_width - m_padding, r.top + r.height);
|
||||||
|
cr->stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = m_client_width + m_port_width + m_padding;
|
||||||
|
BaseList::iterator bit1;
|
||||||
|
for (bit1 = across.begin(); bit1 != across.end(); ++bit1) {
|
||||||
|
BaseList::iterator bit2;
|
||||||
|
Base *b1 = *bit1;
|
||||||
|
|
||||||
|
int y = m_client_height + m_port_height + m_padding;
|
||||||
|
for (bit2 = down.begin(); bit2 != down.end(); ++bit2) {
|
||||||
|
Base *b2 = *bit2;
|
||||||
|
|
||||||
|
ConnectionMode cm = b1->ConnectedTo(b2);
|
||||||
|
|
||||||
|
if (cm != CM_NONE) {
|
||||||
|
// if (p1->m_is_midi) {
|
||||||
|
// cr->set_source_rgb(MIDI_COLOUR);
|
||||||
|
// } else {
|
||||||
|
cr->set_source_rgb(AUDIO_COLOUR);
|
||||||
|
// }
|
||||||
|
cr->rectangle(x + 1, y + 1, m_separation - 1, m_separation - 1);
|
||||||
|
cr->fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
y += m_separation;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += m_separation;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
PortList::iterator plit1;
|
||||||
|
for (plit1 = pm.m_ports.begin(); plit1 != pm.m_ports.end(); ++plit1) {
|
||||||
|
Port *p1 = *plit1;
|
||||||
|
if (p1->pos == 0) continue;
|
||||||
|
PortList::iterator plit2;
|
||||||
|
for (plit2 = p1->m_connections.begin(); plit2 != p1->m_connections.end(); ++plit2) {
|
||||||
|
Port *p2 = *plit2;
|
||||||
|
if (p2->pos == 0) continue;
|
||||||
|
// cr->imove_to(p2->pos, p1->pos);
|
||||||
|
// cr->arc(p1->pos, p2->pos, (m_separation - m_padding * 2) / 2.0, 0, 2 * M_PI);
|
||||||
|
if (p1->m_is_midi) {
|
||||||
|
cr->set_source_rgb(MIDI_COLOUR);
|
||||||
|
} else {
|
||||||
|
cr->set_source_rgb(AUDIO_COLOUR);
|
||||||
|
}
|
||||||
|
cr->rectangle(p1->pos + 1, p2->pos + 1, m_separation - 1, m_separation - 1);
|
||||||
|
cr->fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
|
{
|
||||||
|
// Check expandable boxes
|
||||||
|
ClientList::iterator clit;
|
||||||
|
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
||||||
|
Client *c = *clit;
|
||||||
|
if (c->rect.Hit(event->x, event->y)) {
|
||||||
|
c->m_expanded = !c->m_expanded;
|
||||||
|
Refresh();
|
||||||
|
queue_draw();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
if (pg->rect.Hit(event->x, event->y)) {
|
||||||
|
pg->m_expanded = !pg->m_expanded;
|
||||||
|
Refresh();
|
||||||
|
queue_draw();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Port *p1 = NULL;
|
||||||
|
Port *p2 = NULL;
|
||||||
|
|
||||||
|
// Check port hit
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pm.m_ports.begin(); plit != pm.m_ports.end(); ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
|
||||||
|
if (p->rect.HitX(event->x)) p1 = p;
|
||||||
|
if (p->rect.HitY(event->y)) p2 = p;
|
||||||
|
|
||||||
|
if (p1 != NULL && p2 != NULL) {
|
||||||
|
pm.ToggleConnect(p1, p2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PortGroup *pg1 = NULL;
|
||||||
|
PortGroup *pg2 = NULL;
|
||||||
|
|
||||||
|
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
||||||
|
Client *c = *clit;
|
||||||
|
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
|
||||||
|
if (pg->rect.HitX(event->x)) pg1 = pg;
|
||||||
|
if (pg->rect.HitY(event->y)) pg2 = pg;
|
||||||
|
|
||||||
|
if (p1 != NULL && pg2 != NULL) {
|
||||||
|
pm.ToggleConnect(p1, pg2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (pg1 != NULL && p2 != NULL) {
|
||||||
|
pm.ToggleConnect(pg1, p2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (pg1 != NULL && pg2 != NULL) {
|
||||||
|
pm.ToggleConnect(pg1, pg2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << event->x << ", " << event->y << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef MATRIX_H
|
||||||
|
#define MATRIX_H
|
||||||
|
|
||||||
|
#include <gtkmm.h>
|
||||||
|
#include <list>
|
||||||
|
#include "rect.h"
|
||||||
|
|
||||||
|
#define BACK_COLOUR 0.1020, 0.1059, 0.1059
|
||||||
|
#define MIDI_COLOUR 0.3098, 0.1882, 0.1882
|
||||||
|
#define AUDIO_COLOUR 0.1608, 0.2510, 0.3373
|
||||||
|
#define GROUP_COLOUR 0.1608, 0.3373, 0.1647
|
||||||
|
|
||||||
|
#define GRID_CLIENT 0.00, 0.00, 0.00
|
||||||
|
#define GRID_GROUP 0.10, 0.10, 0.10
|
||||||
|
#define GRID_PORT 0.20, 0.20, 0.20
|
||||||
|
|
||||||
|
typedef std::list<Base *> BaseList;
|
||||||
|
|
||||||
|
class Matrix : public Gtk::DrawingArea
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int m_client_width;
|
||||||
|
int m_client_height;
|
||||||
|
int m_port_width;
|
||||||
|
int m_port_height;
|
||||||
|
int m_separation;
|
||||||
|
int m_padding;
|
||||||
|
int m_width;
|
||||||
|
int m_height;
|
||||||
|
|
||||||
|
int m_font_size;
|
||||||
|
std::string m_typeface;
|
||||||
|
|
||||||
|
BaseList across;
|
||||||
|
BaseList down;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Matrix();
|
||||||
|
virtual ~Matrix();
|
||||||
|
|
||||||
|
void Refresh();
|
||||||
|
|
||||||
|
Gtk::Window *parent;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Box(Cairo::RefPtr<Cairo::Context> cr, float r, float g, float b, Rect &rect);
|
||||||
|
virtual bool on_expose_event(GdkEventExpose *event);
|
||||||
|
virtual bool on_button_press_event(GdkEventButton *event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MATRIX_H
|
Loading…
Reference in New Issue