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