LiVES  3.2.0
paramwindow.c
Go to the documentation of this file.
1 // paramwindow.c
2 // LiVES
3 // (c) G. Finch 2004 - 2018 <salsaman+lives@gmail.com>
4 // released under the GNU GPL 3 or later
5 // see file ../COPYING or www.gnu.org for licensing details
6 
7 // dynamic window generation from parameter arrays :-)
8 
9 #include "main.h"
10 #include "paramwindow.h"
11 #include "callbacks.h"
12 #include "resample.h"
13 #include "effects.h"
14 #include "rte_window.h"
15 #include "framedraw.h"
16 #include "ce_thumbs.h"
17 #include "interface.h"
18 
19 #ifdef ENABLE_GIW
20 #include "giw/giwknob.h"
21 #endif
22 
23 static int ireinit = 0;
24 
25 extern boolean do_effect(lives_rfx_t *, boolean is_preview); //effects.c in LiVES
26 extern void on_realfx_activate(LiVESMenuItem *, livespointer rfx); // effects.c in LiVES
27 
28 static void after_param_text_buffer_changed(LiVESTextBuffer *textbuffer, lives_rfx_t *rfx);
29 
30 // TODO -
31 // use list of these in case we have multiple windows open
32 // right now this is single threaded because of this
33 static LiVESSList *usrgrp_to_livesgrp[2] = {NULL, NULL}; // ordered list of lives_widget_group_t
34 
35 LiVESList *do_onchange_init(lives_rfx_t *rfx) {
36  LiVESList *onchange = NULL;
37  LiVESList *retvals = NULL;
38  char **array;
39  char *type;
40 
41  register int i;
42 
43  if (rfx->status == RFX_STATUS_WEED) return NULL;
44 
45  switch (rfx->status) {
46  case RFX_STATUS_SCRAP:
47  type = lives_strdup(PLUGIN_RFX_SCRAP);
48  break;
49  case RFX_STATUS_BUILTIN:
50  type = lives_strdup(PLUGIN_RENDERED_EFFECTS_BUILTIN);
51  break;
52  case RFX_STATUS_CUSTOM:
53  type = lives_strdup(PLUGIN_RENDERED_EFFECTS_CUSTOM);
54  break;
55  default:
57  break;
58  }
59  if ((onchange = plugin_request_by_line(type, rfx->name, "get_onchange")) != NULL) {
60  for (i = 0; i < lives_list_length(onchange); i++) {
61  array = lives_strsplit((char *)lives_list_nth_data(onchange, i), rfx->delim, -1);
62  if (!strcmp(array[0], "init")) {
63  // onchange is init
64  // create dummy object with data
65  LiVESWidget *dummy_widget = lives_label_new(NULL);
66  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(dummy_widget), PARAM_NUMBER_KEY,
67  LIVES_INT_TO_POINTER(-1));
68  retvals = do_onchange(LIVES_WIDGET_OBJECT(dummy_widget), rfx);
69  lives_widget_destroy(dummy_widget);
70  lives_strfreev(array);
71  break;
72  }
73  lives_strfreev(array);
74  }
75  lives_list_free_all(&onchange);
76  }
77  lives_free(type);
78 
79  return retvals;
80 }
81 
82 
83 static void on_paramwindow_button_clicked2(LiVESButton *button, lives_rfx_t *rfx) {
84  // close from rte window
85  on_paramwindow_button_clicked(button, rfx);
86  lives_freep((void **)&fx_dialog[1]);
87 }
88 
89 
90 void on_paramwindow_button_clicked(LiVESButton *button, lives_rfx_t *rfx) {
91  LiVESWidget *dialog = NULL;
92  boolean def_ok = FALSE;
93  int i;
94 
95  if (button) {
96  lives_widget_set_sensitive(LIVES_WIDGET(button), FALSE);
97  dialog = lives_widget_get_toplevel(LIVES_WIDGET(button));
98  }
99 
100  if (dialog && LIVES_IS_DIALOG(dialog)) {
101  if (lives_dialog_get_response_for_widget(LIVES_DIALOG(dialog), LIVES_WIDGET(button)) == LIVES_RESPONSE_OK) {
102  def_ok = TRUE;
103  }
104  }
105 
106  if (mainw->textwidget_focus && LIVES_IS_WIDGET_OBJECT(mainw->textwidget_focus)) {
107  // make sure text widgets are updated if they activate the default
108  LiVESWidget *textwidget =
109  (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mainw->textwidget_focus), TEXTWIDGET_KEY);
110  after_param_text_changed(textwidget, rfx);
111  }
112 
113  if (!special_cleanup(def_ok)) {
114  lives_dialog_response(LIVES_DIALOG(lives_widget_get_toplevel(LIVES_WIDGET(button))), LIVES_RESPONSE_RETRY);
115  if (button) lives_widget_set_sensitive(LIVES_WIDGET(button), TRUE);
116  return;
117  }
118 
119  mainw->textwidget_focus = NULL;
120 
121  if (def_ok && rfx && rfx->status != RFX_STATUS_SCRAP) mainw->keep_pre = mainw->did_rfx_preview;
122 
124 
125  if (mainw->did_rfx_preview) {
126  if (def_ok) {
127  for (i = 0; i < rfx->num_params; i++) {
128  if (rfx->params[i].changed) {
129  mainw->keep_pre = FALSE;
130  break;
131  }
132  }
133  }
134 
135  if (!mainw->keep_pre) {
137 
138  if (cfile->start == 0) {
139  cfile->start = 1;
140  cfile->end = cfile->frames;
141  }
142 
143  do_rfx_cleanup(rfx);
145  }
146  mainw->show_procd = TRUE;
147  }
148 
149  if (!def_ok) {
150  if (rfx && mainw->is_generating && rfx->source_type == LIVES_RFX_SOURCE_NEWCLIP &&
151  CURRENT_CLIP_IS_NORMAL && rfx->source == cfile &&
152  rfx->name && rfx->status != RFX_STATUS_WEED && rfx->status != RFX_STATUS_SCRAP &&
153  rfx->num_in_channels == 0 && rfx->min_frames >= 0 && !rfx->is_template) {
154  // for a generator, we silently close the (now) temporary file we would have generated frames into
158  if (mainw->multitrack) mainw->pre_src_file = -1;
160  rfx->source = NULL;
162  }
163  mainw->keep_pre = FALSE;
164  }
165 
166  if (!rfx) {
167  if (usrgrp_to_livesgrp[1]) lives_slist_free(usrgrp_to_livesgrp[1]);
168  usrgrp_to_livesgrp[1] = NULL;
169  } else {
170  if (rfx->status == RFX_STATUS_WEED) {
171  if (usrgrp_to_livesgrp[1]) lives_slist_free(usrgrp_to_livesgrp[1]);
172  usrgrp_to_livesgrp[1] = NULL;
174  rfx_free(rfx);
175  lives_free(rfx);
176  }
177  } else {
178  if (usrgrp_to_livesgrp[0]) lives_slist_free(usrgrp_to_livesgrp[0]);
179  usrgrp_to_livesgrp[0] = NULL;
180  }
181  }
182 
184 
185  if (def_ok && rfx && rfx->status == RFX_STATUS_SCRAP) return;
186 
187  if (button)
188  if (dialog) {
189  // prevent a gtk+ crash by removing the focus before detroying the dialog
190  LiVESWidget *content_area = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
191  lives_container_set_focus_child(LIVES_CONTAINER(content_area), NULL);
192  }
193 
194  lives_general_button_clicked(button, NULL);
195 
196  if (def_ok) {
197  if (rfx->status == RFX_STATUS_WEED) on_realfx_activate(NULL, rfx);
198  else on_render_fx_activate(NULL, rfx);
199  }
200 
201  if (mainw->multitrack) {
205  }
206 }
207 
208 
212 static lives_widget_group_t *get_group(lives_rfx_t *rfx, lives_param_t *param) {
213  if (rfx->status == RFX_STATUS_WEED) {
214  return livesgrp_from_usrgrp(usrgrp_to_livesgrp[1], param->group);
215  } else {
216  return livesgrp_from_usrgrp(usrgrp_to_livesgrp[0], param->group);
217  }
218  return NULL;
219 }
220 
221 
222 void on_render_fx_activate(LiVESMenuItem *menuitem, lives_rfx_t *rfx) {
223  uint32_t chk_mask = 0;
224 
225  if (menuitem && rfx->num_in_channels > 0) {
227  if (!check_for_layout_errors(NULL, mainw->current_file, cfile->start, cfile->end, &chk_mask)) {
228  return;
229  }
230  }
231 
232  // do onchange|init
233  if (menuitem) {
234  LiVESList *retvals = do_onchange_init(rfx);
235  lives_list_free_all(&retvals);
236  }
237  if (rfx->min_frames > -1) {
238  do_effect(rfx, FALSE);
239  }
240 
241  if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
242 }
243 
244 
245 static void gen_width_changed(LiVESSpinButton *spin, livespointer user_data) {
246  weed_plant_t *ctmpl = (weed_plant_t *)user_data;
247  int val = lives_spin_button_get_value_as_int(spin);
248  int error, old_val = 0;
249  int step;
250  // value in chantmp in pixels, not macropixels
251  if (weed_plant_has_leaf(ctmpl, WEED_LEAF_HOST_WIDTH)) old_val = weed_get_int_value(ctmpl, WEED_LEAF_HOST_WIDTH, &error);
252  if (val == old_val) return;
253  step = 1;
254  if (weed_plant_has_leaf(ctmpl, WEED_LEAF_HSTEP)) step = weed_get_int_value(ctmpl, WEED_LEAF_HSTEP, &error);
255 
256  val = ALIGN_CEIL(val, step);
257  weed_set_int_value(ctmpl, WEED_LEAF_HOST_WIDTH, val);
258  lives_spin_button_set_value(spin, (double)val);
259 }
260 
261 
262 static void gen_height_changed(LiVESSpinButton *spin, livespointer user_data) {
263  weed_plant_t *ctmpl = (weed_plant_t *)user_data;
264  int val = lives_spin_button_get_value_as_int(spin);
265  int error, old_val = 0;
266  int step;
267 
268  if (weed_plant_has_leaf(ctmpl, WEED_LEAF_HOST_HEIGHT)) old_val = weed_get_int_value(ctmpl, WEED_LEAF_HOST_HEIGHT, &error);
269 
270  if (val == old_val) return;
271  step = 1;
272  if (weed_plant_has_leaf(ctmpl, WEED_LEAF_HSTEP)) step = weed_get_int_value(ctmpl, WEED_LEAF_HSTEP, &error);
273 
274  val = ALIGN_CEIL(val, step);
275  weed_set_int_value(ctmpl, WEED_LEAF_HOST_HEIGHT, val);
276  lives_spin_button_set_value(spin, (double)val);
277 }
278 
279 
280 static void gen_fps_changed(LiVESSpinButton *spin, livespointer user_data) {
281  weed_plant_t *filter = (weed_plant_t *)user_data;
282  double val = lives_spin_button_get_value(spin);
283  weed_set_double_value(filter, WEED_LEAF_HOST_FPS, val);
284 }
285 
286 
287 static void trans_in_out_pressed(lives_rfx_t *rfx, boolean in) {
288  weed_plant_t **in_params;
289 
290  weed_plant_t *inst = (weed_plant_t *)rfx->source;
291  weed_plant_t *filter = weed_instance_get_filter(inst, TRUE);
292  weed_plant_t *tparam;
293  weed_plant_t *tparamtmpl;
294 
295  int key = -1;
296  int ptype, nparams;
297  int trans = get_transition_param(filter, FALSE);
298 
299  do {
300  // handle compound fx
301  if (weed_plant_has_leaf(inst, WEED_LEAF_IN_PARAMETERS)) {
302  nparams = weed_leaf_num_elements(inst, WEED_LEAF_IN_PARAMETERS);
303  if (trans < nparams) break;
304  trans -= nparams;
305  }
306  } while (weed_plant_has_leaf(inst, WEED_LEAF_HOST_NEXT_INSTANCE) &&
307  (inst = weed_get_plantptr_value(inst, WEED_LEAF_HOST_NEXT_INSTANCE, NULL)) != NULL);
308 
309  in_params = weed_instance_get_in_params(inst, NULL);
310  tparam = in_params[trans];
311  tparamtmpl = weed_param_get_template(tparam);
312  ptype = weed_paramtmpl_get_type(tparamtmpl);
313 
314  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
315  if (!filter_mutex_trylock(key)) {
316  if (ptype == WEED_PARAM_INTEGER) {
317  if (in) weed_set_int_value(tparam, WEED_LEAF_VALUE, weed_get_int_value(tparamtmpl, WEED_LEAF_MIN, NULL));
318  else weed_set_int_value(tparam, WEED_LEAF_VALUE, weed_get_int_value(tparamtmpl, WEED_LEAF_MAX, NULL));
319  } else {
320  if (in) weed_set_double_value(tparam, WEED_LEAF_VALUE, weed_get_double_value(tparamtmpl, WEED_LEAF_MIN, NULL));
321  else weed_set_double_value(tparam, WEED_LEAF_VALUE, weed_get_double_value(tparamtmpl, WEED_LEAF_MAX, NULL));
322  }
323  filter_mutex_unlock(key);
324  set_copy_to(inst, trans, rfx, TRUE);
325  }
326 
328  lives_free(in_params);
330 }
331 
332 
333 static void transition_in_pressed(LiVESToggleButton *tbut, livespointer rfx) {
334  trans_in_out_pressed((lives_rfx_t *)rfx, TRUE);
335 }
336 
337 
338 static void transition_out_pressed(LiVESToggleButton *tbut, livespointer rfx) {
339  trans_in_out_pressed((lives_rfx_t *)rfx, FALSE);
340 }
341 
342 
343 static void after_transaudio_toggled(LiVESToggleButton *togglebutton, livespointer rfx) {
344  weed_plant_t *init_event = mainw->multitrack->init_event;
345 
346  if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(togglebutton)))
347  weed_set_boolean_value(init_event, WEED_LEAF_HOST_AUDIO_TRANSITION, WEED_TRUE);
348  else weed_set_boolean_value(init_event, WEED_LEAF_HOST_AUDIO_TRANSITION, WEED_FALSE);
349 }
350 
351 
352 void transition_add_in_out(LiVESBox *vbox, lives_rfx_t *rfx, boolean add_audio_check) {
353  // add in/out radios for multitrack transitions
354  LiVESWidget *radiobutton_in;
355  LiVESWidget *radiobutton_out;
356  LiVESWidget *radiobutton_dummy;
357  LiVESWidget *hbox, *hbox2;
358  LiVESWidget *hseparator;
359 
360  LiVESSList *radiobutton_group = NULL;
361 
362  weed_plant_t *filter = weed_instance_get_filter((weed_plant_t *)rfx->source, TRUE);
363  int trans = get_transition_param(filter, FALSE);
364 
365  char *tmp, *tmp2;
366 
367  hbox = lives_hbox_new(FALSE, 0);
368  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_width);
369 
370  if (add_audio_check) {
371  int error;
372 
373  LiVESWidget *checkbutton;
374 
375  hbox2 = lives_hbox_new(FALSE, 0);
376 
377  if (has_video_chans_in(filter, FALSE))
378  lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, FALSE, widget_opts.packing_width);
379 
380  checkbutton = lives_standard_check_button_new((tmp = (_("_Crossfade audio"))),
381  weed_plant_has_leaf(mainw->multitrack->init_event, WEED_LEAF_HOST_AUDIO_TRANSITION) &&
382  weed_get_boolean_value(mainw->multitrack->init_event, WEED_LEAF_HOST_AUDIO_TRANSITION, &error) == WEED_TRUE,
383  LIVES_BOX(hbox2), (tmp2 = lives_strdup(
384  _("If checked, audio from both layers is mixed relative to the transition parameter.\n"
385  "The setting is applied instantly to the entire transition."))));
386 
387  lives_free(tmp);
388  lives_free(tmp2);
389 
390  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
391  LIVES_GUI_CALLBACK(after_transaudio_toggled),
392  (livespointer)rfx);
393 
394  after_transaudio_toggled(LIVES_TOGGLE_BUTTON(checkbutton), (livespointer)rfx);
395  }
396 
397  // dummy radiobutton so we can have neither in nor out set
398  radiobutton_dummy = lives_standard_radio_button_new(NULL, &radiobutton_group, LIVES_BOX(hbox), NULL);
399  lives_widget_set_no_show_all(radiobutton_dummy, TRUE);
400 
402  radiobutton_out = lives_standard_radio_button_new((tmp = (_("Transition _Out"))),
403  &radiobutton_group, LIVES_BOX(hbox),
404  (tmp2 = (_("Click to set the transition parameter to show only the rear frame"))));
405 
406  lives_free(tmp);
407  lives_free(tmp2);
408 
409  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(radiobutton_out), LIVES_WIDGET_TOGGLED_SIGNAL,
410  LIVES_GUI_CALLBACK(transition_out_pressed),
411  (livespointer)rfx);
412 
413  radiobutton_in = lives_standard_radio_button_new((tmp = (_("Transition _In"))),
414  &radiobutton_group, LIVES_BOX(hbox),
415  (tmp2 = (_("Click to set the transition parameter to show only the front frame"))));
416  lives_free(tmp); lives_free(tmp2);
417 
418  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(radiobutton_in), LIVES_WIDGET_TOGGLED_SIGNAL,
419  LIVES_GUI_CALLBACK(transition_in_pressed), (livespointer)rfx);
420 
422 
423  if (palette->style & STYLE_1) {
424  lives_widget_set_fg_color(hbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
425  }
426 
427  hseparator = lives_hseparator_new();
428  lives_box_pack_start(vbox, hseparator, FALSE, FALSE, 0);
429 
430  rfx->params[trans].widgets[WIDGET_RB_IN] = radiobutton_in;
431  rfx->params[trans].widgets[WIDGET_RB_OUT] = radiobutton_out;
432  rfx->params[trans].widgets[WIDGET_RB_DUMMY] = radiobutton_dummy;
433 }
434 
435 
436 static boolean add_sizes(LiVESBox *vbox, boolean add_fps, boolean has_param, lives_rfx_t *rfx) {
437  // add size settings for generators and resize effects
438  LiVESWidget *label, *hbox;
439  LiVESWidget *spinbuttonh = NULL, *spinbuttonw = NULL;
440  LiVESWidget *spinbuttonf;
441  int num_chans = 0;
442 
443  weed_plant_t *filter = weed_instance_get_filter((weed_plant_t *)rfx->source, TRUE), *tmpl;
444  weed_plant_t **ctmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &num_chans);
445 
446  double def_fps = 0.;
447 
448  char *cname, *ltxt;
449 
450  boolean chk_params = (vbox == NULL);
451  boolean added = FALSE;
452 
453  int def_width = 0, max_width, width_step;
454  int def_height = 0, max_height, height_step;
455  int wopw = widget_opts.packing_width;
456 
457  register int i;
458 
459  if (chk_params) {
460  if (add_fps) return TRUE;
461  } else {
462  if (!has_param) lives_widget_set_size_request(LIVES_WIDGET(vbox), RFX_WINSIZE_H, RFX_WINSIZE_V);
463 
464  if (add_fps) {
465  added = TRUE;
466 
467  hbox = lives_hbox_new(FALSE, 0);
468  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height * 2);
469 
470  add_fill_to_box(LIVES_BOX(hbox));
471 
472  if (weed_plant_has_leaf(filter, WEED_LEAF_HOST_FPS)) def_fps = weed_get_double_value(filter, WEED_LEAF_HOST_FPS, NULL);
473  else if (weed_plant_has_leaf(filter, WEED_LEAF_PREFERRED_FPS))
474  def_fps = weed_get_double_value(filter, WEED_LEAF_PREFERRED_FPS, NULL);
475 
476  if (def_fps == 0.) def_fps = prefs->default_fps;
477 
478  spinbuttonf = lives_standard_spin_button_new(_("Target _FPS (plugin may override this)"),
479  def_fps, 1., FPS_MAX, 1., 10., 3, LIVES_BOX(hbox), NULL);
480 
481  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbuttonf), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
482  LIVES_GUI_CALLBACK(gen_fps_changed), filter);
483 
484  add_fill_to_box(LIVES_BOX(hbox));
485  }
486  }
487 
488  for (i = 0; i < num_chans; i++) {
489  tmpl = ctmpls[i];
490 
491  // TODO ***: allow alteration of "host_disabled" under some circumstances
492  // (e.g. allow enabling a first or second in channel, or first out_channel, or more for alphas)
493 
494  // make this into function called from here and from effects with optional enable-able channels
495  if (weed_get_boolean_value(tmpl, WEED_LEAF_HOST_DISABLED, NULL) == WEED_TRUE) continue;
496  if (weed_get_int_value(tmpl, WEED_LEAF_WIDTH, NULL)) continue;
497  if (weed_get_int_value(tmpl, WEED_LEAF_HEIGHT, NULL)) continue;
498 
499  if (chk_params) return TRUE;
500 
501  added = TRUE;
502 
503  if (rfx->is_template) {
504  cname = weed_get_string_value(tmpl, WEED_LEAF_NAME, NULL);
505  ltxt = lives_strdup_printf(_("%s : size"), cname);
506  lives_free(cname);
507  } else {
508  ltxt = (_("New size (pixels)"));
509  }
510 
511  label = lives_standard_label_new(ltxt);
512  lives_free(ltxt);
513 
514  hbox = lives_hbox_new(FALSE, 0);
515  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
516  lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, widget_opts.packing_width);
517 
518  def_width = weed_get_int_value(tmpl, WEED_LEAF_HOST_WIDTH, NULL);
519  if (!def_width) def_width = DEF_GEN_WIDTH;
520  max_width = weed_get_int_value(tmpl, WEED_LEAF_MAXWIDTH, NULL);
521  if (!max_width) max_width = INT_MAX;
522  if (def_width > max_width) def_width = max_width;
523  width_step = weed_get_int_value(tmpl, WEED_LEAF_HSTEP, NULL);
524  if (!width_step) width_step = 4;
525 
526  spinbuttonw = lives_standard_spin_button_new(_("_Width"), def_width, width_step, max_width, width_step,
527  width_step, 0, LIVES_BOX(hbox), NULL);
528  lives_spin_button_set_snap_to_multiples(LIVES_SPIN_BUTTON(spinbuttonw), width_step);
529  lives_spin_button_update(LIVES_SPIN_BUTTON(spinbuttonw));
530 
531  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbuttonw), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
532  LIVES_GUI_CALLBACK(gen_width_changed), tmpl);
533  weed_leaf_delete(tmpl, WEED_LEAF_HOST_WIDTH); // force a reset
534  gen_width_changed(LIVES_SPIN_BUTTON(spinbuttonw), tmpl);
535 
537  add_fill_to_box(LIVES_BOX(hbox));
538  widget_opts.packing_width = wopw;
539 
540  def_height = weed_get_int_value(tmpl, WEED_LEAF_HOST_HEIGHT, NULL);
541  if (!def_height) def_height = DEF_GEN_HEIGHT;
542  max_height = weed_get_int_value(tmpl, WEED_LEAF_MAXHEIGHT, NULL);
543  if (!max_height) max_height = INT_MAX;
544  if (def_height > max_height) def_height = max_height;
545  height_step = weed_get_int_value(tmpl, WEED_LEAF_VSTEP, NULL);
546  if (!height_step) height_step = 4;
547 
548  spinbuttonh = lives_standard_spin_button_new(_("_Height"), def_height, height_step, max_height, height_step,
549  height_step, 0, LIVES_BOX(hbox), NULL);
550  lives_spin_button_set_snap_to_multiples(LIVES_SPIN_BUTTON(spinbuttonh), height_step);
551  lives_spin_button_update(LIVES_SPIN_BUTTON(spinbuttonh));
552 
553  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbuttonh), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
554  LIVES_GUI_CALLBACK(gen_height_changed), tmpl);
555  weed_leaf_delete(tmpl, WEED_LEAF_HOST_HEIGHT); // force a reset
556  gen_height_changed(LIVES_SPIN_BUTTON(spinbuttonh), tmpl);
557  }
558 
559  if (!rfx->is_template && num_chans == 1) {
560  if (chk_params) return TRUE;
561  added = TRUE;
562  // add "aspectratio" widget
563  add_aspect_ratio_button(LIVES_SPIN_BUTTON(spinbuttonw), LIVES_SPIN_BUTTON(spinbuttonh), LIVES_BOX(vbox));
564  }
565 
566  if (added) {
567  if (has_param) {
568  add_fill_to_box(LIVES_BOX(vbox));
569  add_hsep_to_box(vbox);
570  } else has_param = TRUE;
571  }
572  return has_param;
573 }
574 
575 
576 static void add_gen_to(LiVESBox *vbox, lives_rfx_t *rfx) {
577  // add "generate to clipboard/new clip" for rendered generators
578  LiVESSList *radiobutton_group = NULL;
579 
580  LiVESWidget *radiobutton;
581  LiVESWidget *hseparator;
582 
583  LiVESWidget *hbox = lives_hbox_new(FALSE, 0);
584 
585  char *tmp, *tmp2;
586 
587  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
588 
589  radiobutton = lives_standard_radio_button_new((tmp = (_("Generate to _Clipboard"))),
590  &radiobutton_group, LIVES_BOX(hbox),
591  (tmp2 = (_("Generate frames to the clipboard"))));
592 
593  lives_free(tmp);
594  lives_free(tmp2);
595 
597  radiobutton = lives_standard_radio_button_new((tmp = (_("Generate to _New Clip"))),
598  &radiobutton_group, LIVES_BOX(hbox),
599  (tmp2 = (_("Generate frames to a new clip"))));
601 
602  lives_free(tmp);
603  lives_free(tmp2);
604 
605  hseparator = lives_hseparator_new();
606  lives_box_pack_start(vbox, hseparator, FALSE, FALSE, 0);
607 
608  toggle_toggles_var(LIVES_TOGGLE_BUTTON(radiobutton), &mainw->gen_to_clipboard, TRUE);
609 }
610 
611 
612 static void xspinw_changed(LiVESSpinButton *spinbutton, livespointer user_data) {
613  cfile->ohsize = cfile->hsize = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
615 }
616 
617 static void xspinh_changed(LiVESSpinButton *spinbutton, livespointer user_data) {
618  cfile->ovsize = cfile->vsize = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
620 }
621 
622 static void xspinfr_changed(LiVESSpinButton *spinbutton, livespointer user_data) {
623  cfile->end = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
624 }
625 
626 static void xspinfps_changed(LiVESSpinButton *spinbutton, livespointer user_data) {
627  cfile->pb_fps = cfile->fps = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
629 }
630 
631 static void add_genparams(LiVESWidget *vbox, lives_rfx_t *rfx) {
632  // add nframes, fps, width, heights
633  LiVESWidget *sp_width, *sp_height, *sp_frames, *sp_fps;
634  LiVESWidget *frame = add_video_options(&sp_width, cfile->hsize, &sp_height, cfile->vsize, &sp_fps, cfile->fps,
635  &sp_frames, cfile->end, TRUE, NULL);
636  lives_box_pack_start(LIVES_BOX(vbox), frame, FALSE, TRUE, 0);
637 
638  lives_spin_button_update(LIVES_SPIN_BUTTON(sp_width));
639  lives_spin_button_update(LIVES_SPIN_BUTTON(sp_height));
640  if (sp_frames) lives_spin_button_update(LIVES_SPIN_BUTTON(sp_frames));
641  lives_spin_button_update(LIVES_SPIN_BUTTON(sp_fps));
642  cfile->ohsize = cfile->hsize = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(sp_width));
643  cfile->ovsize = cfile->vsize = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(sp_height));
644 
645  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(sp_width), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
646  LIVES_GUI_CALLBACK(xspinw_changed), NULL);
647  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(sp_height), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
648  LIVES_GUI_CALLBACK(xspinh_changed), NULL);
649  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(sp_frames), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
650  LIVES_GUI_CALLBACK(xspinfr_changed), NULL);
651  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(sp_fps), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
652  LIVES_GUI_CALLBACK(xspinfps_changed), NULL);
653 }
654 
655 
656 LIVES_GLOBAL_INLINE void on_render_fx_pre_activate(LiVESMenuItem *menuitem, lives_rfx_t *rfx) {
657  _fx_dialog *fxdialog;
658  uint32_t chk_mask;
659  int start, end;
660 
662  if ((rfx->props & RFX_PROPS_MAY_RESIZE && rfx->num_in_channels == 1) || rfx->min_frames < 0) {
663  start = 1;
664  end = 0;
665  } else {
666  start = cfile->start;
667  end = cfile->end;
668  }
669 
670  if (rfx->num_in_channels > 0) {
672  if (!check_for_layout_errors(NULL, mainw->current_file, start, end, &chk_mask)) {
673  return;
674  }
675  }
676  fxdialog = on_fx_pre_activate(rfx, FALSE, NULL);
677  if (fxdialog) {
678  if (menuitem == LIVES_MENU_ITEM(mainw->resize_menuitem)) add_resnn_label(LIVES_DIALOG(fxdialog->dialog));
679  /* do { */
680  /* resp = lives_dialog_run(LIVES_DIALOG(fxdialog->dialog)); */
681  /* } while (resp == LIVES_RESPONSE_RETRY); */
682  }
683 
684 }
685 
686 
687 _fx_dialog *on_fx_pre_activate(lives_rfx_t *rfx, boolean is_realtime, LiVESWidget *pbox) {
688  // render a pre dialog for: rendered effects (fx_dialog[0]), or rte(fx_dialog[1]), or encoder plugin, or vpp (fx_dialog[1])
689  LiVESWidget *top_dialog_vbox = NULL;
690  LiVESAccelGroup *fxw_accel_group;
691  LiVESList *retvals = NULL;
692 
693  char *txt;
694 
695  boolean no_process = FALSE;
696  boolean is_defaults = FALSE;
697  boolean add_reset_ok = FALSE;
698  boolean has_param;
699 
700  int scrw, didx = 0;
701 
702  if (mainw->multitrack) {
703  if (mainw->multitrack->idlefunc > 0) {
705  mainw->multitrack->idlefunc = 0;
706  }
708  }
709 
710  if (is_realtime) {
711  didx = 1;
712  no_process = TRUE;
713  } else if (rfx->status != RFX_STATUS_WEED) {
714  retvals = do_onchange_init(rfx);
715  }
716  if (rfx->min_frames < 0) no_process = TRUE;
717 
718  if (!no_process && rfx->num_in_channels == 0) {
719  int new_file;
721 
722  // create a new file to generate frames into
723  if (!get_new_handle((new_file = mainw->first_free_file), NULL)) {
724  if (mainw->multitrack) {
727  }
728 
729  lives_list_free_all(&retvals);
730 
731  return NULL;
732  }
733 
735  mainw->files[new_file]->hsize = cfile->hsize;
736  mainw->files[new_file]->vsize = cfile->vsize;
737  mainw->files[new_file]->fps = cfile->fps;
738  } else {
739  mainw->files[new_file]->hsize = DEF_GEN_WIDTH;
740  mainw->files[new_file]->vsize = DEF_GEN_HEIGHT;
741  mainw->files[new_file]->fps = DEF_FPS;
742  }
743 
745  mainw->current_file = new_file;
747  rfx->source = cfile;
748 
749  cfile->ohsize = cfile->hsize;
750  cfile->ovsize = cfile->vsize;
751  cfile->pb_fps = cfile->fps;
752 
753  // dummy values
754  cfile->start = 1;
755  cfile->end = 100;
756  }
757 
758  if (!no_process && rfx->num_in_channels > 0) {
759  // check we have a real clip open
760  if (!CURRENT_CLIP_IS_VALID) {
761  lives_list_free_all(&retvals);
762  return NULL;
763  }
764  if (cfile->end - cfile->start + 1 < rfx->min_frames) {
765  lives_list_free_all(&retvals);
766  txt = lives_strdup_printf(_("\nYou must select at least %d frames to use this effect.\n\n"),
767  rfx->min_frames);
768  do_error_dialog(txt);
769  lives_free(txt);
770  return NULL;
771  }
772 
773  // here we invalidate cfile->ohsize, cfile->ovsize
774  cfile->ohsize = cfile->hsize;
775  cfile->ovsize = cfile->vsize;
776 
777  if (cfile->undo_action == UNDO_RESIZABLE) {
778  set_undoable(NULL, FALSE);
779  }
780  }
781 
782  if (rfx->status == RFX_STATUS_WEED && rfx->is_template) is_defaults = TRUE;
783 
784  if (!pbox) {
785  char *title, *defstr;
786 
787  // width works well with scale 0.7
788  if (rfx->status == RFX_STATUS_WEED || no_process || (rfx->num_in_channels == 0 &&
789  rfx->props & RFX_PROPS_BATCHG)) scrw = RFX_WINSIZE_H * 2. * widget_opts.scale;
790  else scrw = GUI_SCREEN_WIDTH - SCR_WIDTH_SAFETY;
791 
792  fx_dialog[didx] = (_fx_dialog *)lives_malloc(sizeof(_fx_dialog));
793  fx_dialog[didx]->okbutton = fx_dialog[didx]->cancelbutton = fx_dialog[didx]->resetbutton = NULL;
794  fx_dialog[didx]->rfx = NULL;
795  fx_dialog[didx]->key = fx_dialog[didx]->mode = -1;
796  if (is_defaults) defstr = (_("Defaults for "));
797  else defstr = lives_strdup("");
798  title = lives_strdup_printf("%s%s", defstr, _(rfx->menu_text[0] == '_' ? rfx->menu_text + 1 : rfx->menu_text));
799 
801  lives_free(defstr);
802  lives_free(title);
803  pbox = top_dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(fx_dialog[didx]->dialog));
804  fx_dialog[didx]->rfx = rfx;
806  }
807 
808  if (rfx->status != RFX_STATUS_WEED && !no_process) {
809  // rendered fx preview
810 
811  LiVESWidget *hbox = lives_hbox_new(FALSE, 0);
812  lives_box_pack_start(LIVES_BOX(top_dialog_vbox), hbox, TRUE, TRUE, 0);
813 
816 
817  pbox = lives_vbox_new(FALSE, 0);
818  lives_box_pack_start(LIVES_BOX(hbox), pbox, TRUE, TRUE, 0);
819 
822 
823  // add preview window
824  if (rfx->num_in_channels > 0 || !(rfx->props & RFX_PROPS_BATCHG)) {
825  mainw->framedraw_frame = cfile->start;
826  widget_add_framedraw(LIVES_VBOX(pbox), cfile->start, cfile->end, !(rfx->props & RFX_PROPS_MAY_RESIZE),
827  cfile->hsize, cfile->vsize, rfx);
828  if (rfx->props & RFX_PROPS_MAY_RESIZE) mainw->fd_max_frame = cfile->end;
829  }
830 
831  if (!(rfx->props & RFX_PROPS_BATCHG)) {
832  // connect spinbutton to preview
834  }
835  }
836 
837  // add the param widgets; here we also set parameters for any special widgets in the framedraw
838  //main_thread_execute((lives_funcptr_t)make_param_box, WEED_SEED_BOOLEAN, &has_param, "vv", pbox, rfx);
839  has_param = make_param_box(LIVES_VBOX(pbox), rfx);
840 
841  // update widgets from onchange_init here
842  if (top_dialog_vbox) {
843  fxw_accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
844  lives_window_add_accel_group(LIVES_WINDOW(fx_dialog[didx]->dialog), fxw_accel_group);
845 
846  if (!no_process || is_defaults || rfx->status == RFX_STATUS_SCRAP) {
847  if (!is_defaults) {
848  fx_dialog[didx]->cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(fx_dialog[didx]->dialog),
849  LIVES_STOCK_CANCEL, NULL, LIVES_RESPONSE_CANCEL);
850  fx_dialog[didx]->okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(fx_dialog[didx]->dialog),
851  LIVES_STOCK_OK, NULL, LIVES_RESPONSE_OK);
852  } else add_reset_ok = TRUE;
853  } else {
854  if (rfx->status == RFX_STATUS_WEED) {
855  add_reset_ok = TRUE;
856  }
857  }
858 
859  if (add_reset_ok) {
860  fx_dialog[didx]->resetbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(fx_dialog[didx]->dialog),
861  LIVES_STOCK_REVERT_TO_SAVED, _("Reset"), LIVES_RESPONSE_RESET);
862  fx_dialog[didx]->okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(fx_dialog[didx]->dialog), LIVES_STOCK_APPLY,
863  _("Set as default"), LIVES_RESPONSE_OK);
864  if (!has_param) {
865  lives_widget_set_sensitive(fx_dialog[didx]->resetbutton, FALSE);
866  lives_widget_set_sensitive(fx_dialog[didx]->okbutton, FALSE);
867  }
868  }
869 
870  if (fx_dialog[didx]->cancelbutton == NULL) {
871  fx_dialog[didx]->cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(fx_dialog[didx]->dialog), LIVES_STOCK_CLOSE,
872  _("_Close Window"), LIVES_RESPONSE_CANCEL);
873  }
874  lives_widget_add_accelerator(fx_dialog[didx]->cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, fxw_accel_group,
875  LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
876 
877  if (fx_dialog[didx]->okbutton) {
879  } else {
880  lives_button_grab_default_special(fx_dialog[didx]->cancelbutton);
881  }
882 
883  if (no_process && !is_defaults) {
884  if (!is_realtime) {
885  if (fx_dialog[didx]->okbutton)
886  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
887  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked), rfx);
888  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
889  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked), rfx);
890  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->dialog), LIVES_WIDGET_DELETE_EVENT,
891  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked), rfx);
892  } else {
893  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
894  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked2), rfx);
895  if (rfx->status == RFX_STATUS_SCRAP)
896  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
897  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked2), rfx);
898  else {
899  if (fx_dialog[didx]->okbutton)
900  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
901  LIVES_GUI_CALLBACK(rte_set_key_defs), rfx);
902  if (fx_dialog[didx]->resetbutton) {
903  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(fx_dialog[didx]->resetbutton), LIVES_WIDGET_CLICKED_SIGNAL,
904  LIVES_GUI_CALLBACK(rte_reset_defs_clicked), rfx);
905  }
906  }
907  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->dialog), LIVES_WIDGET_DELETE_EVENT,
908  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked2), rfx);
909  }
910  } else {
911  if (!is_defaults) {
912  if (fx_dialog[didx]->okbutton)
913  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
914  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked), (livespointer)rfx);
915  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
916  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked), (livespointer)rfx);
917  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->dialog), LIVES_WIDGET_DELETE_EVENT,
918  LIVES_GUI_CALLBACK(on_paramwindow_button_clicked), (livespointer)rfx);
919  } else {
920  if (fx_dialog[didx]->okbutton)
921  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(fx_dialog[didx]->okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
922  LIVES_GUI_CALLBACK(rte_set_defs_ok), rfx);
923  if (fx_dialog[didx]->resetbutton) {
924  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(fx_dialog[didx]->resetbutton), LIVES_WIDGET_CLICKED_SIGNAL,
925  LIVES_GUI_CALLBACK(rte_reset_defs_clicked), rfx);
926  }
927  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
928  LIVES_GUI_CALLBACK(rte_set_defs_cancel), rfx);
929  lives_signal_sync_connect(LIVES_GUI_OBJECT(fx_dialog[didx]->dialog), LIVES_WIDGET_DELETE_EVENT,
930  LIVES_GUI_CALLBACK(rte_set_defs_cancel), rfx);
931  }
932  }
933  }
934 
935  // tweak some things to do with framedraw preview
936  if (mainw->framedraw) fd_tweak(rfx);
937 
938  if (!mainw->ce_thumbs)
939  lives_widget_show_all(fx_dialog[didx]->dialog);
940 
941  if (retvals) {
942  // now apply visually anything we got from onchange_init
943  param_demarshall(rfx, retvals, TRUE, TRUE);
944  lives_list_free_all(&retvals);
945  }
946  return fx_dialog[didx];
947 }
948 
949 
950 static void check_hidden_gui(weed_plant_t *inst, lives_param_t *param, int idx) {
951  weed_plant_t *wparam;
952  if (param->type == LIVES_PARAM_UNDISPLAYABLE || param->type == LIVES_PARAM_UNKNOWN)
953  param->hidden |= HIDDEN_UNDISPLAYABLE;
954  if ((param->reinit & REINIT_FUNCTIONAL)
955  && weed_get_int_value(inst, WEED_LEAF_HOST_REFS, NULL) >= 2) {
956  // effect is running and user is editing the params, we should hide reinit params
957  // so as not to disturb the flow !
958  param->hidden |= HIDDEN_NEEDS_REINIT;
959  } else param->hidden &= ~HIDDEN_NEEDS_REINIT;
960 
961  if (is_hidden_param(inst, idx)) param->hidden |= HIDDEN_GUI_PERM;
962 
963  wparam = weed_inst_in_param(inst, idx, FALSE, FALSE);
964 
965  if (wparam) {
966  if (weed_param_is_hidden(wparam, WEED_FALSE) == WEED_FALSE) {
967  if (weed_param_is_hidden(wparam, WEED_TRUE)) param->hidden |= HIDDEN_GUI_TEMP;
968  else param->hidden &= ~HIDDEN_GUI_TEMP;
969  }
970  }
971 }
972 
973 
974 static int num_in_params_for_nth_instance(weed_plant_t *inst, int idx) {
975  // get number of params for nth instance in a compound effect - gives an offset for param number within the compound
976  while (--idx > 0) inst = weed_get_plantptr_value(inst, WEED_LEAF_HOST_NEXT_INSTANCE, NULL);
977  return weed_leaf_num_elements(inst, WEED_LEAF_IN_PARAMETERS);
978 }
979 
980 
981 static boolean fmt_match(char *fmt_string) {
982  const char *myfmt = fmt_string, *xfmt = myfmt + FMT_STRING_SIZE;
983  size_t xlen = lives_strlen(myfmt), ylen;
984 
985  // g_print("\nROW\n");
986  if (xlen == 0) {
987  //g_print("HSEP\n");
988  return FALSE;
989  }
990  ylen = lives_strlen(xfmt);
991  if (ylen == 0) {
992  //g_print("2HSEP\n");
993  return FALSE;
994  }
995 
996  if (xlen < ylen) ylen = xlen;
997 
998  for (int j = 0; j < ylen; j++) {
999  //g_print(" CF %d %d", myfmt[j], xfmt[j]);
1000  if (xfmt[j] != -1 && myfmt[j] != -1 && xfmt[j] != myfmt[j]) return FALSE;
1001  if ((xfmt[j] == -2 || myfmt[j] == -2) && xfmt[j] != myfmt[j]) return FALSE;
1002  }
1003 
1004  //g_print("\nMATch\n");
1005  return TRUE;
1006 }
1007 
1008 
1015 boolean make_param_box(LiVESVBox *top_vbox, lives_rfx_t *rfx) {
1016  lives_param_t *param = NULL;
1017 
1018  LiVESWidget *param_vbox = NULL;
1019  LiVESWidget *top_hbox = NULL;
1020  LiVESWidget *hbox = NULL;
1021  LiVESWidget *last_label = NULL;
1022  LiVESWidget *layoutx = NULL;
1023  LiVESWidget *dummy_label = NULL;
1024 
1025  // put whole thing in scrolled window
1026  LiVESWidget *scrolledwindow;
1027 
1028  LiVESList *hints = NULL;
1029  LiVESList *onchange = NULL;
1030  LiVESList *layout = NULL;
1031  LiVESList *list;
1032 
1033  char **array;
1034  char label_text[256]; // max length of a label in layout hints
1035 
1036  char *line;
1037  char *type = NULL;
1038  char *format = NULL;
1039 
1040  char fmt_strings[MAX_FMT_STRINGS][FMT_STRING_SIZE];
1041 
1042  size_t fmtlen, ll;
1043 
1044  boolean used[rfx->num_params];
1045  boolean has_box = FALSE;
1046  boolean internal = FALSE;
1047  boolean noslid;
1048  boolean has_param = FALSE;
1049  boolean chk_params = FALSE;
1050  boolean needs_sizes = FALSE;
1051  boolean layout_mode = FALSE;
1052  boolean keepsmall;
1053 
1054  int pnum;
1055  int length;
1056  int poffset = 0, inum = 0;
1057  int wofl = widget_opts.filler_len;
1058 
1059  int num_tok;
1060 
1061  int c_fmt_strings = 0;
1062  int pass;
1063  int woph = widget_opts.packing_height;
1064 
1065  int i, j, k;
1066 
1067  char sepnpnum[1024];
1068  size_t sepnpnumlen;
1069 
1070  lives_snprintf(sepnpnum, 1024, "s%s", rfx->delim);
1071  sepnpnumlen = strlen(sepnpnum);
1072 
1073  if (!top_vbox) {
1074  // just check how many non-hidden params without displaying
1075  chk_params = TRUE;
1076  } else {
1077  dummy_label = lives_label_new(NULL);
1078  lives_widget_object_ref_sink(LIVES_WIDGET_OBJECT(dummy_label));
1079 
1080  mainw->textwidget_focus = NULL;
1081 
1082  // initialise special widgets
1083  init_special();
1084 
1085  if (rfx->status == RFX_STATUS_WEED) usrgrp_to_livesgrp[1] = NULL;
1086  else usrgrp_to_livesgrp[0] = NULL;
1087 
1088  // paramwindow start, everything goes in top_hbox
1090 
1091  // param_vbox holds the dynamic parameters
1093  lives_widget_set_halign(param_vbox, LIVES_ALIGN_FILL);
1094  lives_widget_set_valign(param_vbox, LIVES_ALIGN_CENTER);
1095  lives_box_pack_start(LIVES_BOX(top_hbox), param_vbox, TRUE, TRUE, widget_opts.packing_width);
1096 
1097  for (i = 0; i < rfx->num_params; i++) {
1098  used[i] = FALSE;
1099  for (j = 0; j < MAX_PARAM_WIDGETS; j++) {
1100  if (rfx->params[i].transition && j > 0 && j < 4) continue;
1101  rfx->params[i].widgets[j] = NULL;
1102  }
1103  }
1104  }
1105 
1106  switch (rfx->status) {
1107  case RFX_STATUS_BUILTIN:
1108  if (!chk_params) type = lives_strdup(PLUGIN_RENDERED_EFFECTS_BUILTIN);
1109  break;
1110  case RFX_STATUS_CUSTOM:
1111  if (!chk_params) type = lives_strdup(PLUGIN_RENDERED_EFFECTS_CUSTOM);
1112  break;
1113  case RFX_STATUS_SCRAP:
1114  if (!chk_params) type = lives_strdup(PLUGIN_RFX_SCRAP);
1115  break;
1116  case RFX_STATUS_WEED:
1117  if (!mainw->multitrack && rfx->is_template) {
1118  weed_plant_t *filter = weed_instance_get_filter((weed_plant_t *)rfx->source, TRUE);
1119  if (enabled_in_channels(filter, FALSE) == 0 && enabled_out_channels(filter, FALSE) > 0
1120  && has_video_chans_out(filter, TRUE)) {
1121  // out channel size(s) and target_fps for generators
1122  needs_sizes = TRUE;
1123  }
1124  }
1125  // extras for converters
1126  if (weed_instance_is_resizer((weed_plant_t *)rfx->source)) {
1127  has_param = add_sizes(LIVES_BOX(param_vbox), FALSE, FALSE, rfx);
1128  if (chk_params && has_param) return TRUE;
1129  }
1130  internal = TRUE;
1131  break;
1132  default:
1133  if (!chk_params) type = lives_strdup(PLUGIN_RENDERED_EFFECTS_TEST);
1134  break;
1135  }
1136 
1137  if (internal) {
1138  if (mainw->multitrack) {
1139  // extras for multitrack
1140  weed_plant_t *filter = weed_instance_get_filter((weed_plant_t *)rfx->source, TRUE);
1141  if (enabled_in_channels(filter, FALSE) == 2 && get_transition_param(filter, FALSE) != -1) {
1142  // add in/out for multitrack transition
1143  if (chk_params) return TRUE;
1144  has_param = TRUE;
1145  transition_add_in_out(LIVES_BOX(param_vbox), rfx, (mainw->multitrack->opts.pertrack_audio));
1146  }
1147  }
1148  if (!chk_params) hints = get_external_window_hints(rfx);
1149  } else {
1150  if (rfx->status != RFX_STATUS_SCRAP && rfx->num_in_channels == 0 && rfx->min_frames > -1) {
1151  if (!mainw->multitrack) {
1152  if (chk_params) return TRUE;
1153  add_gen_to(LIVES_BOX(param_vbox), rfx);
1154  } else mainw->gen_to_clipboard = FALSE;
1156  add_genparams(param_vbox, rfx);
1157  has_param = TRUE;
1158  }
1159 
1160  if (!chk_params) {
1161  // do onchange|init
1162  if ((onchange = plugin_request_by_line(type, rfx->name, "get_onchange"))) {
1163  for (i = 0; i < lives_list_length(onchange); i++) {
1164  array = lives_strsplit((char *)lives_list_nth_data(onchange, i), rfx->delim, -1);
1165  if (strcmp(array[0], "init")) {
1166  // note other onchanges so we don't have to keep parsing the list
1167  int which = atoi(array[0]);
1168  if (which >= 0 && which < rfx->num_params) {
1169  rfx->params[which].onchange = TRUE;
1170  }
1171  }
1172  lives_strfreev(array);
1173  }
1174  lives_list_free_all(&onchange);
1175  }
1176  hints = plugin_request_by_line(type, rfx->name, "get_param_window");
1177  lives_free(type);
1178  }
1179  }
1180 
1181  // do param window hints
1182  if (hints) {
1183  LiVESList *list;
1184  char *lstring = lives_strconcat("layout", rfx->delim, NULL);
1185  char *sstring = lives_strconcat("special", rfx->delim, NULL);
1186  char *istring = lives_strconcat("internal", rfx->delim, NULL);
1187  for (list = hints; list; list = list->next) {
1188  char *line = (char *)list->data;
1189  if (!lives_strncmp(line, lstring, 7)) {
1190  layout = lives_list_append(layout, lives_strdup(line + 7));
1191  } else if (!lives_strncmp(line, istring, 9)) {
1192  layout = lives_list_append(layout, lives_strdup(line + 9));
1193  } else if (!lives_strncmp(line, sstring, 8)) {
1194  add_to_special(line + 8, rfx); // add any special actions to the framedraw preview
1195  }
1196  }
1197  lives_list_free_all(&hints);
1198  lives_free(lstring);
1199  lives_free(sstring);
1200  lives_free(istring);
1201  }
1202 
1203  lives_memset(fmt_strings, 0, MAX_FMT_STRINGS * FMT_STRING_SIZE);
1204 
1205  for (pass = 0; pass < 2; pass++) {
1206  // in this mode we do 2 passes: first check if the row is similar to the following row
1207  // (ignoring any rows with just labels or hseparators)
1208  // if so we mark it as 'layoutable'
1209 
1210  // to compare: make a string with the following vals: paramtype, or label (-2), or fill (-1)
1211  // following this we compare the strings
1212 
1213  // if the string has the same value as its successor we will create or extend the layout
1214  if (chk_params) pass = 1;
1215  //g_print("in pass %d\n", pass);
1216 
1217  list = layout;
1218  // use layout hints to build as much as we can
1219  for (i = 0; list; i++) {
1220  line = (char *)list->data;
1221  list = list->next;
1222  layout_mode = FALSE;
1223  has_box = FALSE;
1224  last_label = NULL;
1225  noslid = FALSE;
1226  if (i < MAX_FMT_STRINGS - 1) {
1227  format = fmt_strings[i];
1228  if (pass == 1 && !chk_params && (i > 0 || list)) {
1229  if (fmt_match((char *)fmt_strings[list == NULL ? i - 1 : i])) {
1230  layout_mode = TRUE;
1231  if (!layoutx) {
1233  layoutx = lives_layout_new(LIVES_BOX(param_vbox));
1234  lives_widget_set_halign(layoutx, LIVES_ALIGN_CENTER);
1235  widget_opts.packing_height = woph;
1236  }
1237  //g_print("LAYOUT MODE\n");
1238  }
1239  }
1240  } else if (pass == 0) break;
1241 
1242  num_tok = get_token_count(line, (unsigned int)rfx->delim[0]);
1243  // ignore | inside strings
1244  array = lives_strsplit(line, rfx->delim, num_tok);
1245  if (!*(array[num_tok - 1])) num_tok--;
1246 
1247  for (j = 0; j < num_tok; j++) {
1248  if (!strcmp(array[j], "nextfilter")) {
1249  // handling for compound fx - add an offset to the param number
1250  poffset += num_in_params_for_nth_instance((weed_plant_t *)rfx->source, inum);
1251  inum++;
1252  continue;
1253  }
1254 
1255  if (!strcmp(array[j], "hseparator")) {
1256  // hseparator ///////////////
1257  if (pass == 1 && !chk_params) {
1258  // add a separator
1259  if (layoutx) lives_layout_add_separator(LIVES_LAYOUT(layoutx), TRUE);
1260  else add_hsep_to_box(LIVES_BOX(param_vbox));
1261  }
1262  break; // ignore anything after hseparator
1263  }
1264 
1265  if (!strncmp(array[j], "p", 1) && (pnum = atoi((char *)(array[j] + 1))) >= 0
1266  && (pnum = pnum + poffset) < rfx->num_params && !used[pnum]) {
1267  // parameter, eg. p1 ////////////////////////////
1268  param = &rfx->params[pnum];
1269  if (!chk_params && !(rfx->flags & RFX_FLAGS_NO_RESET)) {
1270  rfx->params[pnum].changed = FALSE;
1271  }
1272  if (rfx->source_type == LIVES_RFX_SOURCE_WEED) {
1273  check_hidden_gui((weed_plant_t *)rfx->source, param, pnum);
1274  if (param->hidden & HIDDEN_STRUCTURAL) continue;
1275  }
1276 
1277  has_param = TRUE;
1278 
1279  if (pass == 0) {
1280  if ((fmtlen = lives_strlen((const char *)format)) < FMT_STRING_SIZE - 1) format[fmtlen] = (unsigned char)param->type;
1281  } else {
1282  used[pnum] = TRUE;
1283  if (!has_box) {
1284  // add a new row if needed
1285  if (layoutx) lives_layout_add_row(LIVES_LAYOUT(layoutx));
1286  else {
1287  hbox = lives_hbox_new(FALSE, 0);
1288  lives_box_pack_start(LIVES_BOX(param_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
1289  }
1290  has_box = TRUE;
1291  } else {
1292  widget_opts.filler_len >>= 2;
1293  if (layoutx) lives_layout_add_fill(LIVES_LAYOUT(layoutx), TRUE);
1294  else add_fill_to_box(LIVES_BOX(hbox));
1295  widget_opts.filler_len = wofl;
1296  }
1297 
1298  if (last_label) {
1299  lives_widget_set_halign(last_label, LIVES_ALIGN_START);
1300  }
1301  if (layoutx) hbox = lives_layout_hbox_new(LIVES_LAYOUT(layoutx));
1302  if (add_param_to_box(LIVES_BOX(hbox), rfx, pnum, (j == (num_tok - 1)) && !noslid)) noslid = TRUE;
1303  }
1304  } else if (!strncmp(array[j], "fill", 4)) {
1306  // (can be filln)
1307 
1308  if (strlen(array[j]) == 4 || (length = atoi(array[j] + 4)) == 0) length = 1;
1309 
1310  if (pass == 1) {
1311  if (!has_box) {
1312  // add a new row if needed
1313  if (layoutx) lives_layout_add_row(LIVES_LAYOUT(layoutx));
1314  else {
1315  hbox = lives_hbox_new(FALSE, 0);
1316  lives_box_pack_start(LIVES_BOX(param_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
1317  }
1318  if (layoutx) lives_layout_add_fill(LIVES_LAYOUT(layoutx), TRUE);
1319  else add_fill_to_box(LIVES_BOX(hbox));
1320  has_box = TRUE;
1321  } else {
1322  if (last_label) lives_widget_set_halign(last_label, LIVES_ALIGN_START);
1323  widget_opts.filler_len >>= 1;
1324  if (layoutx) {
1325  lives_layout_add_fill(LIVES_LAYOUT(layoutx), TRUE);
1326  lives_layout_add_fill(LIVES_LAYOUT(layoutx), TRUE);
1327  } else {
1328  add_fill_to_box(LIVES_BOX(hbox));
1329  add_fill_to_box(LIVES_BOX(hbox));
1330  }
1331  widget_opts.filler_len = wofl;
1332  }
1333  }
1334 
1335  for (k = 1; k < length; k++) {
1336  if (pass == 1) {
1337  widget_opts.filler_len >>= 1;
1338  if (layoutx) {
1339  lives_layout_add_fill(LIVES_LAYOUT(layoutx), TRUE);
1340  lives_layout_add_fill(LIVES_LAYOUT(layoutx), TRUE);
1341  } else {
1342  add_fill_to_box(LIVES_BOX(hbox));
1343  add_fill_to_box(LIVES_BOX(hbox));
1344  }
1345  widget_opts.filler_len = wofl;
1346  } else if ((fmtlen = lives_strlen((const char *)format)) < FMT_STRING_SIZE) format[fmtlen] = -1;
1347  }
1348  } else if (*array[j] == '"') {
1349  // add a label
1350  if (pass == 0) {
1351  if ((fmtlen = lives_strlen((const char *)format)) < FMT_STRING_SIZE) format[fmtlen] = -2;
1352  if (has_box) last_label = dummy_label;
1353  continue;
1354  }
1355 
1356  if (!has_box) {
1357  // add a new row if needed
1358  if (layoutx) lives_layout_add_row(LIVES_LAYOUT(layoutx));
1359  else {
1360  hbox = lives_hbox_new(FALSE, 0);
1361  lives_box_pack_start(LIVES_BOX(param_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
1362  }
1363  has_box = TRUE;
1364  } else {
1365  widget_opts.filler_len >>= 1;
1366  if (layoutx) lives_layout_add_fill(LIVES_LAYOUT(layoutx), TRUE);
1367  else add_fill_to_box(LIVES_BOX(hbox));
1368  widget_opts.filler_len = wofl;
1369  }
1370 
1371  ll = lives_snprintf(label_text, 256, "%s", array[j] + 1);
1372  if (ll > 255) ll = 255;
1373 
1374  while (j < num_tok - 1 && label_text[ll - 1] != '"') {
1375  // handle separators within label text
1376  ll += lives_strappend(label_text, 256, rfx->delim);
1377  ll += lives_strappend(label_text, 256, array[++j]);
1378  }
1379 
1380  keepsmall = TRUE;
1381  if (!last_label && !has_param) {
1382  if (j == num_tok - 1 || strncmp(array[j + 1], sepnpnum, sepnpnumlen)) keepsmall = TRUE;
1383  }
1384 
1385  if (ll) {
1386  if (label_text[ll - 1] == '"') label_text[ll - 1] = 0;
1387 
1388  if (!keepsmall) widget_opts.justify = LIVES_JUSTIFY_CENTER;
1389  else if (last_label) {
1390  lives_widget_set_halign(last_label, LIVES_ALIGN_START);
1391  lives_widget_set_hexpand(last_label, FALSE);
1392  }
1393 
1394  if (layoutx) {
1395  last_label = lives_layout_add_label(LIVES_LAYOUT(layoutx), label_text, keepsmall);
1396  } else last_label = add_param_label_to_box(LIVES_BOX(hbox), !keepsmall, label_text);
1398  lives_widget_set_hexpand(last_label, TRUE);
1399  }
1400  }
1401  }
1402  if (!layout_mode) layoutx = NULL;
1403  lives_strfreev(array);
1404  }
1405 
1406  if (!chk_params) {
1407  c_fmt_strings = i;
1408  if (pass == 1) lives_list_free_all(&layout);
1409  }
1410 
1411  // add any unused parameters
1412  for (i = 0; i < rfx->num_params; i++) {
1413  if (!chk_params && !(rfx->flags & RFX_FLAGS_NO_RESET)) {
1414  rfx->params[i].changed = FALSE;
1415  if (used[i]) continue;
1416  }
1417 
1418  layout_mode = FALSE;
1419  format = NULL;
1420 
1421  if (c_fmt_strings + i < MAX_FMT_STRINGS - 1) {
1422  format = fmt_strings[c_fmt_strings + i];
1423  if (pass == 1 && !chk_params) {
1424  if (fmt_match((char *)fmt_strings[i + c_fmt_strings])) {
1425  layout_mode = TRUE;
1426  if (!layoutx) {
1428  layoutx = lives_layout_new(LIVES_BOX(param_vbox));
1429  lives_widget_set_halign(layoutx, LIVES_ALIGN_CENTER);
1430  widget_opts.packing_height = woph;
1431  }
1432  //g_print("LAYOUT MODE\n");
1433  }
1434  }
1435  } else if (pass == 0) break;
1436 
1437  if (rfx->source_type == LIVES_RFX_SOURCE_WEED) {
1438  check_hidden_gui((weed_plant_t *)rfx->source, &rfx->params[i], i);
1439  if (rfx->params[i].hidden & HIDDEN_STRUCTURAL) continue;
1440  }
1441 
1442  if (chk_params) return TRUE;
1443 
1444  has_param = TRUE;
1445  if (pass == 0) {
1446  if ((fmtlen = lives_strlen((const char *)format)) < FMT_STRING_SIZE) format[fmtlen] =
1447  (unsigned char)(rfx->params[i].type);
1448  } else {
1449  if (layoutx) {
1450  add_param_to_box(LIVES_BOX(lives_layout_row_new(LIVES_LAYOUT(layoutx))), rfx, i, TRUE);
1451  } else add_param_to_box(LIVES_BOX(param_vbox), rfx, i, TRUE);
1452  }
1453  if (!layout_mode) layoutx = NULL;
1454  }
1455  }
1456 
1457  if (needs_sizes) has_param = add_sizes(chk_params ? NULL : LIVES_BOX(top_vbox), TRUE, has_param, rfx);
1458  if (chk_params) return has_param;
1459 
1460  if (!has_param) {
1461  widget_opts.justify = LIVES_JUSTIFY_CENTER;
1462  LiVESWidget *label = lives_standard_label_new(_("No parameters"));
1463  hbox = lives_hbox_new(FALSE, 0);
1464  lives_box_pack_start(LIVES_BOX(param_vbox), hbox, TRUE, FALSE, 0);
1465  lives_box_pack_start(LIVES_BOX(hbox), label, TRUE, FALSE, 0);
1467  }
1468 
1469  if (!mainw->multitrack || rfx->status != RFX_STATUS_WEED) {
1470  float box_scale = 1.;
1471  // for resize effects we add the framedraw to get its widgets, but hide it, so the box should get extra width and less height
1472  if (rfx->props & RFX_PROPS_MAY_RESIZE) box_scale = 1.5 * widget_opts.scale;
1473  scrolledwindow = lives_standard_scrolled_window_new(RFX_WINSIZE_H * box_scale, RFX_WINSIZE_V >> 1, top_hbox);
1474  } else scrolledwindow = lives_standard_scrolled_window_new(-1, -1, top_hbox);
1475 
1476  lives_box_pack_start(LIVES_BOX(top_vbox), scrolledwindow, TRUE, TRUE, 0);
1477  lives_widget_destroy(dummy_label);
1478  if (has_param)
1479  update_widget_vis(rfx, -1, -1);
1480  return has_param;
1481 }
1482 
1483 
1484 boolean add_param_to_box(LiVESBox *box, lives_rfx_t *rfx, int pnum, boolean add_slider) {
1485  // box here is vbox inside top_hbox inside top_dialog
1486 
1487  // add paramter pnum for rfx to box
1488 
1489  LiVESWidget *label;
1490  LiVESWidget *checkbutton;
1491  LiVESWidget *radiobutton;
1492  LiVESWidget *spinbutton;
1493  LiVESWidget *scale = NULL;
1494  LiVESWidget *spinbutton_red;
1495  LiVESWidget *spinbutton_green;
1496  LiVESWidget *spinbutton_blue;
1497  LiVESWidget *cbutton;
1498  LiVESWidget *entry = NULL;
1499  LiVESWidget *hbox;
1500  LiVESWidget *combo;
1501  //LiVESWidget *dlabel = NULL;
1502  LiVESWidget *textview = NULL;
1503  LiVESWidget *scrolledwindow;
1504  LiVESWidget *layout = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(box),
1505  WH_LAYOUT_KEY);
1506 
1507  LiVESAdjustment *spinbutton_adj;
1508 
1509  LiVESTextBuffer *textbuffer = NULL;
1510 
1511  lives_param_t *param;
1512  lives_widget_group_t *group;
1513  LiVESSList *rbgroup;
1514 
1515  lives_colRGB48_t rgb;
1516  lives_colRGBA64_t rgba;
1517 
1518  char *name;
1519  char *txt;//, *tmp;
1520  //char *disp_string;
1521 
1522  int wcount = 0;
1523 
1524  boolean use_mnemonic;
1525  boolean was_num = FALSE;
1526 
1527  boolean add_scalers = TRUE;
1528 
1529  if (pnum >= rfx->num_params) {
1530  add_param_label_to_box(box, FALSE, (_("Invalid parameter")));
1531  return FALSE;
1532  }
1533 
1534  param = &rfx->params[pnum];
1535 
1536  name = lives_strdup_printf("%s", param->label);
1537  use_mnemonic = param->use_mnemonic;
1538 
1539  // reinit can cause the window to be redrawn, which invalidates the slider adjustment...and bang !
1540  // so dont add sliders for such params
1541  if (param->reinit) add_scalers = FALSE;
1542 
1543  // for plugins (encoders and video playback) sliders look silly
1544  if (rfx->flags & RFX_FLAGS_NO_SLIDERS) add_scalers = FALSE;
1545 
1546  if (LIVES_IS_HBOX(LIVES_WIDGET(box))) {
1547  hbox = LIVES_WIDGET(box);
1548  } else {
1549  hbox = lives_hbox_new(FALSE, 0);
1550  lives_box_pack_start(LIVES_BOX(box), hbox, FALSE, FALSE, widget_opts.packing_height);
1551  }
1552 
1553  // see if there were any 'special' hints
1554  if (!layout)
1555  check_for_special_type(rfx, param, LIVES_BOX(lives_widget_get_parent(LIVES_WIDGET(box))));
1556  else
1557  check_for_special_type(rfx, param, LIVES_BOX(lives_widget_get_parent(layout)));
1558 
1559  switch (param->type) {
1560  case LIVES_PARAM_BOOL:
1561  if (!param->group) {
1562  widget_opts.mnemonic_label = use_mnemonic;
1563  checkbutton = lives_standard_check_button_new(name, get_bool_param(param->value), (LiVESBox *)hbox, param->desc);
1564  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
1565  LIVES_GUI_CALLBACK(after_boolean_param_toggled),
1566  (livespointer)rfx);
1568 
1569  // store parameter so we know whose trigger to use
1570  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(checkbutton), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1571  param->widgets[0] = checkbutton;
1572  } else {
1573  group = get_group(rfx, param);
1574 
1575  if (group) rbgroup = group->rbgroup;
1576  else rbgroup = NULL;
1577 
1578  widget_opts.mnemonic_label = use_mnemonic;
1579  radiobutton = lives_standard_radio_button_new(name, &rbgroup, LIVES_BOX(hbox), param->desc);
1581 
1582  if (group == NULL) {
1583  if (rfx->status == RFX_STATUS_WEED) {
1584  usrgrp_to_livesgrp[1] = add_usrgrp_to_livesgrp(usrgrp_to_livesgrp[1],
1585  rbgroup, param->group);
1586  } else {
1587  usrgrp_to_livesgrp[0] = add_usrgrp_to_livesgrp(usrgrp_to_livesgrp[0],
1588  rbgroup, param->group);
1589  }
1590  }
1591 
1592  group = get_group(rfx, param);
1593 
1594  if (group) {
1595  group->rbgroup = rbgroup;
1596  if (get_bool_param(param->value)) {
1597  group->active_param = pnum + 1;
1598  }
1599  } else LIVES_WARN("Button group was NULL");
1600 
1601  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton), get_bool_param(param->value));
1602 
1603  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(radiobutton), LIVES_WIDGET_TOGGLED_SIGNAL,
1604  LIVES_GUI_CALLBACK(after_boolean_param_toggled), (livespointer)rfx);
1605 
1606  // store parameter so we know whose trigger to use
1607  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(radiobutton), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1608  param->widgets[0] = radiobutton;
1609  }
1610  param->widgets[1] = widget_opts.last_label;
1611  break;
1612 
1613  case LIVES_PARAM_NUM:
1614  was_num = TRUE;
1615 
1616  widget_opts.mnemonic_label = use_mnemonic;
1617  if (param->dp) {
1618  spinbutton = lives_standard_spin_button_new(name, get_double_param(param->value), param->min,
1619  param->max, param->step_size, param->step_size, param->dp,
1620  (LiVESBox *)hbox, param->desc);
1621  } else {
1622  spinbutton = lives_standard_spin_button_new(name, (double)get_int_param(param->value), param->min,
1623  param->max, param->step_size, param->step_size, param->dp,
1624  (LiVESBox *)hbox, param->desc);
1625  }
1627 
1628  lives_spin_button_set_wrap(LIVES_SPIN_BUTTON(spinbutton), param->wrap);
1629 
1630  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
1631  LIVES_GUI_CALLBACK(after_param_value_changed), (livespointer)rfx);
1632 
1633  // store parameter so we know whose trigger to use
1634  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(spinbutton), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1635  param->widgets[0] = spinbutton;
1636  param->widgets[++wcount] = widget_opts.last_label;
1637  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(param->widgets[0]), RFX_KEY, rfx);
1638 
1639  if (add_scalers) {
1640  spinbutton_adj = lives_spin_button_get_adjustment(LIVES_SPIN_BUTTON(spinbutton));
1641 #ifdef ENABLE_GIW
1642  if (prefs->lamp_buttons) {
1643  scale = giw_knob_new(LIVES_ADJUSTMENT(spinbutton_adj));
1644  giw_knob_set_wrap(GIW_KNOB(scale), param->wrap);
1646  giw_knob_set_legends_digits(GIW_KNOB(scale), 0);
1647  if (layout) {
1648  hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1649  lives_layout_pack(LIVES_HBOX(hbox), scale);
1650  lives_widget_set_show_hide_with(spinbutton, hbox);
1651  } else
1652  lives_box_pack_start(LIVES_BOX(hbox), scale, FALSE, FALSE, widget_opts.packing_width >> 1);
1653  if (param->desc) lives_widget_set_tooltip_text(scale, param->desc);
1654  lives_widget_set_fg_color(scale, LIVES_WIDGET_STATE_NORMAL, &palette->white);
1655  lives_widget_set_fg_color(scale, LIVES_WIDGET_STATE_PRELIGHT, &palette->dark_orange);
1656  lives_widget_set_bg_color(scale, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
1657  param->widgets[++wcount] = scale;
1658  }
1659 #endif
1660 
1661  if (add_slider && !param->wrap && (param->dp || param->transition)) {
1662  spinbutton_adj = lives_spin_button_get_adjustment(LIVES_SPIN_BUTTON(spinbutton));
1663  scale = lives_standard_hscale_new(LIVES_ADJUSTMENT(spinbutton_adj));
1665  if (layout) {
1666  hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
1667  lives_layout_pack(LIVES_HBOX(hbox), scale);
1668  lives_widget_set_show_hide_with(spinbutton, hbox);
1669  } else {
1670  lives_box_pack_start(LIVES_BOX(hbox), scale, TRUE, TRUE, widget_opts.packing_width >> 1);
1671  if (!LIVES_IS_HBOX(LIVES_WIDGET(box))) add_fill_to_box(LIVES_BOX(hbox));
1672  }
1673  lives_widget_apply_theme(scale, LIVES_WIDGET_STATE_NORMAL);
1674  if (param->desc) lives_widget_set_tooltip_text(scale, param->desc);
1675  param->widgets[++wcount] = scale;
1676  }
1677  }
1678 
1679  if (param->desc) lives_widget_set_tooltip_text(scale, param->desc);
1680  break;
1681 
1682  case LIVES_PARAM_COLRGB24:
1683  get_colRGB24_param(param->value, &rgb);
1684 
1685  rgba.red = rgb.red << 8;
1686  rgba.green = rgb.green << 8;
1687  rgba.blue = rgb.blue << 8;
1688  rgba.alpha = 65535;
1689 
1690  widget_opts.mnemonic_label = use_mnemonic;
1691  cbutton = lives_standard_color_button_new(LIVES_BOX(hbox), _(name), FALSE, &rgba, &spinbutton_red, &spinbutton_green,
1692  &spinbutton_blue, NULL);
1695 
1696  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(cbutton), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1697  if (param->desc) lives_widget_set_tooltip_text(cbutton, param->desc);
1698 
1699  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton_red), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
1700  LIVES_GUI_CALLBACK(after_param_red_changed), (livespointer)rfx);
1701  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton_green), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
1702  LIVES_GUI_CALLBACK(after_param_green_changed), (livespointer)rfx);
1703  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(spinbutton_blue), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
1704  LIVES_GUI_CALLBACK(after_param_blue_changed), (livespointer)rfx);
1705 
1706  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(cbutton), LIVES_WIDGET_COLOR_SET_SIGNAL,
1707  LIVES_GUI_CALLBACK(on_pwcolsel), (livespointer)rfx);
1708 
1709  // store parameter so we know whose trigger to use
1710  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(spinbutton_red), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1711  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(spinbutton_green), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1712  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(spinbutton_blue), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1713 
1714  param->widgets[0] = spinbutton_red;
1715  param->widgets[1] = spinbutton_green;
1716  param->widgets[2] = spinbutton_blue;
1717  //param->widgets[3]=spinbutton_alpha;
1718  param->widgets[4] = cbutton;
1719  param->widgets[5] = widget_opts.last_label;
1720  break;
1721 
1722  case LIVES_PARAM_STRING:
1723  if (param->max == 0.) txt = lives_strdup((char *)param->value);
1724  else txt = lives_strndup((char *)param->value, (int)param->max);
1725 
1726  if (((int)param->max > RFX_TEXT_MAGIC || param->max == 0.) &&
1730  LiVESWidget *vbox = lives_vbox_new(FALSE, 0);
1731  int woat = widget_opts.apply_theme;
1732 
1733  widget_opts.justify = LIVES_JUSTIFY_CENTER;
1734  if (use_mnemonic) label = lives_standard_label_new_with_mnemonic_widget(_(name), NULL);
1735  else label = lives_standard_label_new(_(name));
1737 
1738  lives_box_pack_start(LIVES_BOX(hbox), vbox, TRUE, TRUE, widget_opts.packing_width);
1739  if (layout) lives_layout_expansion_row_new(LIVES_LAYOUT(layout), vbox);
1740 
1741  lives_box_pack_start(LIVES_BOX(vbox), label, FALSE, FALSE, widget_opts.packing_height >> 1);
1742 
1743  hbox = lives_hbox_new(FALSE, 0);
1744  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height >> 1);
1745 
1746  param->widgets[0] = textview = lives_text_view_new();
1747  if (param->desc) lives_widget_set_tooltip_text(textview, param->desc);
1748  textbuffer = lives_text_view_get_buffer(LIVES_TEXT_VIEW(textview));
1749 
1750  lives_signal_sync_connect_after(LIVES_WIDGET_OBJECT(textbuffer), LIVES_WIDGET_CHANGED_SIGNAL,
1751  LIVES_GUI_CALLBACK(after_param_text_buffer_changed),
1752  (livespointer) rfx);
1753 
1754  lives_text_view_set_editable(LIVES_TEXT_VIEW(textview), TRUE);
1755  lives_text_view_set_wrap_mode(LIVES_TEXT_VIEW(textview), LIVES_WRAP_WORD);
1756  lives_text_view_set_cursor_visible(LIVES_TEXT_VIEW(textview), TRUE);
1757 
1758  lives_text_buffer_set_text(textbuffer, txt, -1);
1759 
1762  scrolledwindow = lives_standard_scrolled_window_new(-1, RFX_TEXT_SCROLL_HEIGHT, textview);
1764  widget_opts.apply_theme = woat;
1765 
1766  if (mainw->multitrack == NULL)
1767  lives_widget_apply_theme3(textview, LIVES_WIDGET_STATE_NORMAL);
1768  else
1769  lives_widget_apply_theme2(textview, LIVES_WIDGET_STATE_NORMAL, TRUE);
1770 
1771  lives_box_pack_start(LIVES_BOX(hbox), scrolledwindow, TRUE, TRUE, 0);
1772 
1773  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(textbuffer), "textview", textview);
1774  } else {
1775  if (use_mnemonic) label = lives_standard_label_new_with_mnemonic_widget(_(name), NULL);
1776  else label = lives_standard_label_new(_(name));
1777 
1778  lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, widget_opts.packing_width);
1779  param->widgets[0] = entry = lives_standard_entry_new(NULL, txt, (int)param->max,
1780  (int)param->max, LIVES_BOX(hbox), param->desc);
1781 
1782  if (rfx->status == RFX_STATUS_WEED && param->special_type != LIVES_PARAM_SPECIAL_TYPE_FILEREAD) {
1783  lives_signal_sync_connect_after(LIVES_WIDGET_OBJECT(entry), LIVES_WIDGET_CHANGED_SIGNAL,
1784  LIVES_GUI_CALLBACK(after_param_text_changed), (livespointer)rfx);
1785  }
1786  }
1787  param->widgets[1] = widget_opts.last_label;
1788 
1789  if (param->desc) lives_widget_set_tooltip_text(label, param->desc);
1790 
1791  lives_signal_sync_connect_after(LIVES_WIDGET_OBJECT(hbox), LIVES_WIDGET_SET_FOCUS_CHILD_SIGNAL,
1792  LIVES_GUI_CALLBACK(after_param_text_focus_changed),
1793  (livespointer)rfx);
1794 
1795  if (use_mnemonic) lives_label_set_mnemonic_widget(LIVES_LABEL(label), param->widgets[0]);
1796 
1797  lives_free(txt);
1798 
1799  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(hbox), TEXTWIDGET_KEY, (livespointer)param->widgets[0]);
1800  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(param->widgets[0]), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1801  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(param->widgets[0]), RFX_KEY, rfx);
1802 
1803  param->widgets[1] = label;
1804 
1805  break;
1806 
1809  widget_opts.mnemonic_label = use_mnemonic;
1810 
1811  combo = lives_standard_combo_new(name, param->list, (LiVESBox *)hbox, param->desc);
1814 
1815  if (param->list) {
1816  lives_combo_set_active_string(LIVES_COMBO(combo),
1817  (char *)lives_list_nth_data(param->list, get_int_param(param->value)));
1818  }
1819 
1820  lives_signal_sync_connect_after(LIVES_WIDGET_OBJECT(combo), LIVES_WIDGET_CHANGED_SIGNAL,
1821  LIVES_GUI_CALLBACK(after_string_list_changed), (livespointer)rfx);
1822 
1823  // store parameter so we know whose trigger to use
1824  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combo), PARAM_NUMBER_KEY, LIVES_INT_TO_POINTER(pnum));
1825  param->widgets[0] = combo;
1826  param->widgets[1] = widget_opts.last_label;
1827  break;
1828 
1829  default:
1830  break;
1831  }
1832 
1833  // see if there were any 'special' hints
1834  if (!layout) {
1835  check_for_special(rfx, param, LIVES_BOX(lives_widget_get_parent(LIVES_WIDGET(box))));
1836  } else {
1837  check_for_special(rfx, param, LIVES_BOX(lives_widget_get_parent(layout)));
1838  }
1839  lives_free(name);
1840  return was_num;
1841 }
1842 
1843 
1844 LiVESWidget *add_param_label_to_box(LiVESBox *box, boolean do_trans, const char *text) {
1845  LiVESWidget *label;
1846 
1847  lives_box_set_homogeneous(LIVES_BOX(box), FALSE);
1848 
1849  if (do_trans) {
1850  char *markup;
1851 #ifdef GUI_GTK
1852  markup = g_markup_printf_escaped("<span weight=\"bold\" style=\"italic\"> %s </span>", _(text));
1853 #endif
1854 #ifdef GUI_QT
1855  QString qs = QString("<span weight=\"bold\" style=\"italic\"> %s </span>").arg(_(text));
1856  markup = strdup((const char *)qs.toHtmlEscaped().constData());
1857 #endif
1858  label = lives_standard_label_new(NULL);
1859  lives_label_set_markup(LIVES_LABEL(label), markup);
1860  lives_free(markup);
1861  } else label = lives_standard_label_new_with_mnemonic_widget(text, NULL);
1862 
1863  if (LIVES_IS_HBOX(LIVES_WIDGET(box)))
1865  else
1867 
1868  return label;
1869 }
1870 
1871 
1872 LiVESSList *add_usrgrp_to_livesgrp(LiVESSList *u2l, LiVESSList *rbgroup, int usr_number) {
1874  wgroup->usr_number = usr_number;
1875  wgroup->rbgroup = rbgroup;
1876  wgroup->active_param = 0;
1877  u2l = lives_slist_append(u2l, (livespointer)wgroup);
1878  return u2l;
1879 }
1880 
1881 
1882 lives_widget_group_t *livesgrp_from_usrgrp(LiVESSList *u2l, int usrgrp) {
1883  lives_widget_group_t *group;
1884  LiVESSList *list = u2l;
1885  for (; list; list = list->next) {
1886  group = (lives_widget_group_t *)list->data;
1887  if (group->usr_number == usrgrp) return group;
1888  }
1889  return NULL;
1890 }
1891 
1892 
1893 boolean update_widget_vis(lives_rfx_t *rfx, int key, int mode) {
1894  weed_plant_t *wparam = NULL, *inst;
1895  int keyw, modew;
1896  lives_param_t *param;
1897 
1898  if (mainw->multitrack == NULL) {
1899  if (fx_dialog[1]) {
1900  rfx = fx_dialog[1]->rfx;
1901  if (!rfx->is_template) {
1902  keyw = fx_dialog[1]->key;
1903  modew = fx_dialog[1]->mode;
1904  }
1905  if (!rfx->is_template && (key != keyw && mode != modew)) return FALSE;
1906  }
1907  }
1908 
1909  if ((!fx_dialog[1] && !mainw->multitrack) || !rfx || rfx->status != RFX_STATUS_WEED) return FALSE;
1910  inst = (weed_plant_t *)rfx->source;
1911  for (int i = 0; i < rfx->num_params; i++) {
1912  param = &rfx->params[i];
1913  if ((wparam = weed_inst_in_param(inst, i, FALSE, FALSE)) != NULL) {
1914  check_hidden_gui(inst, param, i);
1915  if (param->hidden & HIDDEN_STRUCTURAL) continue;
1916  for (int j = 0; j < RFX_MAX_NORM_WIDGETS; j++) {
1917  if (param->type == LIVES_PARAM_COLRGB24 && j == 3 && !param->widgets[j]) continue;
1918  if (!param->widgets[j]) break;
1919  if (param->hidden) {
1920  lives_widget_hide(param->widgets[j]);
1922  } else {
1924  lives_widget_show_all(param->widgets[j]);
1925  // *INDENT-OFF*
1926  }}}}
1927  // *INDENT-ON*
1928 
1929  return TRUE;
1930 }
1931 
1932 
1933 static void after_any_changed_1(lives_rfx_t *rfx, int param_number, int index) {
1934  weed_plant_t *inst = (weed_plant_t *)rfx->source;
1935  weed_plant_t *wparam = weed_inst_in_param(inst, param_number, FALSE, FALSE), *paramtmpl;
1936  int numvals = weed_leaf_num_elements(wparam, WEED_LEAF_VALUE);
1937  int *ign, nvals;
1940  if (index >= numvals) {
1941  paramtmpl = weed_param_get_template(wparam);
1942  fill_param_vals_to(wparam, paramtmpl, index);
1943  numvals = index + 1;
1944  }
1945 
1946  if (mainw->multitrack && is_perchannel_multi(rfx, param_number)) {
1947  if (weed_plant_has_leaf(wparam, WEED_LEAF_IGNORE)) {
1948  ign = weed_get_boolean_array_counted(wparam, WEED_LEAF_IGNORE, &nvals);
1949  if (index >= 0 && index < nvals) {
1950  ign[index] = WEED_FALSE;
1951  weed_set_boolean_array(wparam, WEED_LEAF_IGNORE, nvals, ign);
1952  }
1953  lives_freep((void **)&ign);
1954  }
1955  }
1956 }
1957 
1958 
1962 static void after_any_changed_2(lives_rfx_t *rfx, lives_param_t *param, boolean needs_update) {
1963  weed_plant_t *wparam = NULL, *gui, *inst = NULL;
1965 
1967  if (needs_update) update_visual_params(rfx, FALSE);
1968  needs_update = FALSE;
1969 
1971  if (--ireinit > 0) {
1972  param->changed = TRUE;
1973  param->change_blocked = FALSE;
1974  return;
1975  }
1976 
1979  if (rfx->status == RFX_STATUS_WEED) {
1980  if (mainw->multitrack) {
1981  for (int i = 0; i < rfx->num_params; i++) {
1982  if ((wparam = weed_inst_in_param(inst, i, FALSE, FALSE)) != NULL) {
1983  if ((gui = weed_param_get_gui(wparam, FALSE)) != NULL) {
1984  if (retval != FILTER_INFO_REDRAWN) {
1985  if (weed_get_boolean_value(gui, "host_hidden_backup", NULL) != weed_get_boolean_value(gui, WEED_LEAF_HIDDEN, NULL))
1986  needs_update = TRUE;
1987  }
1988  weed_leaf_delete(gui, "host_hidden_backup");
1989  // *INDENT-OFF*
1990  }}}}
1991  // *INDENT-ON*
1992 
1993  inst = (weed_plant_t *)rfx->source;
1994  if (rfx->needs_reinit) {
1995  if (!(rfx->needs_reinit & REINIT_FUNCTIONAL)) {
1996  weed_instance_set_flags(inst, weed_instance_get_flags(inst) | WEED_INSTANCE_UPDATE_GUI_ONLY);
1997  }
1998 
1999  retval = weed_reinit_effect(inst, FALSE);
2000 
2001  if (!(rfx->needs_reinit & REINIT_FUNCTIONAL)) {
2002  weed_instance_set_flags(inst, weed_instance_get_flags(inst) ^ WEED_INSTANCE_UPDATE_GUI_ONLY);
2003  }
2004  rfx->needs_reinit = 0;
2005  }
2006  }
2007 
2008  needs_update = FALSE;
2009  rfx->needs_reinit = 0;
2010 
2011  if (fx_dialog[1]) {
2012  // transfer param changes from rte_window to ce_thumbs window, and vice-versa
2013  lives_rfx_t *rte_rfx = fx_dialog[1]->rfx;
2014  int key = fx_dialog[1]->key;
2015  int mode = fx_dialog[1]->mode;
2017  if (rfx == rte_rfx && mainw->ce_thumbs) ce_thumbs_update_visual_params(key);
2018  else if (mode == rte_key_getmode(key + 1)) ce_thumbs_check_for_rte(rfx, rte_rfx, key);
2020  }
2021 
2022  if (!weed_param_value_irrelevant(wparam)) {
2023  param->changed = TRUE;
2024  }
2025 
2026  if (mainw->multitrack && rfx->status == RFX_STATUS_WEED) {
2027  update_widget_vis(rfx, -1, -1);
2029  }
2030 
2031  param->change_blocked = FALSE;
2032 }
2033 
2034 
2035 void after_boolean_param_toggled(LiVESToggleButton * togglebutton, lives_rfx_t *rfx) {
2036  int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(togglebutton), PARAM_NUMBER_KEY));
2037  LiVESList *retvals = NULL;
2038  weed_plant_t *inst = NULL;
2039  lives_param_t *param = &rfx->params[param_number];
2040  boolean old_bool = get_bool_param(param->value), new_bool;
2041  boolean needs_update = FALSE;
2042  int copyto = -1;
2043 
2044  new_bool = lives_toggle_button_get_active(togglebutton);
2045  if (old_bool == new_bool) return;
2046 
2047  if (mainw->block_param_updates) {
2048  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2049  return; // updates are blocked until all params are ready
2050  }
2051 
2052  ireinit++;
2053 
2054  set_bool_param(param->value, new_bool);
2056  param->change_blocked = TRUE;
2057 
2058  if (rfx->status == RFX_STATUS_WEED) {
2059  inst = (weed_plant_t *)rfx->source;
2060  if (inst && WEED_PLANT_IS_FILTER_INSTANCE(inst)) {
2061  //char *disp_string;
2062  int index = 0, numvals;
2063  int key = -1;
2064  weed_plant_t *wparam = weed_inst_in_param(inst, param_number, FALSE, FALSE);
2065  int *valis = weed_get_boolean_array(wparam, WEED_LEAF_VALUE, NULL);
2066 
2067  if (mainw->multitrack && is_perchannel_multi(rfx, param_number)) {
2068  index = mainw->multitrack->track_index;
2069  }
2070 
2071  after_any_changed_1(rfx, param_number, index);
2072 
2073  valis[index] = new_bool;
2074  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2075  numvals = weed_leaf_num_elements(wparam, WEED_LEAF_VALUE);
2076  if (!filter_mutex_trylock(key)) {
2077  weed_set_boolean_array(wparam, WEED_LEAF_VALUE, numvals, valis);
2078  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2079  filter_mutex_unlock(key); \
2080  if (copyto != -1) needs_update = TRUE;
2081  }
2082  lives_freep((void **)&valis);
2083 
2085  // if we are recording, add this change to our event_list
2086  rec_param_change(inst, param_number);
2087  }
2088  if (param->reinit) rfx->needs_reinit |= param->reinit;
2089  }
2090  }
2091 
2092  if (get_bool_param(param->value) != old_bool && param->onchange) {
2093  param->change_blocked = TRUE;
2094  retvals = do_onchange(LIVES_WIDGET_OBJECT(togglebutton), rfx);
2095  lives_list_free_all(&retvals);
2096  needs_update = TRUE;
2097  }
2098  after_any_changed_2(rfx, param, needs_update);
2099 }
2100 
2101 
2102 void after_param_value_changed(LiVESSpinButton * spinbutton, lives_rfx_t *rfx) {
2103  int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(spinbutton), PARAM_NUMBER_KEY));
2104  LiVESList *retvals = NULL;
2105  lives_param_t *param = &rfx->params[param_number];
2106  double new_double = 0., old_double = 0.;
2107  int new_int = 0, old_int = 0;
2108  boolean needs_update = FALSE;
2109  int copyto = -1;
2110 
2111  lives_spin_button_update(LIVES_SPIN_BUTTON(spinbutton));
2112 
2113  if (param->dp > 0) {
2114  old_double = get_double_param(param->value);
2115  new_double = lives_spin_button_get_value(LIVES_SPIN_BUTTON(spinbutton));
2116  if (old_double == new_double) return;
2117  } else {
2118  old_int = get_int_param(param->value);
2119  new_int = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
2120  if (old_int == new_int) return;
2121  }
2122 
2123  if (mainw->block_param_updates) {
2124  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2125  return; // updates are blocked until all params are ready
2126  }
2127 
2128  ireinit++;
2129 
2131 
2133  (prefs->rec_opts & REC_EFFECTS)) {
2134  // if we are recording, add this (pre)change to our event_list
2135  rec_param_change((weed_plant_t *)rfx->source, param_number);
2136  copyto = set_copy_to((weed_plant_t *)rfx->source, param_number, rfx, FALSE);
2137  }
2138 
2139  if (param->dp > 0) {
2140  set_double_param(param->value, new_double);
2141  } else {
2142  set_int_param(param->value, new_int);
2143  }
2144 
2145  param->change_blocked = TRUE;
2146 
2147  if (rfx->status == RFX_STATUS_WEED) {
2148  weed_plant_t *inst = (weed_plant_t *)rfx->source;
2149  if (inst && WEED_PLANT_IS_FILTER_INSTANCE(inst)) {
2150  weed_plant_t *wparam = weed_inst_in_param(inst, param_number, FALSE, FALSE);
2151  int index = 0, numvals;
2152  int key = -1;
2153  double *valds;
2154  int *valis;
2155 
2156  // update transition in/out radios
2157  if (mainw->multitrack) {
2158  weed_plant_t *filter = weed_instance_get_filter(inst, TRUE);
2159  if (enabled_in_channels(filter, FALSE) == 2 && param->transition) {
2160  if (param->dp == 0) {
2161  if (new_int == (int)param->min)
2162  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(param->widgets[WIDGET_RB_IN]), TRUE);
2163  else if (new_int == (int)param->max)
2164  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(param->widgets[WIDGET_RB_OUT]), TRUE);
2165  else lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(param->widgets[WIDGET_RB_DUMMY]), TRUE);
2166  } else {
2167  if (new_double == param->min)
2168  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(param->widgets[WIDGET_RB_IN]), TRUE);
2169  else if (new_double == param->max)
2170  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(param->widgets[WIDGET_RB_OUT]), TRUE);
2171  else lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(param->widgets[WIDGET_RB_DUMMY]), TRUE);
2172  }
2173  }
2174  }
2175 
2176  if (mainw->multitrack && is_perchannel_multi(rfx, param_number)) {
2177  index = mainw->multitrack->track_index;
2178  }
2179 
2180  after_any_changed_1(rfx, param_number, index);
2181 
2182  numvals = weed_leaf_num_elements(wparam, WEED_LEAF_VALUE);
2183  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2184  if (weed_leaf_seed_type(wparam, WEED_LEAF_VALUE) == WEED_SEED_DOUBLE) {
2185  valds = weed_get_double_array(wparam, WEED_LEAF_VALUE, NULL);
2186  if (param->dp > 0) valds[index] = new_double;
2187  else valds[index] = (double)new_int;
2188  if (!filter_mutex_trylock(key)) {
2189  weed_set_double_array(wparam, WEED_LEAF_VALUE, numvals, valds);
2190  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2191  filter_mutex_unlock(key);
2192  if (copyto != -1) needs_update = TRUE;
2193  }
2194  lives_freep((void **)&valds);
2195  } else {
2196  valis = weed_get_int_array(wparam, WEED_LEAF_VALUE, NULL);
2197  valis[index] = new_int;
2198  weed_set_int_array(wparam, WEED_LEAF_VALUE, numvals, valis);
2199  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2200  filter_mutex_unlock(key);
2201  if (copyto != -1) needs_update = TRUE;
2202  lives_freep((void **)&valis);
2203  }
2204  }
2205 
2207  // if we are recording, add this change to our event_list
2208  rec_param_change(inst, param_number);
2209  }
2210  if (param->reinit) rfx->needs_reinit |= param->reinit;
2211  }
2212 
2213  if (((param->dp > 0 && (get_double_param(param->value) != old_double)) || (param->dp == 0 &&
2214  (get_int_param(param->value) != old_int))) && param->onchange) {
2215  param->change_blocked = TRUE;
2216  retvals = do_onchange(LIVES_WIDGET_OBJECT(spinbutton), rfx);
2217  lives_list_free_all(&retvals);
2218  needs_update = TRUE;
2219  }
2220 
2221  after_any_changed_2(rfx, param, needs_update);
2222 }
2223 
2224 
2225 void update_weed_color_value(weed_plant_t *plant, int pnum, int c1, int c2, int c3, int c4, lives_rfx_t *rfx) {
2226  weed_plant_t *ptmpl;
2227  weed_plant_t *param = NULL;
2228 
2229  int *maxs = NULL, *mins = NULL;
2230  int cols[4] = {c1, c2, c3, c4};
2231  int cspace;
2232  int rmax, rmin, gmax, gmin, bmax, bmin;
2233 
2234  boolean is_default = WEED_PLANT_IS_FILTER_CLASS(plant);
2235  boolean is_int;
2236 
2237  double *maxds = NULL, *minds = NULL;
2238  double colds[4];
2239  double rmaxd, rmind, gmaxd, gmind, bmaxd, bmind;
2240 
2241  if (!is_default) {
2242  param = weed_inst_in_param(plant, pnum, FALSE, FALSE);
2243  ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, NULL);
2244  } else {
2245  // called only from rte_set_defs_ok
2246  ptmpl = weed_filter_in_paramtmpl(plant, pnum, FALSE);
2247  }
2248 
2249  if (mainw->block_param_updates) return; // updates are blocked until all params are ready
2250 
2251  is_int = (weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT);
2252  cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, NULL);
2253 
2254  switch (cspace) {
2255  // TODO - other cspaces
2256  case WEED_COLORSPACE_RGB:
2257  if (is_int) {
2258  if (weed_leaf_num_elements(ptmpl, WEED_LEAF_MAX) == 3) {
2259  maxs = weed_get_int_array(ptmpl, WEED_LEAF_MAX, NULL);
2260  rmax = maxs[0];
2261  gmax = maxs[1];
2262  bmax = maxs[2];
2263  lives_free(maxs);
2264  } else rmax = gmax = bmax = weed_get_int_value(ptmpl, WEED_LEAF_MAX, NULL);
2265  if (weed_leaf_num_elements(ptmpl, WEED_LEAF_MIN) == 3) {
2266  mins = weed_get_int_array(ptmpl, WEED_LEAF_MIN, NULL);
2267  rmin = mins[0];
2268  gmin = mins[1];
2269  bmin = mins[2];
2270  lives_free(mins);
2271  } else rmin = gmin = bmin = weed_get_int_value(ptmpl, WEED_LEAF_MIN, NULL);
2272 
2273  cols[0] = rmin + (int)((double)cols[0] / 255.*(double)(rmax - rmin));
2274  cols[1] = gmin + (int)((double)cols[1] / 255.*(double)(gmax - gmin));
2275  cols[2] = bmin + (int)((double)cols[2] / 255.*(double)(bmax - bmin));
2276  if (is_default) {
2277  weed_set_int_array(ptmpl, WEED_LEAF_HOST_DEFAULT, 3, cols);
2278  } else {
2279  int index = 0, numvals;
2280  int *valis;
2281 
2282  if (mainw->multitrack && is_perchannel_multiw(ptmpl)) {
2283  index = mainw->multitrack->track_index;
2284  }
2285  numvals = weed_leaf_num_elements(param, WEED_LEAF_VALUE);
2286  if (index * 3 >= numvals) {
2287  weed_plant_t *paramtmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, NULL);
2288  fill_param_vals_to(param, paramtmpl, index);
2289  numvals = (index + 1) * 3;
2290  }
2291 
2292  if (mainw->multitrack && is_perchannel_multi(rfx, pnum)) {
2293  if (weed_plant_has_leaf(param, WEED_LEAF_IGNORE)) {
2294  int nvals = weed_leaf_num_elements(param, WEED_LEAF_IGNORE);
2295  if (index >= 0 && index < nvals) {
2296  int *ign = weed_get_boolean_array(param, WEED_LEAF_IGNORE, NULL);
2297  ign[index] = WEED_FALSE;
2298  weed_set_boolean_array(param, WEED_LEAF_IGNORE, nvals, ign);
2299  lives_free(ign);
2300  }
2301  }
2302  }
2303 
2304  valis = weed_get_int_array(param, WEED_LEAF_VALUE, NULL);
2305  valis[index * 3] = cols[0];
2306  valis[index * 3 + 1] = cols[1];
2307  valis[index * 3 + 2] = cols[2];
2308  weed_set_int_array(param, WEED_LEAF_VALUE, numvals, valis);
2309  lives_free(valis);
2310  }
2311  break;
2312  } else {
2313  // double
2314  if (weed_leaf_num_elements(ptmpl, WEED_LEAF_MAX) == 3) {
2315  maxds = weed_get_double_array(ptmpl, WEED_LEAF_MAX, NULL);
2316  rmaxd = maxds[0];
2317  gmaxd = maxds[1];
2318  bmaxd = maxds[2];
2319  lives_free(maxds);
2320  } else rmaxd = gmaxd = bmaxd = weed_get_double_value(ptmpl, WEED_LEAF_MAX, NULL);
2321  if (weed_leaf_num_elements(ptmpl, WEED_LEAF_MIN) == 3) {
2322  minds = weed_get_double_array(ptmpl, WEED_LEAF_MIN, NULL);
2323  rmind = minds[0];
2324  gmind = minds[1];
2325  bmind = minds[2];
2326  lives_free(minds);
2327  } else rmind = gmind = bmind = weed_get_double_value(ptmpl, WEED_LEAF_MIN, NULL);
2328  colds[0] = rmind + (double)cols[0] / 255.*(rmaxd - rmind);
2329  colds[1] = gmind + (double)cols[1] / 255.*(gmaxd - gmind);
2330  colds[2] = bmind + (double)cols[2] / 255.*(bmaxd - bmind);
2331  if (is_default) {
2332  weed_set_double_array(ptmpl, WEED_LEAF_HOST_DEFAULT, 3, colds);
2333  } else {
2334  int index = 0, numvals;
2335  double *valds;
2336 
2337  if (mainw->multitrack && is_perchannel_multiw(ptmpl)) {
2338  index = mainw->multitrack->track_index;
2339  }
2340  numvals = weed_leaf_num_elements(param, WEED_LEAF_VALUE);
2341  if (index * 3 >= numvals) {
2342  weed_plant_t *paramtmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, NULL);
2343  fill_param_vals_to(param, paramtmpl, index);
2344  numvals = (index + 1) * 3;
2345  }
2346 
2347  if (mainw->multitrack && is_perchannel_multi(rfx, pnum)) {
2348  if (weed_plant_has_leaf(param, WEED_LEAF_IGNORE)) {
2349  int nvals = weed_leaf_num_elements(param, WEED_LEAF_IGNORE);
2350  if (index >= 0 && index < nvals) {
2351  int *ign = weed_get_boolean_array(param, WEED_LEAF_IGNORE, NULL);
2352  ign[index] = WEED_FALSE;
2353  weed_set_boolean_array(param, WEED_LEAF_IGNORE, nvals, ign);
2354  lives_free(ign);
2355  }
2356  }
2357  }
2358 
2359  valds = weed_get_double_array(param, WEED_LEAF_VALUE, NULL);
2360  valds[index * 3] = colds[0];
2361  valds[index * 3 + 1] = colds[1];
2362  valds[index * 3 + 2] = colds[2];
2363  weed_set_double_array(param, WEED_LEAF_VALUE, numvals, valds);
2364  lives_free(valds);
2365  }
2366  }
2367  break;
2368  }
2369 }
2370 
2371 
2372 void after_param_red_changed(LiVESSpinButton * spinbutton, lives_rfx_t *rfx) {
2373  LiVESList *retvals = NULL;
2374  lives_colRGB48_t old_value;
2375  int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(spinbutton), PARAM_NUMBER_KEY));
2376  int new_red;
2377  boolean needs_update = FALSE;
2378  int copyto = -1;
2379  lives_param_t *param = &rfx->params[param_number];
2380 
2381  get_colRGB24_param(param->value, &old_value);
2382  new_red = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
2383  if (old_value.red == new_red) return;
2384 
2385  if (mainw->block_param_updates) {
2386  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2387  return; // updates are blocked until all params are ready
2388  }
2389 
2390  ireinit++;
2391 
2393  (prefs->rec_opts & REC_EFFECTS)) {
2394  // if we are recording, add this change to our event_list
2395 
2396  rec_param_change((weed_plant_t *)rfx->source, param_number);
2397  copyto = set_copy_to((weed_plant_t *)rfx->source, param_number, rfx, FALSE);
2398  }
2399 
2400  set_colRGB24_param(param->value, new_red, old_value.green, old_value.blue);
2401 
2403  param->change_blocked = TRUE;
2404 
2405  if (rfx->status == RFX_STATUS_WEED) {
2406  int key = -1;
2407  weed_plant_t *inst = (weed_plant_t *)rfx->source;
2408  if (inst && WEED_PLANT_IS_FILTER_INSTANCE(inst)) {
2409  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2410  if (!filter_mutex_trylock(key)) {
2411  update_weed_color_value(inst, param_number, new_red, old_value.green, old_value.blue, 0, rfx);
2412  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2413  filter_mutex_unlock(key);
2414  if (copyto != -1) needs_update = TRUE;
2415  }
2416 
2418  // if we are recording, add this change to our event_list
2419  rec_param_change(inst, param_number);
2420  }
2421  if (param->reinit) rfx->needs_reinit |= param->reinit;
2422  }
2423  }
2424 
2425  if (new_red != old_value.red && param->onchange) {
2426  param->change_blocked = TRUE;
2427  retvals = do_onchange(LIVES_WIDGET_OBJECT(spinbutton), rfx);
2428  lives_list_free_all(&retvals);
2429  needs_update = TRUE;
2430  }
2431  after_any_changed_2(rfx, param, needs_update);
2432 }
2433 
2434 
2435 void after_param_green_changed(LiVESSpinButton * spinbutton, lives_rfx_t *rfx) {
2436  LiVESList *retvals = NULL;
2437  lives_colRGB48_t old_value;
2438  int new_green;
2439  int copyto = -1;
2440  boolean needs_update = FALSE;
2441  int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(spinbutton), PARAM_NUMBER_KEY));
2442  lives_param_t *param = &rfx->params[param_number];
2443 
2444  get_colRGB24_param(param->value, &old_value);
2445  new_green = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
2446  if (old_value.green == new_green) return;
2447 
2448  if (mainw->block_param_updates) {
2449  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2450  return; // updates are blocked until all params are ready
2451  }
2452 
2453  ireinit++;
2454 
2456  (prefs->rec_opts & REC_EFFECTS)) {
2457  // if we are recording, add this change to our event_list
2458  rec_param_change((weed_plant_t *)rfx->source, param_number);
2459  copyto = set_copy_to((weed_plant_t *)rfx->source, param_number, rfx, FALSE);
2460  }
2461 
2462  set_colRGB24_param(param->value, old_value.red, new_green, old_value.blue);
2463 
2465  param->change_blocked = TRUE;
2466 
2467  if (rfx->status == RFX_STATUS_WEED) {
2468  int key = -1;
2469  weed_plant_t *inst = (weed_plant_t *)rfx->source;
2470  if (inst && WEED_PLANT_IS_FILTER_INSTANCE(inst)) {
2471  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2472  if (!filter_mutex_trylock(key)) {
2473  update_weed_color_value(inst, param_number, old_value.red, new_green, old_value.blue, 0, rfx);
2474  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2475  filter_mutex_unlock(key);
2476  if (copyto != -1) needs_update = TRUE;
2477  }
2478 
2480  // if we are recording, add this change to our event_list
2481  rec_param_change(inst, param_number);
2482  }
2483  rfx->needs_reinit |= param->reinit;
2484  }
2485  }
2486 
2487  if (new_green != old_value.green && param->onchange) {
2488  param->change_blocked = TRUE;
2489  retvals = do_onchange(LIVES_WIDGET_OBJECT(spinbutton), rfx);
2490  lives_list_free_all(&retvals);
2491  needs_update = TRUE;
2492  }
2493  after_any_changed_2(rfx, param, needs_update);
2494 }
2495 
2496 
2497 void after_param_blue_changed(LiVESSpinButton * spinbutton, lives_rfx_t *rfx) {
2498  LiVESList *retvals = NULL;
2499  lives_colRGB48_t old_value;
2500  int new_blue;
2501  int copyto = -1;
2502  boolean needs_update = FALSE;
2503  int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(spinbutton), PARAM_NUMBER_KEY));
2504  lives_param_t *param = &rfx->params[param_number];
2505 
2506  get_colRGB24_param(param->value, &old_value);
2507  new_blue = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
2508  if (old_value.blue == new_blue) return;
2509 
2510  if (mainw->block_param_updates) {
2511  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2512  return; // updates are blocked until all params are ready
2513  }
2514 
2515  ireinit++;
2516 
2518  (prefs->rec_opts & REC_EFFECTS)) {
2519  // if we are recording, add this change to our event_list
2520  rec_param_change((weed_plant_t *)rfx->source, param_number);
2521  }
2522 
2523  set_colRGB24_param(param->value, old_value.red, old_value.green, new_blue);
2524 
2526  param->change_blocked = TRUE;
2527 
2528  if (rfx->status == RFX_STATUS_WEED) {
2529  int key = -1;
2530  weed_plant_t *inst = (weed_plant_t *)rfx->source;
2531  if (inst && WEED_PLANT_IS_FILTER_INSTANCE(inst)) {
2532  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2533  if (!filter_mutex_trylock(key)) {
2534  update_weed_color_value(inst, param_number, old_value.red, old_value.green, new_blue, 0, rfx);
2535  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2536  filter_mutex_unlock(key);
2537  if (copyto != -1) needs_update = TRUE;
2538  }
2539 
2541  // if we are recording, add this change to our event_list
2542  rec_param_change(inst, param_number);
2543  }
2544  rfx->needs_reinit |= param->reinit;
2545  }
2546  }
2547 
2548  if (new_blue != old_value.blue && param->onchange) {
2549  param->change_blocked = TRUE;
2550  retvals = do_onchange(LIVES_WIDGET_OBJECT(spinbutton), rfx);
2551  lives_list_free_all(&retvals);
2552  needs_update = TRUE;
2553  }
2554  after_any_changed_2(rfx, param, needs_update);
2555 }
2556 
2557 
2558 void after_param_alpha_changed(LiVESSpinButton * spinbutton, lives_rfx_t *rfx) {
2559  // not used yet
2560  int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(spinbutton), PARAM_NUMBER_KEY));
2561  LiVESList *retvals = NULL;
2562  lives_param_t *param = &rfx->params[param_number];
2563  lives_colRGBA64_t old_value;
2564  int new_alpha = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton));
2565  int copyto = -1;
2566  boolean needs_update = FALSE;
2567 
2568  if (mainw->block_param_updates) {
2569  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2570  return; // updates are blocked until all params are ready
2571  }
2572 
2573  ireinit++;
2574 
2576  (prefs->rec_opts & REC_EFFECTS)) {
2577  // if we are recording, add this change to our event_list
2578  rec_param_change((weed_plant_t *)rfx->source, param_number);
2579  copyto = set_copy_to((weed_plant_t *)rfx->source, param_number, rfx, FALSE);
2580  }
2581 
2582  get_colRGBA32_param(param->value, &old_value);
2583 
2585 
2586  set_colRGBA32_param(param->value, old_value.red, old_value.green, old_value.blue, new_alpha);
2587  param->change_blocked = TRUE;
2588 
2590  (prefs->rec_opts & REC_EFFECTS)) {
2591  // if we are recording, add this change to our event_list
2592  rec_param_change((weed_plant_t *)rfx->source, param_number);
2593  if (copyto != -1) rec_param_change((weed_plant_t *)rfx->source, copyto);
2594  }
2595 
2596  if (new_alpha != old_value.alpha && param->onchange) {
2597  param->change_blocked = TRUE;
2598  retvals = do_onchange(LIVES_WIDGET_OBJECT(spinbutton), rfx);
2599  lives_list_free_all(&retvals);
2600  needs_update = TRUE;
2601  }
2602  after_any_changed_2(rfx, param, needs_update);
2603 }
2604 
2605 
2606 boolean after_param_text_focus_changed(LiVESWidget * hbox, LiVESWidget * child, lives_rfx_t *rfx) {
2607  // for non realtime effects
2608  // we don't usually want to run the trigger every single time the user presses a key in a text widget
2609  // so we only update when the user clicks OK or focusses out of the widget
2610 
2611  LiVESWidget *textwidget;
2612 
2613  if (rfx == NULL) return FALSE;
2614 
2615  if (mainw->multitrack) {
2616  if (child)
2618  else
2620  }
2621 
2622  if (mainw->textwidget_focus) {
2623  textwidget = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mainw->textwidget_focus), TEXTWIDGET_KEY);
2624  after_param_text_changed(textwidget, rfx);
2625  }
2626 
2627  if (hbox) {
2628  mainw->textwidget_focus = hbox;
2629  }
2630 
2631  return FALSE;
2632 }
2633 
2634 
2635 void after_param_text_changed(LiVESWidget * textwidget, lives_rfx_t *rfx) {
2636  //LiVESTextBuffer *textbuffer = NULL;
2637  weed_plant_t *inst = NULL, *wparam = NULL;
2638  LiVESList *retvals = NULL;
2639  lives_param_t *param;
2640  char *old_text;
2641  const char *new_text;
2642  int copyto = -1;
2643  boolean needs_update = FALSE;
2644  int param_number;
2645 
2646  if (rfx == NULL || rfx->params == NULL || textwidget == NULL) return;
2647 
2648 
2649  param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(textwidget), PARAM_NUMBER_KEY));
2650  param = &rfx->params[param_number];
2651  old_text = (char *)param->value;
2652 
2653  if (LIVES_IS_TEXT_VIEW(textwidget)) {
2654  new_text = lives_text_view_get_text(LIVES_TEXT_VIEW(textwidget));
2655  if (!lives_strcmp(new_text, old_text)) return;
2656  } else {
2657  new_text = lives_entry_get_text(LIVES_ENTRY(textwidget));
2658  if (!lives_strcmp(new_text, old_text)) return;
2659  }
2660 
2661  if (mainw->block_param_updates) {
2662  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2663  return; // updates are blocked until all params are ready
2664  }
2665 
2666  ireinit++;
2667 
2668  param->value = lives_strdup(new_text);
2669 
2671  param->change_blocked = TRUE;
2672 
2673  if (rfx->status == RFX_STATUS_WEED) {
2674  inst = (weed_plant_t *)rfx->source;
2675  if (inst && WEED_PLANT_IS_FILTER_INSTANCE(inst)) {
2676  char **valss;
2677  int index = 0, numvals, key = -1;
2678  wparam = weed_inst_in_param(inst, param_number, FALSE, FALSE);
2679 
2680  if (mainw->multitrack && is_perchannel_multi(rfx, param_number)) {
2681  index = mainw->multitrack->track_index;
2682  }
2683 
2684  after_any_changed_1(rfx, param_number, index);
2685 
2686  numvals = weed_leaf_num_elements(wparam, WEED_LEAF_VALUE);
2687 
2688  valss = weed_get_string_array(wparam, WEED_LEAF_VALUE, NULL);
2689  valss[index] = lives_strdup((char *)param->value);
2690 
2691  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2692  if (!filter_mutex_trylock(key)) {
2693  weed_set_string_array(wparam, WEED_LEAF_VALUE, numvals, valss);
2694  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2695  filter_mutex_unlock(key);
2696  if (copyto != -1) needs_update = TRUE;
2697  }
2698  for (int i = 0; i < numvals; i++) lives_free(valss[i]);
2699  lives_free(valss);
2700 
2702  // if we are recording, add this change to our event_list
2703  rec_param_change(inst, param_number);
2704  //if (copyto != -1) rec_param_change(inst, copyto);
2705  }
2706  rfx->needs_reinit |= param->reinit;
2707  }
2708  }
2709 
2710  if (lives_strcmp(old_text, (char *)param->value) && param->onchange) {
2711  param->change_blocked = TRUE;
2712  retvals = do_onchange(LIVES_WIDGET_OBJECT(textwidget), rfx);
2713  lives_list_free_all(&retvals);
2714  needs_update = TRUE;
2715  }
2716  after_any_changed_2(rfx, param, needs_update);
2717 }
2718 
2719 
2720 static void after_param_text_buffer_changed(LiVESTextBuffer * textbuffer, lives_rfx_t *rfx) {
2721  LiVESWidget *textview = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(textbuffer), "textview");
2722  after_param_text_changed(textview, rfx);
2723 }
2724 
2725 
2726 void after_string_list_changed(LiVESWidget * entry, lives_rfx_t *rfx) {
2727  LiVESList *retvals = NULL;
2728  int param_number = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(entry), PARAM_NUMBER_KEY));
2729  LiVESCombo *combo = (LiVESCombo *)(rfx->params[param_number].widgets[0]);
2730  lives_param_t *param = &rfx->params[param_number];
2731  const char *txt = lives_combo_get_active_text(combo);
2732  int old_index = get_int_param(param->value);
2733  int new_index = lives_list_strcmp_index(param->list, txt, TRUE);
2734  boolean needs_update = FALSE;
2735  int copyto = -1;
2736 
2737  if (new_index == -1) return;
2738  if (new_index == old_index) return;
2739 
2740  if (mainw->block_param_updates) {
2741  if (rfx->status == RFX_STATUS_WEED && param->reinit) rfx->needs_reinit |= param->reinit;
2742  return; // updates are blocked until all params are ready
2743  }
2744 
2745  ireinit++;
2746 
2747  set_int_param(param->value, new_index);
2748 
2750  param->change_blocked = TRUE;
2751  if (rfx->status == RFX_STATUS_WEED) {
2752  weed_plant_t *inst = (weed_plant_t *)rfx->source;
2753  if (inst && WEED_PLANT_IS_FILTER_INSTANCE(inst)) {
2754  //char *disp_string = get_weed_display_string(inst, param_number);
2755  weed_plant_t *wparam = weed_inst_in_param(inst, param_number, FALSE, FALSE);
2756  int index = 0, numvals;
2757  int key = -1;
2758  int *valis;
2759 
2760  if (mainw->multitrack && is_perchannel_multi(rfx, param_number)) {
2761  index = mainw->multitrack->track_index;
2762  }
2763 
2764  after_any_changed_1(rfx, param_number, index);
2765 
2766  valis = weed_get_int_array(wparam, WEED_LEAF_VALUE, NULL);
2767  valis[index] = new_index;
2768  numvals = weed_leaf_num_elements(wparam, WEED_LEAF_VALUE);
2769  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2770  if (!filter_mutex_trylock(key)) {
2771  weed_set_int_array(wparam, WEED_LEAF_VALUE, numvals, valis);
2772  copyto = set_copy_to(inst, param_number, rfx, TRUE);
2773  filter_mutex_unlock(key);
2774  if (copyto != -1) needs_update = TRUE;
2775  }
2776  lives_free(valis);
2777 
2779  // if we are recording, add this change to our event_list
2780  rec_param_change(inst, param_number);
2781  //if (copyto != -1) rec_param_change(inst, copyto);
2782  }
2783  rfx->needs_reinit |= param->reinit;
2784  }
2785  }
2786 
2787  if (old_index != new_index && param->onchange) {
2788  param->change_blocked = TRUE;
2789  retvals = do_onchange(LIVES_WIDGET_OBJECT(combo), rfx);
2790  lives_list_free_all(&retvals);
2791  needs_update = TRUE;
2792  }
2793  after_any_changed_2(rfx, param, needs_update);
2794 }
2795 
2796 
2798  // this function will marshall all parameters into a argv array
2799  // last array element will be NULL
2800 
2801  // the returned **argv should be lives_free()'ed after use
2802 
2803  lives_colRGB48_t rgb;
2804 
2805  char **argv = (char **)lives_malloc((rfx->num_params + 1) * (sizeof(char *)));
2806 
2807  char *tmp;
2808 
2809  register int i;
2810 
2811  for (i = 0; i < rfx->num_params; i++) {
2812  switch (rfx->params[i].type) {
2813  case LIVES_PARAM_COLRGB24:
2814  get_colRGB24_param(rfx->params[i].value, &rgb);
2815  argv[i] = lives_strdup_printf("%u", (((rgb.red << 8) + rgb.green) << 8) + rgb.blue);
2816  break;
2817 
2818  case LIVES_PARAM_STRING:
2819  // escape strings
2820  argv[i] = lives_strdup_printf("%s", (tmp = U82L((char *)rfx->params[i].value)));
2821  lives_free(tmp);
2822  break;
2823 
2825  // escape strings
2826  argv[i] = lives_strdup_printf("%d", get_int_param(rfx->params[i].value));
2827  break;
2828 
2829  default:
2830  if (rfx->params[i].dp) {
2831  char *return_pattern = lives_strdup_printf("%%.%df", rfx->params[i].dp);
2832  argv[i] = lives_strdup_printf(return_pattern, get_double_param(rfx->params[i].value));
2833  lives_free(return_pattern);
2834  } else {
2835  argv[i] = lives_strdup_printf("%d", get_int_param(rfx->params[i].value));
2836  }
2837  }
2838  }
2839  argv[i] = NULL;
2840  return argv;
2841 }
2842 
2843 
2844 char *param_marshall(lives_rfx_t *rfx, boolean with_min_max) {
2845  // this function will marshall all parameters into a space separated string
2846  // in case of string parameters, these will be surrounded by " and all
2847  // quotes will be escaped \"
2848 
2849  // the returned string should be lives_free()'ed after use
2850  lives_colRGB48_t rgb;
2851 
2852  char *new_return = lives_strdup("");
2853  char *old_return = new_return;
2854  char *return_pattern;
2855  char *tmp, *mysubst, *mysubst2;
2856 
2857  for (int i = 0; i < rfx->num_params; i++) {
2858  switch (rfx->params[i].type) {
2859  case LIVES_PARAM_UNKNOWN:
2860  continue;
2861  case LIVES_PARAM_COLRGB24:
2862  get_colRGB24_param(rfx->params[i].value, &rgb);
2863  if (!with_min_max) {
2864  new_return = lives_strdup_printf("%s %u", old_return, (((rgb.red << 8) + rgb.green) << 8) + rgb.blue);
2865  } else {
2866  new_return = lives_strdup_printf("%s %d %d %d", old_return, rgb.red, rgb.green, rgb.blue);
2867  }
2868  lives_free(old_return);
2869  old_return = new_return;
2870  break;
2871 
2872  case LIVES_PARAM_STRING:
2873  // we need to doubly escape strings
2874  mysubst = subst((char *)rfx->params[i].value, "\\", "\\\\\\\\");
2875  mysubst2 = subst(mysubst, "\"", "\\\\\\\"");
2876  lives_free(mysubst);
2877  mysubst = subst(mysubst2, "`", "\\`");
2878  lives_free(mysubst2);
2879  mysubst2 = subst(mysubst, "'", "\\`");
2880  lives_free(mysubst);
2881  new_return = lives_strdup_printf("%s \"%s\"", old_return, (tmp = U82L(mysubst2)));
2882  lives_free(tmp);
2883  lives_free(mysubst2);
2884  lives_free(old_return);
2885  old_return = new_return;
2886  break;
2887 
2889  new_return = lives_strdup_printf("%s %d", old_return, get_int_param(rfx->params[i].value));
2890  lives_free(old_return);
2891  old_return = new_return;
2892  break;
2893 
2894  default:
2895  if (rfx->params[i].dp) {
2896  return_pattern = lives_strdup_printf("%%s %%.%df", rfx->params[i].dp);
2897  new_return = lives_strdup_printf(return_pattern, old_return, get_double_param(rfx->params[i].value));
2898  if (with_min_max) {
2899  lives_free(old_return);
2900  old_return = new_return;
2901  new_return = lives_strdup_printf(return_pattern, old_return, rfx->params[i].min);
2902  lives_free(old_return);
2903  old_return = new_return;
2904  new_return = lives_strdup_printf(return_pattern, old_return, rfx->params[i].max);
2905  }
2906  lives_free(return_pattern);
2907  } else {
2908  new_return = lives_strdup_printf("%s %d", old_return, get_int_param(rfx->params[i].value));
2909  if (with_min_max && rfx->params[i].type != LIVES_PARAM_BOOL) {
2910  lives_free(old_return);
2911  old_return = new_return;
2912  new_return = lives_strdup_printf("%s %d", old_return, (int)rfx->params[i].min);
2913  lives_free(old_return);
2914  old_return = new_return;
2915  new_return = lives_strdup_printf("%s %d", old_return, (int)rfx->params[i].max);
2916  }
2917  }
2918  lives_free(old_return);
2919  old_return = new_return;
2920  }
2921  }
2922  if (mainw->current_file > 0 && with_min_max) {
2923  if (rfx->num_in_channels < 2) {
2924  new_return = lives_strdup_printf("%s %d %d %d %d %d", old_return, cfile->hsize, cfile->vsize, cfile->start,
2925  cfile->end, cfile->frames);
2926  } else {
2927  // for transitions, change the end to indicate the merge section
2928  // this is better for length calculations
2929  int cb_frames = clipboard->frames;
2930  int start = cfile->start, end = cfile->end, ttl;
2931 
2932  if (prefs->ins_resample && clipboard->fps != cfile->fps) {
2933  cb_frames = count_resampled_frames(clipboard->frames, clipboard->fps, cfile->fps);
2934  }
2935 
2937  && cfile->end - cfile->start + 1 > (cb_frames * (ttl = lives_spin_button_get_value_as_int
2938  (LIVES_SPIN_BUTTON(merge_opts->spinbutton_loops)))) &&
2939  !merge_opts->loop_to_fit) {
2940  end = cb_frames * ttl;
2941  if (!merge_opts->align_start) {
2942  start = cfile->end - end + 1;
2943  end = cfile->end;
2944  } else {
2945  start = cfile->start;
2946  end += start - 1;
2947  }
2948  }
2949  new_return = lives_strdup_printf("%s %d %d %d %d %d %d %d", old_return, cfile->hsize, cfile->vsize, start, end,
2950  cfile->frames, clipboard->hsize, clipboard->vsize);
2951  }
2952  } else {
2953  new_return = lives_strdup(old_return);
2954  }
2955  lives_free(old_return);
2956 
2957  return new_return;
2958 }
2959 
2960 
2961 char *reconstruct_string(LiVESList * plist, int start, int *offs) {
2962  // convert each piece from locale to utf8
2963  // concat list entries to get reconstruct
2964  // replace \" with "
2965 
2966  char *word = NULL;
2967  char *ret = lives_strdup(""), *ret2;
2968  char *tmp;
2969 
2970  boolean lastword = FALSE;
2971 
2972  register int i;
2973 
2974  word = L2U8((char *)lives_list_nth_data(plist, start));
2975 
2976  if (!word || !*word || word[0] != '\"') {
2977  if (word) lives_free(word);
2978  return 0;
2979  }
2980 
2981  word++;
2982 
2983  for (i = start; i < lives_list_length(plist); i++) {
2984  size_t wl = lives_strlen(word);
2985  if (wl > 0) {
2986  if ((word[wl - 1] == '\"') && (wl == 1 || word[wl - 2] != '\\')) {
2987  lastword = TRUE;
2988  lives_memset(word + wl - 1, 0, 1);
2989  }
2990  }
2991 
2992  ret2 = lives_strconcat(ret, (tmp = subst(word, "\\\"", "\"")), " ", NULL);
2993  lives_free(tmp);
2994  if (ret2 != ret) lives_free(ret);
2995  ret = ret2;
2996 
2997  if (i == start) word--;
2998  lives_free(word);
2999 
3000  if (lastword) break;
3001 
3002  if (i < lives_list_length(plist) - 1) word = L2U8((char *)lives_list_nth_data(plist, i + 1));
3003  }
3004 
3005  set_int_param(offs, i - start + 1);
3006 
3007  // remove trailing space
3008  lives_memset(ret + lives_strlen(ret) - 1, 0, 1);
3009  return ret;
3010 }
3011 
3012 
3013 void param_demarshall(lives_rfx_t *rfx, LiVESList * plist, boolean with_min_max, boolean upd) {
3014  int i;
3015  int pnum = 0;
3016  lives_param_t *param;
3017 
3018  // here we take a LiVESList * of param values, set them in rfx, and if upd is TRUE we also update their visual appearance
3019 
3020  // param->widgets[n] are only valid if upd==TRUE
3021 
3022  if (plist == NULL) return;
3023 
3024  for (i = 0; i < rfx->num_params; i++) {
3025  param = &rfx->params[i];
3026  pnum = set_param_from_list(plist, param, pnum, with_min_max, upd);
3027  }
3028 }
3029 
3030 
3031 LiVESList *argv_to_marshalled_list(lives_rfx_t *rfx, int argc, char **argv) {
3032  LiVESList *plist = NULL;
3033 
3034  char *tmp, *tmp2, *tmp3;
3035 
3036  register int i;
3037 
3038  if (argc == 0) return plist;
3039 
3040  for (i = 0; i <= argc && argv[i]; i++) {
3041  if (rfx->params[i].type == LIVES_PARAM_STRING) {
3042  tmp = lives_strdup_printf("\"%s\"", (tmp2 = U82L(tmp3 = subst(argv[i], "\"", "\\\""))));
3043  plist = lives_list_append(plist, tmp);
3044  lives_free(tmp2);
3045  lives_free(tmp3);
3046  } else {
3047  plist = lives_list_append(plist, lives_strdup(argv[i]));
3048  }
3049  }
3050  return plist;
3051 }
3052 
3053 
3065 int set_param_from_list(LiVESList * plist, lives_param_t *param, int pnum, boolean with_min_max, boolean upd) {
3066  char *tmp;
3067  char *strval;
3068  int red, green, blue;
3069  int offs = 0;
3070  int maxlen = lives_list_length(plist) - 1;
3071 
3072  if (ABS(pnum) > maxlen) return 0;
3073 
3074  switch (param->type) {
3075  case LIVES_PARAM_BOOL:
3076  if (param->change_blocked) {
3077  pnum++;
3078  break;
3079  }
3080  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3081  if (upd) {
3082  if (param->widgets[0] && LIVES_IS_TOGGLE_BUTTON(param->widgets[0])) {
3083  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(param->widgets[0]), atoi(tmp));
3084  }
3085  } else set_bool_param(param->def, (atoi(tmp)));
3086  if (upd && param->widgets[0] && LIVES_IS_TOGGLE_BUTTON(param->widgets[0])) {
3087  set_bool_param(param->value,
3088  lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(param->widgets[0])));
3089  } else set_bool_param(param->value, (atoi(tmp)));
3090  lives_free(tmp);
3091  break;
3092  case LIVES_PARAM_NUM:
3093  if (param->change_blocked) {
3094  pnum++;
3095  if (with_min_max) pnum += 2;
3096  break;
3097  }
3098  if (param->dp) {
3099  double double_val;
3100  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3101  double_val = lives_strtod(tmp, NULL);
3102  lives_free(tmp);
3103  if (with_min_max) {
3104  if (ABS(pnum) > maxlen) return 1;
3105  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3106  param->min = lives_strtod(tmp, NULL);
3107  lives_free(tmp);
3108  if (ABS(pnum) > maxlen) return 2;
3109  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3110  param->max = lives_strtod(tmp, NULL);
3111  lives_free(tmp);
3112  if (double_val < param->min) double_val = param->min;
3113  if (double_val > param->max) double_val = param->max;
3114  }
3115  if (upd) {
3116  if (param->widgets[0] && LIVES_IS_SPIN_BUTTON(param->widgets[0])) {
3117  lives_rfx_t *rfx = (lives_rfx_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(param->widgets[0]), RFX_KEY);
3118  lives_signal_handlers_block_by_func(param->widgets[0], (livespointer)after_param_value_changed, (livespointer)rfx);
3119  lives_spin_button_set_range(LIVES_SPIN_BUTTON(param->widgets[0]), param->min, param->max);
3120  lives_spin_button_update(LIVES_SPIN_BUTTON(param->widgets[0]));
3121  lives_signal_handlers_unblock_by_func(param->widgets[0], (livespointer)after_param_value_changed, (livespointer)rfx);
3122  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[0]), double_val);
3123  lives_spin_button_update(LIVES_SPIN_BUTTON(param->widgets[0]));
3124  }
3125  } else set_double_param(param->def, double_val);
3126  if (upd && param->widgets[0] && LIVES_IS_SPIN_BUTTON(param->widgets[0])) {
3127  set_double_param(param->value,
3128  lives_spin_button_get_value(LIVES_SPIN_BUTTON(param->widgets[0])));
3129  } else set_double_param(param->value, double_val);
3130  } else {
3131  int int_value;
3132  int int_min, int_max;
3133  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3134  int_value = atoi(tmp);
3135  lives_free(tmp);
3136  if (param->step_size > 1.)
3137  int_value = (int)((double)int_value / param->step_size + .5) * (int)param->step_size;
3138  int_min = (int)param->min;
3139  int_max = (int)param->max;
3140  if (int_value < int_min) int_value = int_min;
3141  if (int_value > int_max) int_value = int_max;
3142 
3143  if (with_min_max) {
3144  if (ABS(pnum) > maxlen) return 1;
3145  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3146  int_min = atoi(tmp);
3147  lives_free(tmp);
3148  if (ABS(pnum) > maxlen) return 2;
3149  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3150  int_max = atoi(tmp);
3151  lives_free(tmp);
3152  if (int_value < int_min) int_value = int_min;
3153  if (int_value > int_max) int_value = int_max;
3154  param->min = (double)int_min;
3155  param->max = (double)int_max;
3156  }
3157  if (upd) {
3158  if (param->widgets[0] && LIVES_IS_SPIN_BUTTON(param->widgets[0])) {
3159  lives_rfx_t *rfx = (lives_rfx_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(param->widgets[0]), RFX_KEY);
3160  lives_signal_handlers_block_by_func(param->widgets[0], (livespointer)after_param_value_changed, (livespointer)rfx);
3161  lives_spin_button_set_range(LIVES_SPIN_BUTTON(param->widgets[0]), param->min, param->max);
3162  lives_spin_button_update(LIVES_SPIN_BUTTON(param->widgets[0]));
3163  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[0]), (double)int_value);
3164  lives_spin_button_update(LIVES_SPIN_BUTTON(param->widgets[0]));
3165  lives_signal_handlers_unblock_by_func(param->widgets[0], (livespointer)after_param_value_changed, (livespointer)rfx);
3166  }
3167  } else set_int_param(param->def, int_value);
3168  if (upd && param->widgets[0] && LIVES_IS_SPIN_BUTTON(param->widgets[0])) {
3169  set_int_param(param->value,
3170  lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(param->widgets[0])));
3171  } else set_int_param(param->value, int_value);
3172  }
3173  break;
3174  case LIVES_PARAM_COLRGB24:
3175  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3176  red = atoi(tmp);
3177  lives_free(tmp);
3178  if (ABS(pnum) > maxlen) return 1;
3179  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3180  green = atoi(tmp);
3181  lives_free(tmp);
3182  if (ABS(pnum) > maxlen) return 2;
3183  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3184  blue = atoi(tmp);
3185  lives_free(tmp);
3186  if (param->change_blocked) break;
3187  if (upd) {
3188  if (param->widgets[0] && LIVES_IS_SPIN_BUTTON(param->widgets[0])) {
3189  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[0]), (double)red);
3190  }
3191  if (param->widgets[1] && LIVES_IS_SPIN_BUTTON(param->widgets[1])) {
3192  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[1]), (double)green);
3193  }
3194  if (param->widgets[2] && LIVES_IS_SPIN_BUTTON(param->widgets[2])) {
3195  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[2]), (double)blue);
3196  }
3197  } else set_colRGB24_param(param->def, red, green, blue);
3198  if (upd && param->widgets[0] && LIVES_IS_SPIN_BUTTON(param->widgets[0])
3199  && param->widgets[1] && LIVES_IS_SPIN_BUTTON(param->widgets[1])
3200  && param->widgets[2] && LIVES_IS_SPIN_BUTTON(param->widgets[2])) {
3201  set_colRGB24_param(param->value,
3202  lives_spin_button_get_value(LIVES_SPIN_BUTTON(param->widgets[0])),
3203  lives_spin_button_get_value(LIVES_SPIN_BUTTON(param->widgets[1])),
3204  lives_spin_button_get_value(LIVES_SPIN_BUTTON(param->widgets[2])));
3205  } else set_colRGB24_param(param->value, red, green, blue);
3206  break;
3207  case LIVES_PARAM_STRING:
3208  strval = reconstruct_string(plist, pnum, &offs);
3209  pnum += offs;
3210  if (param->change_blocked) {
3211  lives_free(strval);
3212  break;
3213  }
3214  if (upd) {
3215  if (param->widgets[0]) {
3216  if (LIVES_IS_TEXT_VIEW(param->widgets[0])) {
3217  lives_text_view_set_text(LIVES_TEXT_VIEW(param->widgets[0]), strval, -1);
3218  } else {
3219  lives_entry_set_text(LIVES_ENTRY(param->widgets[0]), strval);
3220 
3221  }
3222  }
3223  } else {
3224  if (param->def) lives_free(param->def);
3225  param->def = (void *)lives_strdup(strval);
3226  }
3227  if (param->value) lives_free(param->value);
3228 
3230  if (upd && param->widgets[0] && (LIVES_IS_TEXT_VIEW(param->widgets[0])
3231  || LIVES_IS_ENTRY(param->widgets[0]))) {
3232  lives_free(strval);
3233  if (LIVES_IS_TEXT_VIEW(param->widgets[0])) {
3234  param->value = lives_strdup(lives_text_view_get_text(LIVES_TEXT_VIEW(param->widgets[0])));
3235  } else {
3236  param->value = lives_strdup(lives_entry_get_text(LIVES_ENTRY(param->widgets[0])));
3237  }
3238  } else {
3239  param->value = strval;
3240  }
3241  break;
3242  case LIVES_PARAM_STRING_LIST: {
3243  int int_value;
3244  tmp = lives_strdup((char *)lives_list_nth_data(plist, pnum++));
3245  int_value = atoi(tmp);
3246  lives_free(tmp);
3247  if (param->change_blocked) break;
3248  if (upd && param->widgets[0] && LIVES_IS_COMBO(param->widgets[0]) && int_value < lives_list_length(param->list))
3249  lives_combo_set_active_string(LIVES_COMBO(param->widgets[0]), (char *)lives_list_nth_data(param->list, int_value));
3250  if (!upd) set_int_param(param->def, int_value);
3251  if (upd && param->widgets[0] && LIVES_IS_COMBO(param->widgets[0])) {
3252  const char *txt = lives_combo_get_active_text(LIVES_COMBO(param->widgets[0]));
3253  int new_index = lives_list_strcmp_index(param->list, txt, TRUE);
3254  set_int_param(param->value, new_index);
3255  } else set_int_param(param->value, int_value);
3256  break;
3257  }
3258  default:
3259  break;
3260  }
3261  return pnum;
3262 }
3263 
3264 
3265 LiVESList *do_onchange(LiVESWidgetObject * object, lives_rfx_t *rfx) {
3266  LiVESList *retvals;
3267 
3268  int which = LIVES_POINTER_TO_INT(lives_widget_object_get_data(object, PARAM_NUMBER_KEY));
3269  int width = 0, height = 0;
3270 
3271  const char *handle = "";
3272 
3273  char *plugdir;
3274  char *com, *tmp;
3275 
3276  // weed plugins do not have triggers
3277  if (rfx->status == RFX_STATUS_WEED) return NULL;
3278 
3279  if (which < 0) {
3280  // init
3281  switch (rfx->status) {
3282  case RFX_STATUS_BUILTIN:
3283  plugdir = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_RENDERED_EFFECTS_BUILTIN, NULL);
3284  break;
3285  case RFX_STATUS_CUSTOM:
3286  plugdir = lives_build_filename(prefs->config_datadir, PLUGIN_RENDERED_EFFECTS_CUSTOM, NULL);
3287  break;
3288  case RFX_STATUS_TEST:
3289  plugdir = lives_build_filename(prefs->config_datadir, PLUGIN_RENDERED_EFFECTS_TEST, NULL);
3290  break;
3291  default:
3292  plugdir = lives_strdup_printf("%s", prefs->workdir);
3293  }
3294 
3295  if (mainw->current_file > 0) {
3296  width = cfile->hsize;
3297  height = cfile->vsize;
3298  handle = cfile->handle;
3299  }
3300 
3301  com = lives_strdup_printf("%s \"fxinit_%s\" \"%s\" \"%s\" %d %d %s", prefs->backend_sync, rfx->name, handle, plugdir,
3302  width, height, (tmp = param_marshall(rfx, TRUE)));
3303  retvals = plugin_request_by_space(NULL, NULL, com);
3304 
3305  lives_free(tmp);
3306  lives_free(plugdir);
3307  } else {
3308  com = lives_strdup_printf("onchange_%d%s", which, param_marshall(rfx, TRUE));
3309  switch (rfx->status) {
3310  case RFX_STATUS_BUILTIN:
3312  break;
3313  case RFX_STATUS_CUSTOM:
3315  break;
3316  case RFX_STATUS_TEST:
3318  break;
3319  default:
3320  retvals = plugin_request_by_space(PLUGIN_RFX_SCRAP, rfx->name, com);
3321  }
3322  }
3323 
3324  if (retvals) {
3325  param_demarshall(rfx, retvals, TRUE, which >= 0);
3326  } else {
3327  if (which <= 0 && mainw->error) {
3328  mainw->error = FALSE;
3329  do_error_dialog(lives_strdup_printf("\n\n%s\n\n", mainw->msg));
3330  }
3331  }
3332  lives_free(com);
3333 
3334  return retvals;
3335 }
3336 
3337 
3338 void on_pwcolsel(LiVESButton * button, lives_rfx_t *rfx) {
3339  LiVESWidgetColor selected;
3340 
3341  int pnum = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(button), PARAM_NUMBER_KEY));
3342  int r, g, b;
3343 
3344  lives_param_t *param = &rfx->params[pnum];
3345 
3346  lives_color_button_get_color(LIVES_COLOR_BUTTON(button), &selected);
3347 
3348  r = (int)((double)(selected.red + LIVES_WIDGET_COLOR_SCALE_255(0.5)) / (double)LIVES_WIDGET_COLOR_SCALE_255(1.));
3349  g = (int)((double)(selected.green + LIVES_WIDGET_COLOR_SCALE_255(0.5)) / (double)LIVES_WIDGET_COLOR_SCALE_255(1.));
3350  b = (int)((double)(selected.blue + LIVES_WIDGET_COLOR_SCALE_255(0.5)) / (double)LIVES_WIDGET_COLOR_SCALE_255(1.));
3351 
3352  set_colRGB24_param(param->value, r, g, b);
3353 
3354  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[0]), (double)r);
3355  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[1]), (double)g);
3356  lives_spin_button_set_value(LIVES_SPIN_BUTTON(param->widgets[2]), (double)b);
3357  lives_color_button_set_color(LIVES_COLOR_BUTTON(param->widgets[4]), &selected);
3358 }
3359 
3360 
3361 void update_visual_params(lives_rfx_t *rfx, boolean update_hidden) {
3362  // update parameters visually from an rfx object
3363  LiVESList *list;
3364 
3365  weed_plant_t **in_params, *in_param;
3366  weed_plant_t *inst = (weed_plant_t *)rfx->source;
3367  weed_plant_t *paramtmpl;
3368 
3369  int *colsi, *colsis, *valis;
3370  int *maxis = NULL, *minis = NULL;
3371 
3372  double *colsd, *colsds, *valds;
3373  double *maxds = NULL, *minds = NULL;
3374 
3375  double red_maxd, green_maxd, blue_maxd;
3376  double red_mind, green_mind, blue_mind;
3377  double vald, mind, maxd;
3378 
3379  char **valss;
3380 
3381  char *vals, *pattern;
3382  char *tmp, *tmp2;
3383 
3384  int cspace;
3385  int error;
3386  int num_params = 0;
3387  int param_type;
3388  int vali, mini, maxi;
3389 
3390  int red_max, green_max, blue_max;
3391  int red_min, green_min, blue_min;
3392 
3393  int index, numvals;
3394  int key = -1;
3395 
3396  register int i, j;
3397 
3398  if (rfx->source_type != LIVES_RFX_SOURCE_WEED) return;
3399 
3400  in_params = weed_instance_get_in_params(inst, &num_params);
3401  if (num_params == 0) return;
3402 
3403  if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, &error);
3404 
3405  for (i = 0; i < num_params; i++) {
3406  if (!is_hidden_param(inst, i) || (!(rfx->params[i].hidden & HIDDEN_STRUCTURAL) && update_hidden)) {
3407  // by default we dont update hidden or reinit params
3408  in_param = in_params[i];
3409  paramtmpl = weed_param_get_template(in_param);
3410  param_type = weed_paramtmpl_get_type(paramtmpl);
3411  list = NULL;
3412 
3413  // assume index is 0, unless we are a framedraw multi parameter
3414  // most of the time this will be ok, as other such multivalued parameters should be hidden
3415  index = 0;
3416 
3417  if (mainw->multitrack && is_perchannel_multi(rfx, i)) {
3418  index = mainw->multitrack->track_index;
3419  }
3420 
3421  filter_mutex_lock(key);
3422 
3423  numvals = weed_leaf_num_elements(in_param, WEED_LEAF_VALUE);
3424 
3425  if (param_type != WEED_PARAM_COLOR && index >= numvals) {
3426  fill_param_vals_to(in_param, paramtmpl, index);
3427  numvals = index + 1;
3428  }
3429 
3430  switch (param_type) {
3431  case WEED_PARAM_INTEGER:
3432  valis = weed_get_int_array(in_param, WEED_LEAF_VALUE, &error);
3433  vali = valis[index];
3434  lives_free(valis);
3435 
3436  mini = weed_get_int_value(paramtmpl, WEED_LEAF_MIN, &error);
3437  maxi = weed_get_int_value(paramtmpl, WEED_LEAF_MAX, &error);
3438 
3439  list = lives_list_append(list, lives_strdup_printf("%d", vali));
3440  list = lives_list_append(list, lives_strdup_printf("%d", mini));
3441  list = lives_list_append(list, lives_strdup_printf("%d", maxi));
3442  set_param_from_list(list, &rfx->params[i], 0, TRUE, TRUE);
3443  lives_list_free_all(&list);
3444 
3445  break;
3446  case WEED_PARAM_FLOAT:
3447  valds = weed_get_double_array(in_param, WEED_LEAF_VALUE, &error);
3448  vald = valds[index];
3449  lives_free(valds);
3450 
3451  mind = weed_get_double_value(paramtmpl, WEED_LEAF_MIN, &error);
3452  maxd = weed_get_double_value(paramtmpl, WEED_LEAF_MAX, &error);
3453 
3454  pattern = lives_strdup("%.2f");
3455 
3456  if (weed_plant_has_leaf(paramtmpl, WEED_LEAF_GUI)) {
3457  weed_plant_t *gui = weed_get_plantptr_value(paramtmpl, WEED_LEAF_GUI, &error);
3458  if (weed_plant_has_leaf(gui, WEED_LEAF_DECIMALS)) {
3459  int dp = weed_get_int_value(gui, WEED_LEAF_DECIMALS, &error);
3460  lives_free(pattern);
3461  pattern = lives_strdup_printf("%%.%df", dp);
3462  }
3463  }
3464 
3465  list = lives_list_append(list, lives_strdup_printf(pattern, vald));
3466  list = lives_list_append(list, lives_strdup_printf(pattern, mind));
3467  list = lives_list_append(list, lives_strdup_printf(pattern, maxd));
3468 
3469  lives_free(pattern);
3470 
3471  set_param_from_list(list, &rfx->params[i], 0, TRUE, TRUE);
3472  lives_list_free_all(&list);
3473 
3474  break;
3475  case WEED_PARAM_SWITCH:
3476  valis = weed_get_boolean_array(in_param, WEED_LEAF_VALUE, &error);
3477  vali = valis[index];
3478  lives_free(valis);
3479 
3480  list = lives_list_append(list, lives_strdup_printf("%d", vali));
3481  set_param_from_list(list, &rfx->params[i], 0, FALSE, TRUE);
3482  lives_list_free_all(&list);
3483 
3484  break;
3485  case WEED_PARAM_TEXT:
3486  valss = weed_get_string_array(in_param, WEED_LEAF_VALUE, &error);
3487  vals = valss[index];
3488  list = lives_list_append(list, lives_strdup_printf("\"%s\"", (tmp = U82L(tmp2 = subst(vals, "\"", "\\\"")))));
3489  lives_free(tmp);
3490  lives_free(tmp2);
3491  set_param_from_list(list, &rfx->params[i], 0, FALSE, TRUE);
3492  for (j = 0; j < numvals; j++) {
3493  lives_free(valss[j]);
3494  }
3495  lives_free(valss);
3496  lives_list_free_all(&list);
3497 
3498  break;
3499  case WEED_PARAM_COLOR:
3500  cspace = weed_get_int_value(paramtmpl, WEED_LEAF_COLORSPACE, &error);
3501  switch (cspace) {
3502  case WEED_COLORSPACE_RGB:
3503  numvals = weed_leaf_num_elements(in_param, WEED_LEAF_VALUE);
3504  if (index * 3 >= numvals) fill_param_vals_to(in_param, paramtmpl, index);
3505 
3506  if (weed_leaf_seed_type(paramtmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
3507  colsis = weed_get_int_array(in_param, WEED_LEAF_VALUE, &error);
3508  colsi = &colsis[3 * index];
3509 
3510  if (weed_leaf_num_elements(paramtmpl, WEED_LEAF_MAX) == 1) {
3511  red_max = green_max = blue_max = weed_get_int_value(paramtmpl, WEED_LEAF_MAX, &error);
3512  } else {
3513  maxis = weed_get_int_array(paramtmpl, WEED_LEAF_MAX, &error);
3514  red_max = maxis[0];
3515  green_max = maxis[1];
3516  blue_max = maxis[2];
3517  }
3518  if (weed_leaf_num_elements(paramtmpl, WEED_LEAF_MIN) == 1) {
3519  red_min = green_min = blue_min = weed_get_int_value(paramtmpl, WEED_LEAF_MIN, &error);
3520  } else {
3521  minis = weed_get_int_array(paramtmpl, WEED_LEAF_MIN, &error);
3522  red_min = minis[0];
3523  green_min = minis[1];
3524  blue_min = minis[2];
3525  }
3526 
3527  colsi[0] = (int)((double)(colsi[0] - red_min) / (double)(red_max - red_min) * 255. + .5);
3528  colsi[1] = (int)((double)(colsi[1] - green_min) / (double)(green_max - green_min) * 255. + .5);
3529  colsi[2] = (int)((double)(colsi[2] - blue_min) / (double)(blue_max - blue_min) * 255. + .5);
3530 
3531  if (colsi[0] < red_min) colsi[0] = red_min;
3532  if (colsi[1] < green_min) colsi[1] = green_min;
3533  if (colsi[2] < blue_min) colsi[2] = blue_min;
3534  if (colsi[0] > red_max) colsi[0] = red_max;
3535  if (colsi[1] > green_max) colsi[1] = green_max;
3536  if (colsi[2] > blue_max) colsi[2] = blue_max;
3537 
3538  list = lives_list_append(list, lives_strdup_printf("%d", colsi[0]));
3539  list = lives_list_append(list, lives_strdup_printf("%d", colsi[1]));
3540  list = lives_list_append(list, lives_strdup_printf("%d", colsi[2]));
3541 
3542  set_param_from_list(list, &rfx->params[i], 0, FALSE, TRUE);
3543 
3544  lives_list_free_all(&list);
3545  lives_free(colsis);
3546  if (maxis) lives_free(maxis);
3547  if (minis) lives_free(minis);
3548  } else {
3549  colsds = weed_get_double_array(in_param, WEED_LEAF_VALUE, &error);
3550  colsd = &colsds[3 * index];
3551  if (weed_leaf_num_elements(paramtmpl, WEED_LEAF_MAX) == 1) {
3552  red_maxd = green_maxd = blue_maxd = weed_get_double_value(paramtmpl, WEED_LEAF_MAX, &error);
3553  } else {
3554  maxds = weed_get_double_array(paramtmpl, WEED_LEAF_MAX, &error);
3555  red_maxd = maxds[0];
3556  green_maxd = maxds[1];
3557  blue_maxd = maxds[2];
3558  }
3559  if (weed_leaf_num_elements(paramtmpl, WEED_LEAF_MIN) == 1) {
3560  red_mind = green_mind = blue_mind = weed_get_double_value(paramtmpl, WEED_LEAF_MIN, &error);
3561  } else {
3562  minds = weed_get_double_array(paramtmpl, WEED_LEAF_MIN, &error);
3563  red_mind = minds[0];
3564  green_mind = minds[1];
3565  blue_mind = minds[2];
3566  }
3567  colsd[0] = (colsd[0] - red_mind) / (red_maxd - red_mind) * 255. + .5;
3568  colsd[1] = (colsd[1] - green_mind) / (green_maxd - green_mind) * 255. + .5;
3569  colsd[2] = (colsd[2] - blue_mind) / (blue_maxd - blue_mind) * 255. + .5;
3570 
3571  if (colsd[0] < red_mind) colsd[0] = red_mind;
3572  if (colsd[1] < green_mind) colsd[1] = green_mind;
3573  if (colsd[2] < blue_mind) colsd[2] = blue_mind;
3574  if (colsd[0] > red_maxd) colsd[0] = red_maxd;
3575  if (colsd[1] > green_maxd) colsd[1] = green_maxd;
3576  if (colsd[2] > blue_maxd) colsd[2] = blue_maxd;
3577 
3578  list = lives_list_append(list, lives_strdup_printf("%.2f", colsd[0]));
3579  list = lives_list_append(list, lives_strdup_printf("%.2f", colsd[1]));
3580  list = lives_list_append(list, lives_strdup_printf("%.2f", colsd[2]));
3581  set_param_from_list(list, &rfx->params[i], 0, FALSE, TRUE);
3582 
3583  lives_list_free_all(&list);
3584  lives_free(colsds);
3585  if (maxds) lives_free(maxds);
3586  if (minds) lives_free(minds);
3587  }
3588  break;
3589  // TODO - other color spaces, e.g. RGBA24
3590  }
3591  break;
3592  } // hint
3593  }
3594  filter_mutex_unlock(key);
3595  }
3596  lives_free(in_params);
3597 }
mainwindow::framedraw_frame
int framedraw_frame
current displayed frame
Definition: mainwindow.h:1278
lives_freep
boolean lives_freep(void **ptr)
Definition: utils.c:1411
LIVES_GLOBAL_INLINE
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
widget_opts_t::packing_width
int packing_width
horizontal pixels between widgets
Definition: widget-helper.h:1410
lives_source_remove
WIDGET_HELPER_GLOBAL_INLINE boolean lives_source_remove(uint32_t handle)
Definition: widget-helper.c:7361
_prefs::ins_resample
boolean ins_resample
Definition: preferences.h:184
lives_standard_label_new_with_mnemonic_widget
LiVESWidget * lives_standard_label_new_with_mnemonic_widget(const char *text, LiVESWidget *mnemonic_widget)
Definition: widget-helper.c:8720
merge_opts
_merge_opts * merge_opts
Definition: mainwindow.h:1849
lives_spin_button_set_range
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_range(LiVESSpinButton *button, double min, double max)
Definition: widget-helper.c:5129
WH_LAYOUT_KEY
#define WH_LAYOUT_KEY
Definition: widget-helper.h:1495
lives_text_view_get_text
char * lives_text_view_get_text(LiVESTextView *textview)
Definition: widget-helper.c:11706
LIVES_IS_PLAYING
#define LIVES_IS_PLAYING
Definition: main.h:840
lives_param_t::special_type
lives_param_special_t special_type
Definition: plugins.h:607
HIDDEN_GUI_TEMP
#define HIDDEN_GUI_TEMP
Definition: plugins.h:558
lives_color_button_get_color
WIDGET_HELPER_GLOBAL_INLINE LiVESWidgetColor * lives_color_button_get_color(LiVESColorButton *button, LiVESWidgetColor *color)
Definition: widget-helper.c:7077
_fx_dialog::okbutton
LiVESWidget * okbutton
Definition: mainwindow.h:1841
lives_combo_set_active_string
WIDGET_HELPER_GLOBAL_INLINE boolean lives_combo_set_active_string(LiVESCombo *combo, const char *active_str)
Definition: widget-helper.c:12290
rte_window.h
lives_param_t::transition
boolean transition
Definition: plugins.h:564
lives_dialog_add_button_from_stock
LiVESWidget * lives_dialog_add_button_from_stock(LiVESDialog *dialog, const char *stock_id, const char *label, int response_id)
Definition: widget-helper.c:9892
PLUGIN_RENDERED_EFFECTS_TEST
#define PLUGIN_RENDERED_EFFECTS_TEST
Definition: plugins.h:473
do_onchange_init
LiVESList * do_onchange_init(lives_rfx_t *rfx)
Definition: paramwindow.c:35
set_undoable
void set_undoable(const char *what, boolean sensitive)
Definition: utils.c:4784
lives_colRGB48_t::red
uint16_t red
Definition: main.h:317
WEED_LEAF_HOST_DISABLED
#define WEED_LEAF_HOST_DISABLED
Definition: effects-weed.h:70
_palette::normal_back
LiVESWidgetColor normal_back
Definition: mainwindow.h:324
PLUGIN_RENDERED_EFFECTS_BUILTIN
#define PLUGIN_RENDERED_EFFECTS_BUILTIN
external rendered fx plugins (RFX plugins)
Definition: plugins.h:469
lives_list_strcmp_index
int lives_list_strcmp_index(LiVESList *list, livesconstpointer data, boolean case_sensitive)
Definition: utils.c:4678
lives_free
#define lives_free
Definition: machinestate.h:52
set_colRGBA32_param
void set_colRGBA32_param(void *value, short red, short green, short blue, short alpha)
Definition: plugins.c:3166
RFX_WINSIZE_V
#define RFX_WINSIZE_V
Definition: mainwindow.h:177
lives_rfx_t::is_template
boolean is_template
Definition: plugins.h:656
LIVES_WARN
#define LIVES_WARN(x)
Definition: main.h:1862
PLUGIN_RFX_SCRAP
#define PLUGIN_RFX_SCRAP
scraps are passed between programs to generate param windows
Definition: plugins.h:483
update_visual_params
void update_visual_params(lives_rfx_t *rfx, boolean update_hidden)
apply internal value changes to interface widgets
Definition: paramwindow.c:3361
WARN_MASK_LAYOUT_ALTER_FRAMES
#define WARN_MASK_LAYOUT_ALTER_FRAMES
off by default on a fresh install
Definition: preferences.h:102
lives_widget_add_accelerator
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_add_accelerator(LiVESWidget *widget, const char *accel_signal, LiVESAccelGroup *accel_group, uint32_t accel_key, LiVESXModifierType accel_mods, LiVESAccelFlags accel_flags)
Definition: widget-helper.c:2953
plugin_request_by_line
LIVES_GLOBAL_INLINE LiVESList * plugin_request_by_line(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:59
lives_layout_expansion_row_new
LiVESWidget * lives_layout_expansion_row_new(LiVESLayout *layout, LiVESWidget *widget)
Definition: widget-helper.c:7640
lives_malloc
#define lives_malloc
Definition: machinestate.h:46
widget_opts_t::filler_len
int filler_len
length of extra "fill" between widgets
Definition: widget-helper.h:1424
UNDO_RESIZABLE
@ UNDO_RESIZABLE
Definition: main.h:662
widget_opts_t::justify
LiVESJustification justify
justify for labels
Definition: widget-helper.h:1412
mainwindow::record
volatile boolean record
Definition: mainwindow.h:794
mt_desensitise
void mt_desensitise(lives_mt *mt)
Definition: multitrack.c:16979
lives_widget_destroy
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
Definition: widget-helper.c:1553
lives_standard_spin_button_new
LiVESWidget * lives_standard_spin_button_new(const char *labeltext, double val, double min, double max, double step, double page, int dp, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9397
weed_instance_get_in_params
WEED_GLOBAL_INLINE weed_plant_t ** weed_instance_get_in_params(weed_plant_t *instance, int *nparams)
Definition: weed-effects-utils.c:602
lives_colRGBA64_t::alpha
uint16_t alpha
Definition: main.h:326
_fx_dialog
Definition: mainwindow.h:1838
_prefs::workdir
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
lives_spin_button_set_value
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_value(LiVESSpinButton *button, double value)
Definition: widget-helper.c:5119
lives_spin_button_get_value_as_int
WIDGET_HELPER_GLOBAL_INLINE int lives_spin_button_get_value_as_int(LiVESSpinButton *button)
Definition: widget-helper.c:5091
lives_container_set_focus_child
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_set_focus_child(LiVESContainer *cont, LiVESWidget *child)
Definition: widget-helper.c:4988
lives_dialog_get_content_area
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_dialog_get_content_area(LiVESDialog *dialog)
Definition: widget-helper.c:2479
lives_param_t::onchange
boolean onchange
is there a trigger ?
Definition: plugins.h:595
mainwindow::current_file
int current_file
Definition: mainwindow.h:727
lives_rfx_t::status
lives_rfx_status_t status
Definition: plugins.h:631
DEF_GEN_HEIGHT
#define DEF_GEN_HEIGHT
Definition: mainwindow.h:150
weed_param_get_template
WEED_GLOBAL_INLINE weed_plant_t * weed_param_get_template(weed_plant_t *param)
Definition: weed-effects-utils.c:518
LIVES_PARAM_STRING
@ LIVES_PARAM_STRING
Definition: plugins.h:505
set_param_from_list
int set_param_from_list(LiVESList *plist, lives_param_t *param, int pnum, boolean with_min_max, boolean upd)
update values for param using values in plist if upd is TRUE, the widgets for that param also are upd...
Definition: paramwindow.c:3065
LIVES_EXPAND_EXTRA
#define LIVES_EXPAND_EXTRA
Definition: widget-helper.h:1317
_palette::style
int style
Definition: mainwindow.h:297
cfile
#define cfile
Definition: main.h:1833
lives_label_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_label_new(const char *text)
Definition: widget-helper.c:3457
lives_widget_hide
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
Definition: widget-helper.c:1514
count_resampled_frames
int count_resampled_frames(int in_frames, double orig_fps, double resampled_fps)
Definition: resample.c:72
_fx_dialog::cancelbutton
LiVESWidget * cancelbutton
Definition: mainwindow.h:1840
RFX_WINSIZE_H
#define RFX_WINSIZE_H
size of the fx dialog windows scrollwindow
Definition: mainwindow.h:175
lives_dialog_response
WIDGET_HELPER_GLOBAL_INLINE boolean lives_dialog_response(LiVESDialog *dialog, int response)
Definition: widget-helper.c:1820
effects.h
lives_label_set_mnemonic_widget
WIDGET_HELPER_GLOBAL_INLINE boolean lives_label_set_mnemonic_widget(LiVESLabel *label, LiVESWidget *widget)
Definition: widget-helper.c:6086
lives_box_set_homogeneous
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_set_homogeneous(LiVESBox *box, boolean homogenous)
Definition: widget-helper.c:3213
plugin_request_by_space
LIVES_GLOBAL_INLINE LiVESList * plugin_request_by_space(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:64
lives_rfx_t::name
char * name
the name of the executable (so we can run it !)
Definition: plugins.h:626
add_param_label_to_box
LiVESWidget * add_param_label_to_box(LiVESBox *box, boolean do_trans, const char *text)
Definition: paramwindow.c:1844
get_colRGB24_param
void get_colRGB24_param(void *value, lives_colRGB48_t *rgb)
Definition: plugins.c:3093
_palette::normal_fore
LiVESWidgetColor normal_fore
Definition: mainwindow.h:325
set_bool_param
void set_bool_param(void *value, boolean _const)
Definition: plugins.c:3103
lives_rfx_t::params
lives_param_t * params
Definition: plugins.h:649
transition_add_in_out
void transition_add_in_out(LiVESBox *vbox, lives_rfx_t *rfx, boolean add_audio_check)
Definition: paramwindow.c:352
livesgrp_from_usrgrp
lives_widget_group_t * livesgrp_from_usrgrp(LiVESSList *u2l, int usrgrp)
Definition: paramwindow.c:1882
LIVES_JUSTIFY_DEFAULT
#define LIVES_JUSTIFY_DEFAULT
Definition: widget-helper.h:1289
set_copy_to
int set_copy_to(weed_plant_t *inst, int pnum, lives_rfx_t *rfx, boolean update)
Definition: effects-weed.c:8918
lives_signal_handlers_block_by_func
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handlers_block_by_func(livespointer instance, LiVESGuiCallback func, livespointer data)
Definition: widget-helper.c:1417
lives_standard_dialog_new
LiVESWidget * lives_standard_dialog_new(const char *title, boolean add_std_buttons, int width, int height)
Definition: widget-helper.c:9971
weed_instance_get_flags
WEED_GLOBAL_INLINE int weed_instance_get_flags(weed_plant_t *inst)
Definition: weed-effects-utils.c:580
rte_set_key_defs
void rte_set_key_defs(LiVESButton *button, lives_rfx_t *rfx)
Definition: rte_window.c:2531
prefs
_prefs * prefs
Definition: preferences.h:847
lives_strcmp
LIVES_GLOBAL_INLINE boolean lives_strcmp(const char *st1, const char *st2)
returns FALSE if strings match
Definition: machinestate.c:1506
_merge_opts::align_start
boolean align_start
Definition: mainwindow.h:1830
polymorph
void polymorph(lives_mt *mt, lives_mt_poly_state_t poly)
Definition: multitrack.c:12777
_prefs::lib_dir
char lib_dir[PATH_MAX]
Definition: preferences.h:75
set_int_param
void set_int_param(void *value, int _const)
Definition: plugins.c:3114
_fx_dialog::dialog
LiVESWidget * dialog
Definition: mainwindow.h:1839
LIVES_PARAM_COLRGB24
@ LIVES_PARAM_COLRGB24
Definition: plugins.h:504
lives_rfx_t::menu_text
char * menu_text
for Weed, this is the filter_class "name"
Definition: plugins.h:627
lives_layout_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_new(LiVESBox *box)
Definition: widget-helper.c:7732
lives_text_view_get_buffer
WIDGET_HELPER_GLOBAL_INLINE LiVESTextBuffer * lives_text_view_get_buffer(LiVESTextView *tview)
Definition: widget-helper.c:3950
REC_EFFECTS
#define REC_EFFECTS
Definition: preferences.h:199
FILTER_SUCCESS
@ FILTER_SUCCESS
Definition: effects-weed.h:15
param_marshall_to_argv
char ** param_marshall_to_argv(lives_rfx_t *rfx)
Definition: paramwindow.c:2797
WEED_LEAF_HOST_WIDTH
#define WEED_LEAF_HOST_WIDTH
Definition: effects-weed.h:63
lives_label_set_markup
WIDGET_HELPER_GLOBAL_INLINE boolean lives_label_set_markup(LiVESLabel *label, const char *markup)
Definition: widget-helper.c:6076
add_hsep_to_box
LiVESWidget * add_hsep_to_box(LiVESBox *box)
Definition: widget-helper.c:12355
_prefs::rec_opts
int rec_opts
Definition: preferences.h:196
activate_mt_preview
void activate_mt_preview(lives_mt *mt)
sensitize Show Preview and Apply buttons
Definition: multitrack.c:19400
RFX_MAX_NORM_WIDGETS
#define RFX_MAX_NORM_WIDGETS
Definition: plugins.h:490
lives_spin_button_get_adjustment
WIDGET_HELPER_GLOBAL_INLINE LiVESAdjustment * lives_spin_button_get_adjustment(LiVESSpinButton *button)
Definition: widget-helper.c:5099
_prefs::backend_sync
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
_fx_dialog::key
int key
Definition: mainwindow.h:1844
lives_button_grab_default_special
boolean lives_button_grab_default_special(LiVESWidget *button)
Definition: widget-helper.c:7587
fd_tweak
void fd_tweak(lives_rfx_t *rfx)
Definition: paramspecial.c:159
lives_widget_set_no_show_all
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_no_show_all(LiVESWidget *widget, boolean set)
Definition: widget-helper.c:4868
get_token_count
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
widget_opts_t::apply_theme
int apply_theme
theming variation for widget (0 -> no theme, 1 -> normal colours, 2+ -> theme variants)
Definition: widget-helper.h:1409
add_fill_to_box
LiVESWidget * add_fill_to_box(LiVESBox *box)
Definition: widget-helper.c:12377
check_storage_space
boolean check_storage_space(int clipno, boolean is_processing)
Definition: dialogs.c:1086
fx_dialog
_fx_dialog * fx_dialog[2]
Definition: mainwindow.h:1851
LIVES_RFX_SOURCE_RFX
@ LIVES_RFX_SOURCE_RFX
Definition: plugins.h:513
enabled_in_channels
int enabled_in_channels(weed_plant_t *plant, boolean count_repeats)
Definition: effects-weed.c:3985
get_int_param
int get_int_param(void *value)
Definition: plugins.c:3079
lives_text_view_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_text_view_new(void)
Definition: widget-helper.c:3932
ABS
#define ABS(a)
Definition: videoplugin.h:63
_fx_dialog::rfx
lives_rfx_t * rfx
Definition: mainwindow.h:1843
widget_add_framedraw
void widget_add_framedraw(LiVESVBox *box, int start, int end, boolean add_preview_button, int width, int height, lives_rfx_t *rfx)
call this to add framedraw widget to an hbox
Definition: framedraw.c:279
check_for_special
void check_for_special(lives_rfx_t *rfx, lives_param_t *param, LiVESBox *pbox)
Definition: paramspecial.c:298
_prefs::lamp_buttons
boolean lamp_buttons
Definition: preferences.h:343
set_double_param
void set_double_param(void *value, double _const)
Definition: plugins.c:3119
lives_widget_group_t::usr_number
int usr_number
Definition: paramwindow.h:11
HIDDEN_STRUCTURAL
#define HIDDEN_STRUCTURAL
Definition: plugins.h:554
lives_layout_add_separator
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_add_separator(LiVESLayout *layout, boolean horizontal)
Definition: widget-helper.c:7855
weed_inst_in_param
weed_plant_t * weed_inst_in_param(weed_plant_t *inst, int param_num, boolean skip_hidden, boolean skip_internal)
Definition: effects-weed.c:8724
lives_widget_set_vexpand
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_vexpand(LiVESWidget *widget, boolean state)
Definition: widget-helper.c:6359
param_demarshall
void param_demarshall(lives_rfx_t *rfx, LiVESList *plist, boolean with_min_max, boolean upd)
Definition: paramwindow.c:3013
lives_colRGB48_t::blue
uint16_t blue
Definition: main.h:319
LIVES_PARAM_NUM
@ LIVES_PARAM_NUM
Definition: plugins.h:502
rfx_free
void rfx_free(lives_rfx_t *rfx)
Definition: plugins.c:2987
do_onchange
LiVESList * do_onchange(LiVESWidgetObject *object, lives_rfx_t *rfx)
object should have g_set_object_data "param_number" set to parameter number
Definition: paramwindow.c:3265
do_rfx_cleanup
void do_rfx_cleanup(lives_rfx_t *rfx)
Definition: plugins.c:2671
lives_param_t::dp
int dp
decimals, 0 for int and bool
Definition: plugins.h:575
on_paramwindow_button_clicked
void on_paramwindow_button_clicked(LiVESButton *button, lives_rfx_t *rfx)
Definition: paramwindow.c:90
do_error_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
on_pwcolsel
void on_pwcolsel(LiVESButton *button, lives_rfx_t *rfx)
Definition: paramwindow.c:3338
lives_standard_entry_new
LiVESWidget * lives_standard_entry_new(const char *labeltext, const char *txt, int dispwidth, int maxchars, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9688
lives_window_add_accel_group
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_add_accel_group(LiVESWindow *window, LiVESAccelGroup *group)
Definition: widget-helper.c:2968
mainwindow::resize_menuitem
LiVESWidget * resize_menuitem
Definition: mainwindow.h:1436
TRUE
#define TRUE
Definition: videoplugin.h:59
lives_param_t::reinit
int reinit
Definition: plugins.h:569
lives_rfx_t::num_in_channels
int num_in_channels
Definition: plugins.h:630
lives_colRGBA64_t::green
uint16_t green
Definition: main.h:324
update_widget_vis
boolean update_widget_vis(lives_rfx_t *rfx, int key, int mode)
show / hide widgets set by plugin in init_func()
Definition: paramwindow.c:1893
lives_memset
#define lives_memset
Definition: machinestate.h:61
RFX_PROPS_BATCHG
#define RFX_PROPS_BATCHG
is a batch generator
Definition: plugins.h:636
lives_widget_set_hexpand
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_hexpand(LiVESWidget *widget, boolean state)
Definition: widget-helper.c:6347
filter_mutex_lock
LIVES_GLOBAL_INLINE int filter_mutex_lock(int key)
Definition: effects-weed.c:96
_prefs::default_fps
double default_fps
Definition: preferences.h:173
weed_filter_in_paramtmpl
weed_plant_t * weed_filter_in_paramtmpl(weed_plant_t *filter, int param_num, boolean skip_internal)
Definition: effects-weed.c:8795
update_weed_color_value
void update_weed_color_value(weed_plant_t *plant, int pnum, int c1, int c2, int c3, int c4, lives_rfx_t *rfx)
Definition: paramwindow.c:2225
is_hidden_param
boolean is_hidden_param(weed_plant_t *plant, int i)
returns the permanent (structural) state c.f check_hidden_gui() which sets flag values for params lin...
Definition: effects-weed.c:8587
lives_widget_group_t::active_param
int active_param
Definition: paramwindow.h:13
set_colRGB24_param
void set_colRGB24_param(void *value, short red, short green, short blue)
Definition: plugins.c:3149
lives_standard_combo_new
LiVESWidget * lives_standard_combo_new(const char *labeltext, LiVESList *list, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9544
after_param_value_changed
void after_param_value_changed(LiVESSpinButton *spinbutton, lives_rfx_t *rfx)
Definition: paramwindow.c:2102
lives_rfx_t
Definition: plugins.h:625
lives_layout_pack
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_pack(LiVESHBox *box, LiVESWidget *widget)
Definition: widget-helper.c:7699
lives_clip_t::fps
double fps
Definition: main.h:893
lives_param_t::max
double max
for string this is max characters
Definition: plugins.h:579
lives_widget_set_bg_color
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_bg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
Definition: widget-helper.c:2056
weed_param_get_gui
WEED_GLOBAL_INLINE weed_plant_t * weed_param_get_gui(weed_plant_t *param, int create_if_not_exists)
Definition: weed-effects-utils.c:166
lives_layout_add_label
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_add_label(LiVESLayout *layout, const char *text, boolean horizontal)
Definition: widget-helper.c:7810
RFX_STATUS_WEED
@ RFX_STATUS_WEED
indicates an internal RFX, created from a weed instance
Definition: plugins.h:616
widget_opts_t::last_label
LiVESWidget * last_label
commonly adjusted values //////
Definition: widget-helper.h:1406
LIVES_PARAM_SPECIAL_TYPE_FILEREAD
@ LIVES_PARAM_SPECIAL_TYPE_FILEREAD
Definition: plugins.h:528
WEED_PLANT_IS_FILTER_CLASS
#define WEED_PLANT_IS_FILTER_CLASS(plant)
Definition: weed-effects-utils.h:36
check_for_layout_errors
boolean check_for_layout_errors(const char *operation, int fileno, int start, int end, uint32_t *in_mask)
check for layout errors, using in_mask as a guide (mask values are taken from prefs->warn_mask,...
Definition: callbacks.c:4059
lives_layout_hbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_hbox_new(LiVESLayout *layout)
Definition: widget-helper.c:7757
callbacks.h
make_param_box
boolean make_param_box(LiVESVBox *top_vbox, lives_rfx_t *rfx)
make a dynamic parameter window
Definition: paramwindow.c:1015
after_param_alpha_changed
void after_param_alpha_changed(LiVESSpinButton *spinbutton, lives_rfx_t *rfx)
Definition: paramwindow.c:2558
lives_colRGBA64_t::blue
uint16_t blue
Definition: main.h:325
lives_toggle_button_get_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_get_active(LiVESToggleButton *button)
Definition: widget-helper.c:4472
add_param_to_box
boolean add_param_to_box(LiVESBox *box, lives_rfx_t *rfx, int pnum, boolean add_slider)
Definition: paramwindow.c:1484
widget_opts_t::mnemonic_label
boolean mnemonic_label
if underscore in label text should be mnemonic accelerator
Definition: widget-helper.h:1420
DEF_SLIDER_WIDTH
#define DEF_SLIDER_WIDTH
Definition: paramwindow.h:27
WIDGET_RB_OUT
#define WIDGET_RB_OUT
Definition: plugins.h:494
lives_param_t
Definition: plugins.h:538
GIW_KNOB_HEIGHT
#define GIW_KNOB_HEIGHT
Definition: paramwindow.h:25
get_external_window_hints
LiVESList * get_external_window_hints(lives_rfx_t *rfx)
get the interface hints set by a Weed filter in the filter_class.
Definition: plugins.c:3618
ce_thumbs_update_visual_params
void ce_thumbs_update_visual_params(int key)
Definition: ce_thumbs.c:590
close_current_file
void close_current_file(int file_to_switch_to)
close current file, and try to switch to file_to_switch_to
Definition: main.c:9373
LIVES_PARAM_UNDISPLAYABLE
@ LIVES_PARAM_UNDISPLAYABLE
Definition: plugins.h:509
on_realfx_activate
void on_realfx_activate(LiVESMenuItem *, livespointer rfx)
Definition: effects.c:799
mainwindow::keep_pre
boolean keep_pre
set if previewed frames should be retained as processed frames (for rendered effects / generators)
Definition: mainwindow.h:1567
lives_widget_apply_theme3
void lives_widget_apply_theme3(LiVESWidget *widget, LiVESWidgetState state)
Definition: widget-helper.c:11183
reset_framedraw_preview
void reset_framedraw_preview(void)
Definition: paramspecial.c:27
lives_rfx_t::props
uint32_t props
Definition: plugins.h:633
filter_mutex_unlock
LIVES_GLOBAL_INLINE int filter_mutex_unlock(int key)
Definition: effects-weed.c:108
lives_general_button_clicked
void lives_general_button_clicked(LiVESButton *button, livespointer data_to_free)
Definition: widget-helper.c:12306
REINIT_FUNCTIONAL
#define REINIT_FUNCTIONAL
Definition: plugins.h:566
RFX_TEXT_SCROLL_HEIGHT
#define RFX_TEXT_SCROLL_HEIGHT
height of textview scrolled window
Definition: paramwindow.h:22
lives_rfx_t::num_params
int num_params
Definition: plugins.h:644
mainwindow::msg
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
mainwindow::pre_src_file
int pre_src_file
video file we were playing before any ext input started
Definition: mainwindow.h:971
add_video_options
LiVESWidget * add_video_options(LiVESWidget **spwidth, int defwidth, LiVESWidget **spheight, int defheight, LiVESWidget **spfps, double deffps, LiVESWidget **spframes, int defframes, boolean add_aspect, LiVESWidget *extra)
Definition: events.c:6072
lives_spin_button_get_value
WIDGET_HELPER_GLOBAL_INLINE double lives_spin_button_get_value(LiVESSpinButton *button)
Definition: widget-helper.c:5083
RFX_FLAGS_NO_SLIDERS
#define RFX_FLAGS_NO_SLIDERS
internal use
Definition: plugins.h:646
lives_signal_handlers_unblock_by_func
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handlers_unblock_by_func(livespointer instance, LiVESGuiCallback func, livespointer data)
Definition: widget-helper.c:1435
_palette::white
LiVESWidgetColor white
Definition: mainwindow.h:306
lives_standard_label_new
LiVESWidget * lives_standard_label_new(const char *text)
Definition: widget-helper.c:8601
mainwindow::textwidget_focus
LiVESWidget * textwidget_focus
Definition: mainwindow.h:1569
lives_param_t::min
double min
Definition: plugins.h:578
weed_paramtmpl_get_type
WEED_GLOBAL_INLINE int weed_paramtmpl_get_type(weed_plant_t *paramtmpl)
Definition: weed-effects-utils.c:312
PLUGIN_EXEC_DIR
#define PLUGIN_EXEC_DIR
Definition: mainwindow.h:599
lives_filter_error_t
lives_filter_error_t
filter apply errors
Definition: effects-weed.h:14
do_effect
boolean do_effect(lives_rfx_t *, boolean is_preview)
defined as extern in paramwindow.c
Definition: effects.c:127
interface.h
lives_vbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_vbox_new(boolean homogeneous, int spacing)
Definition: widget-helper.c:3267
lives_layout_add_row
WIDGET_HELPER_GLOBAL_INLINE int lives_layout_add_row(LiVESLayout *layout)
Definition: widget-helper.c:7783
add_usrgrp_to_livesgrp
LiVESSList * add_usrgrp_to_livesgrp(LiVESSList *u2l, LiVESSList *rbgroup, int usr_number)
Definition: paramwindow.c:1872
RFX_FLAGS_NO_RESET
#define RFX_FLAGS_NO_RESET
Definition: plugins.h:647
PLUGIN_RENDERED_EFFECTS_CUSTOM
#define PLUGIN_RENDERED_EFFECTS_CUSTOM
in the config directory
Definition: plugins.h:472
lives_param_t::list
LiVESList * list
for string list (choices)
Definition: plugins.h:582
lives_widget_get_parent
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_parent(LiVESWidget *widget)
Definition: widget-helper.c:4739
filter_mutex_trylock
LIVES_GLOBAL_INLINE int filter_mutex_trylock(int key)
Definition: effects-weed.c:74
lives_rfx_t::delim
char delim[2]
Definition: plugins.h:652
get_double_param
double get_double_param(void *value)
Definition: plugins.c:3086
mainwindow::files
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
weed_instance_set_flags
WEED_GLOBAL_INLINE void weed_instance_set_flags(weed_plant_t *inst, int flags)
Definition: weed-effects-utils.c:585
POLY_CLIPS
@ POLY_CLIPS
Definition: multitrack.h:123
FILTER_INFO_REDRAWN
@ FILTER_INFO_REDRAWN
Definition: effects-weed.h:41
lives_spin_button_set_snap_to_multiples
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_snap_to_multiples(LiVESSpinButton *button, double mult)
Definition: widget-helper.c:9374
toggle_toggles_var
WIDGET_HELPER_GLOBAL_INLINE boolean toggle_toggles_var(LiVESToggleButton *tbut, boolean *var, boolean invert)
Definition: widget-helper.c:11485
ALIGN_CEIL
#define ALIGN_CEIL(a, b)
Definition: main.h:286
WIDGET_RB_IN
#define WIDGET_RB_IN
special widgets
Definition: plugins.h:493
mainwindow::first_free_file
int first_free_file
Definition: mainwindow.h:728
mainwindow::fd_max_frame
int fd_max_frame
max effected / generated frame
Definition: mainwindow.h:1279
WEED_LEAF_HOST_KEY
#define WEED_LEAF_HOST_KEY
Definition: effects-weed.h:67
widget_opts_t::packing_height
int packing_height
vertical pixels between widgets
Definition: widget-helper.h:1411
add_to_special
void add_to_special(const char *sp_string, lives_rfx_t *rfx)
Definition: paramspecial.c:53
has_video_chans_out
boolean has_video_chans_out(weed_plant_t *filter, boolean count_opt)
Definition: effects-weed.c:676
LIVES_PARAM_SPECIAL_TYPE_FONT_CHOOSER
@ LIVES_PARAM_SPECIAL_TYPE_FONT_CHOOSER
Definition: plugins.h:531
WEED_LEAF_HOST_HEIGHT
#define WEED_LEAF_HOST_HEIGHT
Definition: effects-weed.h:64
palette
_palette * palette
interface colour settings
Definition: main.c:101
lives_widget_object_ref_sink
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_object_ref_sink(livespointer object)
Definition: widget-helper.c:845
after_param_green_changed
void after_param_green_changed(LiVESSpinButton *spinbutton, lives_rfx_t *rfx)
Definition: paramwindow.c:2435
error
error("LSD_RANDFUNC(ptr, size) must be defined")
lives_hbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
Definition: widget-helper.c:3253
widget_opts_t::pack_end
boolean pack_end
pack widget at end or start
Definition: widget-helper.h:1418
DEF_BUTTON_WIDTH
#define DEF_BUTTON_WIDTH
Definition: mainwindow.h:182
lives_color_button_set_color
WIDGET_HELPER_GLOBAL_INLINE boolean lives_color_button_set_color(LiVESColorButton *button, const LiVESWidgetColor *color)
Definition: widget-helper.c:7124
FX_CANDIDATE_RESIZER
#define FX_CANDIDATE_RESIZER
Definition: plugins.h:695
fill_param_vals_to
void fill_param_vals_to(weed_plant_t *param, weed_plant_t *paramtmpl, int index)
for a multi valued parameter or pchange, we will fill WEED_LEAF_VALUE up to element index with WEED_L...
Definition: effects-weed.c:9913
lives_layout_row_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_row_new(LiVESLayout *layout)
Definition: widget-helper.c:7791
fd_connect_spinbutton
void fd_connect_spinbutton(lives_rfx_t *rfx)
Definition: paramspecial.c:174
clipboard
#define clipboard
Definition: main.h:1835
ce_thumbs.h
lives_rfx_t::flags
uint32_t flags
Definition: plugins.h:645
lives_spin_button_set_wrap
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_wrap(LiVESSpinButton *button, boolean wrap)
Definition: widget-helper.c:5138
MAX_PARAM_WIDGETS
#define MAX_PARAM_WIDGETS
max number of display widgets per parameter (currently 7 for transition param with mergealign - spin ...
Definition: plugins.h:488
lives_param_t::label
char * label
Definition: plugins.h:543
LIVES_PARAM_SPECIAL_TYPE_FILEWRITE
@ LIVES_PARAM_SPECIAL_TYPE_FILEWRITE
Definition: plugins.h:529
widget_opts_t::scale
double scale
scale factor for all sizes
Definition: widget-helper.h:1433
mainwindow::gen_to_clipboard
boolean gen_to_clipboard
rendered generators
Definition: mainwindow.h:1564
subst
char * subst(const char *string, const char *from, const char *to)
Definition: utils.c:5484
mainwindow::framedraw_preview
LiVESWidget * framedraw_preview
the 'redraw' button
Definition: mainwindow.h:1265
lives_fx_candidate_t::rfx
lives_rfx_t * rfx
pointer to rfx for current delegate (or NULL)
Definition: plugins.h:690
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
after_param_text_changed
void after_param_text_changed(LiVESWidget *textwidget, lives_rfx_t *rfx)
Definition: paramwindow.c:2635
lives_rfx_t::needs_reinit
int needs_reinit
Definition: plugins.h:657
on_fx_pre_activate
_fx_dialog * on_fx_pre_activate(lives_rfx_t *rfx, boolean is_realtime, LiVESWidget *pbox)
Definition: paramwindow.c:687
paramwindow.h
after_boolean_param_toggled
void after_boolean_param_toggled(LiVESToggleButton *togglebutton, lives_rfx_t *rfx)
Definition: paramwindow.c:2035
lives_list_free_all
void lives_list_free_all(LiVESList **)
Definition: utils.c:4873
argv_to_marshalled_list
LiVESList * argv_to_marshalled_list(lives_rfx_t *rfx, int argc, char **argv)
Definition: paramwindow.c:3031
lives_clip_t::hsize
int hsize
frame width (horizontal) in pixels (NOT macropixels !)
Definition: main.h:896
popup_lmap_errors
void popup_lmap_errors(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9335
LIVES_MAIN_WINDOW_WIDGET
#define LIVES_MAIN_WINDOW_WIDGET
Definition: mainwindow.h:188
check_for_special_type
void check_for_special_type(lives_rfx_t *rfx, lives_param_t *param, LiVESBox *pbox)
Definition: paramspecial.c:228
lives_text_view_set_text
boolean lives_text_view_set_text(LiVESTextView *textview, const char *text, int len)
Definition: widget-helper.c:11715
DEF_FPS
#define DEF_FPS
Definition: mainwindow.h:47
is_perchannel_multi
boolean is_perchannel_multi(lives_rfx_t *rfx, int i)
Definition: paramspecial.c:765
enabled_out_channels
int enabled_out_channels(weed_plant_t *plant, boolean count_repeats)
Definition: effects-weed.c:4043
rte_reset_defs_clicked
void rte_reset_defs_clicked(LiVESButton *button, lives_rfx_t *rfx)
Definition: rte_window.c:2599
lives_widget_set_show_hide_with
boolean lives_widget_set_show_hide_with(LiVESWidget *widget, LiVESWidget *other)
Definition: widget-helper.c:8902
lives_widget_set_valign
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_valign(LiVESWidget *widget, LiVESAlign align)
Definition: widget-helper.c:3537
_fx_dialog::mode
int mode
Definition: mainwindow.h:1845
mainwindow::is_generating
boolean is_generating
Definition: mainwindow.h:1565
get_transition_param
int get_transition_param(weed_plant_t *filter, boolean skip_internal)
Definition: effects-weed.c:8656
rte_set_defs_ok
void rte_set_defs_ok(LiVESButton *button, lives_rfx_t *rfx)
Definition: rte_window.c:2547
lives_widget_group_t
Definition: paramwindow.h:10
GIW_KNOB_WIDTH
#define GIW_KNOB_WIDTH
Definition: paramwindow.h:24
WEED_PLANT_IS_FILTER_INSTANCE
#define WEED_PLANT_IS_FILTER_INSTANCE(plant)
Definition: weed-effects-utils.h:38
lives_colRGB48_t
Definition: main.h:316
lives_dialog_get_response_for_widget
WIDGET_HELPER_GLOBAL_INLINE int lives_dialog_get_response_for_widget(LiVESDialog *dialog, LiVESWidget *widget)
Definition: widget-helper.c:1829
RFX_KEY
#define RFX_KEY
Definition: widget-helper.h:1491
mainwindow::block_param_updates
boolean block_param_updates
block visual param changes from updating real values
Definition: mainwindow.h:1550
lives_text_view_set_cursor_visible
WIDGET_HELPER_GLOBAL_INLINE boolean lives_text_view_set_cursor_visible(LiVESTextView *tview, boolean setting)
Definition: widget-helper.c:3977
mainwindow::framedraw
LiVESWidget * framedraw
for the framedraw special widget - TODO - use a sub-struct
Definition: mainwindow.h:1263
lives_strlen
LIVES_GLOBAL_INLINE size_t lives_strlen(const char *s)
Definition: machinestate.c:1468
reconstruct_string
char * reconstruct_string(LiVESList *plist, int start, int *offs)
Definition: paramwindow.c:2961
lives_param_t::hidden
uint32_t hidden
Definition: plugins.h:546
lives_widget_set_sensitive
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_sensitive(LiVESWidget *widget, boolean state)
Definition: widget-helper.c:1477
lives_strappend
LIVES_GLOBAL_INLINE int lives_strappend(const char *string, int len, const char *xnew)
Definition: machinestate.c:1436
lives_accel_group_new
WIDGET_HELPER_GLOBAL_INLINE LiVESAccelGroup * lives_accel_group_new(void)
Definition: widget-helper.c:2915
CURRENT_CLIP_IS_NORMAL
#define CURRENT_CLIP_IS_NORMAL
Definition: main.h:838
RFX_STATUS_BUILTIN
@ RFX_STATUS_BUILTIN
factory presets
Definition: plugins.h:612
HIDDEN_NEEDS_REINIT
#define HIDDEN_NEEDS_REINIT
non-structural (temporary)
Definition: plugins.h:557
lives_layout_add_fill
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_add_fill(LiVESLayout *layout, boolean horizontal)
Definition: widget-helper.c:7841
lives_text_view_set_editable
WIDGET_HELPER_GLOBAL_INLINE boolean lives_text_view_set_editable(LiVESTextView *tview, boolean setting)
Definition: widget-helper.c:3959
mainwindow::multitrack
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
lives_widget_apply_theme
void lives_widget_apply_theme(LiVESWidget *widget, LiVESWidgetState state)
Definition: widget-helper.c:11156
CURRENT_CLIP_IS_VALID
#define CURRENT_CLIP_IS_VALID
Definition: main.h:809
lives_spin_button_update
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_update(LiVESSpinButton *button)
Definition: widget-helper.c:5165
after_param_text_focus_changed
boolean after_param_text_focus_changed(LiVESWidget *hbox, LiVESWidget *child, lives_rfx_t *rfx)
Definition: paramwindow.c:2606
mainwindow::suppress_dprint
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
LIVES_PARAM_UNKNOWN
@ LIVES_PARAM_UNKNOWN
Definition: plugins.h:501
DEF_GEN_WIDTH
#define DEF_GEN_WIDTH
Definition: mainwindow.h:149
mainwindow::record_paused
volatile boolean record_paused
pause during recording
Definition: mainwindow.h:1557
lives_window_remove_accel_group
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_remove_accel_group(LiVESWindow *window, LiVESAccelGroup *group)
Definition: widget-helper.c:3007
RFX_PROPS_MAY_RESIZE
#define RFX_PROPS_MAY_RESIZE
is a tool
Definition: plugins.h:635
mainwindow::ce_thumbs
boolean ce_thumbs
Definition: mainwindow.h:1676
RFX_TEXT_MAGIC
#define RFX_TEXT_MAGIC
length at which entry turns into textview
Definition: paramwindow.h:16
RFX_STATUS_SCRAP
@ RFX_STATUS_SCRAP
used for parsing RFX scraps from external apps
Definition: plugins.h:617
on_render_fx_pre_activate
LIVES_GLOBAL_INLINE void on_render_fx_pre_activate(LiVESMenuItem *menuitem, lives_rfx_t *rfx)
Definition: paramwindow.c:656
main.h
RFX_STATUS_TEST
@ RFX_STATUS_TEST
test effects in the advanced menu
Definition: plugins.h:614
lives_rfx_t::source_type
lives_rfx_source_t source_type
Definition: plugins.h:650
lives_colRGBA64_t
Definition: main.h:322
LIVES_EXPAND_DEFAULT
#define LIVES_EXPAND_DEFAULT
Definition: widget-helper.h:1314
lives_combo_get_active_text
WIDGET_HELPER_GLOBAL_INLINE const char * lives_combo_get_active_text(LiVESCombo *combo)
Definition: widget-helper.c:3874
_fx_dialog::resetbutton
LiVESWidget * resetbutton
Definition: mainwindow.h:1842
lives_param_t::changed
boolean changed
Definition: plugins.h:597
resample.h
_palette::dark_orange
LiVESWidgetColor dark_orange
Definition: mainwindow.h:312
after_param_blue_changed
void after_param_blue_changed(LiVESSpinButton *spinbutton, lives_rfx_t *rfx)
Definition: paramwindow.c:2497
weed_instance_is_resizer
LIVES_GLOBAL_INLINE boolean weed_instance_is_resizer(weed_plant_t *inst)
Definition: effects-weed.c:571
on_render_fx_activate
void on_render_fx_activate(LiVESMenuItem *menuitem, lives_rfx_t *rfx)
Definition: paramwindow.c:222
mainw
mainwindow * mainw
Definition: main.c:103
lives_widget_set_halign
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_halign(LiVESWidget *widget, LiVESAlign align)
Definition: widget-helper.c:3504
framedraw.h
LIVES_RFX_SOURCE_WEED
@ LIVES_RFX_SOURCE_WEED
Definition: plugins.h:514
lives_standard_hscale_new
LiVESWidget * lives_standard_hscale_new(LiVESAdjustment *adj)
Definition: widget-helper.c:10192
get_bool_param
boolean get_bool_param(void *value)
Definition: plugins.c:3072
lives_standard_scrolled_window_new
LiVESWidget * lives_standard_scrolled_window_new(int width, int height, LiVESWidget *child)
Definition: widget-helper.c:10272
mainwindow::did_rfx_preview
boolean did_rfx_preview
Definition: mainwindow.h:1056
_merge_opts::spinbutton_loops
LiVESWidget * spinbutton_loops
Definition: mainwindow.h:1827
lives_param_t::step_size
double step_size
Definition: plugins.h:562
lives_entry_set_text
WIDGET_HELPER_GLOBAL_INLINE boolean lives_entry_set_text(LiVESEntry *entry, const char *text)
Definition: widget-helper.c:6211
WEED_LEAF_HOST_AUDIO_TRANSITION
#define WEED_LEAF_HOST_AUDIO_TRANSITION
Definition: events.h:86
lives_kill_subprocesses
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
WEED_LEAF_HOST_NEXT_INSTANCE
#define WEED_LEAF_HOST_NEXT_INSTANCE
Definition: effects-weed.h:104
lives_param_t::widgets
LiVESWidget * widgets[MAX_PARAM_WIDGETS]
TODO - change to LiVESWidget **widgets, terminated with a NULL.
Definition: plugins.h:594
weed_param_value_irrelevant
WEED_GLOBAL_INLINE int weed_param_value_irrelevant(weed_plant_t *param)
Definition: weed-effects-utils.c:543
add_resnn_label
void add_resnn_label(LiVESDialog *dialog)
Definition: dialogs.c:4567
lives_widget_show_all
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
Definition: widget-helper.c:1523
get_colRGBA32_param
void get_colRGBA32_param(void *value, lives_colRGBA64_t *rgba)
Definition: plugins.c:3098
WEED_LEAF_HOST_REFS
#define WEED_LEAF_HOST_REFS
Definition: effects-weed.h:72
has_video_chans_in
boolean has_video_chans_in(weed_plant_t *filter, boolean count_opt)
Definition: effects-weed.c:620
weed_param_is_hidden
WEED_GLOBAL_INLINE int weed_param_is_hidden(weed_plant_t *param, int temporary)
Definition: weed-effects-utils.c:170
mainwindow::fx_candidates
lives_fx_candidate_t fx_candidates[MAX_FX_CANDIDATE_TYPES]
< effects which can have candidates from which a delegate is selected (current examples are: audio_vo...
Definition: mainwindow.h:1514
lives_toggle_button_set_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_set_active(LiVESToggleButton *button, boolean active)
Definition: widget-helper.c:4483
widget_opts
widget_opts_t widget_opts
Definition: widget-helper.h:1442
weed_instance_get_filter
weed_plant_t * weed_instance_get_filter(weed_plant_t *inst, boolean get_compound_parent)
Definition: effects-weed.c:180
lives_entry_get_text
WIDGET_HELPER_GLOBAL_INLINE const char * lives_entry_get_text(LiVESEntry *entry)
Definition: widget-helper.c:6203
mainwindow::show_procd
boolean show_procd
override showing of "processing..." dialog
Definition: mainwindow.h:1548
lives_clip_t::vsize
int vsize
frame height (vertical) in pixels
Definition: main.h:897
lives_param_t::value
void * value
current value(s)
Definition: plugins.h:576
widget_opts_t::expand
lives_expand_t expand
how much space to apply between widgets
Definition: widget-helper.h:1408
mt_sensitise
void mt_sensitise(lives_mt *mt)
Definition: multitrack.c:17052
special_cleanup
boolean special_cleanup(boolean is_ok)
Definition: paramspecial.c:641
lives_hseparator_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hseparator_new(void)
Definition: widget-helper.c:3301
WEED_LEAF_HOST_FPS
#define WEED_LEAF_HOST_FPS
Definition: effects-weed.h:65
lives_colRGB48_t::green
uint16_t green
Definition: main.h:318
lives_standard_color_button_new
LiVESWidget * lives_standard_color_button_new(LiVESBox *box, const char *name, boolean use_alpha, lives_colRGBA64_t *rgba, LiVESWidget **sb_red, LiVESWidget **sb_green, LiVESWidget **sb_blue, LiVESWidget **sb_alpha)
Definition: widget-helper.c:10683
lives_colRGBA64_t::red
uint16_t red
Definition: main.h:323
LIVES_RFX_SOURCE_NEWCLIP
@ LIVES_RFX_SOURCE_NEWCLIP
Definition: plugins.h:515
after_param_red_changed
void after_param_red_changed(LiVESSpinButton *spinbutton, lives_rfx_t *rfx)
Definition: paramwindow.c:2372
lives_param_t::wrap
boolean wrap
Definition: plugins.h:571
param_marshall
char * param_marshall(lives_rfx_t *rfx, boolean with_min_max)
Definition: paramwindow.c:2844
MAX_FMT_STRINGS
#define MAX_FMT_STRINGS
Definition: paramwindow.h:19
lives_rfx_t::source
void * source
points to the source (e.g. a weed_plant_t)
Definition: plugins.h:651
GUI_SCREEN_WIDTH
#define GUI_SCREEN_WIDTH
Definition: mainwindow.h:99
after_string_list_changed
void after_string_list_changed(LiVESWidget *entry, lives_rfx_t *rfx)
Definition: paramwindow.c:2726
ce_thumbs_check_for_rte
void ce_thumbs_check_for_rte(lives_rfx_t *rfx, lives_rfx_t *rte_rfx, int key)
Definition: ce_thumbs.c:602
HIDDEN_UNDISPLAYABLE
#define HIDDEN_UNDISPLAYABLE
structural (permanent)
Definition: plugins.h:550
FPS_MAX
#define FPS_MAX
maximum fps we will allow (double)
Definition: main.h:218
lives_standard_check_button_new
LiVESWidget * lives_standard_check_button_new(const char *labeltext, boolean active, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9048
FMT_STRING_SIZE
#define FMT_STRING_SIZE
Definition: paramwindow.h:20
lives_text_buffer_set_text
WIDGET_HELPER_GLOBAL_INLINE boolean lives_text_buffer_set_text(LiVESTextBuffer *tbuff, const char *text, int len)
Definition: widget-helper.c:4054
lives_text_view_set_wrap_mode
WIDGET_HELPER_GLOBAL_INLINE boolean lives_text_view_set_wrap_mode(LiVESTextView *tview, LiVESWrapMode wrapmode)
Definition: widget-helper.c:3986
lives_param_t::change_blocked
boolean change_blocked
Definition: plugins.h:600
rte_key_getmode
int rte_key_getmode(int key)
returns current active mode for a key (or -1)
Definition: effects-weed.c:9424
rte_set_defs_cancel
void rte_set_defs_cancel(LiVESButton *button, lives_rfx_t *rfx)
Definition: rte_window.c:2593
lives_widget_set_fg_color
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_fg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
Definition: widget-helper.c:2079
HIDDEN_GUI_PERM
#define HIDDEN_GUI_PERM
Definition: plugins.h:551
lives_widget_get_toplevel
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_toplevel(LiVESWidget *widget)
Definition: widget-helper.c:4750
lives_widget_group_t::rbgroup
LiVESSList * rbgroup
Definition: paramwindow.h:12
_prefs::config_datadir
char config_datadir[PATH_MAX]
kept in locale encoding (general config files) (default ~/.local/share/lives)
Definition: preferences.h:64
lives_param_t::def
void * def
default values
Definition: plugins.h:581
is_perchannel_multiw
boolean is_perchannel_multiw(weed_plant_t *param)
Definition: effects-weed.c:8693
FALSE
#define FALSE
Definition: videoplugin.h:60
WEED_LEAF_HOST_DEFAULT
#define WEED_LEAF_HOST_DEFAULT
Definition: effects-weed.h:62
init_special
void init_special(void)
Definition: paramspecial.c:30
lives_widget_set_size_request
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_size_request(LiVESWidget *widget, int width, int height)
Definition: widget-helper.c:1614
TEXTWIDGET_KEY
#define TEXTWIDGET_KEY
Definition: widget-helper.h:1492
weed_reinit_effect
lives_filter_error_t weed_reinit_effect(weed_plant_t *inst, boolean reinit_compound)
Definition: effects-weed.c:1169
LIVES_PARAM_BOOL
@ LIVES_PARAM_BOOL
Definition: plugins.h:503
add_aspect_ratio_button
const lives_special_aspect_t * add_aspect_ratio_button(LiVESSpinButton *sp_width, LiVESSpinButton *sp_height, LiVESBox *box)
Definition: interface.c:4963
mt_idle_add
uint32_t mt_idle_add(lives_mt *mt)
Definition: multitrack.c:901
_
#define _(String)
Definition: support.h:44
lives_param_t::group
int group
Definition: plugins.h:572
STYLE_1
#define STYLE_1
turn on theming if set
Definition: mainwindow.h:299
lives_widget_set_tooltip_text
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_set_tooltip_text(LiVESWidget *widget, const char *tip_text)
Definition: widget-helper.c:4641
mainwindow::error
boolean error
Definition: mainwindow.h:801
POLY_NONE
@ POLY_NONE
Definition: multitrack.h:122
lives_param_t::use_mnemonic
boolean use_mnemonic
Definition: plugins.h:545
LIVES_PARAM_STRING_LIST
@ LIVES_PARAM_STRING_LIST
Definition: plugins.h:506
rec_param_change
void rec_param_change(weed_plant_t *inst, int pnum)
record a parameter value change in our event_list
Definition: effects-weed.c:9000
lives_widget_apply_theme2
void lives_widget_apply_theme2(LiVESWidget *widget, LiVESWidgetState state, boolean set_fg)
Definition: widget-helper.c:11169
lives_param_t::type
lives_param_type_t type
Definition: plugins.h:573
_merge_opts::loop_to_fit
boolean loop_to_fit
Definition: mainwindow.h:1829
SCR_WIDTH_SAFETY
#define SCR_WIDTH_SAFETY
sepwin/screen size safety margins in pixels
Definition: mainwindow.h:89
lives_strncmp
LIVES_GLOBAL_INLINE boolean lives_strncmp(const char *st1, const char *st2, size_t len)
returns FALSE if strings match
Definition: machinestate.c:1554
lives_rfx_t::min_frames
int min_frames
for Weed, 1
Definition: plugins.h:629
lives_standard_radio_button_new
LiVESWidget * lives_standard_radio_button_new(const char *labeltext, LiVESSList **rbgroup, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9265
WIDGET_RB_DUMMY
#define WIDGET_RB_DUMMY
Definition: plugins.h:495
RFX_STATUS_CUSTOM
@ RFX_STATUS_CUSTOM
custom effects in the custom menu
Definition: plugins.h:613
lives_param_t::desc
char * desc
Definition: plugins.h:541
lives_box_pack_start
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_pack_start(LiVESBox *box, LiVESWidget *child, boolean expand, boolean fill, uint32_t padding)
Definition: widget-helper.c:3281
get_new_handle
boolean get_new_handle(int index, const char *name)
Definition: saveplay.c:3821
PARAM_NUMBER_KEY
#define PARAM_NUMBER_KEY
Definition: widget-helper.h:1494