Gui changes - highlight tabs on pointer motion
Use inheritance for common base properties git-svn-id: file:///home/vcs/svn/jsweeper/trunk@22 6611ac79-6612-48ef-a1e9-b906f853523emaster
parent
93688e170f
commit
962e84ba07
12
src/colour.h
12
src/colour.h
|
@ -13,6 +13,18 @@ struct Colour
|
||||||
Colour();
|
Colour();
|
||||||
Colour(std::string Code);
|
Colour(std::string Code);
|
||||||
std::string ToCode() const;
|
std::string ToCode() const;
|
||||||
|
|
||||||
|
const Colour operator *(float scale) const
|
||||||
|
{
|
||||||
|
Colour res = *this;
|
||||||
|
res.r *= scale;
|
||||||
|
res.g *= scale;
|
||||||
|
res.b *= scale;
|
||||||
|
if (res.r > 1.0) res.r = 1.0;
|
||||||
|
if (res.g > 1.0) res.g = 1.0;
|
||||||
|
if (res.b > 1.0) res.b = 1.0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COLOUR_H
|
#endif // COLOUR_H
|
||||||
|
|
|
@ -87,7 +87,7 @@ void Config::Write()
|
||||||
AliasList::const_iterator it;
|
AliasList::const_iterator it;
|
||||||
for (it = list.begin(); it != list.end(); ++it) {
|
for (it = list.begin(); it != list.end(); ++it) {
|
||||||
const Alias &a = *it;
|
const Alias &a = *it;
|
||||||
group->SetValue(a.match, a.replace);
|
group->SetValue(a.m_match, a.m_replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
ini.SaveToDisk(m_filename);
|
ini.SaveToDisk(m_filename);
|
||||||
|
|
176
src/matrix.cpp
176
src/matrix.cpp
|
@ -9,12 +9,13 @@
|
||||||
const Rect Rect::None = Rect(0, 0, -1, -1);
|
const Rect Rect::None = Rect(0, 0, -1, -1);
|
||||||
|
|
||||||
Matrix::Matrix(PortType port_type) :
|
Matrix::Matrix(PortType port_type) :
|
||||||
m_client_width(0), m_client_height(0), m_port_width(0), m_port_height(0), m_separation(0), m_port_type(port_type)
|
m_client_width(0), m_client_height(0), m_port_width(0), m_port_height(0), m_separation(0), m_x_rect(Rect::None), m_y_rect(Rect::None), m_port_type(port_type)
|
||||||
{
|
{
|
||||||
set_size_request(0, 0);
|
set_size_request(0, 0);
|
||||||
show();
|
show();
|
||||||
|
|
||||||
add_events(Gdk::BUTTON_PRESS_MASK);
|
add_events(Gdk::BUTTON_PRESS_MASK);
|
||||||
|
add_events(Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix::~Matrix()
|
Matrix::~Matrix()
|
||||||
|
@ -109,7 +110,7 @@ void Matrix::Refresh()
|
||||||
cr->get_text_extents(p->m_name, p->extents);
|
cr->get_text_extents(p->m_name, p->extents);
|
||||||
|
|
||||||
int width = pg->extents.width + p->extents.width + cfg.CellPadding * (pg->extents.width > 0 ? 4 : 2);
|
int width = pg->extents.width + p->extents.width + cfg.CellPadding * (pg->extents.width > 0 ? 4 : 2);
|
||||||
if (p->m_flags & JackPortIsInput) {
|
if (p->m_is_input) {
|
||||||
if (width > m_port_height) m_port_height = width;
|
if (width > m_port_height) m_port_height = width;
|
||||||
cols++;
|
cols++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -291,22 +292,26 @@ void Matrix::Refresh()
|
||||||
set_size_request(w, h);
|
set_size_request(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetColour(Cairo::RefPtr<Cairo::Context> cr, Colour &c)
|
static void SetColour(Cairo::RefPtr<Cairo::Context> cr, Colour c)
|
||||||
{
|
{
|
||||||
cr->set_source_rgb(c.r, c.g, c.b);
|
cr->set_source_rgb(c.r, c.g, c.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Matrix::Box(Cairo::RefPtr<Cairo::Context> cr, Colour &c, Rect &rect)
|
void Matrix::Box(Cairo::RefPtr<Cairo::Context> cr, Colour &c, Rect &rect, bool highlight)
|
||||||
{
|
{
|
||||||
SetColour(cr, c);
|
SetColour(cr, c * (highlight ? 1.5 : 1.0));
|
||||||
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
||||||
cr->fill();
|
cr->fill();
|
||||||
|
|
||||||
cr->set_source_rgb(0.75, 0.75, 0.75);
|
if (highlight) {
|
||||||
|
cr->set_source_rgb(1.0, 1.0, 1.0);
|
||||||
|
} else {
|
||||||
|
cr->set_source_rgb(0.75, 0.75, 0.75);
|
||||||
|
}
|
||||||
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
cr->rectangle(rect.left, rect.top, rect.width, rect.height);
|
||||||
cr->stroke();
|
cr->stroke();
|
||||||
|
|
||||||
SetColour(cr, cfg.Text);
|
SetColour(cr, cfg.Text * (highlight ? 1.5 : 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Matrix::on_expose_event(GdkEventExpose *event)
|
bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
|
@ -351,7 +356,7 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
r = c->rect;
|
r = c->rect;
|
||||||
|
|
||||||
if (c->m_is_input) {
|
if (c->m_is_input) {
|
||||||
Box(cr, cfg.TabClient, r);
|
Box(cr, cfg.TabClient, r, m_y_rect == r);
|
||||||
|
|
||||||
cr->save();
|
cr->save();
|
||||||
cr->move_to(r.left + cfg.CellPadding - c->extents.y_bearing, r.top + r.height - cfg.CellPadding - c->extents.x_bearing);
|
cr->move_to(r.left + cfg.CellPadding - c->extents.y_bearing, r.top + r.height - cfg.CellPadding - c->extents.x_bearing);
|
||||||
|
@ -376,7 +381,7 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
r = pg->rect;
|
r = pg->rect;
|
||||||
|
|
||||||
if (pg->m_name != "") {
|
if (pg->m_name != "") {
|
||||||
Box(cr, cfg.TabGroup, r);
|
Box(cr, cfg.TabGroup, r, m_y_rect == r);
|
||||||
|
|
||||||
cr->save();
|
cr->save();
|
||||||
cr->move_to(r.left + cfg.CellPadding - pg->extents.y_bearing, r.top + r.height - cfg.CellPadding - pg->extents.x_bearing);
|
cr->move_to(r.left + cfg.CellPadding - pg->extents.y_bearing, r.top + r.height - cfg.CellPadding - pg->extents.x_bearing);
|
||||||
|
@ -405,7 +410,7 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
Port *p = *plit;
|
Port *p = *plit;
|
||||||
r = p->rect;
|
r = p->rect;
|
||||||
|
|
||||||
Box(cr, p->m_is_midi ? cfg.TabPortMidi : cfg.TabPortAudio, r);
|
Box(cr, p->m_is_midi ? cfg.TabPortMidi : cfg.TabPortAudio, r, m_y_rect == r);
|
||||||
|
|
||||||
cr->save();
|
cr->save();
|
||||||
cr->move_to(r.left + cfg.CellPadding - p->extents.y_bearing, r.top + r.height - cfg.CellPadding - p->extents.x_bearing);
|
cr->move_to(r.left + cfg.CellPadding - p->extents.y_bearing, r.top + r.height - cfg.CellPadding - p->extents.x_bearing);
|
||||||
|
@ -426,7 +431,7 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Box(cr, cfg.TabClient, r);
|
Box(cr, cfg.TabClient, r, m_x_rect == r);
|
||||||
|
|
||||||
cr->move_to(r.left + cfg.CellPadding - c->extents.x_bearing, r.top + cfg.CellPadding - c->extents.y_bearing);
|
cr->move_to(r.left + cfg.CellPadding - c->extents.x_bearing, r.top + cfg.CellPadding - c->extents.y_bearing);
|
||||||
cr->show_text(c->m_name);
|
cr->show_text(c->m_name);
|
||||||
|
@ -448,7 +453,7 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
r = pg->rect;
|
r = pg->rect;
|
||||||
|
|
||||||
if (pg->m_name != "") {
|
if (pg->m_name != "") {
|
||||||
Box(cr, cfg.TabGroup, r);
|
Box(cr, cfg.TabGroup, r, m_x_rect == r);
|
||||||
cr->move_to(r.left + cfg.CellPadding - pg->extents.x_bearing, r.top + cfg.CellPadding - pg->extents.y_bearing);
|
cr->move_to(r.left + cfg.CellPadding - pg->extents.x_bearing, r.top + cfg.CellPadding - pg->extents.y_bearing);
|
||||||
cr->show_text(pg->m_name);
|
cr->show_text(pg->m_name);
|
||||||
|
|
||||||
|
@ -473,7 +478,7 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
Port *p = *plit;
|
Port *p = *plit;
|
||||||
r = p->rect;
|
r = p->rect;
|
||||||
|
|
||||||
Box(cr, p->m_is_midi ? cfg.TabPortMidi : cfg.TabPortAudio, r);
|
Box(cr, p->m_is_midi ? cfg.TabPortMidi : cfg.TabPortAudio, r, m_x_rect == r);
|
||||||
|
|
||||||
cr->move_to(r.left + cfg.CellPadding - p->extents.x_bearing, r.top + cfg.CellPadding - p->extents.y_bearing);
|
cr->move_to(r.left + cfg.CellPadding - p->extents.x_bearing, r.top + cfg.CellPadding - p->extents.y_bearing);
|
||||||
cr->show_text(p->m_name);
|
cr->show_text(p->m_name);
|
||||||
|
@ -493,6 +498,8 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float radius = (float)(m_separation - cfg.CellPadding) * 0.4;
|
||||||
|
|
||||||
int x = m_client_width + m_port_width + cfg.CellPadding;
|
int x = m_client_width + m_port_width + cfg.CellPadding;
|
||||||
BaseList::iterator bit1;
|
BaseList::iterator bit1;
|
||||||
for (bit1 = across.begin(); bit1 != across.end(); ++bit1) {
|
for (bit1 = across.begin(); bit1 != across.end(); ++bit1) {
|
||||||
|
@ -506,12 +513,13 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
ConnectionMode cm = b1->ConnectedTo(b2);
|
ConnectionMode cm = b1->ConnectedTo(b2);
|
||||||
|
|
||||||
if (cm != CM_NONE) {
|
if (cm != CM_NONE) {
|
||||||
// if (p1->m_is_midi) {
|
if (b1->m_is_midi) {
|
||||||
// cr->set_source_rgb(MIDI_COLOUR);
|
SetColour(cr, cfg.TabPortMidi * 1.5);
|
||||||
// } else {
|
} else {
|
||||||
SetColour(cr, cfg.TabPortAudio);
|
SetColour(cr, cfg.TabPortAudio * 1.5);
|
||||||
// }
|
}
|
||||||
cr->rectangle(x + 1, y + 1, m_separation - 2, m_separation - 2);
|
//cr->rectangle(x + 1, y + 1, m_separation - 2, m_separation - 2);
|
||||||
|
cr->arc((float)x + m_separation * 0.5, (float)y + m_separation * 0.5, radius, 0, 2 * M_PI);
|
||||||
cr->fill();
|
cr->fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,32 +528,35 @@ bool Matrix::on_expose_event(GdkEventExpose *event)
|
||||||
|
|
||||||
x += m_separation;
|
x += m_separation;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
PortList::iterator plit1;
|
if (m_x_rect && m_y_rect && m_x_is_midi == m_y_is_midi) {
|
||||||
for (plit1 = pm.m_ports.begin(); plit1 != pm.m_ports.end(); ++plit1) {
|
int x = m_client_width + m_port_width + cfg.CellPadding;
|
||||||
Port *p1 = *plit1;
|
int y = m_client_height + m_port_height + cfg.CellPadding;
|
||||||
if (p1->pos == 0) continue;
|
|
||||||
PortList::iterator plit2;
|
float line_x = (float)m_y_rect.left + m_separation * 0.5;
|
||||||
for (plit2 = p1->m_connections.begin(); plit2 != p1->m_connections.end(); ++plit2) {
|
float line_y = (float)m_x_rect.top + m_separation * 0.5;
|
||||||
Port *p2 = *plit2;
|
|
||||||
if (p2->pos == 0) continue;
|
SetColour(cr, cfg.Text);
|
||||||
// cr->imove_to(p2->pos, p1->pos);
|
|
||||||
// cr->arc(p1->pos, p2->pos, (m_separation - cfg.CellPadding * 2) / 2.0, 0, 2 * M_PI);
|
cr->move_to(x, line_y);
|
||||||
if (p1->m_is_midi) {
|
cr->line_to(line_x - radius, line_y);
|
||||||
cr->set_source_rgb(MIDI_COLOUR);
|
cr->move_to(line_x, y);
|
||||||
} else {
|
cr->line_to(line_x, line_y - radius);
|
||||||
cr->set_source_rgb(AUDIO_COLOUR);
|
cr->stroke();
|
||||||
}
|
|
||||||
cr->rectangle(p1->pos + 1, p2->pos + 1, m_separation - 1, m_separation - 1);
|
cr->arc(line_x, line_y, radius, 0, 2 * M_PI);
|
||||||
cr->fill();
|
cr->stroke();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Matrix::on_button_press_event(GdkEventButton *event)
|
bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
{
|
{
|
||||||
|
// Adjust for window borders
|
||||||
|
int x = event->x - 1;
|
||||||
|
int y = event->y - 1;
|
||||||
|
|
||||||
// Check expandable boxes
|
// Check expandable boxes
|
||||||
ClientList::iterator clit;
|
ClientList::iterator clit;
|
||||||
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
||||||
|
@ -553,7 +564,7 @@ bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
|
|
||||||
if (m_port_type != PT_ALL && m_port_type != (c->m_is_midi ? PT_MIDI : PT_AUDIO)) continue;
|
if (m_port_type != PT_ALL && m_port_type != (c->m_is_midi ? PT_MIDI : PT_AUDIO)) continue;
|
||||||
|
|
||||||
if (c->rect.Hit(event->x, event->y)) {
|
if (c->rect.Hit(x, y)) {
|
||||||
c->m_expanded = !c->m_expanded;
|
c->m_expanded = !c->m_expanded;
|
||||||
Refresh();
|
Refresh();
|
||||||
queue_draw();
|
queue_draw();
|
||||||
|
@ -563,7 +574,7 @@ bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
PortGroupList::iterator pglit;
|
PortGroupList::iterator pglit;
|
||||||
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end(); ++pglit) {
|
||||||
PortGroup *pg = *pglit;
|
PortGroup *pg = *pglit;
|
||||||
if (pg->rect.Hit(event->x, event->y)) {
|
if (pg->rect.Hit(x, y)) {
|
||||||
pg->m_expanded = !pg->m_expanded;
|
pg->m_expanded = !pg->m_expanded;
|
||||||
Refresh();
|
Refresh();
|
||||||
queue_draw();
|
queue_draw();
|
||||||
|
@ -572,6 +583,9 @@ bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nothing selected...
|
||||||
|
if (!m_x_rect || !m_y_rect) return false;
|
||||||
|
|
||||||
// Check port hit
|
// Check port hit
|
||||||
PortGroup *pg1 = NULL;
|
PortGroup *pg1 = NULL;
|
||||||
PortGroup *pg2 = NULL;
|
PortGroup *pg2 = NULL;
|
||||||
|
@ -591,8 +605,8 @@ bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end(); ++plit) {
|
||||||
Port *p = *plit;
|
Port *p = *plit;
|
||||||
|
|
||||||
if (p->rect.HitX(event->x)) p1 = p;
|
if (p->rect.HitX(x)) p1 = p;
|
||||||
if (p->rect.HitY(event->y)) p2 = p;
|
if (p->rect.HitY(y)) p2 = p;
|
||||||
|
|
||||||
if (p1 != NULL && p2 != NULL) {
|
if (p1 != NULL && p2 != NULL) {
|
||||||
pm.ToggleConnect(p1, p2);
|
pm.ToggleConnect(p1, p2);
|
||||||
|
@ -600,8 +614,8 @@ bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pg->rect.HitX(event->x)) pg1 = pg;
|
if (pg->rect.HitX(x)) pg1 = pg;
|
||||||
if (pg->rect.HitY(event->y)) pg2 = pg;
|
if (pg->rect.HitY(y)) pg2 = pg;
|
||||||
|
|
||||||
if (p1 != NULL && pg2 != NULL) {
|
if (p1 != NULL && pg2 != NULL) {
|
||||||
pm.ToggleConnect(p1, pg2);
|
pm.ToggleConnect(p1, pg2);
|
||||||
|
@ -620,3 +634,75 @@ bool Matrix::on_button_press_event(GdkEventButton *event)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Matrix::on_motion_notify_event(GdkEventMotion *event)
|
||||||
|
{
|
||||||
|
int x = event->x;
|
||||||
|
int y = event->y;
|
||||||
|
|
||||||
|
Gdk::ModifierType state = Gdk::ModifierType(event->state);
|
||||||
|
if (event->is_hint) {
|
||||||
|
get_window()->get_pointer(x, y, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
x -= 1;
|
||||||
|
y -= 1;
|
||||||
|
|
||||||
|
Rect x_rect = Rect::None;
|
||||||
|
Rect y_rect = Rect::None;
|
||||||
|
bool x_set = false;
|
||||||
|
bool y_set = false;
|
||||||
|
|
||||||
|
ClientList::iterator clit;
|
||||||
|
PortGroupList::iterator pglit;
|
||||||
|
PortList::iterator plit;
|
||||||
|
|
||||||
|
for (clit = pm.m_clients.begin(); clit != pm.m_clients.end(); ++clit) {
|
||||||
|
Client *c = *clit;
|
||||||
|
|
||||||
|
if (m_port_type != PT_ALL && m_port_type != (c->m_is_midi ? PT_MIDI : PT_AUDIO)) continue;
|
||||||
|
|
||||||
|
if (c->m_is_input) {
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end() && !y_rect; ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end() && !y_rect; ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
p->rect.SetIfHitX(x, y_rect);
|
||||||
|
}
|
||||||
|
pg->rect.SetIfHitX(x, y_rect);
|
||||||
|
}
|
||||||
|
c->rect.SetIfHitX(x, y_rect);
|
||||||
|
if (y_rect && !y_set) { m_y_is_midi = c->m_is_midi; y_set = true; }
|
||||||
|
} else {
|
||||||
|
for (pglit = c->m_groups.begin(); pglit != c->m_groups.end() && !x_rect; ++pglit) {
|
||||||
|
PortGroup *pg = *pglit;
|
||||||
|
PortList::iterator plit;
|
||||||
|
for (plit = pg->m_ports.begin(); plit != pg->m_ports.end() && !x_rect; ++plit) {
|
||||||
|
Port *p = *plit;
|
||||||
|
p->rect.SetIfHitY(y, x_rect);
|
||||||
|
}
|
||||||
|
pg->rect.SetIfHitY(y, x_rect);
|
||||||
|
}
|
||||||
|
c->rect.SetIfHitY(y, x_rect);
|
||||||
|
if (x_rect && !x_set) { m_x_is_midi = c->m_is_midi; x_set = true; }
|
||||||
|
}
|
||||||
|
if (x_rect && y_rect) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If either box is unselected, make sure both are.
|
||||||
|
if (!x_rect || !y_rect) {
|
||||||
|
x_rect = Rect::None;
|
||||||
|
y_rect = Rect::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the selection has changed, redraw matrix.
|
||||||
|
if (x_rect != m_x_rect || y_rect != m_y_rect) {
|
||||||
|
m_x_rect = x_rect;
|
||||||
|
m_y_rect = y_rect;
|
||||||
|
|
||||||
|
queue_draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,12 @@ private:
|
||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
|
|
||||||
|
Rect m_x_rect;
|
||||||
|
Rect m_y_rect;
|
||||||
|
|
||||||
|
bool m_x_is_midi;
|
||||||
|
bool m_y_is_midi;
|
||||||
|
|
||||||
PortType m_port_type;
|
PortType m_port_type;
|
||||||
|
|
||||||
BaseList across;
|
BaseList across;
|
||||||
|
@ -38,9 +44,10 @@ public:
|
||||||
void Refresh();
|
void Refresh();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Box(Cairo::RefPtr<Cairo::Context> cr, Colour &c, Rect &rect);
|
void Box(Cairo::RefPtr<Cairo::Context> cr, Colour &c, Rect &rect, bool highlight);
|
||||||
virtual bool on_expose_event(GdkEventExpose *event);
|
virtual bool on_expose_event(GdkEventExpose *event);
|
||||||
virtual bool on_button_press_event(GdkEventButton *event);
|
virtual bool on_button_press_event(GdkEventButton *event);
|
||||||
|
virtual bool on_motion_notify_event(GdkEventMotion *event);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MATRIX_H
|
#endif // MATRIX_H
|
||||||
|
|
29
src/port.h
29
src/port.h
|
@ -48,6 +48,12 @@ struct Base {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool m_is_input;
|
||||||
|
bool m_is_midi;
|
||||||
|
Cairo::TextExtents extents;
|
||||||
|
bool m_expanded;
|
||||||
|
Rect rect;
|
||||||
|
|
||||||
virtual ConnectionMode ConnectedTo(Client *client) = 0;
|
virtual ConnectionMode ConnectedTo(Client *client) = 0;
|
||||||
virtual ConnectionMode ConnectedTo(PortGroup *group) = 0;
|
virtual ConnectionMode ConnectedTo(PortGroup *group) = 0;
|
||||||
virtual ConnectionMode ConnectedTo(Port *port) = 0;
|
virtual ConnectionMode ConnectedTo(Port *port) = 0;
|
||||||
|
@ -56,13 +62,8 @@ struct Base {
|
||||||
struct Client : Base
|
struct Client : Base
|
||||||
{
|
{
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
bool m_is_input;
|
|
||||||
bool m_is_midi;
|
|
||||||
PortGroupList m_groups;
|
PortGroupList m_groups;
|
||||||
PortList m_ports;
|
PortList m_ports;
|
||||||
Cairo::TextExtents extents;
|
|
||||||
bool m_expanded;
|
|
||||||
Rect rect;
|
|
||||||
|
|
||||||
virtual ConnectionMode ConnectedTo(Port *port);
|
virtual ConnectionMode ConnectedTo(Port *port);
|
||||||
virtual ConnectionMode ConnectedTo(PortGroup *group);
|
virtual ConnectionMode ConnectedTo(PortGroup *group);
|
||||||
|
@ -74,11 +75,7 @@ struct Client : Base
|
||||||
struct PortGroup : Base
|
struct PortGroup : Base
|
||||||
{
|
{
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
JackPortFlags m_flags;
|
|
||||||
PortList m_ports;
|
PortList m_ports;
|
||||||
Cairo::TextExtents extents;
|
|
||||||
bool m_expanded;
|
|
||||||
Rect rect;
|
|
||||||
|
|
||||||
virtual ConnectionMode ConnectedTo(Port *port);
|
virtual ConnectionMode ConnectedTo(Port *port);
|
||||||
virtual ConnectionMode ConnectedTo(PortGroup *group);
|
virtual ConnectionMode ConnectedTo(PortGroup *group);
|
||||||
|
@ -89,15 +86,11 @@ struct PortGroup : Base
|
||||||
|
|
||||||
struct Port : Base
|
struct Port : Base
|
||||||
{
|
{
|
||||||
jack_port_t *m_port;
|
jack_port_t *m_port;
|
||||||
JackPortFlags m_flags;
|
std::string m_name;
|
||||||
std::string m_name;
|
Client *m_client;
|
||||||
bool m_is_midi;
|
PortGroup *m_group;
|
||||||
Client *m_client;
|
PortList m_connections;
|
||||||
PortGroup *m_group;
|
|
||||||
PortList m_connections;
|
|
||||||
Cairo::TextExtents extents;
|
|
||||||
Rect rect;
|
|
||||||
|
|
||||||
virtual ConnectionMode ConnectedTo(Port *port);
|
virtual ConnectionMode ConnectedTo(Port *port);
|
||||||
virtual ConnectionMode ConnectedTo(PortGroup *group);
|
virtual ConnectionMode ConnectedTo(PortGroup *group);
|
||||||
|
|
|
@ -6,19 +6,30 @@
|
||||||
#include "portmanager.h"
|
#include "portmanager.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
Alias::Alias(std::string match, std::string replace)
|
||||||
|
{
|
||||||
|
m_match = match;
|
||||||
|
m_replace = replace;
|
||||||
|
}
|
||||||
|
|
||||||
bool Alias::Match(std::string name)
|
bool Alias::Match(std::string name)
|
||||||
{
|
{
|
||||||
pcrecpp::RE re(match);
|
pcrecpp::RE re(m_match);
|
||||||
return re.FullMatch(name);
|
return re.FullMatch(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Alias::Replace(std::string name)
|
std::string Alias::Replace(std::string name)
|
||||||
{
|
{
|
||||||
pcrecpp::RE re(match);
|
pcrecpp::RE re(m_match);
|
||||||
re.Replace(replace, &name);
|
re.Replace(m_replace, &name);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Connection::Match(std::string port1, std::string port2)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void PortManager::Refresh()
|
void PortManager::Refresh()
|
||||||
{
|
{
|
||||||
// Clear all information
|
// Clear all information
|
||||||
|
@ -92,14 +103,14 @@ void PortManager::Add(jack_port_t *port)
|
||||||
|
|
||||||
Port *p = new Port();
|
Port *p = new Port();
|
||||||
p->m_port = port;
|
p->m_port = port;
|
||||||
p->m_flags = (JackPortFlags)jack_port_flags(port);
|
p->m_is_input = (JackPortFlags)jack_port_flags(port) & JackPortIsInput;
|
||||||
|
|
||||||
std::string type = jack_port_type(port);
|
std::string type = jack_port_type(port);
|
||||||
p->m_is_midi = type == JACK_DEFAULT_MIDI_TYPE;
|
p->m_is_midi = type == JACK_DEFAULT_MIDI_TYPE;
|
||||||
|
|
||||||
// Client
|
// Client
|
||||||
client_name = jack_name.substr(0, pos1);
|
client_name = jack_name.substr(0, pos1);
|
||||||
p->m_client = FindOrMakeClient(client_name, p->m_flags & JackPortIsInput, p->m_is_midi);
|
p->m_client = FindOrMakeClient(client_name, p->m_is_input, p->m_is_midi);
|
||||||
|
|
||||||
if (pos2 != std::string::npos) {
|
if (pos2 != std::string::npos) {
|
||||||
// Group
|
// Group
|
||||||
|
@ -110,7 +121,7 @@ void PortManager::Add(jack_port_t *port)
|
||||||
port_name = jack_name.substr(pos1 + 1);
|
port_name = jack_name.substr(pos1 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->m_group = FindOrMakeGroup(p->m_client, p->m_flags, group_name);
|
p->m_group = FindOrMakeGroup(p->m_client, group_name);
|
||||||
p->m_group->m_ports.push_back(p);
|
p->m_group->m_ports.push_back(p);
|
||||||
|
|
||||||
p->m_name = port_name;
|
p->m_name = port_name;
|
||||||
|
@ -164,7 +175,7 @@ void PortManager::Connect(jack_port_t *port_a, jack_port_t *port_b)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1->m_flags & JackPortIsInput) {
|
if (p1->m_is_input) {
|
||||||
p1->m_connections.push_back(p2);
|
p1->m_connections.push_back(p2);
|
||||||
} else {
|
} else {
|
||||||
p2->m_connections.push_back(p1);
|
p2->m_connections.push_back(p1);
|
||||||
|
@ -183,7 +194,7 @@ void PortManager::Disconnect(jack_port_t *port_a, jack_port_t *port_b)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1->m_flags & JackPortIsInput) {
|
if (p1->m_is_input) {
|
||||||
p1->m_connections.remove(p2);
|
p1->m_connections.remove(p2);
|
||||||
} else {
|
} else {
|
||||||
p2->m_connections.remove(p1);
|
p2->m_connections.remove(p1);
|
||||||
|
@ -217,17 +228,18 @@ Client *PortManager::FindOrMakeClient(std::string name, bool is_input, bool is_m
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortGroup *PortManager::FindOrMakeGroup(Client *client, JackPortFlags flags, std::string name)
|
PortGroup *PortManager::FindOrMakeGroup(Client *client, std::string name)
|
||||||
{
|
{
|
||||||
PortGroupList::iterator it;
|
PortGroupList::iterator it;
|
||||||
for (it = client->m_groups.begin(); it != client->m_groups.end(); ++it) {
|
for (it = client->m_groups.begin(); it != client->m_groups.end(); ++it) {
|
||||||
PortGroup *pg = *it;
|
PortGroup *pg = *it;
|
||||||
if (pg->m_flags == flags && pg->m_name == name) return pg;
|
if (pg->m_name == name) return pg;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortGroup *pg = new PortGroup();
|
PortGroup *pg = new PortGroup();
|
||||||
pg->m_name = name;
|
pg->m_name = name;
|
||||||
pg->m_flags = flags;
|
pg->m_is_input = client->m_is_input;
|
||||||
|
pg->m_is_midi = client->m_is_midi;
|
||||||
pg->m_expanded = cfg.ExpandGroups;
|
pg->m_expanded = cfg.ExpandGroups;
|
||||||
|
|
||||||
client->m_groups.push_back(pg);
|
client->m_groups.push_back(pg);
|
||||||
|
@ -388,10 +400,7 @@ void PortManager::AliasClear()
|
||||||
|
|
||||||
void PortManager::AliasAdd(std::string source, std::string target)
|
void PortManager::AliasAdd(std::string source, std::string target)
|
||||||
{
|
{
|
||||||
Alias a;
|
m_aliases.push_back(Alias(source, target));
|
||||||
a.match = source;
|
|
||||||
a.replace = target;
|
|
||||||
m_aliases.push_back(a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -7,14 +7,27 @@
|
||||||
|
|
||||||
struct Alias
|
struct Alias
|
||||||
{
|
{
|
||||||
std::string match;
|
std::string m_match;
|
||||||
std::string replace;
|
std::string m_replace;
|
||||||
|
|
||||||
|
Alias(std::string match, std::string replace);
|
||||||
bool Match(std::string name);
|
bool Match(std::string name);
|
||||||
std::string Replace(std::string name);
|
std::string Replace(std::string name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Connection
|
||||||
|
{
|
||||||
|
std::string m_match1;
|
||||||
|
std::string m_match2;
|
||||||
|
int m_disconnect:1;
|
||||||
|
int m_continue:1;
|
||||||
|
int m_condition:1;
|
||||||
|
|
||||||
|
bool Match(std::string port1, std::string port2);
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::vector<Alias> AliasList;
|
typedef std::vector<Alias> AliasList;
|
||||||
|
typedef std::vector<Connection> ConnectionList;
|
||||||
|
|
||||||
class PortManager
|
class PortManager
|
||||||
{
|
{
|
||||||
|
@ -34,7 +47,7 @@ public:
|
||||||
void Rename(jack_port_t *port);
|
void Rename(jack_port_t *port);
|
||||||
|
|
||||||
Client *FindOrMakeClient(std::string name, bool is_input, bool is_midi);
|
Client *FindOrMakeClient(std::string name, bool is_input, bool is_midi);
|
||||||
PortGroup *FindOrMakeGroup(Client *client, JackPortFlags flags, std::string name);
|
PortGroup *FindOrMakeGroup(Client *client, std::string name);
|
||||||
Port *FindPort(jack_port_t *port);
|
Port *FindPort(jack_port_t *port);
|
||||||
|
|
||||||
void Sort();
|
void Sort();
|
||||||
|
@ -43,6 +56,21 @@ public:
|
||||||
void ToggleConnect(Port *a, PortGroup *b);
|
void ToggleConnect(Port *a, PortGroup *b);
|
||||||
void ToggleConnect(PortGroup *a, Port *b);
|
void ToggleConnect(PortGroup *a, Port *b);
|
||||||
void ToggleConnect(PortGroup *a, PortGroup *b);
|
void ToggleConnect(PortGroup *a, PortGroup *b);
|
||||||
|
void ToggleConnect(Base *a, Base *b)
|
||||||
|
{
|
||||||
|
switch (a->get_type()) {
|
||||||
|
case 1:
|
||||||
|
switch (b->get_type()) {
|
||||||
|
case 1: ToggleConnect((PortGroup *)a, (PortGroup *)b); break;
|
||||||
|
case 2: ToggleConnect((PortGroup *)a, (Port *)b); break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
switch (b->get_type()) {
|
||||||
|
case 1: ToggleConnect((Port *)a, (PortGroup *)b); break;
|
||||||
|
case 2: ToggleConnect((Port *)a, (Port *)b); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetAlias(std::string port_name);
|
std::string GetAlias(std::string port_name);
|
||||||
void AliasBay(jack_port_t *port, int num_aliases, char *aliases[2]);
|
void AliasBay(jack_port_t *port, int num_aliases, char *aliases[2]);
|
||||||
|
|
|
@ -56,17 +56,7 @@ Preferences::Preferences(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builde
|
||||||
m_tree_model_aliases = Gtk::ListStore::create(m_columns);
|
m_tree_model_aliases = Gtk::ListStore::create(m_columns);
|
||||||
treeview_aliases->set_model(m_tree_model_aliases);
|
treeview_aliases->set_model(m_tree_model_aliases);
|
||||||
|
|
||||||
const AliasList &list = pm.AliasGetList();
|
RefreshAliases();
|
||||||
AliasList::const_iterator it;
|
|
||||||
int i = 0;
|
|
||||||
for (it = list.begin(); it != list.end(); ++it, i++) {
|
|
||||||
const Alias &a = *it;
|
|
||||||
Gtk::TreeModel::Row row = *(m_tree_model_aliases->append());
|
|
||||||
|
|
||||||
row[m_columns.m_row] = i;
|
|
||||||
row[m_columns.m_first] = a.match;
|
|
||||||
row[m_columns.m_second] = a.replace;
|
|
||||||
}
|
|
||||||
|
|
||||||
treeview_aliases->append_column("Match", m_columns.m_first);
|
treeview_aliases->append_column("Match", m_columns.m_first);
|
||||||
treeview_aliases->append_column("Replace", m_columns.m_second);
|
treeview_aliases->append_column("Replace", m_columns.m_second);
|
||||||
|
@ -128,8 +118,8 @@ void Preferences::RefreshAliases()
|
||||||
Gtk::TreeModel::Row row = *(m_tree_model_aliases->append());
|
Gtk::TreeModel::Row row = *(m_tree_model_aliases->append());
|
||||||
|
|
||||||
row[m_columns.m_row] = i;
|
row[m_columns.m_row] = i;
|
||||||
row[m_columns.m_first] = a.match;
|
row[m_columns.m_first] = a.m_match;
|
||||||
row[m_columns.m_second] = a.replace;
|
row[m_columns.m_second] = a.m_replace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,12 +192,12 @@ void Preferences::on_button_aliases_up_click()
|
||||||
Gtk::TreeModel::Row trow2 = m_tree_model_aliases->children()[row - 1];
|
Gtk::TreeModel::Row trow2 = m_tree_model_aliases->children()[row - 1];
|
||||||
|
|
||||||
trow1[m_columns.m_row] = row;
|
trow1[m_columns.m_row] = row;
|
||||||
trow1[m_columns.m_first] = list[row].match;
|
trow1[m_columns.m_first] = list[row].m_match;
|
||||||
trow1[m_columns.m_second] = list[row].replace;
|
trow1[m_columns.m_second] = list[row].m_replace;
|
||||||
|
|
||||||
trow2[m_columns.m_row] = row - 1;
|
trow2[m_columns.m_row] = row - 1;
|
||||||
trow2[m_columns.m_first] = list[row - 1].match;
|
trow2[m_columns.m_first] = list[row - 1].m_match;
|
||||||
trow2[m_columns.m_second] = list[row - 1].replace;
|
trow2[m_columns.m_second] = list[row - 1].m_replace;
|
||||||
|
|
||||||
treeview_aliases->get_selection()->select(trow2);
|
treeview_aliases->get_selection()->select(trow2);
|
||||||
}
|
}
|
||||||
|
@ -228,12 +218,12 @@ void Preferences::on_button_aliases_down_click()
|
||||||
Gtk::TreeModel::Row trow2 = m_tree_model_aliases->children()[row + 1];
|
Gtk::TreeModel::Row trow2 = m_tree_model_aliases->children()[row + 1];
|
||||||
|
|
||||||
trow1[m_columns.m_row] = row;
|
trow1[m_columns.m_row] = row;
|
||||||
trow1[m_columns.m_first] = list[row].match;
|
trow1[m_columns.m_first] = list[row].m_match;
|
||||||
trow1[m_columns.m_second] = list[row].replace;
|
trow1[m_columns.m_second] = list[row].m_replace;
|
||||||
|
|
||||||
trow2[m_columns.m_row] = row + 1;
|
trow2[m_columns.m_row] = row + 1;
|
||||||
trow2[m_columns.m_first] = list[row + 1].match;
|
trow2[m_columns.m_first] = list[row + 1].m_match;
|
||||||
trow2[m_columns.m_second] = list[row + 1].replace;
|
trow2[m_columns.m_second] = list[row + 1].m_replace;
|
||||||
|
|
||||||
treeview_aliases->get_selection()->select(trow2);
|
treeview_aliases->get_selection()->select(trow2);
|
||||||
}
|
}
|
||||||
|
|
20
src/rect.h
20
src/rect.h
|
@ -23,6 +23,16 @@ struct Rect
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator !() const
|
||||||
|
{
|
||||||
|
return *this == None;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return *this != None;
|
||||||
|
}
|
||||||
|
|
||||||
bool HitX(int x) const
|
bool HitX(int x) const
|
||||||
{
|
{
|
||||||
return x >= left && x < left + width;
|
return x >= left && x < left + width;
|
||||||
|
@ -37,6 +47,16 @@ struct Rect
|
||||||
{
|
{
|
||||||
return HitX(x) && HitY(y);
|
return HitX(x) && HitY(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetIfHitX(int x, Rect &other)
|
||||||
|
{
|
||||||
|
if (!other && HitX(x)) other = *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIfHitY(int y, Rect &other)
|
||||||
|
{
|
||||||
|
if (!other && HitY(y)) other = *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RECT_H
|
#endif // RECT_H
|
||||||
|
|
Loading…
Reference in New Issue