1 /* 2 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net> 3 * Copyright (C) 2008-2012 Paul Davis <paul@linuxaudiosystems.com> 4 * Copyright (C) 2009-2011 David Robillard <d@drobilla.net> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #ifndef __gtk_ardour_port_matrix_h__ 22 #define __gtk_ardour_port_matrix_h__ 23 24 #include <list> 25 #include <gtkmm/box.h> 26 #include <gtkmm/scrollbar.h> 27 #include <gtkmm/table.h> 28 #include <gtkmm/label.h> 29 #include <gtkmm/checkbutton.h> 30 #include <gtkmm/notebook.h> 31 #include <boost/shared_ptr.hpp> 32 33 #include "ardour/bundle.h" 34 #include "ardour/types.h" 35 #include "ardour/session_handle.h" 36 37 #include "port_group.h" 38 #include "port_matrix_types.h" 39 40 /** The `port matrix' UI. This is a widget which lets the user alter 41 * associations between one set of ports and another. e.g. to connect 42 * things together. 43 * 44 * It is made up of a body, PortMatrixBody, which is rendered using cairo, 45 * and some scrollbars and other stuff. All of this is arranged inside the 46 * Table that we inherit from. 47 */ 48 49 namespace ARDOUR { 50 class Bundle; 51 } 52 53 namespace Gtk { 54 namespace Menu_Helpers { 55 class MenuList; 56 } 57 } 58 59 class PortMatrixBody; 60 61 class PortMatrix : public Gtk::Table, public ARDOUR::SessionHandlePtr 62 { 63 public: 64 PortMatrix (Gtk::Window*, ARDOUR::Session *, ARDOUR::DataType); 65 ~PortMatrix (); 66 67 void set_type (ARDOUR::DataType); 68 type()69 ARDOUR::DataType type () const { 70 return _type; 71 } 72 73 void disassociate_all (); 74 void setup_scrollbars (); 75 void popup_menu (ARDOUR::BundleChannel, ARDOUR::BundleChannel, uint32_t); 76 min_height_divisor()77 int min_height_divisor () const { 78 return _min_height_divisor; 79 } set_min_height_divisor(int f)80 void set_min_height_divisor (int f) { 81 _min_height_divisor = f; 82 } 83 84 enum Arrangement { 85 TOP_TO_RIGHT, ///< column labels on top, row labels to the right 86 LEFT_TO_BOTTOM ///< row labels to the left, column labels on the bottom 87 }; 88 89 90 /** @return Arrangement in use */ arrangement()91 Arrangement arrangement () const { 92 return _arrangement; 93 } 94 show_only_bundles()95 bool show_only_bundles () const { 96 return _show_only_bundles; 97 } 98 99 PortGroupList const * columns () const; 100 boost::shared_ptr<const PortGroup> visible_columns () const; 101 102 /** @return index into the _ports array for the list which is displayed as columns */ column_index()103 int column_index () const { 104 return _column_index; 105 } 106 107 PortGroupList const * rows () const; 108 boost::shared_ptr<const PortGroup> visible_rows () const; 109 110 /** @return index into the _ports array for the list which is displayed as rows */ row_index()111 int row_index () const { 112 return _row_index; 113 } 114 ports(int d)115 PortGroupList const * ports (int d) const { 116 return &_ports[d]; 117 } 118 119 boost::shared_ptr<const PortGroup> visible_ports (int d) const; 120 121 void init (); 122 void setup (); 123 virtual void setup_ports (int) = 0; 124 void setup_all_ports (); 125 126 std::pair<uint32_t, uint32_t> max_size () const; 127 128 bool should_show (ARDOUR::DataType) const; 129 uint32_t count_of_our_type (ARDOUR::ChanCount) const; 130 uint32_t count_of_our_type_min_1 (ARDOUR::ChanCount) const; 131 132 PortMatrixNode::State get_association (PortMatrixNode) const; 133 134 void flip (); 135 bool key_press (GdkEventKey *); 136 137 /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1]. 138 * @param s New state. 139 */ 140 virtual void set_state (ARDOUR::BundleChannel c[2], bool s) = 0; 141 142 /** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1]. 143 * @return state 144 */ 145 virtual PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const = 0; 146 virtual bool list_is_global (int) const = 0; 147 148 virtual bool can_add_channels (boost::shared_ptr<ARDOUR::Bundle>) const; 149 virtual void add_channel (boost::shared_ptr<ARDOUR::Bundle>, ARDOUR::DataType); 150 virtual bool can_remove_channels (boost::shared_ptr<ARDOUR::Bundle>) const; 151 virtual void remove_channel (ARDOUR::BundleChannel); 152 virtual void remove_all_channels (boost::weak_ptr<ARDOUR::Bundle>); can_rename_channels(boost::shared_ptr<ARDOUR::Bundle>)153 virtual bool can_rename_channels (boost::shared_ptr<ARDOUR::Bundle>) const { 154 return false; 155 } 156 virtual bool can_add_port (boost::shared_ptr<ARDOUR::Bundle>, ARDOUR::DataType t) const; rename_channel(ARDOUR::BundleChannel)157 virtual void rename_channel (ARDOUR::BundleChannel) {} 158 virtual std::string disassociation_verb () const = 0; 159 virtual std::string channel_noun () const; 160 161 enum Result { 162 Cancelled, 163 Accepted 164 }; 165 166 sigc::signal<void, Result> Finished; 167 168 static bool bundle_with_channels (boost::shared_ptr<ARDOUR::Bundle>); 169 170 protected: 171 172 /** We have two port group lists. One will be presented on the rows of the matrix, 173 the other on the columns. The PortMatrix chooses the arrangement based on which has 174 more ports in it. Subclasses must fill these two lists with the port groups that they 175 wish to present. The PortMatrix will arrange its layout such that signal flow is vaguely 176 from left to right as you go from list 0 to list 1. Hence subclasses which deal with 177 inputs and outputs should put outputs in list 0 and inputs in list 1. */ 178 PortGroupList _ports[2]; 179 180 private: 181 182 void hscroll_changed (); 183 void vscroll_changed (); 184 void routes_changed (); 185 void reconnect_to_routes (); 186 void select_arrangement (); 187 bool can_add_port_proxy (boost::weak_ptr<ARDOUR::Bundle>, ARDOUR::DataType) const; 188 void add_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, ARDOUR::DataType); 189 void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t); 190 void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t); 191 void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int); 192 void disassociate_all_on_bundle (boost::weak_ptr<ARDOUR::Bundle>, int); 193 void setup_global_ports (); 194 void setup_global_ports_proxy (); 195 void toggle_show_only_bundles (); 196 bool on_scroll_event (GdkEventScroll *); 197 boost::shared_ptr<ARDOUR::IO> io_from_bundle (boost::shared_ptr<ARDOUR::Bundle>) const; 198 void setup_notebooks (); 199 void remove_notebook_pages (Gtk::Notebook &); 200 void notebook_page_selected (GtkNotebookPage *, guint); 201 void route_processors_changed (ARDOUR::RouteProcessorChange); 202 void body_dimensions_changed (); 203 void session_going_away (); 204 void add_remove_option (Gtk::Menu_Helpers::MenuList &, boost::weak_ptr<ARDOUR::Bundle>, int); 205 void add_disassociate_option (Gtk::Menu_Helpers::MenuList &, boost::weak_ptr<ARDOUR::Bundle>, int, int); 206 void port_connected_or_disconnected (); 207 void update_tab_highlighting (); 208 std::pair<int, int> check_flip () const; 209 bool can_flip () const; 210 void parameter_changed (std::string); 211 212 Gtk::Window* _parent; 213 214 /** port type that we are working with, or NIL if we are working with all of them */ 215 ARDOUR::DataType _type; 216 PBD::ScopedConnectionList _route_connections; 217 PBD::ScopedConnectionList _changed_connections; 218 PBD::ScopedConnectionList _bundle_changed_connections; 219 220 PortMatrixBody* _body; 221 Gtk::HScrollbar _hscroll; 222 Gtk::VScrollbar _vscroll; 223 Gtk::Notebook _vnotebook; 224 Gtk::Notebook _hnotebook; 225 Gtk::Label _vlabel; 226 Gtk::Label _hlabel; 227 Gtk::VBox _vbox; 228 Gtk::HBox _hbox; 229 Gtk::Label _hspacer; 230 Gtk::Label _vspacer; 231 Gtk::Menu* _menu; 232 Arrangement _arrangement; 233 int _row_index; 234 int _column_index; 235 int _min_height_divisor; 236 bool _show_only_bundles; 237 bool _inhibit_toggle_show_only_bundles; 238 bool _ignore_notebook_page_selected; 239 }; 240 241 #endif 242