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