The matrix used to highlight connections on click-hold on a row or column label; now this happens, without a click, on any mouseover. Also mouseover a bundle name highlights everything connected to that bundle. Some cleanups along the way.

git-svn-id: svn://localhost/ardour2/branches/3.0@6102 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2009-11-17 00:30:42 +00:00
parent 25ccf0f580
commit f2dbcec61d
10 changed files with 290 additions and 221 deletions

View File

@ -34,22 +34,25 @@ PortMatrixBody::PortMatrixBody (PortMatrix* p)
_alloc_height (0),
_xoffset (0),
_yoffset (0),
_mouse_over_grid (false),
_ignore_component_size_changed (false)
{
_column_labels = new PortMatrixColumnLabels (p, this);
_row_labels = new PortMatrixRowLabels (p, this);
_grid = new PortMatrixGrid (p, this);
_components.push_back (_column_labels);
_components.push_back (_row_labels);
_components.push_back (_grid);
add_events (Gdk::LEAVE_NOTIFY_MASK | Gdk::POINTER_MOTION_MASK);
}
PortMatrixBody::~PortMatrixBody ()
{
delete _column_labels;
delete _row_labels;
delete _grid;
for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
delete *i;
}
}
bool
@ -86,79 +89,40 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
bool intersects;
Gdk::Rectangle r = exposure;
/* the get_pixmap call may cause things to be rerendered and sizes to change,
so fetch the pixmap before calculating where to put it */
GdkPixmap* p = _column_labels->get_pixmap (get_window()->gobj());
r.intersect (_column_labels->parent_rectangle(), intersects);
for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
if (intersects) {
Gdk::Rectangle r = exposure;
gdk_draw_drawable (
get_window()->gobj(),
get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
p,
_column_labels->parent_to_component_x (r.get_x()),
_column_labels->parent_to_component_y (r.get_y()),
r.get_x(),
r.get_y(),
r.get_width(),
r.get_height()
);
}
/* the get_pixmap call may cause things to be rerendered and sizes to change,
so fetch the pixmap before calculating where to put it */
GdkPixmap* p = (*i)->get_pixmap (get_window()->gobj());
r.intersect ((*i)->parent_rectangle(), intersects);
r = exposure;
p = _row_labels->get_pixmap (get_window()->gobj());
r.intersect (_row_labels->parent_rectangle(), intersects);
if (intersects) {
gdk_draw_drawable (
get_window()->gobj(),
get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
p,
(*i)->parent_to_component_x (r.get_x()),
(*i)->parent_to_component_y (r.get_y()),
r.get_x(),
r.get_y(),
r.get_width(),
r.get_height()
);
}
if (intersects) {
gdk_draw_drawable (
get_window()->gobj(),
get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
p,
_row_labels->parent_to_component_x (r.get_x()),
_row_labels->parent_to_component_y (r.get_y()),
r.get_x(),
r.get_y(),
r.get_width(),
r.get_height()
);
}
r = exposure;
p = _grid->get_pixmap (get_window()->gobj());
r.intersect (_grid->parent_rectangle(), intersects);
if (intersects) {
gdk_draw_drawable (
get_window()->gobj(),
get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
p,
_grid->parent_to_component_x (r.get_x()),
_grid->parent_to_component_y (r.get_y()),
r.get_x(),
r.get_y(),
r.get_width(),
r.get_height()
);
}
cairo_t* cr = gdk_cairo_create (get_window()->gobj());
cairo_save (cr);
set_cairo_clip (cr, _grid->parent_rectangle ());
_grid->draw_extra (cr);
cairo_restore (cr);
cairo_save (cr);
set_cairo_clip (cr, _row_labels->parent_rectangle ());
_row_labels->draw_extra (cr);
cairo_restore (cr);
cairo_save (cr);
set_cairo_clip (cr, _column_labels->parent_rectangle ());
_column_labels->draw_extra (cr);
cairo_restore (cr);
for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
cairo_save (cr);
set_cairo_clip (cr, (*i)->parent_rectangle ());
(*i)->draw_extra (cr);
cairo_restore (cr);
}
cairo_destroy (cr);
@ -295,9 +259,9 @@ PortMatrixBody::setup ()
);
}
_column_labels->setup ();
_row_labels->setup ();
_grid->setup ();
for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
(*i)->setup ();
}
set_mouseover (PortMatrixNode ());
@ -348,29 +312,14 @@ PortMatrixBody::set_yoffset (uint32_t yo)
bool
PortMatrixBody::on_button_press_event (GdkEventButton* ev)
{
if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
_grid->button_press (
_grid->parent_to_component_x (ev->x),
_grid->parent_to_component_y (ev->y),
ev->button, ev->time
);
} else if (Gdk::Region (_row_labels->parent_rectangle()).point_in (ev->x, ev->y)) {
_row_labels->button_press (
_row_labels->parent_to_component_x (ev->x),
_row_labels->parent_to_component_y (ev->y),
ev->button, ev->time
);
} else if (Gdk::Region (_column_labels->parent_rectangle()).point_in (ev->x, ev->y)) {
_column_labels->button_press (
_column_labels->parent_to_component_x (ev->x),
_column_labels->parent_to_component_y (ev->y),
ev->button, ev->time
);
for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
if (Gdk::Region ((*i)->parent_rectangle()).point_in (ev->x, ev->y)) {
(*i)->button_press (
(*i)->parent_to_component_x (ev->x),
(*i)->parent_to_component_y (ev->y),
ev->button, ev->time
);
}
}
return true;
@ -379,13 +328,7 @@ PortMatrixBody::on_button_press_event (GdkEventButton* ev)
bool
PortMatrixBody::on_button_release_event (GdkEventButton* ev)
{
if (Gdk::Region (_row_labels->parent_rectangle()).point_in (ev->x, ev->y) ||
Gdk::Region (_column_labels->parent_rectangle()).point_in (ev->x, ev->y)) {
_row_labels->clear_channel_highlights ();
_column_labels->clear_channel_highlights ();
} else if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
_grid->button_release (
_grid->parent_to_component_x (ev->x),
@ -432,38 +375,59 @@ PortMatrixBody::on_leave_notify_event (GdkEventCrossing* ev)
bool
PortMatrixBody::on_motion_notify_event (GdkEventMotion* ev)
{
if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
bool done = false;
for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
if (Gdk::Region ((*i)->parent_rectangle()).point_in (ev->x, ev->y)) {
(*i)->motion (
(*i)->parent_to_component_x (ev->x),
(*i)->parent_to_component_y (ev->y)
);
_grid->motion (
_grid->parent_to_component_x (ev->x),
_grid->parent_to_component_y (ev->y)
);
_mouse_over_grid = true;
} else {
if (_mouse_over_grid) {
set_mouseover (PortMatrixNode ());
_mouse_over_grid = false;
done = true;
}
}
if (!done) {
set_mouseover (PortMatrixNode ());
}
return true;
}
void
PortMatrixBody::set_mouseover (PortMatrixNode const & n)
{
list<PortMatrixNode> m;
m.push_back (n);
set_mouseover (m);
}
void
PortMatrixBody::set_mouseover (list<PortMatrixNode> const & n)
{
if (n == _mouseover) {
return;
}
PortMatrixNode old = _mouseover;
_mouseover = n;
/* Channel highlights are set up only on mouseovers, so
it's reasonable to remove all channel highlights here.
We can't let individual components clear their own highlights
because of the case where, say, the row labels set up some column
highlights, and then we ask the column labels to set up their
own highlights and they clear them out before they start.
*/
_grid->mouseover_changed (old);
_row_labels->mouseover_changed (old);
_column_labels->mouseover_changed (old);
_row_labels->clear_channel_highlights ();
_column_labels->clear_channel_highlights ();
list<PortMatrixNode> old = _mouseover;
_mouseover = n;
for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
(*i)->mouseover_changed (old);
}
}
void

View File

@ -28,6 +28,7 @@ class PortMatrix;
class PortMatrixColumnLabels;
class PortMatrixRowLabels;
class PortMatrixGrid;
class PortMatrixComponent;
/** The main body of the port matrix. It is made up of three parts:
* column labels, grid and row labels, each drawn using cairo.
@ -57,7 +58,8 @@ public:
void rebuild_and_draw_grid ();
void set_mouseover (PortMatrixNode const &);
PortMatrixNode mouseover () const {
void set_mouseover (std::list<PortMatrixNode> const &);
std::list<PortMatrixNode> mouseover () const {
return _mouseover;
}
@ -85,6 +87,7 @@ private:
PortMatrixColumnLabels* _column_labels;
PortMatrixRowLabels* _row_labels;
PortMatrixGrid* _grid;
std::list<PortMatrixComponent*> _components;
uint32_t _alloc_width; ///< allocated width
uint32_t _alloc_height; ///< allocated height
@ -94,8 +97,7 @@ private:
uint32_t _xoffset;
uint32_t _yoffset;
PortMatrixNode _mouseover;
bool _mouse_over_grid;
std::list<PortMatrixNode> _mouseover;
bool _ignore_component_size_changed;
std::list<sigc::connection> _bundle_connections;

View File

@ -215,11 +215,19 @@ PortMatrixColumnLabels::parent_to_component_y (double y) const
}
void
PortMatrixColumnLabels::mouseover_changed (PortMatrixNode const &)
PortMatrixColumnLabels::mouseover_changed (list<PortMatrixNode> const &)
{
clear_channel_highlights ();
if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) {
add_channel_highlight (_body->mouseover().column);
list<PortMatrixNode> const m = _body->mouseover ();
for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
ARDOUR::BundleChannel c = i->column;
ARDOUR::BundleChannel r = i->row;
if (c.bundle && r.bundle) {
add_channel_highlight (c);
} else if (c.bundle) {
_body->highlight_associated_channels (_matrix->column_index(), c);
}
}
}
@ -447,46 +455,49 @@ PortMatrixColumnLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
}
}
void
PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixColumnLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
{
uint32_t cx = 0;
uint32_t const gh = _highest_group_name + 2 * name_pad();
bool group_name = false;
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
if (y > (_height - gh)) {
if (o > (_height - gh)) {
group_name = true;
cx = x;
cx = p;
} else {
cx = x - (_height - gh - y) * tan (angle ());
cx = p - (_height - gh - o) * tan (angle ());
}
} else {
if (y < gh) {
if (o < gh) {
group_name = true;
cx = x - _overhang;
cx = p - _overhang;
} else {
cx = x - (_height - y) * tan (angle ());
cx = p - (_height - o) * tan (angle ());
}
}
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> gc = position_to_group_and_channel (cx / grid_spacing(), _matrix->columns());
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (cx, o, groups);
if (b == 1) {
if (group_name) {
w.second.bundle.reset ();
}
if (group_name && gc.first) {
gc.first->set_visible (!gc.first->visible ());
} else if (gc.second.bundle) {
_body->highlight_associated_channels (_matrix->column_index(), gc.second);
}
return w;
}
} else if (b == 3) {
void
PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> gc = position_to_group_and_channel (x, y, _matrix->columns());
_matrix->popup_menu (
gc,
make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
t
);
if (b == 3) {
_matrix->popup_menu (
gc,
make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
t
);
}
}
@ -555,3 +566,37 @@ PortMatrixColumnLabels::draw_extra (cairo_t* cr)
}
}
void
PortMatrixColumnLabels::motion (double x, double y)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> const w = position_to_group_and_channel (x, y, _matrix->columns());
if (w.second.bundle == 0) {
_body->set_mouseover (PortMatrixNode ());
return;
}
uint32_t const bh = _highest_group_name + _longest_channel_name * sin (angle ()) + _highest_text / cos (angle ());
if (
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && y > bh) ||
(_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && y < (_height - bh))
) {
/* if the mouse is over a bundle name, highlight all channels in the bundle */
list<PortMatrixNode> n;
for (uint32_t i = 0; i < w.second.bundle->nchannels(); ++i) {
ARDOUR::BundleChannel const bc (w.second.bundle, i);
n.push_back (PortMatrixNode (ARDOUR::BundleChannel (), bc));
}
_body->set_mouseover (n);
} else {
_body->set_mouseover (PortMatrixNode (ARDOUR::BundleChannel (), w.second));
}
}

View File

@ -42,8 +42,9 @@ public:
double parent_to_component_x (double x) const;
double component_to_parent_y (double y) const;
double parent_to_component_y (double y) const;
void mouseover_changed (PortMatrixNode const &);
void mouseover_changed (std::list<PortMatrixNode> const &);
void draw_extra (cairo_t *);
void motion (double, double);
uint32_t overhang () const {
return _overhang;
@ -55,6 +56,7 @@ private:
double channel_x (ARDOUR::BundleChannel const &) const;
double channel_y (ARDOUR::BundleChannel const &) const;
void queue_draw_for (ARDOUR::BundleChannel const &);
std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
void render (cairo_t *);
void compute_dimensions ();

View File

@ -192,8 +192,10 @@ PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, PortGroupLis
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixComponent::position_to_group_and_channel (uint32_t p, PortGroupList const * groups) const
PortMatrixComponent::position_to_group_and_channel (double p, double, PortGroupList const * groups) const
{
p /= grid_spacing ();
PortGroupList::List::const_iterator i = groups->begin ();
while (i != groups->end()) {

View File

@ -47,8 +47,10 @@ public:
virtual double parent_to_component_x (double x) const = 0;
virtual double component_to_parent_y (double y) const = 0;
virtual double parent_to_component_y (double y) const = 0;
virtual void mouseover_changed (PortMatrixNode const &) = 0;
virtual void mouseover_changed (std::list<PortMatrixNode> const &) = 0;
virtual void draw_extra (cairo_t *) = 0;
virtual void button_press (double, double, int, uint32_t) {}
virtual void motion (double, double) {}
void set_show_ports (bool);
void setup ();
@ -170,7 +172,7 @@ protected:
void set_source_rgba (cairo_t *, Gdk::Color const &, double);
uint32_t group_size (boost::shared_ptr<const PortGroup>) const;
uint32_t channel_to_position (ARDOUR::BundleChannel, PortGroupList const *) const;
std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (uint32_t, PortGroupList const *) const;
virtual std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
/** Render the complete component to a cairo context. */
virtual void render (cairo_t *) = 0;

View File

@ -260,19 +260,19 @@ PortMatrixGrid::draw_empty_square (cairo_t* cr, uint32_t x, uint32_t y)
}
PortMatrixNode
PortMatrixGrid::position_to_node (uint32_t x, uint32_t y) const
PortMatrixGrid::position_to_node (double x, double y) const
{
return PortMatrixNode (
position_to_group_and_channel (y, _matrix->rows()).second,
position_to_group_and_channel (x, _matrix->columns()).second
position_to_group_and_channel (y, x, _matrix->rows()).second,
position_to_group_and_channel (x, y, _matrix->columns()).second
);
}
void
PortMatrixGrid::button_press (double x, double y, int b, uint32_t t)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> px = position_to_group_and_channel (x / grid_spacing(), _matrix->columns());
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> py = position_to_group_and_channel (y / grid_spacing(), _matrix->rows());
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> px = position_to_group_and_channel (x, y, _matrix->columns());
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> py = position_to_group_and_channel (y, x, _matrix->rows());
if (b == 1) {
@ -295,7 +295,6 @@ PortMatrixGrid::get_association (PortMatrixNode node) const
{
if (_matrix->show_only_bundles()) {
bool have_unknown = false;
bool have_off_diagonal_association = false;
bool have_diagonal_association = false;
bool have_diagonal_not_association = false;
@ -399,7 +398,7 @@ PortMatrixGrid::button_release (double x, double y, int b, uint32_t /*t*/)
} else {
PortMatrixNode const n = position_to_node (x / grid_spacing(), y / grid_spacing());
PortMatrixNode const n = position_to_node (x, y);
if (n.row.bundle && n.column.bundle) {
PortMatrixNode::State const s = get_association (n);
set_association (n, toggle_state (s));
@ -420,26 +419,31 @@ PortMatrixGrid::draw_extra (cairo_t* cr)
set_source_rgba (cr, mouseover_line_colour(), 0.3);
cairo_set_line_width (cr, mouseover_line_width());
double const x = component_to_parent_x (channel_to_position (_body->mouseover().column, _matrix->columns()) * grid_spacing()) + grid_spacing() / 2;
double const y = component_to_parent_y (channel_to_position (_body->mouseover().row, _matrix->rows()) * grid_spacing()) + grid_spacing() / 2;
list<PortMatrixNode> const m = _body->mouseover ();
if (_body->mouseover().row.bundle && _body->mouseover().column.bundle) {
for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
double const x = component_to_parent_x (channel_to_position (i->column, _matrix->columns()) * grid_spacing()) + grid_spacing() / 2;
double const y = component_to_parent_y (channel_to_position (i->row, _matrix->rows()) * grid_spacing()) + grid_spacing() / 2;
cairo_move_to (cr, x, y);
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
cairo_line_to (cr, component_to_parent_x (0), y);
} else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
cairo_line_to (cr, _parent_rectangle.get_x() + _parent_rectangle.get_width(), y);
if (i->row.bundle && i->column.bundle) {
cairo_move_to (cr, x, y);
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
cairo_line_to (cr, component_to_parent_x (0), y);
} else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
cairo_line_to (cr, _parent_rectangle.get_x() + _parent_rectangle.get_width(), y);
}
cairo_stroke (cr);
cairo_move_to (cr, x, y);
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
cairo_line_to (cr, x, _parent_rectangle.get_y() + _parent_rectangle.get_height());
} else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
cairo_line_to (cr, x, component_to_parent_y (0));
}
cairo_stroke (cr);
}
cairo_stroke (cr);
cairo_move_to (cr, x, y);
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
cairo_line_to (cr, x, _parent_rectangle.get_y() + _parent_rectangle.get_height());
} else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
cairo_line_to (cr, x, component_to_parent_y (0));
}
cairo_stroke (cr);
}
if (_dragging && _drag_valid && _moved) {
@ -487,7 +491,7 @@ PortMatrixGrid::draw_extra (cairo_t* cr)
}
void
PortMatrixGrid::mouseover_changed (PortMatrixNode const& old)
PortMatrixGrid::mouseover_changed (list<PortMatrixNode> const & old)
{
queue_draw_for (old);
queue_draw_for (_body->mouseover());
@ -496,7 +500,7 @@ PortMatrixGrid::mouseover_changed (PortMatrixNode const& old)
void
PortMatrixGrid::motion (double x, double y)
{
_body->set_mouseover (position_to_node (x / grid_spacing(), y / grid_spacing()));
_body->set_mouseover (position_to_node (x, y));
int const px = x / grid_spacing ();
int const py = y / grid_spacing ();
@ -513,29 +517,32 @@ PortMatrixGrid::motion (double x, double y)
}
void
PortMatrixGrid::queue_draw_for (PortMatrixNode const &n)
PortMatrixGrid::queue_draw_for (list<PortMatrixNode> const &n)
{
if (n.row.bundle) {
for (list<PortMatrixNode>::const_iterator i = n.begin(); i != n.end(); ++i) {
if (i->row.bundle) {
double const y = channel_to_position (n.row, _matrix->rows()) * grid_spacing ();
_body->queue_draw_area (
_parent_rectangle.get_x(),
component_to_parent_y (y),
_parent_rectangle.get_width(),
grid_spacing()
);
}
double const y = channel_to_position (i->row, _matrix->rows()) * grid_spacing ();
_body->queue_draw_area (
_parent_rectangle.get_x(),
component_to_parent_y (y),
_parent_rectangle.get_width(),
grid_spacing()
);
}
if (n.column.bundle) {
if (i->column.bundle) {
double const x = channel_to_position (n.column, _matrix->columns()) * grid_spacing ();
_body->queue_draw_area (
component_to_parent_x (x),
_parent_rectangle.get_y(),
grid_spacing(),
_parent_rectangle.get_height()
);
double const x = channel_to_position (i->column, _matrix->columns()) * grid_spacing ();
_body->queue_draw_area (
component_to_parent_x (x),
_parent_rectangle.get_y(),
grid_spacing(),
_parent_rectangle.get_height()
);
}
}
}
@ -600,12 +607,12 @@ PortMatrixGrid::nodes_on_line (int x0, int y0, int x1, int y1) const
for (int x = x0; x <= x1; ++x) {
if (steep) {
PortMatrixNode n = position_to_node (y, x);
PortMatrixNode n = position_to_node (y * grid_spacing (), x * grid_spacing ());
if (n.row.bundle && n.column.bundle) {
p.push_back (n);
}
} else {
PortMatrixNode n = position_to_node (x, y);
PortMatrixNode n = position_to_node (x * grid_spacing (), y * grid_spacing ());
if (n.row.bundle && n.column.bundle) {
p.push_back (n);
}

View File

@ -49,7 +49,7 @@ public:
double parent_to_component_x (double x) const;
double component_to_parent_y (double y) const;
double parent_to_component_y (double y) const;
void mouseover_changed (PortMatrixNode const &);
void mouseover_changed (std::list<PortMatrixNode> const &);
void draw_extra (cairo_t *);
private:
@ -58,8 +58,8 @@ private:
void render (cairo_t *);
void render_group_pair (cairo_t *, boost::shared_ptr<const PortGroup>, boost::shared_ptr<const PortGroup>, uint32_t, uint32_t);
PortMatrixNode position_to_node (uint32_t, uint32_t) const;
void queue_draw_for (PortMatrixNode const &);
PortMatrixNode position_to_node (double, double) const;
void queue_draw_for (std::list<PortMatrixNode> const &);
void draw_association_indicator (cairo_t *, uint32_t, uint32_t, double p = 1);
void draw_empty_square (cairo_t *, uint32_t, uint32_t);
std::list<PortMatrixNode> nodes_on_line (int, int, int, int) const;

View File

@ -133,32 +133,30 @@ PortMatrixRowLabels::render (cairo_t* cr)
}
}
void
PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixRowLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (p, o, _matrix->rows());
uint32_t const gw = (_highest_group_name + 2 * name_pad());
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = position_to_group_and_channel (y / grid_spacing (), _matrix->rows());
if (
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < gw) ||
(_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x > (_width - gw))
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && o < gw) ||
(_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && o > (_width - gw))
) {
w.second.bundle.reset ();
}
if (b == 1) {
return w;
}
if (w.second.bundle) {
_body->highlight_associated_channels (_matrix->row_index(), w.second);
} else {
if (w.first) {
w.first->set_visible (!w.first->visible());
}
}
void
PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = position_to_group_and_channel (y, x, _matrix->rows());
} else if (b == 3) {
if (b == 3) {
_matrix->popup_menu (
make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
@ -313,11 +311,19 @@ PortMatrixRowLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
}
void
PortMatrixRowLabels::mouseover_changed (PortMatrixNode const &)
PortMatrixRowLabels::mouseover_changed (list<PortMatrixNode> const &)
{
clear_channel_highlights ();
if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) {
add_channel_highlight (_body->mouseover().row);
list<PortMatrixNode> const m = _body->mouseover ();
for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
ARDOUR::BundleChannel c = i->column;
ARDOUR::BundleChannel r = i->row;
if (c.bundle && r.bundle) {
add_channel_highlight (r);
} else if (r.bundle) {
_body->highlight_associated_channels (_matrix->row_index(), r);
}
}
}
@ -381,3 +387,40 @@ PortMatrixRowLabels::draw_extra (cairo_t* cr)
++g;
}
}
void
PortMatrixRowLabels::motion (double x, double y)
{
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> const w = position_to_group_and_channel (y, x, _matrix->rows());
if (w.second.bundle == 0) {
/* not over any bundle */
_body->set_mouseover (PortMatrixNode ());
return;
}
uint32_t const bw = _highest_group_name + 2 * name_pad() + _longest_bundle_name + 2 * name_pad();
if (
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < bw) ||
(_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x > (_width - bw))
) {
/* if the mouse is over a bundle name, highlight all channels in the bundle */
list<PortMatrixNode> n;
for (uint32_t i = 0; i < w.second.bundle->nchannels(); ++i) {
ARDOUR::BundleChannel const bc (w.second.bundle, i);
n.push_back (PortMatrixNode (bc, ARDOUR::BundleChannel ()));
}
_body->set_mouseover (n);
} else {
_body->set_mouseover (PortMatrixNode (w.second, ARDOUR::BundleChannel ()));
}
}

View File

@ -49,14 +49,16 @@ public:
double parent_to_component_x (double x) const;
double component_to_parent_y (double y) const;
double parent_to_component_y (double y) const;
void mouseover_changed (PortMatrixNode const &);
void mouseover_changed (std::list<PortMatrixNode> const &);
void draw_extra (cairo_t *);
void motion (double, double);
private:
void render_channel_name (cairo_t *, Gdk::Color, Gdk::Color, double, double, ARDOUR::BundleChannel const &);
void render_bundle_name (cairo_t *, Gdk::Color, Gdk::Color, double, double, boost::shared_ptr<ARDOUR::Bundle>);
double channel_x (ARDOUR::BundleChannel const &) const;
double channel_y (ARDOUR::BundleChannel const &) const;
virtual std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
void render (cairo_t *);
void compute_dimensions ();