Restore add channel option to port matrix context menu.
[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 <boost/shared_ptr.hpp>
30 #include "ardour/bundle.h"
31 #include "port_group.h"
32 #include "port_matrix_types.h"
33
34 /** The `port matrix' UI.  This is a widget which lets the user alter
35  *  associations between one set of ports and another.  e.g. to connect
36  *  things together.
37  *
38  *  It is made up of a body, PortMatrixBody, which is rendered using cairo,
39  *  and some scrollbars and other stuff.  All of this is arranged inside the
40  *  Table that we inherit from.
41  */
42
43 namespace ARDOUR {
44         class Bundle;
45 }
46
47 class PortMatrixBody;
48
49 class PortMatrix : public Gtk::Table
50 {
51 public:
52         PortMatrix (ARDOUR::Session&, ARDOUR::DataType);
53         ~PortMatrix ();
54
55         void set_type (ARDOUR::DataType);
56
57         ARDOUR::DataType type () const {
58                 return _type;
59         }
60         
61         void disassociate_all ();
62         void setup_scrollbars ();
63         void popup_menu (
64                 std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>,
65                 std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>,
66                 uint32_t
67                 );
68
69         int min_height_divisor () const {
70                 return _min_height_divisor;
71         }
72         void set_min_height_divisor (int f) {
73                 _min_height_divisor = f;
74         }
75
76         enum Arrangement {
77                 TOP_TO_RIGHT,  ///< column labels on top, row labels to the right
78                 LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
79         };
80
81         /** @return Arrangement in use */
82         Arrangement arrangement () const {
83                 return _arrangement;
84         }
85
86         bool show_only_bundles () const {
87                 return _show_only_bundles;
88         }
89
90         PortGroupList const * columns () const;
91
92         /** @return index into the _ports array for the list which is displayed as columns */
93         int column_index () const {
94                 return _column_index;
95         }
96
97         PortGroupList const * rows () const;
98
99         /** @return index into the _ports array for the list which is displayed as rows */
100         int row_index () const {
101                 return _row_index;
102         }
103
104         PortGroupList const * ports (int d) const {
105                 return &_ports[d];
106         }
107         
108         void setup ();
109         virtual void setup_ports (int) = 0;
110         void setup_all_ports ();
111
112         std::pair<uint32_t, uint32_t> max_size () const;
113         void setup_max_size ();
114         sigc::signal<void> MaxSizeChanged;
115
116         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
117          *  @param s New state.
118          */
119         virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0;
120
121         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
122          *  @return state
123          */
124         virtual PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const = 0;
125         virtual bool list_is_global (int) const = 0;
126
127         /** If adding a channel is allowed in this situation, return the name of the
128          *  thing that it would be added to.
129          *  @return Name.
130          */
131         virtual std::string add_channel_name () const { return ""; }
132         virtual void add_channel () {}
133         virtual bool can_remove_channels (int) const = 0;
134         virtual void remove_channel (ARDOUR::BundleChannel) = 0;
135         virtual bool can_rename_channels (int) const = 0;
136         virtual void rename_channel (ARDOUR::BundleChannel) {}
137         virtual std::string disassociation_verb () const = 0;
138         
139         enum Result {
140                 Cancelled,
141                 Accepted
142         };
143
144         sigc::signal<void, Result> Finished;
145
146 protected:
147
148         /** We have two port group lists.  One will be presented on the rows of the matrix,
149             the other on the columns.  The PortMatrix chooses the arrangement based on which has
150             more ports in it.  Subclasses must fill these two lists with the port groups that they
151             wish to present.  The PortMatrix will arrange its layout such that signal flow is vaguely
152             from left to right as you go from list 0 to list 1.  Hence subclasses which deal with
153             inputs and outputs should put outputs in list 0 and inputs in list 1. */
154         PortGroupList _ports[2];
155         ARDOUR::Session& _session;
156         
157 private:
158
159         void hscroll_changed ();
160         void vscroll_changed ();
161         void routes_changed ();
162         void reconnect_to_routes ();
163         void select_arrangement ();
164         void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
165         void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
166         void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
167         void setup_global_ports ();
168         void hide_group (boost::weak_ptr<PortGroup>);
169         void show_group (boost::weak_ptr<PortGroup>);
170         void toggle_show_only_bundles ();
171         bool on_scroll_event (GdkEventScroll *);
172
173         /// port type that we are working with
174         ARDOUR::DataType _type;
175         std::vector<sigc::connection> _route_connections;
176
177         PortMatrixBody* _body;
178         Gtk::HScrollbar _hscroll;
179         Gtk::VScrollbar _vscroll;
180         Gtk::Menu* _menu;
181         Arrangement _arrangement;
182         int _row_index;
183         int _column_index;
184         int _min_height_divisor;
185         bool _show_only_bundles;
186         bool _inhibit_toggle_show_only_bundles;
187         bool _realized;
188 };
189
190 #endif