0bcdb5dc396000411a6fb8bf5a1cc617ac558f74
[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             ParamLabelModelString *ps = new ParamLabelModelString();
220             ps->s = encoder_config.entries[i].param;
221             connect (ps->signal_value_changed, [this,i] (const std::string& s) { on_change_enc_entry (i, s.c_str(), nullptr); });
222
223             ParamLabelModelString *vs = new ParamLabelModelString();
224             vs->s = encoder_config.entries[i].value;
225             connect (vs->signal_value_changed, [this,i] (const std::string& s) { on_change_enc_entry (i, nullptr, s.c_str()); });
226
227             ParamLabel *plabel = new ParamLabel (scroll_widget, ps);
228             ParamLabel *vlabel = new ParamLabel (scroll_widget, vs);
229             ToolButton *tbutton = new ToolButton (scroll_widget, 'x');
230
231             grid.add_widget (plabel, 2, y, 20, 3);
232             grid.add_widget (vlabel, 21, y, 11, 3);
233             grid.add_widget (tbutton, 32.5, y + 0.5, 2, 2);
234             y += 3;
235             enc_widgets.push_back (plabel);
236             enc_widgets.push_back (vlabel);
237             enc_widgets.push_back (tbutton);
238
239             connect (tbutton->signal_clicked, [this,i]() { on_remove_enc_entry (i); });
240           }
241         Button *add_button = new Button (scroll_widget, "Add Entry");
242         grid.add_widget (add_button, 2, y, 12, 3);
243         connect (add_button->signal_clicked, this, &InstEditParams::on_add_enc_entry);
244         enc_widgets.push_back (add_button);
245         y += 3;
246       }
247
248     scroll_widget->height = y * 8;
249     scroll_widget->width = 32 * 8;
250     scroll_view->on_widget_size_changed();
251   }
252   void
253   on_auto_volume_changed (bool new_value)
254   {
255     Instrument::AutoVolume av = instrument->auto_volume();
256     av.enabled = new_value;
257
258     instrument->set_auto_volume (av);
259   }
260   void
261   on_auto_volume_method_changed()
262   {
263     Instrument::AutoVolume av = instrument->auto_volume();
264
265     int idx = auto_volume_method_combobox->current_index();
266     if (idx == 0)
267       av.method = Instrument::AutoVolume::FROM_LOOP;
268     else
269       av.method = Instrument::AutoVolume::GLOBAL;
270
271     instrument->set_auto_volume (av);
272   }
273   void
274   on_auto_volume_gain_changed (double gain)
275   {
276     Instrument::AutoVolume av = instrument->auto_volume();
277     av.gain = gain;
278
279     instrument->set_auto_volume (av);
280   }
281   void
282   on_auto_tune_changed (bool new_value)
283   {
284     auto at = instrument->auto_tune();
285     at.enabled = new_value;
286
287     instrument->set_auto_tune (at);
288   }
289   void
290   on_auto_tune_method_changed()
291   {
292     auto at = instrument->auto_tune();
293
294     int idx = auto_tune_method_combobox->current_index();
295     if (idx == 0)
296       at.method = Instrument::AutoTune::SIMPLE;
297     if (idx == 1)
298       at.method = Instrument::AutoTune::ALL_FRAMES;
299     if (idx == 2)
300       at.method = Instrument::AutoTune::SMOOTH;
301
302     instrument->set_auto_tune (at);
303   }
304   void
305   on_auto_tune_partials_changed (int p)
306   {
307     auto at = instrument->auto_tune();
308     at.partials = p;
309
310     instrument->set_auto_tune (at);
311   }
312   void
313   on_auto_tune_time_changed (double t)
314   {
315     auto at = instrument->auto_tune();
316     at.time = t;
317
318     instrument->set_auto_tune (at);
319   }
320   void
321   on_auto_tune_amount_changed (double a)
322   {
323     auto at = instrument->auto_tune();
324     at.amount = a;
325
326     instrument->set_auto_tune (at);
327   }
328   void
329   on_enc_cfg_changed (bool new_value)
330   {
331     auto enc_cfg = instrument->encoder_config();
332     enc_cfg.enabled = new_value;
333
334     instrument->set_encoder_config (enc_cfg);
335   }
336   void
337   on_remove_enc_entry (size_t i)
338   {
339     auto enc_cfg = instrument->encoder_config();
340
341     if (i < enc_cfg.entries.size())
342       enc_cfg.entries.erase (enc_cfg.entries.begin() + i);
343
344     instrument->set_encoder_config (enc_cfg);
345   }
346   void
347   on_add_enc_entry()
348   {
349     auto enc_cfg = instrument->encoder_config();
350
351     Instrument::EncoderEntry entry {"key", "value" };
352     enc_cfg.entries.push_back (entry);
353
354     instrument->set_encoder_config (enc_cfg);
355   }
356   void
357   on_change_enc_entry (size_t i, const char *k, const char *v)
358   {
359     auto enc_cfg = instrument->encoder_config();
360
361     if (i < enc_cfg.entries.size())
362       {
363         if (k)
364           enc_cfg.entries[i].param = k;
365         if (v)
366           enc_cfg.entries[i].value = v;
367       }
368
369     instrument->set_encoder_config (enc_cfg);
370   }
371 };
372
373 }
374
375 #endif