Click and hold button 1 over a channel name in the port matrix highlights
[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 "port_matrix_body.h"
31 #include "port_group.h"
32
33 /** The `port matrix' UI.  This is a widget which lets the user alter
34  *  associations between one set of ports and another.  e.g. to connect
35  *  things together.
36  *
37  *  It is made up of a body, PortMatrixBody, which is rendered using cairo,
38  *  and some scrollbars and other stuff.  All of this is arranged inside the
39  *  VBox that we inherit from.
40  */
41
42 namespace ARDOUR {
43         class Bundle;
44 }
45
46 class PortMatrix : public Gtk::VBox
47 {
48 public:
49         PortMatrix (ARDOUR::Session&, ARDOUR::DataType);
50         ~PortMatrix ();
51
52         void set_type (ARDOUR::DataType);
53
54         ARDOUR::DataType type () const {
55                 return _type;
56         }
57         
58         void disassociate_all ();
59         void setup_scrollbars ();
60         void popup_channel_context_menu (int, uint32_t, uint32_t);
61
62         enum Arrangement {
63                 TOP_TO_RIGHT,  ///< column labels on top, row labels to the right
64                 LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom
65         };
66
67         /** @return Arrangement in use */
68         Arrangement arrangement () const {
69                 return _arrangement;
70         }
71
72         PortGroupList const * columns () const;
73
74         /** @return index into the _ports array for the list which is displayed as columns */
75         int column_index () const {
76                 return _column_index;
77         }
78
79         PortGroupList const * rows () const;
80
81         /** @return index into the _ports array for the list which is displayed as rows */
82         int row_index () const {
83                 return _row_index;
84         }
85
86         PortGroupList const * ports (int d) const {
87                 return &_ports[d];
88         }
89         
90         virtual void setup ();
91
92         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
93          *  @param s New state.
94          */
95         virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0;
96
97         enum State {
98                 ASSOCIATED,     ///< the ports are associaed
99                 NOT_ASSOCIATED, ///< the ports are not associated
100                 UNKNOWN         ///< we don't know anything about these two ports' relationship
101         };
102
103         /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
104          *  @return state
105          */
106         virtual State get_state (ARDOUR::BundleChannel c[2]) const = 0;
107
108         virtual void add_channel (boost::shared_ptr<ARDOUR::Bundle>) = 0;
109         virtual bool can_remove_channels (int) const = 0;
110         virtual void remove_channel (ARDOUR::BundleChannel) = 0;
111         virtual bool can_rename_channels (int) const = 0;
112         virtual void rename_channel (ARDOUR::BundleChannel) {}
113         
114         enum Result {
115                 Cancelled,
116                 Accepted
117         };
118
119         sigc::signal<void, Result> Finished;
120
121 protected:
122
123         /** We have two port group lists.  One will be presented on the rows of the matrix,
124             the other on the columns.  The PortMatrix chooses the arrangement based on which has
125             more ports in it.  Subclasses must fill these two lists with the port groups that they
126             wish to present.  The PortMatrix will arrange its layout such that signal flow is vaguely
127             from left to right as you go from list 0 to list 1.  Hence subclasses which deal with
128             inputs and outputs should put outputs in list 0 and inputs in list 1. */
129         PortGroupList _ports[2];
130         ARDOUR::Session& _session;
131         
132 private:
133
134         void hscroll_changed ();
135         void vscroll_changed ();
136         void routes_changed ();
137         void reconnect_to_routes ();
138         void visibility_toggled (boost::weak_ptr<PortGroup>, Gtk::CheckButton *);
139         void select_arrangement ();
140         void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
141         void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
142
143         /// port type that we are working with
144         ARDOUR::DataType _type;
145         std::vector<sigc::connection> _route_connections;
146
147         PortMatrixBody _body;
148         Gtk::HScrollbar _hscroll;
149         Gtk::VScrollbar _vscroll;
150         Gtk::HBox _main_hbox;
151         Gtk::HBox _column_visibility_box;
152         bool _column_visibility_box_added;
153         Gtk::Label _column_visibility_label;
154         std::vector<Gtk::CheckButton*> _column_visibility_buttons;
155         Gtk::VBox _row_visibility_box;
156         bool _row_visibility_box_added;
157         Gtk::Label _row_visibility_label;
158         std::vector<Gtk::CheckButton*> _row_visibility_buttons;
159         Gtk::Table _scroller_table;
160         Gtk::Menu* _menu;
161         bool _setup_once;
162         Arrangement _arrangement;
163         int _row_index;
164         int _column_index;
165 };
166
167 #endif