f1790740a5732f7d0b2714f86f0a7caf054abe11
[spectmorph.git] / glui / sminsteditparams.hh
1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2
3 #ifndef SPECTMORPH_INST_EDIT_PARAMS_HH
4 #define SPECTMORPH_INST_EDIT_PARAMS_HH
5
6 #include "smcheckbox.hh"
7 #include "smparamlabel.hh"
8 #include "smbutton.hh"
9
10 namespace SpectMorph
11 {
12
13 class InstEditParams : public Window
14 {
15   Instrument *instrument = nullptr;
16
17   CheckBox   *auto_volume_checkbox = nullptr;
18   ComboBox   *auto_volume_method_combobox = nullptr;
19   Label      *auto_volume_method_label = nullptr;
20   Label      *auto_volume_gain_label = nullptr;
21   ParamLabel *auto_volume_gain_param_label = nullptr;
22
23   CheckBox   *auto_tune_checkbox = nullptr;
24   ComboBox   *auto_tune_method_combobox = nullptr;
25   Label      *auto_tune_method_label = nullptr;
26
27   Label      *auto_tune_partials_label = nullptr;
28   ParamLabel *auto_tune_partials_param_label = nullptr;
29
30   Label      *auto_tune_time_label = nullptr;
31   ParamLabel *auto_tune_time_param_label = nullptr;
32
33   Label      *auto_tune_amount_label = nullptr;
34   ParamLabel *auto_tune_amount_param_label = nullptr;
35
36   CheckBox   *enc_cfg_checkbox = nullptr;
37   std::vector<Widget *> enc_widgets;
38
39   ScrollView *scroll_view = nullptr;
40   Widget     *scroll_widget = nullptr;
41 public:
42   InstEditParams (Window *window, Instrument *instrument) :
43     Window ("Instrument Params", 320, 400, 0, false, window->native_window()),
44     instrument (instrument)
45   {
46     window->add_child_window (this);
47     set_close_callback ([this,window]() { window->remove_child_window (this); });
48
49     FixedGrid grid;
50     grid.add_widget (scroll_view = new ScrollView (this), 1, 1, width / 8 - 2, height / 8 - 2);
51     scroll_widget = new Widget (scroll_view);
52     scroll_view->set_scroll_widget (scroll_widget, false, true);
53
54     auto_volume_checkbox = new CheckBox (scroll_widget, "Auto Volume");
55     connect (auto_volume_checkbox->signal_toggled, this, &InstEditParams::on_auto_volume_changed);
56
57     /*--- auto volume method ---*/
58     auto_volume_method_combobox = new ComboBox (scroll_widget);
59     auto_volume_method_label = new Label (scroll_widget, "Method");
60
61     connect (auto_volume_method_combobox->signal_item_changed, this, &InstEditParams::on_auto_volume_method_changed);
62     auto_volume_method_combobox->add_item ("From Loop"); // default
63     auto_volume_method_combobox->add_item ("Global");
64
65     /*--- auto volume gain ---*/
66     auto_volume_gain_label = new Label (scroll_widget, "Gain");
67
68     auto gain_mod = new ParamLabelModelDouble (instrument->auto_volume().gain, -48.0, 48.0, "%.2f", "%.2f dB");
69     auto_volume_gain_param_label = new ParamLabel (scroll_widget, gain_mod);
70
71     connect (gain_mod->signal_value_changed, this, &InstEditParams::on_auto_volume_gain_changed);
72
73     auto_tune_checkbox = new CheckBox (scroll_widget, "Auto Tune");
74     connect (auto_tune_checkbox->signal_toggled, this, &InstEditParams::on_auto_tune_changed);
75
76     /*--- auto tune method ---*/
77     auto_tune_method_combobox = new ComboBox (scroll_widget);
78     auto_tune_method_label = new Label (scroll_widget, "Method");
79
80     connect (auto_tune_method_combobox->signal_item_changed, this, &InstEditParams::on_auto_tune_method_changed);
81     auto_tune_method_combobox->add_item ("Simple"); // default
82     auto_tune_method_combobox->add_item ("All Frames");
83     auto_tune_method_combobox->add_item ("Smooth");
84
85     /*--- auto tune partials ---*/
86     auto_tune_partials_label = new Label (scroll_widget, "Partials");
87
88     auto partials_mod = new ParamLabelModelInt (instrument->auto_tune().partials, 1, 3);
89     auto_tune_partials_param_label = new ParamLabel (scroll_widget, partials_mod);
90
91     connect (partials_mod->signal_value_changed, this, &InstEditParams::on_auto_tune_partials_changed);
92
93     /*--- auto tune time ---*/
94     auto_tune_time_label = new Label (scroll_widget, "Time");
95
96     auto time_mod = new ParamLabelModelDouble (instrument->auto_tune().time, 1, 2000, "%.2f", "%.2f ms");
97     auto_tune_time_param_label = new ParamLabel (scroll_widget, time_mod);
98
99     connect (time_mod->signal_value_changed, this, &InstEditParams::on_auto_tune_time_changed);
100
101     /*--- auto tune amount ---*/
102     auto_tune_amount_label = new Label (scroll_widget, "Amount");
103
104     auto amount_mod = new ParamLabelModelDouble (instrument->auto_tune().amount, 0, 100, "%.1f", "%.1f %%");
105     auto_tune_amount_param_label = new ParamLabel (scroll_widget, amount_mod);
106
107     connect (time_mod->signal_value_changed, this, &InstEditParams::on_auto_tune_amount_changed);
108
109     /*--- encoder config ---*/
110     enc_cfg_checkbox = new CheckBox (scroll_widget, "Custom Analysis Parameters");
111     connect (enc_cfg_checkbox->signal_toggled, this, &InstEditParams::on_enc_cfg_changed);
112
113
114     connect (instrument->signal_global_changed, this, &InstEditParams::on_global_changed);
115     on_global_changed();
116     show();
117   }
118   void
119   on_global_changed()
120   {
121     FixedGrid grid;
122
123     const auto auto_volume = instrument->auto_volume();
124     auto_volume_checkbox->set_checked (auto_volume.enabled);
125     auto_volume_method_label->set_visible (auto_volume.enabled);
126     auto_volume_method_combobox->set_visible (auto_volume.enabled);
127     auto_volume_gain_label->set_visible (auto_volume.enabled && auto_volume.method == Instrument::AutoVolume::GLOBAL);
128     auto_volume_gain_param_label->set_visible (auto_volume.enabled && auto_volume.method == Instrument::AutoVolume::GLOBAL);
129
130     double y = 0;
131     grid.add_widget (auto_volume_checkbox, 0, y, 20, 2);
132     y += 2;
133     if (auto_volume.enabled)
134       {
135         grid.add_widget (auto_volume_method_label, 2, y, 10, 3);
136         grid.add_widget (auto_volume_method_combobox, 11, y, 23, 3);
137         y += 3;
138         if (auto_volume.method == Instrument::AutoVolume::GLOBAL)
139           {
140             grid.add_widget (auto_volume_gain_label, 2, y, 10, 3);
141             grid.add_widget (auto_volume_gain_param_label, 11, y, 10, 3);
142             y += 3;
143           }
144       }
145     const auto auto_tune = instrument->auto_tune();
146     auto_tune_method_label->set_visible (auto_tune.enabled);
147     auto_tune_method_combobox->set_visible (auto_tune.enabled);
148
149     auto_tune_partials_label->set_visible (auto_tune.enabled &&
150       (auto_tune.method == Instrument::AutoTune::ALL_FRAMES || auto_tune.method == Instrument::AutoTune::SMOOTH));
151     auto_tune_partials_param_label->set_visible (auto_tune_partials_label->visible());
152
153     auto_tune_time_label->set_visible (auto_tune.enabled && auto_tune.method == Instrument::AutoTune::SMOOTH);
154     auto_tune_time_param_label->set_visible (auto_tune_time_label->visible());
155
156     auto_tune_amount_label->set_visible (auto_tune.enabled && auto_tune.method == Instrument::AutoTune::SMOOTH);
157     auto_tune_amount_param_label->set_visible (auto_tune_amount_label->visible());
158
159     grid.add_widget (auto_tune_checkbox, 0, y, 20, 2);
160     y += 2;
161     if (auto_tune.enabled)
162       {
163         grid.add_widget (auto_tune_method_label, 2, y, 10, 3);
164         grid.add_widget (auto_tune_method_combobox, 11, y, 23, 3);
165         y += 3;
166         if (auto_tune_partials_label->visible())
167           {
168             grid.add_widget (auto_tune_partials_label, 2, y, 10, 3);
169             grid.add_widget (auto_tune_partials_param_label, 11, y, 10, 3);
170             y += 3;
171           }
172         if (auto_tune_time_label->visible())
173           {
174             grid.add_widget (auto_tune_time_label, 2, y, 10, 3);
175             grid.add_widget (auto_tune_time_param_label, 11, y, 10, 3);
176             y += 3;
177           }
178         if (auto_tune_amount_label->visible())
179           {
180             grid.add_widget (auto_tune_amount_label, 2, y, 10, 3);
181             grid.add_widget (auto_tune_amount_param_label, 11, y, 10, 3);
182             y += 3;
183           }
184       }
185     grid.add_widget (enc_cfg_checkbox, 0, y, 30, 2);
186     y += 2;
187
188     switch (auto_tune.method)
189     {
190       case Instrument::AutoTune::SIMPLE:
191         auto_tune_method_combobox->set_text ("Simple");
192         break;
193       case Instrument::AutoTune::ALL_FRAMES:
194         auto_tune_method_combobox->set_text ("All Frames");
195         break;
196       case Instrument::AutoTune::SMOOTH:
197         auto_tune_method_combobox->set_text ("Smooth");
198         break;
199     }
200
201     auto_tune_checkbox->set_checked (instrument->auto_tune().enabled);
202     enc_cfg_checkbox->set_checked (instrument->encoder_config().enabled);
203
204     if (instrument->auto_volume().method == Instrument::AutoVolume::GLOBAL)
205       auto_volume_method_combobox->set_text ("Global");
206     else
207       auto_volume_method_combobox->set_text ("From Loop");
208
209     auto encoder_config = instrument->encoder_config();
210
211     for (auto w : enc_widgets) /* delete old enc widgets */
212       w->delete_later();
213     enc_widgets.clear();
214
215     if (encoder_config.enabled)
216       {
217         for (size_t i = 0; i < encoder_config.entries.size(); i++)
218           {
219             auto param_mod = new ParamLabelModelString (encoder_config.entries[i].param);
220             connect (param_mod->signal_value_changed, [this,i] (const std::string& s) { on_change_enc_entry (i, s.c_str(), nullptr); });
221
222             auto value_mod = new ParamLabelModelString (encoder_config.entries[i].value);
223             connect (value_mod->signal_value_changed, [this,i] (const std::string& s) { on_change_enc_entry (i, nullptr, s.c_str()); });
224
225             ParamLabel *plabel = new ParamLabel (scroll_widget, param_mod);
226             ParamLabel *vlabel = new ParamLabel (scroll_widget, value_mod);
227             ToolButton *tbutton = new ToolButton (scroll_widget, 'x');
228
229             grid.add_widget (plabel, 2, y, 20, 3);
230             grid.add_widget (vlabel, 21, y, 11, 3);
231             grid.add_widget (tbutton, 32.5, y + 0.5, 2, 2);
232             y += 3;
233             enc_widgets.push_back (plabel);
234             enc_widgets.push_back (vlabel);
235             enc_widgets.push_back (tbutton);
236
237             connect (tbutton->signal_clicked, [this,i]() { on_remove_enc_entry (i); });
238           }
239         Button *add_button = new Button (scroll_widget, "Add Entry");
240         grid.add_widget (add_button, 2, y, 12, 3);
241         connect (add_button->signal_clicked, this, &InstEditParams::on_add_enc_entry);
242         enc_widgets.push_back (add_button);
243         y += 3;
244       }
245
246     scroll_widget->height = y * 8;
247     scroll_widget->width = 32 * 8;
248     scroll_view->on_widget_size_changed();
249   }
250   void
251   on_auto_volume_changed (bool new_value)
252   {
253     Instrument::AutoVolume av = instrument->auto_volume();
254     av.enabled = new_value;
255
256     instrument->set_auto_volume (av);
257   }
258   void
259   on_auto_volume_method_changed()
260   {
261     Instrument::AutoVolume av = instrument->auto_volume();
262
263     int idx = auto_volume_method_combobox->current_index();
264     if (idx == 0)
265       av.method = Instrument::AutoVolume::FROM_LOOP;
266     else
267       av.method = Instrument::AutoVolume::GLOBAL;
268
269     instrument->set_auto_volume (av);
270   }
271   void
272   on_auto_volume_gain_changed (double gain)
273   {
274     Instrument::AutoVolume av = instrument->auto_volume();
275     av.gain = gain;
276
277     instrument->set_auto_volume (av);
278   }
279   void
280   on_auto_tune_changed (bool new_value)
281   {
282     auto at = instrument->auto_tune();
283     at.enabled = new_value;
284
285     instrument->set_auto_tune (at);
286   }
287   void
288   on_auto_tune_method_changed()
289   {
290     auto at = instrument->auto_tune();
291
292     int idx = auto_tune_method_combobox->current_index();
293     if (idx == 0)
294       at.method = Instrument::AutoTune::SIMPLE;
295     if (idx == 1)
296       at.method = Instrument::AutoTune::ALL_FRAMES;
297     if (idx == 2)
298       at.method = Instrument::AutoTune::SMOOTH;
299
300     instrument->set_auto_tune (at);
301   }
302   void
303   on_auto_tune_partials_changed (int p)
304   {
305     auto at = instrument->auto_tune();
306     at.partials = p;
307
308     instrument->set_auto_tune (at);
309   }
310   void
311   on_auto_tune_time_changed (double t)
312   {
313     auto at = instrument->auto_tune();
314     at.time = t;
315
316     instrument->set_auto_tune (at);
317   }
318   void
319   on_auto_tune_amount_changed (double a)
320   {
321     auto at = instrument->auto_tune();
322     at.amount = a;
323
324     instrument->set_auto_tune (at);
325   }
326   void
327   on_enc_cfg_changed (bool new_value)
328   {
329     auto enc_cfg = instrument->encoder_config();
330     enc_cfg.enabled = new_value;
331
332     instrument->set_encoder_config (enc_cfg);
333   }
334   void
335   on_remove_enc_entry (size_t i)
336   {
337     auto enc_cfg = instrument->encoder_config();
338
339     if (i < enc_cfg.entries.size())
340       enc_cfg.entries.erase (enc_cfg.entries.begin() + i);
341
342     instrument->set_encoder_config (enc_cfg);
343   }
344   void
345   on_add_enc_entry()
346   {
347     auto enc_cfg = instrument->encoder_config();
348
349     Instrument::EncoderEntry entry {"key", "value" };
350     enc_cfg.entries.push_back (entry);
351
352     instrument->set_encoder_config (enc_cfg);
353   }
354   void
355   on_change_enc_entry (size_t i, const char *k, const char *v)
356   {
357     auto enc_cfg = instrument->encoder_config();
358
359     if (i < enc_cfg.entries.size())
360       {
361         if (k)
362           enc_cfg.entries[i].param = k;
363         if (v)
364           enc_cfg.entries[i].value = v;
365       }
366
367     instrument->set_encoder_config (enc_cfg);
368   }
369 };
370
371 }
372
373 #endif