From 5249fa7d89dfa19575b317241f1869da9e429614 Mon Sep 17 00:00:00 2001 From: petern Date: Thu, 26 Nov 2009 07:47:47 +0000 Subject: [PATCH] Split matrix widget code to separate file git-svn-id: file:///home/vcs/svn/jsweeper/trunk@3 6611ac79-6612-48ef-a1e9-b906f853523e --- CMakeLists.txt | 2 + src/gui.cpp | 605 ------------------------------------------------ src/gui.h | 46 +--- src/matrix.cpp | 612 +++++++++++++++++++++++++++++++++++++++++++++++++ src/matrix.h | 51 +++++ 5 files changed, 666 insertions(+), 650 deletions(-) create mode 100644 src/matrix.cpp create mode 100644 src/matrix.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7aeec68..a0b6aaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ SET(SOURCES src/jack.cpp src/jack.h src/jsweeper.cpp + src/matrix.cpp + src/matrix.h src/port.cpp src/port.h src/portmanager.cpp diff --git a/src/gui.cpp b/src/gui.cpp index afd6ad5..72fc238 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -6,611 +6,6 @@ #include "gui.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 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 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 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 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 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() { set_title("JACK Sweeper"); diff --git a/src/gui.h b/src/gui.h index 2b069d8..88d8b92 100644 --- a/src/gui.h +++ b/src/gui.h @@ -2,51 +2,7 @@ #define GUI_H #include -#include -#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 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 cr, float r, float g, float b, Rect &rect); - virtual bool on_expose_event(GdkEventExpose *event); - virtual bool on_button_press_event(GdkEventButton *event); -}; +#include "matrix.h" class Gui : public Gtk::Window { diff --git a/src/matrix.cpp b/src/matrix.cpp new file mode 100644 index 0000000..a51983a --- /dev/null +++ b/src/matrix.cpp @@ -0,0 +1,612 @@ +#include +#include +#include +#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 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 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 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 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 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; +} diff --git a/src/matrix.h b/src/matrix.h new file mode 100644 index 0000000..ebb69e8 --- /dev/null +++ b/src/matrix.h @@ -0,0 +1,51 @@ +#ifndef MATRIX_H +#define MATRIX_H + +#include +#include +#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 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 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