2 Copyright (C) 2002-2007 Paul Davis
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.
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.
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.
20 #include <gtkmm/messagedialog.h>
21 #include <glibmm/objectbase.h>
23 #include <gtkmm2ext/doi.h>
25 #include "ardour/port_insert.h"
26 #include "ardour/session.h"
27 #include "ardour/io.h"
28 #include "ardour/audioengine.h"
29 #include "ardour/track.h"
30 #include "ardour/audio_track.h"
31 #include "ardour/midi_track.h"
32 #include "ardour/data_type.h"
33 #include "ardour/port.h"
34 #include "ardour/bundle.h"
36 #include "io_selector.h"
38 #include "gui_thread.h"
41 using namespace ARDOUR
;
44 IOSelector::IOSelector (Gtk::Window
* p
, ARDOUR::Session
& session
, boost::shared_ptr
<ARDOUR::IO
> io
)
45 : PortMatrix (p
, session
, io
->default_type())
48 /* signal flow from 0 to 1 */
50 _find_inputs_for_io_outputs
= (_io
->direction() == IO::Output
);
52 if (_find_inputs_for_io_outputs
) {
60 _port_group
.reset (new PortGroup (""));
61 _ports
[_ours
].add_group (_port_group
);
67 IOSelector::setup_ports (int dim
)
69 _ports
[dim
].suspend_signals ();
73 _ports
[_other
].gather (_session
, _find_inputs_for_io_outputs
);
77 _port_group
->clear ();
78 _port_group
->add_bundle (_io
->bundle (), _io
);
81 _ports
[dim
].resume_signals ();
85 IOSelector::set_state (ARDOUR::BundleChannel c
[2], bool s
)
87 ARDOUR::Bundle::PortList
const & our_ports
= c
[_ours
].bundle
->channel_ports (c
[_ours
].channel
);
88 ARDOUR::Bundle::PortList
const & other_ports
= c
[_other
].bundle
->channel_ports (c
[_other
].channel
);
90 for (ARDOUR::Bundle::PortList::const_iterator i
= our_ports
.begin(); i
!= our_ports
.end(); ++i
) {
91 for (ARDOUR::Bundle::PortList::const_iterator j
= other_ports
.begin(); j
!= other_ports
.end(); ++j
) {
93 Port
* f
= _session
.engine().get_port_by_name (*i
);
99 _io
->connect (f
, *j
, 0);
101 _io
->disconnect (f
, *j
, 0);
107 PortMatrixNode::State
108 IOSelector::get_state (ARDOUR::BundleChannel c
[2]) const
110 ARDOUR::Bundle::PortList
const & our_ports
= c
[_ours
].bundle
->channel_ports (c
[_ours
].channel
);
111 ARDOUR::Bundle::PortList
const & other_ports
= c
[_other
].bundle
->channel_ports (c
[_other
].channel
);
113 if (our_ports
.empty() || other_ports
.empty()) {
114 /* we're looking at a bundle with no parts associated with this channel,
115 so nothing to connect */
116 return PortMatrixNode::UNKNOWN
;
119 for (ARDOUR::Bundle::PortList::const_iterator i
= our_ports
.begin(); i
!= our_ports
.end(); ++i
) {
120 for (ARDOUR::Bundle::PortList::const_iterator j
= other_ports
.begin(); j
!= other_ports
.end(); ++j
) {
122 Port
* f
= _session
.engine().get_port_by_name (*i
);
124 /* since we are talking about an IO, our ports should all have an associated Port *,
125 so the above call should never fail */
128 if (!f
->connected_to (*j
)) {
129 /* if any one thing is not connected, all bets are off */
130 return PortMatrixNode::NOT_ASSOCIATED
;
135 return PortMatrixNode::ASSOCIATED
;
139 IOSelector::n_io_ports () const
141 if (!_find_inputs_for_io_outputs
) {
142 return _io
->n_ports().get (_io
->default_type());
144 return _io
->n_ports().get (_io
->default_type());
149 IOSelector::list_is_global (int dim
) const
151 return (dim
== _other
);
154 IOSelectorWindow::IOSelectorWindow (ARDOUR::Session
& session
, boost::shared_ptr
<ARDOUR::IO
> io
, bool /*can_cancel*/)
155 : _selector (this, session
, io
)
157 set_name ("IOSelectorWindow2");
158 set_title (_("I/O selector"));
162 set_position (Gtk::WIN_POS_MOUSE
);
164 io_name_changed (this);
168 signal_delete_event().connect (mem_fun (*this, &IOSelectorWindow::wm_delete
));
172 IOSelectorWindow::wm_delete (GdkEventAny
* /*event*/)
174 _selector
.Finished (IOSelector::Accepted
);
181 IOSelectorWindow::on_map ()
183 _selector
.setup_all_ports ();
188 IOSelectorWindow::on_show ()
190 Gtk::Window::on_show ();
191 pair
<uint32_t, uint32_t> const pm_max
= _selector
.max_size ();
192 resize_window_to_proportion_of_monitor (this, pm_max
.first
, pm_max
.second
);
196 IOSelectorWindow::io_name_changed (void* src
)
198 ENSURE_GUI_THREAD(bind (mem_fun(*this, &IOSelectorWindow::io_name_changed
), src
));
202 if (!_selector
.find_inputs_for_io_outputs()) {
203 title
= string_compose(_("%1 input"), _selector
.io()->name());
205 title
= string_compose(_("%1 output"), _selector
.io()->name());
211 PortInsertUI::PortInsertUI (Gtk::Window
* parent
, ARDOUR::Session
& sess
, boost::shared_ptr
<ARDOUR::PortInsert
> pi
)
212 : input_selector (parent
, sess
, pi
->input())
213 , output_selector (parent
, sess
, pi
->output())
215 output_selector
.set_min_height_divisor (2);
216 input_selector
.set_min_height_divisor (2);
218 pack_start (output_selector
, true, true);
219 pack_start (input_selector
, true, true);
223 PortInsertUI::redisplay ()
225 input_selector
.setup_ports (input_selector
.other());
226 output_selector
.setup_ports (output_selector
.other());
230 PortInsertUI::finished (IOSelector::Result r
)
232 input_selector
.Finished (r
);
233 output_selector
.Finished (r
);
237 PortInsertWindow::PortInsertWindow (ARDOUR::Session
& sess
, boost::shared_ptr
<ARDOUR::PortInsert
> pi
, bool can_cancel
)
238 : ArdourDialog ("port insert dialog"),
239 _portinsertui (this, sess
, pi
),
240 ok_button (can_cancel
? _("OK"): _("Close")),
241 cancel_button (_("Cancel"))
244 set_name ("IOSelectorWindow");
245 string title
= _("ardour: ");
249 ok_button
.set_name ("IOSelectorButton");
251 ok_button
.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::CLOSE
, Gtk::ICON_SIZE_BUTTON
)));
253 cancel_button
.set_name ("IOSelectorButton");
256 cancel_button
.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::CANCEL
, Gtk::ICON_SIZE_BUTTON
)));
257 get_action_area()->pack_start (cancel_button
, false, false);
259 cancel_button
.hide();
261 get_action_area()->pack_start (ok_button
, false, false);
263 get_vbox()->pack_start (_portinsertui
);
265 ok_button
.signal_clicked().connect (mem_fun (*this, &PortInsertWindow::accept
));
266 cancel_button
.signal_clicked().connect (mem_fun (*this, &PortInsertWindow::cancel
));
268 signal_delete_event().connect (mem_fun (*this, &PortInsertWindow::wm_delete
), false);
270 going_away_connection
= pi
->GoingAway
.connect (mem_fun (*this, &PortInsertWindow::plugin_going_away
));
274 PortInsertWindow::wm_delete (GdkEventAny
* /*event*/)
281 PortInsertWindow::plugin_going_away ()
283 ENSURE_GUI_THREAD (mem_fun (*this, &PortInsertWindow::plugin_going_away
));
285 going_away_connection
.disconnect ();
286 delete_when_idle (this);
290 PortInsertWindow::on_map ()
292 _portinsertui
.redisplay ();
298 PortInsertWindow::cancel ()
300 _portinsertui
.finished (IOSelector::Cancelled
);
305 PortInsertWindow::accept ()
307 _portinsertui
.finished (IOSelector::Accepted
);