f6e3518fa1662ecbf74c1a97b3ad3d191874db78
[goodguy/history.git] / cinelerra-5.1 / cinelerra / pluginlv2gui.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2018 GG
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
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "clip.h"
23 #include "cstrdup.h"
24 #include "bchash.h"
25 #include "filexml.h"
26 #include "language.h"
27 #include "mwindow.h"
28 #include "pluginlv2client.h"
29 #include "pluginlv2config.h"
30 #include "pluginlv2gui.h"
31 #include "pluginserver.h"
32 #include "preferences.h"
33 #include "samples.h"
34
35 #include <ctype.h>
36 #include <string.h>
37
38
39 PluginLV2ClientUI::PluginLV2ClientUI(PluginLV2ClientWindow *gui, int x, int y)
40  : BC_GenericButton(x, y, _("UI"))
41 {
42         this->gui = gui;
43 }
44
45 PluginLV2ClientUI::~PluginLV2ClientUI()
46 {
47 }
48
49 int PluginLV2ClientUI::handle_event()
50 {
51         PluginLV2ParentUI *ui = gui->get_ui();
52         if( ui->show() )
53                 flicker(8, 64);
54         return 1;
55 }
56
57 PluginLV2ClientReset::
58 PluginLV2ClientReset(PluginLV2ClientWindow *gui, int x, int y)
59  : BC_GenericButton(x, y, _("Reset"))
60 {
61         this->gui = gui;
62 }
63
64 PluginLV2ClientReset::
65 ~PluginLV2ClientReset()
66 {
67 }
68
69 int PluginLV2ClientReset::handle_event()
70 {
71         PluginLV2Client *client = gui->client;
72         client->config.init_lv2(client->lilv, client);
73         client->config.update();
74         client->update_lv2();
75         gui->update(0);
76         client->send_configure_change();
77         return 1;
78 }
79
80 PluginLV2ClientText::PluginLV2ClientText(PluginLV2ClientWindow *gui, int x, int y, int w)
81  : BC_TextBox(x, y, w, 1, (char *)"")
82 {
83         this->gui = gui;
84 }
85
86 PluginLV2ClientText::~PluginLV2ClientText()
87 {
88 }
89
90 int PluginLV2ClientText::handle_event()
91 {
92         return 0;
93 }
94
95
96 PluginLV2ClientApply::PluginLV2ClientApply(PluginLV2ClientWindow *gui, int x, int y)
97  : BC_GenericButton(x, y, _("Apply"))
98 {
99         this->gui = gui;
100 }
101
102 PluginLV2ClientApply::~PluginLV2ClientApply()
103 {
104 }
105
106 int PluginLV2ClientApply::handle_event()
107 {
108         const char *text = gui->text->get_text();
109         if( text && gui->selected ) {
110                 gui->selected->update(atof(text));
111                 gui->update_selected();
112                 gui->client->send_configure_change();
113         }
114         return 1;
115 }
116
117
118 PluginLV2Client_OptPanel::PluginLV2Client_OptPanel(PluginLV2ClientWindow *gui,
119                 int x, int y, int w, int h)
120  : BC_ListBox(x, y, w, h, LISTBOX_TEXT), opts(items[0]), vals(items[1])
121 {
122         this->gui = gui;
123         update();  // init col/wid/columns
124 }
125
126 PluginLV2Client_OptPanel::~PluginLV2Client_OptPanel()
127 {
128 }
129
130 int PluginLV2Client_OptPanel::selection_changed()
131 {
132         PluginLV2Client_Opt *opt = 0;
133         BC_ListBoxItem *item = get_selection(0, 0);
134         if( item ) {
135                 PluginLV2Client_OptName *opt_name = (PluginLV2Client_OptName *)item;
136                 opt = opt_name->opt;
137         }
138         gui->update(opt);
139         return 1;
140 }
141
142 void PluginLV2Client_OptPanel::update()
143 {
144         opts.remove_all();
145         vals.remove_all();
146         PluginLV2ClientConfig &conf = gui->client->config;
147         for( int i=0; i<conf.size(); ++i ) {
148                 PluginLV2Client_Opt *opt = conf[i];
149                 opts.append(opt->item_name);
150                 vals.append(opt->item_value);
151         }
152         const char *cols[] = { "option", "value", };
153         const int col1_w = 150;
154         int wids[] = { col1_w, get_w()-col1_w };
155         BC_ListBox::update(&items[0], &cols[0], &wids[0], sizeof(items)/sizeof(items[0]));
156 }
157
158 PluginLV2ClientPot::PluginLV2ClientPot(PluginLV2ClientWindow *gui, int x, int y)
159  : BC_FPot(x, y, 0.f, 0.f, 0.f)
160 {
161         this->gui = gui;
162 }
163
164 int PluginLV2ClientPot::handle_event()
165 {
166         if( gui->selected ) {
167                 gui->selected->update(get_value());
168                 gui->update_selected();
169                 gui->client->send_configure_change();
170         }
171         return 1;
172 }
173
174 PluginLV2ClientSlider::PluginLV2ClientSlider(PluginLV2ClientWindow *gui, int x, int y)
175  : BC_FSlider(x, y, 0, gui->get_w()-x-20, gui->get_w()-x-20, 0.f, 0.f, 0.f)
176 {
177         this->gui = gui;
178 }
179
180 int PluginLV2ClientSlider::handle_event()
181 {
182         if( gui->selected ) {
183                 gui->selected->update(get_value());
184                 gui->update_selected();
185                 gui->client->send_configure_change();
186         }
187         return 1;
188 }
189
190 PluginLV2ClientWindow::PluginLV2ClientWindow(PluginLV2Client *client)
191  : PluginClientWindow(client, 500, 300, 500, 300, 1)
192 {
193         this->client = client;
194         selected = 0;
195 }
196
197 void PluginLV2ClientWindow::done_event(int result)
198 {
199         PluginLV2ParentUI *ui = PluginLV2ParentUI::plugin_lv2.del_ui(this);
200         if( ui ) ui->hide();
201 }
202
203 PluginLV2ClientWindow::~PluginLV2ClientWindow()
204 {
205         done_event(0);
206 }
207
208
209 void PluginLV2ClientWindow::create_objects()
210 {
211         BC_Title *title;
212         int x = 10, y = 10, x1;
213         add_subwindow(title = new BC_Title(x, y, client->title));
214 #ifdef HAVE_LV2UI
215         x1 = get_w() - BC_GenericButton::calculate_w(this, _("UI")) - 8;
216         add_subwindow(ui = new PluginLV2ClientUI(this, x1, y));
217 #else
218         ui = 0;
219 #endif
220         y += title->get_h() + 10;
221         add_subwindow(varbl = new BC_Title(x, y, ""));
222         add_subwindow(range = new BC_Title(x+160, y, ""));
223         x1 = get_w() - BC_GenericButton::calculate_w(this, _("Reset")) - 8;
224         add_subwindow(reset = new PluginLV2ClientReset(this, x1, y));
225         y += title->get_h() + 10;
226         x1 = get_w() - BC_GenericButton::calculate_w(this, _("Apply")) - 8;
227         add_subwindow(apply = new PluginLV2ClientApply(this, x1, y));
228         add_subwindow(text = new PluginLV2ClientText(this, x, y, x1-x - 8));
229         y += title->get_h() + 10;
230         add_subwindow(pot = new PluginLV2ClientPot(this, x, y));
231         x1 = x + pot->get_w() + 10;
232         add_subwindow(slider = new PluginLV2ClientSlider(this, x1, y+10));
233         y += pot->get_h() + 10;
234
235         client->init_lv2();
236         client->load_configuration();
237         client->config.update();
238
239         int panel_x = x, panel_y = y;
240         int panel_w = get_w()-10 - panel_x;
241         int panel_h = get_h()-10 - panel_y;
242         panel = new PluginLV2Client_OptPanel(this, panel_x, panel_y, panel_w, panel_h);
243         add_subwindow(panel);
244         panel->update();
245         show_window(1);
246
247         if( client->server->mwindow->preferences->autostart_lv2ui ) {
248                 PluginLV2ParentUI *ui = get_ui();
249                 ui->show();
250         }
251 }
252
253 int PluginLV2ClientWindow::resize_event(int w, int h)
254 {
255         int x1;
256 #ifdef HAVE_LV2UI
257         x1 = w - ui->get_w() - 8;
258         ui->reposition_window(x1, ui->get_y());
259 #endif
260         x1 = w - reset->get_w() - 8;
261         reset->reposition_window(x1, reset->get_y());
262         x1 = w - apply->get_w() - 8;
263         apply->reposition_window(x1, apply->get_y());
264         text->reposition_window(text->get_x(), text->get_y(), x1-text->get_x() - 8);
265         x1 = pot->get_x() + pot->get_w() + 10;
266         int w1 = w - slider->get_x() - 20;
267         slider->set_pointer_motion_range(w1);
268         slider->reposition_window(x1, slider->get_y(), w1, slider->get_h());
269         int panel_x = panel->get_x(), panel_y = panel->get_y();
270         panel->reposition_window(panel_x, panel_y, w-10-panel_x, h-10-panel_y);
271         return 1;
272 }
273
274 void PluginLV2ClientWindow::update_selected()
275 {
276         update(selected);
277         if( !selected ) return;
278         PluginLV2ParentUI *ui = find_ui();
279         if( !ui ) return;
280         PluginLV2ClientConfig &conf = client->config;
281         ui->send_child(LV2_UPDATE, conf.ctls, sizeof(float)*conf.nb_ports);
282 }
283
284 int PluginLV2ClientWindow::scalar(float f, char *rp)
285 {
286         const char *cp = 0;
287              if( f == FLT_MAX ) cp = "FLT_MAX";
288         else if( f == FLT_MIN ) cp = "FLT_MIN";
289         else if( f == -FLT_MAX ) cp = "-FLT_MAX";
290         else if( f == -FLT_MIN ) cp = "-FLT_MIN";
291         else if( f == 0 ) cp = signbit(f) ? "-0" : "0";
292         else if( isnan(f) ) cp = signbit(f) ? "-NAN" : "NAN";
293         else if( isinf(f) ) cp = signbit(f) ? "-INF" : "INF";
294         else return sprintf(rp, "%g", f);
295         return sprintf(rp, "%s", cp);
296 }
297
298 void PluginLV2ClientWindow::update(PluginLV2Client_Opt *opt)
299 {
300         if( selected != opt ) {
301                 if( selected ) selected->item_name->set_selected(0);
302                 selected = opt;
303                 if( selected ) selected->item_name->set_selected(1);
304         }
305         char var[BCSTRLEN];  var[0] = 0;
306         char val[BCSTRLEN];  val[0] = 0;
307         char rng[BCTEXTLEN]; rng[0] = 0;
308         if( opt ) {
309                 sprintf(var,"%s:", opt->conf->names[opt->idx]);
310                 char *cp = rng;
311                 cp += sprintf(cp,"( ");
312                 float min = opt->conf->mins[opt->idx];
313                 cp += scalar(min, cp);
314                 cp += sprintf(cp, " .. ");
315                 float max = opt->conf->maxs[opt->idx];
316                 cp += scalar(max, cp);
317                 cp += sprintf(cp, " )");
318                 float v = opt->get_value();
319                 sprintf(val, "%f", v);
320                 float p = (max-min) / slider->get_w();
321                 slider->set_precision(p);
322                 slider->update(slider->get_w(), v, min, max);
323                 pot->set_precision(p);
324                 pot->update(v, min, max);
325         }
326         else {
327                 slider->update(slider->get_w(), 0.f, 0.f, 0.f);
328                 pot->update(0.f, 0.f, 0.f);
329         }
330         varbl->update(var);
331         range->update(rng);
332         text->update(val);
333         panel->update();
334 }
335
336 void PluginLV2ClientWindow::lv2_update()
337 {
338         lock_window("PluginLV2ClientWindow::lv2_update");
339         PluginLV2ClientConfig &conf = client->config;
340         int ret = conf.update();
341         if( ret > 0 ) update(0);
342         unlock_window();
343         if( ret > 0 )
344                 client->send_configure_change();
345 }
346
347 void PluginLV2ClientWindow::lv2_update(float *vals)
348 {
349         PluginLV2ClientConfig &conf = client->config;
350         int nb_ports = conf.nb_ports;
351         float *ctls = conf.ctls;
352         for( int i=0; i<nb_ports; ++i ) *ctls++ = *vals++;
353         lv2_update();
354 }
355
356 void PluginLV2ClientWindow::lv2_set(int idx, float val)
357 {
358         PluginLV2ClientConfig &conf = client->config;
359         conf[idx]->set_value(val);
360         lv2_update();
361 }
362