X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fport_matrix_grid.cc;h=6e7fad70915a66ddedef23dd8d59100176154aff;hb=b857756f6034f1d9baf4181e824a5166dfd1acc8;hp=13e1dcf4c200fac8980fa6cfac5c1a8dc8c77c11;hpb=0187028eb0e7e3e42b9799b7e55388f1d099abdb;p=ardour.git diff --git a/gtk2_ardour/port_matrix_grid.cc b/gtk2_ardour/port_matrix_grid.cc index 13e1dcf4c2..6e7fad7091 100644 --- a/gtk2_ardour/port_matrix_grid.cc +++ b/gtk2_ardour/port_matrix_grid.cc @@ -20,12 +20,13 @@ #include #include #include "ardour/bundle.h" +#include "ardour/types.h" #include "port_matrix_grid.h" #include "port_matrix.h" +#include "port_matrix_body.h" -PortMatrixGrid::PortMatrixGrid (PortMatrix* p, PortMatrixBody* b) - : PortMatrixComponent (b), - _port_matrix (p) +PortMatrixGrid::PortMatrixGrid (PortMatrix* m, PortMatrixBody* b) + : PortMatrixComponent (m, b) { } @@ -34,13 +35,15 @@ void PortMatrixGrid::compute_dimensions () { _width = 0; - for (uint32_t i = 0; i < _body->column_bundles().size(); ++i) { - _width += _body->column_bundles()[i]->nchannels() * column_width(); + ARDOUR::BundleList const c = _matrix->columns()->bundles(); + for (ARDOUR::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) { + _width += (*i)->nchannels() * column_width(); } _height = 0; - for (uint32_t i = 0; i < _body->row_bundles().size(); ++i) { - _height += _body->row_bundles()[i]->nchannels() * row_height(); + ARDOUR::BundleList const r = _matrix->rows()->bundles(); + for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) { + _height += (*i)->nchannels() * row_height(); } } @@ -58,17 +61,18 @@ PortMatrixGrid::render (cairo_t* cr) set_source_rgb (cr, grid_colour()); uint32_t x = 0; - for (std::vector >::size_type i = 0; i < _body->column_bundles().size(); ++i) { + ARDOUR::BundleList const c = _matrix->columns()->bundles(); + for (ARDOUR::BundleList::size_type i = 0; i < c.size(); ++i) { cairo_set_line_width (cr, thin_grid_line_width()); - for (uint32_t j = 1; j < _body->column_bundles()[i]->nchannels(); ++j) { + for (uint32_t j = 1; j < c[i]->nchannels(); ++j) { x += column_width(); cairo_move_to (cr, x, 0); cairo_line_to (cr, x, _height); cairo_stroke (cr); } - if (i < (_body->column_bundles().size() - 1)) { + if (i < (c.size() - 1)) { x += column_width(); cairo_set_line_width (cr, thick_grid_line_width()); cairo_move_to (cr, x, 0); @@ -82,17 +86,18 @@ PortMatrixGrid::render (cairo_t* cr) /* HORIZONTAL GRID LINES */ uint32_t y = 0; - for (std::vector >::size_type i = 0; i < _body->row_bundles().size(); ++i) { + ARDOUR::BundleList const r = _matrix->rows()->bundles(); + for (ARDOUR::BundleList::size_type i = 0; i < r.size(); ++i) { cairo_set_line_width (cr, thin_grid_line_width()); - for (uint32_t j = 1; j < _body->row_bundles()[i]->nchannels(); ++j) { + for (uint32_t j = 1; j < r[i]->nchannels(); ++j) { y += row_height(); cairo_move_to (cr, 0, y); cairo_line_to (cr, grid_width, y); cairo_stroke (cr); } - if (i < (_body->row_bundles().size() - 1)) { + if (i < (r.size() - 1)) { y += row_height(); cairo_set_line_width (cr, thick_grid_line_width()); cairo_move_to (cr, 0, y); @@ -106,18 +111,22 @@ PortMatrixGrid::render (cairo_t* cr) uint32_t bx = 0; uint32_t by = 0; - for (std::vector >::const_iterator i = _body->column_bundles().begin(); i < _body->column_bundles().end(); ++i) { + for (ARDOUR::BundleList::const_iterator i = c.begin(); i < c.end(); ++i) { by = 0; - for (std::vector >::const_iterator j = _body->row_bundles().begin(); j < _body->row_bundles().end(); ++j) { + for (ARDOUR::BundleList::const_iterator j = r.begin(); j < r.end(); ++j) { x = bx; for (uint32_t k = 0; k < (*i)->nchannels (); k++) { y = by; for (uint32_t l = 0; l < (*j)->nchannels (); ++l) { + + ARDOUR::BundleChannel c[2]; + c[_matrix->column_index()] = ARDOUR::BundleChannel (*i, k); + c[_matrix->row_index()] = ARDOUR::BundleChannel (*j, l); - PortMatrix::State const s = _port_matrix->get_state (*j, l, *i, k); + PortMatrix::State const s = _matrix->get_state (c); switch (s) { case PortMatrix::ASSOCIATED: @@ -163,52 +172,78 @@ PortMatrixGrid::render (cairo_t* cr) } -void -PortMatrixGrid::button_press (double x, double y, int b) +PortMatrixNode +PortMatrixGrid::position_to_node (double x, double y) const { - uint32_t grid_column = x / column_width (); - uint32_t grid_row = y / row_height (); - - boost::shared_ptr our_bundle; - uint32_t our_channel = 0; - boost::shared_ptr other_bundle; - uint32_t other_channel = 0; - - for (std::vector >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) { - if (grid_row < (*i)->nchannels ()) { - our_bundle = *i; - our_channel = grid_row; - break; + return PortMatrixNode ( + position_to_channel (y, _matrix->rows()->bundles(), row_height()), + position_to_channel (x, _matrix->columns()->bundles(), column_width()) + ); +} + + +ARDOUR::BundleChannel +PortMatrixGrid::position_to_channel (double p, ARDOUR::BundleList const& bundles, double inc) const +{ + uint32_t pos = p / inc; + + for (ARDOUR::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) { + if (pos < (*i)->nchannels()) { + return ARDOUR::BundleChannel (*i, pos); } else { - grid_row -= (*i)->nchannels (); + pos -= (*i)->nchannels(); } } + + return ARDOUR::BundleChannel (boost::shared_ptr (), 0); +} + + +double +PortMatrixGrid::channel_position ( + ARDOUR::BundleChannel bc, + ARDOUR::BundleList const& bundles, + double inc) const +{ + double p = 0; + + ARDOUR::BundleList::const_iterator i = bundles.begin (); + while (i != bundles.end() && *i != bc.bundle) { + p += inc * (*i)->nchannels(); + ++i; + } - for (std::vector >::const_iterator i = _body->column_bundles().begin(); i != _body->column_bundles().end(); ++i) { - if (grid_column < (*i)->nchannels ()) { - other_bundle = *i; - other_channel = grid_column; - break; - } else { - grid_column -= (*i)->nchannels (); - } + if (i == bundles.end()) { + return 0; } + p += inc * bc.channel; + + return p; +} + +void +PortMatrixGrid::button_press (double x, double y, int b) +{ + PortMatrixNode const node = position_to_node (x, y); - if (our_bundle && other_bundle) { + if (node.row.bundle && node.column.bundle) { + + ARDOUR::BundleChannel c[2]; + c[_matrix->row_index()] = node.row; + c[_matrix->column_index()] = node.column; + + PortMatrix::State const s = _matrix->get_state (c); - PortMatrix::State const s = _port_matrix->get_state ( - our_bundle, our_channel, other_bundle, other_channel - ); - if (s == PortMatrix::ASSOCIATED || s == PortMatrix::NOT_ASSOCIATED) { bool const n = !(s == PortMatrix::ASSOCIATED); + + ARDOUR::BundleChannel c[2]; + c[_matrix->row_index()] = node.row; + c[_matrix->column_index()] = node.column; - _port_matrix->set_state ( - our_bundle, our_channel, other_bundle, other_channel, - n, 0 - ); + _matrix->set_state (c, n); } require_render (); @@ -216,4 +251,104 @@ PortMatrixGrid::button_press (double x, double y, int b) } } +void +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_position (_body->mouseover().column, _matrix->columns()->bundles(), column_width()) + column_width() / 2 + ); + + double const y = component_to_parent_y ( + channel_position (_body->mouseover().row, _matrix->rows()->bundles(), row_height()) + row_height() / 2 + ); + + if (_body->mouseover().row.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); + } + + if (_body->mouseover().column.bundle) { + + 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); + } +} + +void +PortMatrixGrid::mouseover_changed (PortMatrixNode const& old) +{ + queue_draw_for (old); + queue_draw_for (_body->mouseover()); +} + +void +PortMatrixGrid::mouseover_event (double x, double y) +{ + _body->set_mouseover (position_to_node (x, y)); +} + +void +PortMatrixGrid::queue_draw_for (PortMatrixNode const &n) +{ + if (n.row.bundle) { + + double const y = channel_position (n.row, _matrix->rows()->bundles(), row_height()); + _body->queue_draw_area ( + _parent_rectangle.get_x(), + component_to_parent_y (y), + _parent_rectangle.get_width(), + row_height() + ); + } + + if (n.column.bundle) { + + double const x = channel_position (n.column, _matrix->columns()->bundles(), column_width()); + + _body->queue_draw_area ( + component_to_parent_x (x), + _parent_rectangle.get_y(), + column_width(), + _parent_rectangle.get_height() + ); + } +} + +double +PortMatrixGrid::component_to_parent_x (double x) const +{ + return x - _body->xoffset() + _parent_rectangle.get_x(); +} + +double +PortMatrixGrid::parent_to_component_x (double x) const +{ + return x + _body->xoffset() - _parent_rectangle.get_x(); +} + +double +PortMatrixGrid::component_to_parent_y (double y) const +{ + return y - _body->yoffset() + _parent_rectangle.get_y(); +} + +double +PortMatrixGrid::parent_to_component_y (double y) const +{ + return y + _body->yoffset() - _parent_rectangle.get_y(); +}