Support for the port matrix working at the bundle level and hiding details of ports.
[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_channel_context_menu (int, uint32_t, uint32_t);
64
65         int min_height_divisor () const {
66                 return _min_height_divisor;
67         }
68         void set_min_height_divisor (int f) {
69                 _min_height_divisor = f;
70         }
71
72         enum Arrangement {
73                 TOP_TO_RIGHT,  ///< column labels on top, row labels to the right
74                 LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
75         };
76
77         /** @return Arrangement in use */
78         Arrangement arrangement () const {
79                 return _arrangement;
80         }
81
82         bool show_only_bundles () const {
83                 return _show_only_bundles;
84         }
85
86         void set_show_only_bundles (bool);
87
88         PortGroupList const * columns () const;
89
90         /** @return index into the _ports array for the list which is displayed as columns */
91         int column_index () const {
92                 return _column_index;
93         }
94
95         PortGroupList const * rows () const;
96
97         /** @return index into the _ports array for the list which is displayed as rows */
98         int row_index () const {
99                 return _row_index;
100         }
101
102         PortGroupList const * ports (int d) const {
103                 return &_ports[d];
104         }
105         
106         void setup ();
107         virtual void setup_ports (int) = 0;
108         void setup_all_ports ();
109
110         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
111          *  @param s New state.
112          */
113         virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0;
114
115         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
116          *  @return state
117          */
118         virtual PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const = 0;
119         virtual bool list_is_global (int) const = 0;
120
121         virtual void add_channel (boost::shared_ptr<ARDOUR::Bundle>) = 0;
122         virtual bool can_remove_channels (int) const = 0;
123         virtual void remove_channel (ARDOUR::BundleChannel) = 0;
124         virtual bool can_rename_channels (int) const = 0;
125         virtual void rename_channel (ARDOUR::BundleChannel) {}
126         
127         enum Result {
128                 Cancelled,
129                 Accepted
130         };
131
132         sigc::signal<void, Result> Finished;
133
134 protected:
135
136         /** We have two port group lists.  One will be presented on the rows of the matrix,
137             the other on the columns.  The PortMatrix chooses the arrangement based on which has
138             more ports in it.  Subclasses must fill these two lists with the port groups that they
139             wish to present.  The PortMatrix will arrange its layout such that signal flow is vaguely
140             from left to right as you go from list 0 to list 1.  Hence subclasses which deal with
141             inputs and outputs should put outputs in list 0 and inputs in list 1. */
142         PortGroupList _ports[2];
143         ARDOUR::Session& _session;
144         
145 private:
146
147         void hscroll_changed ();
148         void vscroll_changed ();
149         void routes_changed ();
150         void reconnect_to_routes ();
151         void visibility_toggled (boost::weak_ptr<PortGroup>, Gtk::CheckButton *);
152         void select_arrangement ();
153         void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
154         void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
155         void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
156         void setup_global_ports ();
157
158         /// port type that we are working with
159         ARDOUR::DataType _type;
160         std::vector<sigc::connection> _route_connections;
161
162         PortMatrixBody* _body;
163         Gtk::HScrollbar _hscroll;
164         Gtk::VScrollbar _vscroll;
165         Gtk::HBox _column_visibility_box;
166         bool _column_visibility_box_added;
167         Gtk::Label _column_visibility_label;
168         std::vector<Gtk::CheckButton*> _column_visibility_buttons;
169         Gtk::VBox _row_visibility_box;
170         bool _row_visibility_box_added;
171         Gtk::Label _row_visibility_label;
172         std::vector<Gtk::CheckButton*> _row_visibility_buttons;
173         Gtk::Table _scroller_table;
174         Gtk::Menu* _menu;
175         bool _setup_once;
176         Arrangement _arrangement;
177         int _row_index;
178         int _column_index;
179         int _min_height_divisor;
180         bool _show_only_bundles;
181 };
182
183 #endif