NO-OP; clean up script spacing and remove goto
[ardour.git] / gtk2_ardour / plugin_setup_dialog.cc
1 /*
2  * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
3  * Copyright (C) 2011 Paul Davis
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include <gtkmm/frame.h>
21 #include <gtkmm/label.h>
22
23 #include "plugin_setup_dialog.h"
24 #include "pbd/i18n.h"
25
26 using namespace ARDOUR;
27 using namespace Gtk;
28
29 PluginSetupDialog::PluginSetupDialog (boost::shared_ptr<ARDOUR::Route> r, boost::shared_ptr<ARDOUR::PluginInsert> pi, ARDOUR::Route::PluginSetupOptions flags)
30         : ArdourDialog (_("Plugin Setup"), true, false)
31         , _route (r)
32         , _pi (pi)
33         , _keep_mapping (_("Copy I/O Map"), ArdourButton::led_default_elements)
34         , _fan_out (_("Fan out"), ArdourButton::led_default_elements)
35 {
36         assert (flags != Route::None);
37
38         Gtk::Table *tbl = manage (new Gtk::Table ());
39         tbl->set_spacings (6);
40         get_vbox()->pack_start (*tbl);
41         int row = 0;
42
43         if (flags & Route::CanReplace) {
44                 boost::shared_ptr<Processor> old = _route->the_instrument ();
45                 boost::shared_ptr<PluginInsert> opi = boost::dynamic_pointer_cast<PluginInsert> (old);
46                 assert (opi);
47
48                 opi->configured_io (_cur_inputs, _cur_outputs);
49
50                 Gtk::Label* l = manage (new Label (
51                                                 _("An Instrument plugin is already present.")
52                                                 ));
53                 tbl->attach (*l, 0, 2, row, row + 1, EXPAND|FILL, SHRINK); ++row;
54
55                 l = manage (new Label (_("Replace"), ALIGN_END));
56                 tbl->attach (*l, 0, 1, row, row + 1, EXPAND|FILL, SHRINK);
57
58                 l = manage (new Label (string_compose ("'%1'", old->name ()), ALIGN_START));
59                 tbl->attach (*l, 1, 2, row, row + 1, EXPAND|FILL, SHRINK); ++row;
60
61                 l = manage (new Label (_("with"), ALIGN_END));
62                 tbl->attach (*l, 0, 1, row, row + 1, EXPAND|FILL, SHRINK);
63
64                 l = manage (new Label (string_compose ("'%1'", pi->name ()), ALIGN_START));
65                 tbl->attach (*l, 1, 2, row, row + 1, EXPAND|FILL, SHRINK); ++row;
66
67                 Box* box = manage (new HBox ());
68                 box->set_border_width (2);
69                 box->pack_start (_keep_mapping, true, true);
70                 Frame* f = manage (new Frame ());
71                 f->set_label (_("I/O Pin Mapping"));
72                 f->add (*box);
73                 tbl->attach (*f, 0, 1, row, row + 1, EXPAND|FILL, SHRINK, 0, 8);
74
75                 _keep_mapping.signal_clicked.connect (sigc::mem_fun (*this, &PluginSetupDialog::apply_mapping));
76                 add_button ("Replace", 2);
77         } else {
78
79                 Gtk::Label *l = manage (new Label (string_compose (
80                                                 _("Configure Plugin '%1'"), pi->name ()
81                                                 )));
82                 tbl->attach (*l, 0, 2, row, row + 1, EXPAND|FILL, SHRINK); ++row;
83         }
84
85         if (flags & Route::MultiOut) {
86                 setup_output_presets ();
87                 Box* box = manage (new HBox ());
88                 box->set_border_width (2);
89                 box->pack_start (_out_presets, true, true);
90                 box->pack_start (_fan_out, false, false);
91                 Frame* f = manage (new Frame ());
92                 f->set_label (_("Output Configuration"));
93                 f->add (*box);
94                 tbl->attach (*f, 1, 2, row, row + 1, EXPAND|FILL, SHRINK, 0, 8);
95                 _fan_out.signal_clicked.connect (sigc::mem_fun (*this, &PluginSetupDialog::toggle_fan_out));
96         } else {
97                 _pi->set_preset_out (_pi->natural_output_streams ());
98                 update_sensitivity (_pi->natural_output_streams ().n_audio ());
99         }
100
101         _keep_mapping.set_active (false);
102         _fan_out.set_active (false);
103         apply_mapping ();
104
105         add_button (Stock::ADD, 0);
106         add_button (Stock::CANCEL, 1);
107         set_default_response (0);
108         show_all ();
109 }
110
111
112 void
113 PluginSetupDialog::setup_output_presets ()
114 {
115         // compare to PluginPinDialog::refill_output_presets ()
116         using namespace Menu_Helpers;
117         PluginOutputConfiguration ppc (_pi->plugin (0)->possible_output ());
118
119         _out_presets.AddMenuElem (MenuElem (_("Automatic"), sigc::bind (sigc::mem_fun (*this, &PluginSetupDialog::select_output_preset), 0)));
120
121         if (ppc.find (0) != ppc.end ()) {
122                 // anyting goes
123                 ppc.clear ();
124                 ppc.insert (1);
125                 ppc.insert (2);
126                 ppc.insert (8);
127                 ppc.insert (16);
128                 ppc.insert (24);
129                 ppc.insert (32);
130                 if (ppc.find (_cur_outputs.n_audio ()) == ppc.end ()) {
131                         ppc.insert (_cur_outputs.n_audio ());
132                 }
133         }
134
135         bool have_matching_io = false;
136
137         for (PluginOutputConfiguration::const_iterator i = ppc.begin () ; i != ppc.end (); ++i) {
138                 assert (*i > 0);
139                 _out_presets.AddMenuElem (MenuElem (preset_label (*i), sigc::bind (sigc::mem_fun (*this, &PluginSetupDialog::select_output_preset), *i)));
140                 if (*i == _cur_outputs.n_audio ()) {
141                         have_matching_io = true;
142                 }
143         }
144
145         if (have_matching_io) {
146                 select_output_preset (_cur_outputs.n_audio ());
147         } else {
148                 select_output_preset (0);
149         }
150 }
151
152 void
153 PluginSetupDialog::select_output_preset (uint32_t n_audio)
154 {
155         _pi->set_preset_out (ChanCount (DataType::AUDIO, n_audio));
156         _out_presets.set_text (preset_label (n_audio));
157         update_sensitivity (n_audio);
158 }
159
160 void
161 PluginSetupDialog::update_sensitivity (uint32_t n_audio)
162 {
163         if (_cur_outputs.n_audio () > 0 && _cur_outputs.n_audio () == n_audio) {
164                 // TODO check _cur_inputs if not reconfigurable?
165                 _keep_mapping.set_sensitive (true);
166         } else {
167                 _keep_mapping.set_sensitive (false);
168         }
169         _fan_out.set_sensitive (n_audio > 2);
170 }
171
172 bool
173 PluginSetupDialog::io_match () const
174 {
175         if (_cur_outputs.n_audio () > 0 && _cur_outputs.n_audio () == _pi->preset_out ().n_audio ()) {
176                 return true;
177         } else {
178                 return false;
179         }
180 }
181
182 void
183 PluginSetupDialog::apply_mapping ()
184 {
185         // toggle button
186         _keep_mapping.set_active (!_keep_mapping.get_active ());
187
188         boost::shared_ptr<Processor> old = _route->the_instrument ();
189         boost::shared_ptr<PluginInsert> opi = boost::dynamic_pointer_cast<PluginInsert> (old);
190
191         if (_keep_mapping.get_active () && opi && io_match ()) {
192                 _pi->pre_seed (_cur_inputs, _cur_outputs, opi->input_map (0), opi->output_map (0), opi->thru_map ());
193         } else {
194                 _pi->pre_seed (ChanCount (), ChanCount (), ChanMapping (), ChanMapping (), ChanMapping());
195         }
196 }
197
198 void
199 PluginSetupDialog::toggle_fan_out ()
200 {
201         _fan_out.set_active (!_fan_out.get_active ());
202 }
203
204 std::string
205 PluginSetupDialog::preset_label (uint32_t n_audio) const
206 {
207                 std::string rv;
208                 switch (n_audio) {
209                         case 0:
210                                 rv = _("Automatic");
211                                 break;
212                         case 1:
213                                 rv = _("Mono");
214                                 break;
215                         case 2:
216                                 rv = _("Stereo");
217                                 break;
218                         default:
219                                 rv = string_compose (P_("%1 Channel", "%1 Channels", n_audio), n_audio);
220                                 break;
221                 }
222                 return rv;
223 }