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