e93b5cb1c9b98c8dedf139df8c5ec82e2d25fc6a
[ardour.git] / gtk2_ardour / io_selector.h
1 /*
2     Copyright (C) 2002-2007 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 __ardour_ui_io_selector_h__
21 #define __ardour_ui_io_selector_h__
22
23 #include <gtkmm/box.h>
24 #include <gtkmm/checkbutton.h>
25 #include <gtkmm/table.h>
26 #include <gtkmm/frame.h>
27
28 #include "ardour_dialog.h"
29
30 namespace ARDOUR {
31         class Session;
32         class IO;
33         class PortInsert;
34 }
35
36 /// A group of port names
37 class PortGroup
38 {
39   public:
40         PortGroup (std::string const & n, std::string const & p) : name (n), prefix (p), visible (true) {}
41
42         void add (std::string const & p);
43
44         std::string name;
45         std::string prefix; ///< prefix (before colon) e.g. "ardour:"
46         std::vector<std::string> ports; ///< port names
47         bool visible;
48 };
49
50 /// A table of checkbuttons to provide the GUI for connecting to a PortGroup
51 class PortGroupTable
52 {
53   public:
54         PortGroupTable (PortGroup&, boost::shared_ptr<ARDOUR::IO>, bool);
55
56         Gtk::Widget& get_widget ();
57         std::pair<int, int> unit_size () const;
58         PortGroup& port_group () { return _port_group; }
59
60   private:
61         void check_button_toggled (Gtk::CheckButton*, int, std::string const &);
62         
63         Gtk::Table _table;
64         Gtk::EventBox _box;
65         PortGroup& _port_group;
66         std::vector<std::vector<Gtk::CheckButton* > > _check_buttons;
67         bool _ignore_check_button_toggle;
68         boost::shared_ptr<ARDOUR::IO> _io;
69         bool _for_input;
70 };
71
72 /// A list of PortGroups
73 class PortGroupList : public std::list<PortGroup>
74 {
75   public:
76         PortGroupList (ARDOUR::Session &, boost::shared_ptr<ARDOUR::IO>, bool);
77
78         void refresh ();
79         int n_visible_ports () const;
80         std::string get_port_by_index (int, bool with_prefix = true) const;
81
82   private:
83         ARDOUR::Session& _session;
84         boost::shared_ptr<ARDOUR::IO> _io;
85         bool _for_input;
86 };
87
88
89 /// A widget which provides a set of rotated text labels
90 class RotatedLabelSet : public Gtk::Widget {
91   public:
92         RotatedLabelSet (PortGroupList&);
93         virtual ~RotatedLabelSet ();
94
95         void set_angle (int);
96         void set_base_width (int);
97         void update_visibility ();
98         
99   protected:
100         virtual void on_size_request (Gtk::Requisition*);
101         virtual void on_size_allocate (Gtk::Allocation&);
102         virtual void on_realize ();
103         virtual void on_unrealize ();
104         virtual bool on_expose_event (GdkEventExpose*);
105
106         Glib::RefPtr<Gdk::Window> _gdk_window;
107
108   private:
109         std::pair<int, int> setup_layout (std::string const &);
110
111         PortGroupList& _port_group_list; ///< list of ports to display
112         int _angle_degrees; ///< label rotation angle in degrees
113         double _angle_radians; ///< label rotation angle in radians
114         int _base_width; ///< width of labels; see set_base_width() for more details
115         Glib::RefPtr<Pango::Context> _pango_context;
116         Glib::RefPtr<Pango::Layout> _pango_layout;
117         Glib::RefPtr<Gdk::GC> _gc;
118         Gdk::Color _fg_colour;
119         Gdk::Color _bg_colour;
120 };
121
122
123
124 /// Widget for selecting what an IO is connected to
125 class IOSelector : public Gtk::VBox {
126   public:
127         IOSelector (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool);
128         ~IOSelector ();
129
130         void redisplay ();
131
132         enum Result {
133                 Cancelled,
134                 Accepted
135         };
136
137         sigc::signal<void, Result> Finished;
138
139   private:
140         void setup ();
141         void clear ();
142         void setup_dimensions ();
143         void ports_changed (ARDOUR::IOChange, void*);
144         bool row_label_button_pressed (GdkEventButton*, int);
145         void add_port ();
146         void remove_port (int);
147         void group_visible_toggled (Gtk::CheckButton*, std::string const &);
148
149         PortGroupList _port_group_list;
150         boost::shared_ptr<ARDOUR::IO> _io;
151         bool _for_input;
152         std::vector<PortGroupTable*> _port_group_tables;
153         std::vector<Gtk::EventBox*> _row_labels[2];
154         Gtk::VBox* _row_labels_vbox[2];
155         RotatedLabelSet _column_labels;
156         Gtk::HBox _overall_hbox;
157         Gtk::VBox _side_vbox[2];
158         Gtk::HBox _port_group_hbox;
159         Gtk::ScrolledWindow _scrolled_window;
160         Gtk::Label* _side_vbox_pad[2];
161 };
162
163
164 class IOSelectorWindow : public ArdourDialog
165 {
166   public:
167         IOSelectorWindow (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool for_input, bool can_cancel = false);
168         ~IOSelectorWindow ();
169
170         IOSelector& selector() { return _selector; }
171
172   protected:
173         void on_map ();
174         
175   private:
176         IOSelector _selector;
177
178         /* overall operation buttons */
179
180         Gtk::Button ok_button;
181         Gtk::Button cancel_button;
182         Gtk::Button rescan_button;
183
184         void rescan ();
185         void cancel ();
186         void accept ();
187 };
188
189
190 class PortInsertUI : public Gtk::VBox
191 {
192   public: 
193         PortInsertUI (ARDOUR::Session&, boost::shared_ptr<ARDOUR::PortInsert>);
194         
195         void redisplay ();
196         void finished (IOSelector::Result);
197
198   private:
199         Gtk::HBox hbox;
200         IOSelector input_selector;
201         IOSelector output_selector;
202 };
203
204 class PortInsertWindow : public ArdourDialog
205 {
206   public: 
207         PortInsertWindow (ARDOUR::Session&, boost::shared_ptr<ARDOUR::PortInsert>, bool can_cancel = false);
208         
209   protected:
210         void on_map ();
211         
212   private:
213         PortInsertUI _portinsertui;
214         Gtk::VBox vbox;
215         
216         Gtk::Button ok_button;
217         Gtk::Button cancel_button;
218         Gtk::Button rescan_button;
219         Gtk::Frame button_frame;
220         
221         void rescan ();
222         void cancel ();
223         void accept ();
224
225         void plugin_going_away ();
226         sigc::connection going_away_connection;
227 };
228
229
230 #endif