Stop bundles disappearing from the port matrix when they
[ardour2.git] / gtk2_ardour / port_matrix.h
blob75b2abf2797fbacbe31247a20b9cd373859ebcb3
1 /*
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__
23 #include <list>
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>
32 #include "ardour/bundle.h"
33 #include "ardour/types.h"
34 #include "ardour/session_handle.h"
36 #include "port_group.h"
37 #include "port_matrix_types.h"
39 /** The `port matrix' UI. This is a widget which lets the user alter
40 * associations between one set of ports and another. e.g. to connect
41 * things together.
43 * It is made up of a body, PortMatrixBody, which is rendered using cairo,
44 * and some scrollbars and other stuff. All of this is arranged inside the
45 * Table that we inherit from.
48 namespace ARDOUR {
49 class Bundle;
52 namespace Gtk {
53 namespace Menu_Helpers {
54 class MenuList;
58 class PortMatrixBody;
60 class PortMatrix : public Gtk::Table, public ARDOUR::SessionHandlePtr
62 public:
63 PortMatrix (Gtk::Window*, ARDOUR::Session *, ARDOUR::DataType);
64 ~PortMatrix ();
66 void set_type (ARDOUR::DataType);
68 ARDOUR::DataType type () const {
69 return _type;
72 void disassociate_all ();
73 void setup_scrollbars ();
74 void popup_menu (ARDOUR::BundleChannel, ARDOUR::BundleChannel, uint32_t);
76 int min_height_divisor () const {
77 return _min_height_divisor;
79 void set_min_height_divisor (int f) {
80 _min_height_divisor = f;
83 enum Arrangement {
84 TOP_TO_RIGHT, ///< column labels on top, row labels to the right
85 LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
89 /** @return Arrangement in use */
90 Arrangement arrangement () const {
91 return _arrangement;
94 bool show_only_bundles () const {
95 return _show_only_bundles;
98 PortGroupList const * columns () const;
99 boost::shared_ptr<const PortGroup> visible_columns () const;
101 /** @return index into the _ports array for the list which is displayed as columns */
102 int column_index () const {
103 return _column_index;
106 PortGroupList const * rows () const;
107 boost::shared_ptr<const PortGroup> visible_rows () const;
109 /** @return index into the _ports array for the list which is displayed as rows */
110 int row_index () const {
111 return _row_index;
114 PortGroupList const * ports (int d) const {
115 return &_ports[d];
118 boost::shared_ptr<const PortGroup> visible_ports (int d) const;
120 void init ();
121 void setup ();
122 virtual void setup_ports (int) = 0;
123 void setup_all_ports ();
125 std::pair<uint32_t, uint32_t> max_size () const;
127 bool should_show (ARDOUR::DataType) const;
128 uint32_t count_of_our_type (ARDOUR::ChanCount) const;
129 uint32_t count_of_our_type_min_1 (ARDOUR::ChanCount) const;
131 PortMatrixNode::State get_association (PortMatrixNode) const;
133 /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
134 * @param s New state.
136 virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0;
138 /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
139 * @return state
141 virtual PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const = 0;
142 virtual bool list_is_global (int) const = 0;
144 virtual bool can_add_channel (boost::shared_ptr<ARDOUR::Bundle>) const;
145 virtual void add_channel (boost::shared_ptr<ARDOUR::Bundle>, ARDOUR::DataType);
146 virtual bool can_remove_channels (boost::shared_ptr<ARDOUR::Bundle>) const;
147 virtual void remove_channel (ARDOUR::BundleChannel);
148 virtual void remove_all_channels (boost::weak_ptr<ARDOUR::Bundle>);
149 virtual bool can_rename_channels (boost::shared_ptr<ARDOUR::Bundle>) const {
150 return false;
152 virtual void rename_channel (ARDOUR::BundleChannel) {}
153 virtual std::string disassociation_verb () const = 0;
154 virtual std::string channel_noun () const;
156 enum Result {
157 Cancelled,
158 Accepted
161 sigc::signal<void, Result> Finished;
163 static bool bundle_with_channels (boost::shared_ptr<ARDOUR::Bundle>);
165 protected:
167 /** We have two port group lists. One will be presented on the rows of the matrix,
168 the other on the columns. The PortMatrix chooses the arrangement based on which has
169 more ports in it. Subclasses must fill these two lists with the port groups that they
170 wish to present. The PortMatrix will arrange its layout such that signal flow is vaguely
171 from left to right as you go from list 0 to list 1. Hence subclasses which deal with
172 inputs and outputs should put outputs in list 0 and inputs in list 1. */
173 PortGroupList _ports[2];
175 private:
177 void hscroll_changed ();
178 void vscroll_changed ();
179 void routes_changed ();
180 void reconnect_to_routes ();
181 void select_arrangement ();
182 void add_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, ARDOUR::DataType);
183 void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
184 void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
185 void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
186 void disassociate_all_on_bundle (boost::weak_ptr<ARDOUR::Bundle>, int);
187 void setup_global_ports ();
188 void setup_global_ports_proxy ();
189 void toggle_show_only_bundles ();
190 bool on_scroll_event (GdkEventScroll *);
191 boost::shared_ptr<ARDOUR::IO> io_from_bundle (boost::shared_ptr<ARDOUR::Bundle>) const;
192 void setup_notebooks ();
193 void remove_notebook_pages (Gtk::Notebook &);
194 void notebook_page_selected (GtkNotebookPage *, guint);
195 void route_processors_changed (ARDOUR::RouteProcessorChange);
196 void body_dimensions_changed ();
197 void session_going_away ();
198 void add_remove_option (Gtk::Menu_Helpers::MenuList &, boost::weak_ptr<ARDOUR::Bundle>, int);
199 void add_disassociate_option (Gtk::Menu_Helpers::MenuList &, boost::weak_ptr<ARDOUR::Bundle>, int, int);
200 void port_connected_or_disconnected ();
202 Gtk::Window* _parent;
204 /// port type that we are working with, or NIL if we are working with all of them
205 ARDOUR::DataType _type;
206 PBD::ScopedConnectionList _route_connections;
207 PBD::ScopedConnectionList _changed_connections;
208 PBD::ScopedConnectionList _bundle_changed_connections;
210 PortMatrixBody* _body;
211 Gtk::HScrollbar _hscroll;
212 Gtk::VScrollbar _vscroll;
213 Gtk::Notebook _vnotebook;
214 Gtk::Notebook _hnotebook;
215 Gtk::Label _vlabel;
216 Gtk::Label _hlabel;
217 Gtk::VBox _vbox;
218 Gtk::HBox _hbox;
219 Gtk::Label _hspacer;
220 Gtk::Label _vspacer;
221 Gtk::Menu* _menu;
222 Arrangement _arrangement;
223 int _row_index;
224 int _column_index;
225 int _min_height_divisor;
226 bool _show_only_bundles;
227 bool _inhibit_toggle_show_only_bundles;
228 bool _ignore_notebook_page_selected;
231 #endif