2 Copyright (C) 2002-2009 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <gtkmm/scrolledwindow.h>
22 #include <gtkmm/adjustment.h>
23 #include <gtkmm/label.h>
24 #include "ardour/bundle.h"
25 #include "port_matrix.h"
28 /** PortMatrix constructor.
29 * @param session Our session.
30 * @param type Port type that we are handling.
31 * @param offer_inputs true to offer inputs, otherwise false.
32 * @param mask Mask of port groups to offer.
34 PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type, bool offer_inputs, PortGroupList::Mask mask)
35 : _offer_inputs (offer_inputs),
36 _port_group_list (session, type, offer_inputs, mask),
38 _body (this, offer_inputs ? PortMatrixBody::BOTTOM_AND_LEFT : PortMatrixBody::TOP_AND_RIGHT)
40 /* checkbuttons for visibility of groups */
41 Gtk::HBox* visibility_buttons = Gtk::manage (new Gtk::HBox);
43 visibility_buttons->pack_start (*Gtk::manage (new Gtk::Label (_("Show:"))), Gtk::PACK_SHRINK);
45 for (std::list<PortGroup*>::iterator i = _port_group_list.begin(); i != _port_group_list.end(); ++i) {
46 _port_group_uis.push_back (new PortGroupUI (this, *i));
49 for (std::list<PortGroupUI*>::iterator i = _port_group_uis.begin(); i != _port_group_uis.end(); ++i) {
50 visibility_buttons->pack_start ((*i)->visibility_checkbutton(), Gtk::PACK_SHRINK);
53 pack_start (*visibility_buttons, Gtk::PACK_SHRINK);
54 pack_start (_hscroll, Gtk::PACK_SHRINK);
55 Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox);
56 hbox->pack_start (_body);
57 hbox->pack_start (_vscroll, Gtk::PACK_SHRINK);
60 _hscroll.signal_value_changed().connect (sigc::mem_fun (*this, &PortMatrix::hscroll_changed));
61 _vscroll.signal_value_changed().connect (sigc::mem_fun (*this, &PortMatrix::vscroll_changed));
64 /* XXX hard-coded initial size suggestion */
65 set_size_request (400, 200);
69 PortMatrix::~PortMatrix ()
71 for (std::list<PortGroupUI*>::iterator i = _port_group_uis.begin(); i != _port_group_uis.end(); ++i) {
79 _port_group_list.refresh ();
81 std::vector<boost::shared_ptr<ARDOUR::Bundle> > column;
82 std::vector<boost::shared_ptr<ARDOUR::Bundle> > row;
84 for (PortGroupList::iterator i = _port_group_list.begin (); i != _port_group_list.end (); ++i) {
87 std::copy ((*i)->bundles.begin(), (*i)->bundles.end(), std::back_inserter (column));
89 /* make a bundle for the ports, if there are any */
90 if (!(*i)->ports.empty()) {
92 boost::shared_ptr<ARDOUR::Bundle> b (new ARDOUR::Bundle ("", _type, !_offer_inputs));
94 std::string const pre = common_prefix ((*i)->ports);
96 b->set_name (pre.substr (0, pre.length() - 1));
99 for (uint32_t j = 0; j < (*i)->ports.size(); ++j) {
100 std::string const p = (*i)->ports[j];
101 b->add_channel (p.substr (pre.length()));
105 column.push_back (b);
110 row.push_back (_our_bundle);
112 _body.setup (row, column);
118 PortMatrix::set_offer_inputs (bool s)
121 _port_group_list.set_offer_inputs (s);
126 PortMatrix::set_type (ARDOUR::DataType t)
129 _port_group_list.set_type (t);
134 PortMatrix::hscroll_changed ()
136 _body.set_xoffset (_hscroll.get_adjustment()->get_value());
140 PortMatrix::vscroll_changed ()
142 _body.set_yoffset (_vscroll.get_adjustment()->get_value());
146 PortMatrix::setup_scrollbars ()
148 Gtk::Adjustment* a = _hscroll.get_adjustment ();
150 a->set_upper (_body.full_scroll_width());
151 a->set_page_size (_body.alloc_scroll_width());
152 a->set_step_increment (32);
153 a->set_page_increment (128);
155 a = _vscroll.get_adjustment ();
157 a->set_upper (_body.full_scroll_height());
158 a->set_page_size (_body.alloc_scroll_height());
159 a->set_step_increment (32);
160 a->set_page_increment (128);
164 PortMatrix::common_prefix (std::vector<std::string> const & p) const
166 /* common prefix before '/' ? */
167 if (p[0].find_first_of ("/") != std::string::npos) {
168 std::string const fp = p[0].substr (0, (p[0].find_first_of ("/") + 1));
170 while (j < p.size()) {
171 if (p[j].substr (0, fp.length()) != fp) {
182 /* or before ':' ? */
183 if (p[0].find_first_of (":") != std::string::npos) {
184 std::string const fp = p[0].substr (0, (p[0].find_first_of (":") + 1));
186 while (j < p.size()) {
187 if (p[j].substr (0, fp.length()) != fp) {
202 PortMatrix::disassociate_all ()
204 for (PortGroupList::iterator i = _port_group_list.begin(); i != _port_group_list.end(); ++i) {
206 for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::iterator j = (*i)->bundles.begin(); j != (*i)->bundles.end(); ++j) {
208 for (uint32_t k = 0; k < (*j)->nchannels(); ++k) {
210 for (uint32_t l = 0; l < _our_bundle->nchannels(); ++l) {
213 _our_bundle, l, *j, k, false, 0
220 _body.repaint_grid ();