Add remove all and disconnect all to port matrix menu. Hide bundles whose channels...
[ardour.git] / gtk2_ardour / port_matrix.h
1 /*
2     Copyright (C) 2002-2009 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #ifndef __gtk_ardour_port_matrix_h__
21 #define __gtk_ardour_port_matrix_h__
22
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>
31
32 #include "ardour/bundle.h"
33 #include "ardour/types.h"
34 #include "ardour/session_handle.h"
35
36 #include "port_group.h"
37 #include "port_matrix_types.h"
38 #include "i18n.h"
39
40 /** The `port matrix' UI.  This is a widget which lets the user alter
41  *  associations between one set of ports and another.  e.g. to connect
42  *  things together.
43  *
44  *  It is made up of a body, PortMatrixBody, which is rendered using cairo,
45  *  and some scrollbars and other stuff.  All of this is arranged inside the
46  *  Table that we inherit from.
47  */
48
49 namespace ARDOUR {
50         class Bundle;
51 }
52
53 namespace Gtk {
54         namespace Menu_Helpers {
55                 class MenuList;
56         }
57 }
58
59 class PortMatrixBody;
60
61 class PortMatrix : public Gtk::Table, public ARDOUR::SessionHandlePtr
62 {
63 public:
64         PortMatrix (Gtk::Window*, ARDOUR::Session *, ARDOUR::DataType);
65         ~PortMatrix ();
66
67         void set_type (ARDOUR::DataType);
68
69         ARDOUR::DataType type () const {
70                 return _type;
71         }
72
73         void disassociate_all ();
74         void setup_scrollbars ();
75         void popup_menu (ARDOUR::BundleChannel, ARDOUR::BundleChannel, uint32_t);
76
77         int min_height_divisor () const {
78                 return _min_height_divisor;
79         }
80         void set_min_height_divisor (int f) {
81                 _min_height_divisor = f;
82         }
83
84         enum Arrangement {
85                 TOP_TO_RIGHT,  ///< column labels on top, row labels to the right
86                 LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
87         };
88
89         
90         /** @return Arrangement in use */
91         Arrangement arrangement () const {
92                 return _arrangement;
93         }
94
95         bool show_only_bundles () const {
96                 return _show_only_bundles;
97         }
98
99         PortGroupList const * columns () const;
100         boost::shared_ptr<const PortGroup> visible_columns () const;
101
102         /** @return index into the _ports array for the list which is displayed as columns */
103         int column_index () const {
104                 return _column_index;
105         }
106
107         PortGroupList const * rows () const;
108         boost::shared_ptr<const PortGroup> visible_rows () const;
109
110         /** @return index into the _ports array for the list which is displayed as rows */
111         int row_index () const {
112                 return _row_index;
113         }
114
115         PortGroupList const * ports (int d) const {
116                 return &_ports[d];
117         }
118
119         boost::shared_ptr<const PortGroup> visible_ports (int d) const;
120         
121         void init ();
122         void setup ();
123         virtual void setup_ports (int) = 0;
124         void setup_all_ports ();
125
126         std::pair<uint32_t, uint32_t> max_size () const;
127
128         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
129          *  @param s New state.
130          */
131         virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0;
132
133         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
134          *  @return state
135          */
136         virtual PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const = 0;
137         virtual bool list_is_global (int) const = 0;
138
139         virtual bool can_add_channel (boost::shared_ptr<ARDOUR::Bundle>) const;
140         virtual void add_channel (boost::shared_ptr<ARDOUR::Bundle>);
141         virtual bool can_remove_channels (boost::shared_ptr<ARDOUR::Bundle>) const;
142         virtual void remove_channel (ARDOUR::BundleChannel);
143         virtual void remove_all_channels (boost::weak_ptr<ARDOUR::Bundle>);
144         virtual bool can_rename_channels (boost::shared_ptr<ARDOUR::Bundle>) const {
145                 return false;
146         }
147         virtual void rename_channel (ARDOUR::BundleChannel) {}
148         virtual std::string disassociation_verb () const = 0;
149         virtual std::string channel_noun () const { return _("channel"); }
150
151         enum Result {
152                 Cancelled,
153                 Accepted
154         };
155
156         sigc::signal<void, Result> Finished;
157
158 protected:
159
160         /** We have two port group lists.  One will be presented on the rows of the matrix,
161             the other on the columns.  The PortMatrix chooses the arrangement based on which has
162             more ports in it.  Subclasses must fill these two lists with the port groups that they
163             wish to present.  The PortMatrix will arrange its layout such that signal flow is vaguely
164             from left to right as you go from list 0 to list 1.  Hence subclasses which deal with
165             inputs and outputs should put outputs in list 0 and inputs in list 1. */
166         PortGroupList _ports[2];
167
168 private:
169
170         void hscroll_changed ();
171         void vscroll_changed ();
172         void routes_changed ();
173         void reconnect_to_routes ();
174         void select_arrangement ();
175         void add_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>);
176         void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
177         void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
178         void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
179         void disassociate_all_on_bundle (boost::weak_ptr<ARDOUR::Bundle>, int);
180         void setup_global_ports ();
181         void toggle_show_only_bundles ();
182         bool on_scroll_event (GdkEventScroll *);
183         boost::shared_ptr<ARDOUR::IO> io_from_bundle (boost::shared_ptr<ARDOUR::Bundle>) const;
184         void setup_notebooks ();
185         void remove_notebook_pages (Gtk::Notebook &);
186         void notebook_page_selected (GtkNotebookPage *, guint);
187         void route_processors_changed (ARDOUR::RouteProcessorChange);
188         void body_dimensions_changed ();
189         void session_going_away ();
190         void add_remove_option (Gtk::Menu_Helpers::MenuList &, boost::weak_ptr<ARDOUR::Bundle>, int);
191         void add_disassociate_option (Gtk::Menu_Helpers::MenuList &, boost::weak_ptr<ARDOUR::Bundle>, int, int);
192
193         Gtk::Window* _parent;
194
195         /// port type that we are working with
196         ARDOUR::DataType _type;
197         PBD::ScopedConnectionList _route_connections;
198         PBD::ScopedConnectionList _changed_connections;
199         PBD::ScopedConnectionList _bundle_changed_connections;
200
201         PortMatrixBody* _body;
202         Gtk::HScrollbar _hscroll;
203         Gtk::VScrollbar _vscroll;
204         Gtk::Notebook _vnotebook;
205         Gtk::Notebook _hnotebook;
206         Gtk::Label _vlabel;
207         Gtk::Label _hlabel;
208         Gtk::VBox _vbox;
209         Gtk::HBox _hbox;
210         Gtk::Label _hspacer;
211         Gtk::Label _vspacer;
212         Gtk::Menu* _menu;
213         Arrangement _arrangement;
214         int _row_index;
215         int _column_index;
216         int _min_height_divisor;
217         bool _show_only_bundles;
218         bool _inhibit_toggle_show_only_bundles;
219         bool _ignore_notebook_page_selected;
220 };
221
222 #endif