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.
20 #ifndef __gtk_ardour_port_matrix_h__
21 #define __gtk_ardour_port_matrix_h__
24 #include <gtkmm/box.h>
25 #include <gtkmm/scrollbar.h>
26 #include <gtkmm/table.h>
27 #include <gtkmm/label.h>
28 #include <gtkmm/checkbutton.h>
29 #include <gtkmm/notebook.h>
30 #include <boost/shared_ptr.hpp>
31 #include "ardour/bundle.h"
32 #include "port_group.h"
33 #include "port_matrix_types.h"
36 /** The `port matrix' UI. This is a widget which lets the user alter
37 * associations between one set of ports and another. e.g. to connect
40 * It is made up of a body, PortMatrixBody, which is rendered using cairo,
41 * and some scrollbars and other stuff. All of this is arranged inside the
42 * Table that we inherit from.
51 class PortMatrix : public Gtk::Table
54 PortMatrix (Gtk::Window*, ARDOUR::Session&, ARDOUR::DataType);
57 void set_type (ARDOUR::DataType);
59 ARDOUR::DataType type () const {
63 void disassociate_all ();
64 void setup_scrollbars ();
65 void popup_menu (ARDOUR::BundleChannel, ARDOUR::BundleChannel, uint32_t);
67 int min_height_divisor () const {
68 return _min_height_divisor;
70 void set_min_height_divisor (int f) {
71 _min_height_divisor = f;
75 TOP_TO_RIGHT, ///< column labels on top, row labels to the right
76 LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
80 /** @return Arrangement in use */
81 Arrangement arrangement () const {
85 bool show_only_bundles () const {
86 return _show_only_bundles;
89 PortGroupList const * columns () const;
90 boost::shared_ptr<PortGroup> visible_columns () const;
92 /** @return index into the _ports array for the list which is displayed as columns */
93 int column_index () const {
97 PortGroupList const * rows () const;
98 boost::shared_ptr<PortGroup> visible_rows () const;
100 /** @return index into the _ports array for the list which is displayed as rows */
101 int row_index () const {
105 PortGroupList const * ports (int d) const {
109 boost::shared_ptr<const PortGroup> visible_ports (int d) const {
110 return _visible_ports[d];
115 virtual void setup_ports (int) = 0;
116 void setup_all_ports ();
118 std::pair<uint32_t, uint32_t> max_size () const;
120 /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
121 * @param s New state.
123 virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0;
125 /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
128 virtual PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const = 0;
129 virtual bool list_is_global (int) const = 0;
131 virtual bool can_add_channel (boost::shared_ptr<ARDOUR::Bundle>) const;
132 virtual void add_channel (boost::shared_ptr<ARDOUR::Bundle>);
133 virtual bool can_remove_channels (boost::shared_ptr<ARDOUR::Bundle>) const;
134 virtual void remove_channel (ARDOUR::BundleChannel);
135 virtual bool can_rename_channels (boost::shared_ptr<ARDOUR::Bundle>) const {
138 virtual void rename_channel (ARDOUR::BundleChannel) {}
139 virtual std::string disassociation_verb () const = 0;
140 virtual std::string channel_noun () const { return _("channel"); }
147 sigc::signal<void, Result> Finished;
151 /** We have two port group lists. One will be presented on the rows of the matrix,
152 the other on the columns. The PortMatrix chooses the arrangement based on which has
153 more ports in it. Subclasses must fill these two lists with the port groups that they
154 wish to present. The PortMatrix will arrange its layout such that signal flow is vaguely
155 from left to right as you go from list 0 to list 1. Hence subclasses which deal with
156 inputs and outputs should put outputs in list 0 and inputs in list 1. */
157 PortGroupList _ports[2];
158 boost::shared_ptr<PortGroup> _visible_ports[2];
159 ARDOUR::Session& _session;
163 void hscroll_changed ();
164 void vscroll_changed ();
165 void routes_changed ();
166 void reconnect_to_routes ();
167 void select_arrangement ();
168 void add_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>);
169 void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
170 void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
171 void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
172 void setup_global_ports ();
173 void toggle_show_only_bundles ();
174 bool on_scroll_event (GdkEventScroll *);
175 boost::shared_ptr<ARDOUR::IO> io_from_bundle (boost::shared_ptr<ARDOUR::Bundle>) const;
176 void bundle_changed (ARDOUR::Bundle::Change);
177 void setup_notebooks ();
178 void remove_notebook_pages (Gtk::Notebook &);
179 void v_page_selected (GtkNotebookPage *, guint);
180 void h_page_selected (GtkNotebookPage *, guint);
182 Gtk::Window* _parent;
184 /// port type that we are working with
185 ARDOUR::DataType _type;
186 std::vector<sigc::connection> _route_connections;
188 PortMatrixBody* _body;
189 Gtk::HScrollbar _hscroll;
190 Gtk::VScrollbar _vscroll;
191 Gtk::Notebook _vnotebook;
192 Gtk::Notebook _hnotebook;
198 Arrangement _arrangement;
201 int _min_height_divisor;
202 bool _show_only_bundles;
203 bool _inhibit_toggle_show_only_bundles;
204 bool _in_setup_notebooks;