LiVES  3.2.0
framedraw.c
Go to the documentation of this file.
1 // framedraw.c
2 // LiVES
3 // (c) G. Finch (salsaman+lives@gmail.com) 2002 - 2019
4 // see file COPYING for licensing details : released under the GNU GPL 3 or later
5 
6 // functions for the 'framedraw' widget - lets users draw on frames :-)
7 
8 #include "main.h"
9 #include "callbacks.h"
10 #include "interface.h"
11 #include "effects.h"
12 #include "cvirtual.h"
13 #include "framedraw.h"
14 
15 // set by mouse button press
16 static double xstart, ystart;
17 static double xcurrent, ycurrent;
18 static double xinit, yinit;
19 static volatile boolean b1_held;
20 
21 static volatile boolean noupdate = FALSE;
22 
23 static LiVESWidget *fbord_eventbox;
24 
25 
26 static double calc_fd_scale(int width, int height) {
27  double scale = 1.;
28 
29  if (width < MIN_PRE_X) {
30  width = MIN_PRE_X;
31  }
32  if (height < MIN_PRE_Y) {
33  height = MIN_PRE_Y;
34  }
35 
36  if (width > MAX_PRE_X) scale = (double)width / (double)MAX_PRE_X;
37  if (height > MAX_PRE_Y && (height / MAX_PRE_Y < scale)) scale = (double)height / (double)MAX_PRE_Y;
38  return scale;
39 }
40 
41 
48 
49  if (frame_draw->rfx->props & RFX_PROPS_MAY_RESIZE) return;
50 
53  lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton), cfile->start);
54  lives_range_set_value(LIVES_RANGE(mainw->framedraw_scale), cfile->start);
55  lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton), cfile->start, cfile->start);
56  mainw->framedraw_frame = cfile->start;
58 }
59 
60 
61 static void start_preview(LiVESButton *button, lives_rfx_t *rfx) {
62  int i;
63  char *com;
64 
65  if (fx_dialog[0]) {
66  if (fx_dialog[0]->okbutton) lives_widget_set_sensitive(fx_dialog[0]->okbutton, FALSE);
67  if (fx_dialog[0]->cancelbutton) lives_widget_set_sensitive(fx_dialog[0]->cancelbutton, FALSE);
68  }
69 
71  if (fx_dialog[0]) {
72  if (fx_dialog[0]->okbutton) lives_widget_set_sensitive(fx_dialog[0]->okbutton, TRUE);
73  if (fx_dialog[0]->cancelbutton) lives_widget_set_sensitive(fx_dialog[0]->cancelbutton, TRUE);
74  }
75  return;
76  }
77 
80 
81  if (mainw->did_rfx_preview) {
83 
84  if (cfile->start == 0) {
85  cfile->start = 1;
86  cfile->end = cfile->frames;
87  }
88 
89  do_rfx_cleanup(rfx);
90  }
91 
92  com = lives_strdup_printf("%s clear_pre_files \"%s\" 2>%s", prefs->backend_sync, cfile->handle, LIVES_DEVNULL);
93  lives_system(com, TRUE); // clear any .pre files from before
94 
95  for (i = 0; i < rfx->num_params; i++) {
96  rfx->params[i].changed = FALSE;
97  }
98 
100  mainw->error = FALSE;
101 
102  if (rfx->num_in_channels == 0) {
103  // reset values to specified
104  cfile->hsize = cfile->ohsize;
105  cfile->vsize = cfile->ovsize;
106  cfile->fps = cfile->pb_fps;
107  }
108 
109  // within do_effect() we check and if
110  do_effect(rfx, TRUE); // actually start effect processing in the background
111  load_rfx_preview(rfx);
112 
115  if (fx_dialog[0]) {
116  if (fx_dialog[0]->okbutton) lives_widget_set_sensitive(fx_dialog[0]->okbutton, TRUE);
117  if (fx_dialog[0]->cancelbutton) lives_widget_set_sensitive(fx_dialog[0]->cancelbutton, TRUE);
118  }
119  lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton), cfile->start, cfile->start + 1);
121 }
122 
123 
124 static void framedraw_redraw_cb(LiVESWidget *widget, lives_special_framedraw_rect_t *framedraw) {
125  if (mainw->multitrack) return;
126  framedraw_redraw(framedraw, mainw->fd_layer_orig);
127 }
128 
129 
130 static void after_framedraw_frame_spinbutton_changed(LiVESSpinButton *spinbutton, lives_special_framedraw_rect_t *framedraw) {
131  // update the single frame/framedraw preview
132  // after the "frame number" spinbutton has changed
134  if (fx_dialog[0]) {
135  if (fx_dialog[0]->okbutton) lives_widget_set_sensitive(fx_dialog[0]->okbutton, FALSE);
136  if (fx_dialog[0]->cancelbutton) lives_widget_set_sensitive(fx_dialog[0]->cancelbutton, FALSE);
137  }
139  if (!(framedraw->rfx->props & RFX_PROPS_MAY_RESIZE)) {
141  //lives_widget_context_update();
142  load_rfx_preview(framedraw->rfx);
143  } else framedraw_redraw(framedraw, NULL);
144  if (fx_dialog[0]) {
145  if (fx_dialog[0]->okbutton) lives_widget_set_sensitive(fx_dialog[0]->okbutton, TRUE);
146  if (fx_dialog[0]->cancelbutton) lives_widget_set_sensitive(fx_dialog[0]->cancelbutton, TRUE);
147  }
149 }
150 
151 
153  framedraw->rfx = rfx;
154 
155  mainw->fd_spin_func = lives_signal_connect_after(LIVES_GUI_OBJECT(mainw->framedraw_spinbutton),
156  LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
157  LIVES_GUI_CALLBACK(after_framedraw_frame_spinbutton_changed), framedraw);
158  lives_signal_connect_after(LIVES_GUI_OBJECT(mainw->framedraw_opscale), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
159  LIVES_GUI_CALLBACK(framedraw_redraw_cb), framedraw);
160  lives_signal_connect(LIVES_GUI_OBJECT(mainw->framedraw_cbutton), LIVES_WIDGET_COLOR_SET_SIGNAL,
161  LIVES_GUI_CALLBACK(framedraw_redraw_cb), framedraw);
162 }
163 
164 
165 void framedraw_connect(lives_special_framedraw_rect_t *framedraw, int width, int height, lives_rfx_t *rfx) {
166  // add mouse fn's so we can draw on frames
167  lives_signal_connect(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_MOTION_NOTIFY_EVENT,
168  LIVES_GUI_CALLBACK(on_framedraw_mouse_update), framedraw);
169  lives_signal_connect(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_BUTTON_RELEASE_EVENT,
170  LIVES_GUI_CALLBACK(on_framedraw_mouse_reset), framedraw);
171  lives_signal_connect(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_BUTTON_PRESS_EVENT,
172  LIVES_GUI_CALLBACK(on_framedraw_mouse_start), framedraw);
173  lives_signal_connect(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_ENTER_EVENT,
174  LIVES_GUI_CALLBACK(on_framedraw_enter), framedraw);
175  lives_signal_connect(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_LEAVE_NOTIFY_EVENT,
176  LIVES_GUI_CALLBACK(on_framedraw_leave), framedraw);
177  lives_signal_sync_connect(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_SCROLL_EVENT,
178  LIVES_GUI_CALLBACK(on_framedraw_scroll), NULL);
179 
180  framedraw_connect_spinbutton(framedraw, rfx);
181 
182  lives_widget_set_bg_color(mainw->fd_frame, LIVES_WIDGET_STATE_NORMAL, &palette->light_red);
183  lives_widget_set_bg_color(fbord_eventbox, LIVES_WIDGET_STATE_NORMAL, &palette->light_red);
184 
186 }
187 
188 
189 void framedraw_add_label(LiVESVBox *box) {
190  LiVESWidget *label;
191 
192  // TRANSLATORS - Preview refers to preview window; keep this phrase short
193  widget_opts.justify = LIVES_JUSTIFY_CENTER;
194  label = lives_standard_label_new(_("You can click in Preview to change these values"));
195  lives_box_pack_start(LIVES_BOX(box), label, FALSE, FALSE, widget_opts.packing_height / 2.);
197 }
198 
199 
200 void framedraw_add_reset(LiVESVBox *box, lives_special_framedraw_rect_t *framedraw) {
201  LiVESWidget *hbox_rst;
202 
203  framedraw_add_label(box);
204 
205  mainw->framedraw_reset = lives_standard_button_new_from_stock(LIVES_STOCK_REFRESH, NULL,
207  hbox_rst = lives_hbox_new(FALSE, 0);
208  lives_box_pack_start(LIVES_BOX(box), hbox_rst, FALSE, FALSE, 4. * widget_opts.scale);
209 
210  lives_button_set_label(LIVES_BUTTON(mainw->framedraw_reset), _("_Reset Values"));
211  lives_box_pack_start(LIVES_BOX(hbox_rst), mainw->framedraw_reset, TRUE, FALSE, 0);
213 
214  lives_signal_connect(mainw->framedraw_reset, LIVES_WIDGET_CLICKED_SIGNAL, LIVES_GUI_CALLBACK(on_framedraw_reset_clicked),
215  framedraw);
216 }
217 
218 
219 static void redraw_framedraw_image(weed_layer_t *layer) {
220  // layer should be mainw->fd_frame
221  // size layer, convert palette
222  // then draw it in mainw->fd_surface
223  // changes 'layer' itself
224 
225  lives_painter_t *cr, *cr2;
226  LiVESWidget *fd_widget;
227 
228  int fd_width, fd_height;
229  int width, height, cx, cy;
230 
231  if (!layer) return;
232 
233  if (!CURRENT_CLIP_IS_VALID) return;
234 
235  if (mainw->multitrack) fd_widget = mainw->multitrack->preview_eventbox;
236  else fd_widget = mainw->framedraw;
237 
238  if (!LIVES_IS_WIDGET(fd_widget)) return;
239 
240  fd_width = lives_widget_get_allocation_width(fd_widget);
241  fd_height = lives_widget_get_allocation_height(fd_widget);
242 
243  width = cfile->hsize;
244  height = cfile->vsize;
245 
247  calc_maxspect(fd_width, fd_height, &width, &height);
248 
249  // resize to correct size
250  resize_layer(layer, width, height, LIVES_INTERP_BEST,
251  LIVES_PAINTER_COLOR_PALETTE(capable->byte_order), 0);
252 
254 
255  cr = layer_to_lives_painter(layer);
256 
257  cx = (fd_width - width) / 2;
258  cy = (fd_height - height) / 2;
259 
261  lives_painter_rectangle(cr2, cx, cy, width, height);
262  lives_painter_fill(cr2);
264 
265  lives_painter_to_layer(cr, layer);
266  lives_widget_queue_draw(fd_widget);
267 }
268 
269 
270 static boolean expose_fd_event(LiVESWidget *widget, lives_painter_t *cr, livespointer user_data) {
271  if (!LIVES_IS_WIDGET(widget)) return TRUE;
272  //redraw_framedraw_image(mainw->fd_layer, cr);
275  return TRUE;
276 }
277 
278 
279 void widget_add_framedraw(LiVESVBox *box, int start, int end, boolean add_preview_button, int width, int height,
280  lives_rfx_t *rfx) {
281  // adds the frame draw widget to box
282  // the redraw button should be connected to an appropriate redraw function
283  // after calling this function
284 
285  LiVESAdjustment *spinbutton_adj;
286 
287  LiVESWidget *vseparator;
288  LiVESWidget *vbox;
289  LiVESWidget *hbox;
290  LiVESWidget *label;
291  LiVESWidget *cbutton;
292  LiVESWidget *frame;
293  lives_colRGBA64_t opcol;
294 
295  double fd_scale;
296 
297  b1_held = FALSE;
298 
299  mainw->framedraw_reset = NULL;
300 
301  vseparator = lives_vseparator_new();
302  lives_box_pack_start(LIVES_BOX(lives_widget_get_parent(LIVES_WIDGET(box))), vseparator, FALSE, FALSE, 0);
303  lives_widget_show(vseparator);
304 
305  vbox = lives_vbox_new(FALSE, 0);
306  lives_box_pack_start(LIVES_BOX(lives_widget_get_parent(LIVES_WIDGET(box))), vbox, FALSE, FALSE, 0);
308 
309  fd_scale = calc_fd_scale(width, height);
310  width /= fd_scale;
311  height /= fd_scale;
312 
313  hbox = lives_hbox_new(FALSE, 0);
314  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, 0);
315 
316  fbord_eventbox = lives_event_box_new();
317  lives_container_set_border_width(LIVES_CONTAINER(fbord_eventbox), widget_opts.border_width);
318 
319  frame = lives_standard_frame_new(_("Preview"), 0., TRUE);
320 
321  lives_box_pack_start(LIVES_BOX(hbox), frame, TRUE, TRUE, 0);
322 
323  mainw->fd_frame = frame;
324 
325  hbox = lives_hbox_new(FALSE, 0);
326  lives_container_set_border_width(LIVES_CONTAINER(hbox), 0);
327  lives_container_add(LIVES_CONTAINER(frame), hbox);
328 
329  if (palette->style & STYLE_1) {
330  lives_widget_set_bg_color(frame, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
331  lives_widget_set_bg_color(hbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
332  }
333 
334  //mainw->framedraw = lives_event_box_new();
335  mainw->framedraw = lives_standard_drawing_area_new(LIVES_GUI_CALLBACK(expose_fd_event),
336  &mainw->fd_surface);
338 
339  if (palette->style & STYLE_1) {
340  lives_widget_set_bg_color(hbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
341  }
342 
343  lives_widget_set_events(mainw->framedraw, LIVES_BUTTON1_MOTION_MASK | LIVES_BUTTON_RELEASE_MASK |
344  LIVES_BUTTON_PRESS_MASK | LIVES_ENTER_NOTIFY_MASK | LIVES_LEAVE_NOTIFY_MASK);
345 
346  mainw->framedraw_frame = start;
347 
348  lives_box_pack_start(LIVES_BOX(hbox), fbord_eventbox, FALSE, FALSE, 0);
349 
350  lives_container_add(LIVES_CONTAINER(fbord_eventbox), mainw->framedraw);
351 
352  if (palette->style & STYLE_1) {
353  lives_widget_set_bg_color(mainw->framedraw, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
354  lives_widget_set_fg_color(mainw->framedraw, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
355  }
356 
357  /* if (mainw->multitrack == NULL) */
358  /* lives_signal_connect_after(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_EXPOSE_EVENT, */
359  /* LIVES_GUI_CALLBACK(expose_fd_event), NULL); */
360 
361  // mask colour and opacity controls
364  label = lives_standard_label_new(_("Mask: opacity"));
366  spinbutton_adj = lives_adjustment_new(DEF_MASK_OPACITY, 0.0, 1.0, 0.1, 0.1, 0);
367  mainw->framedraw_opscale = lives_standard_hscale_new(LIVES_ADJUSTMENT(spinbutton_adj));
369  opcol = lives_rgba_col_new(0, 0, 0, 65535);
370  cbutton = lives_standard_color_button_new(LIVES_BOX(mainw->framedraw_maskbox), _("color"),
371  FALSE, &opcol, NULL, NULL, NULL, NULL);
372  mainw->framedraw_cbutton = cbutton;
373 
374  hbox = lives_hbox_new(FALSE, 2);
375  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
376 
378  start, start, end, 1., 10., 0, LIVES_BOX(hbox), NULL);
379 
380  spinbutton_adj = lives_spin_button_get_adjustment(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton));
381 
382  mainw->framedraw_preview = lives_standard_button_new_from_stock(LIVES_STOCK_REFRESH, _("Preview"),
384 
385  lives_box_pack_start(LIVES_BOX(hbox), mainw->framedraw_preview, TRUE, FALSE, 0);
387 
388  hbox = lives_hbox_new(FALSE, 2);
389  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
390 
391  mainw->framedraw_scale = lives_standard_hscale_new(LIVES_ADJUSTMENT(spinbutton_adj));
392  if (palette->style & STYLE_1) {
393  lives_widget_set_fg_color(mainw->framedraw_scale, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
394  }
396  if (!(rfx->props & RFX_PROPS_MAY_RESIZE)) {
397  gtk_range_set_show_fill_level(GTK_RANGE(mainw->framedraw_scale), TRUE);
398  gtk_range_set_restrict_to_fill_level(GTK_RANGE(mainw->framedraw_scale), TRUE);
399  gtk_range_set_fill_level(GTK_RANGE(mainw->framedraw_scale), end > start ? (double)start + 1. :
400  (double)start);
403  }
404  lives_signal_connect(mainw->framedraw_preview, LIVES_WIDGET_CLICKED_SIGNAL, LIVES_GUI_CALLBACK(start_preview), rfx);
405 
406  lives_widget_show_all(vbox);
407 
408  if (add_preview_button) {
411  }
412 
414 
415  if (start == 0) {
416  mainw->fd_max_frame = 1;
417  } else {
418  mainw->fd_max_frame = start;
419  }
420 }
421 
422 
424  // overlay framedrawing on a layer
425  // if layer is NULL then we reload the frame from current file into mainw->fd_layer_orig
426  // if called from multitrack then the preview layer is passed in via mt_framedraw()
427  // for overlaying we pass in mainw->fd_layer_orig again
428  // from c.e, layer is mainw->fd_orig_layer
429  //
430  // the input layer is copied: (mainw->fd_layer_orig -> mainw->fd_layer)
431  // mainw->fd_layer is drawn over, resized, gamma corrected and painted
432  // the output layer is also returned (mainw->fd_layer)
433 
434  lives_painter_t *cr;
435  LiVESWidget *fd_widget;
436 
437  double xstartf, ystartf, xendf, yendf;
438 
439  int fd_height;
440  int fd_width;
441  int width, height;
442 
443  if (!CURRENT_CLIP_IS_VALID) return NULL;
444 
445  if (framedraw->rfx->source_type == LIVES_RFX_SOURCE_RFX)
446  if (noupdate) return NULL; // static volatile
447 
448  if (mainw->multitrack) fd_widget = mainw->multitrack->preview_eventbox;
449  else fd_widget = mainw->framedraw;
450  if (!LIVES_IS_WIDGET(fd_widget)) return NULL;
451 
452  fd_width = lives_widget_get_allocation_width(fd_widget);
453  fd_height = lives_widget_get_allocation_height(fd_widget);
454 
455  if (fd_width < 4 || fd_height < 4) return NULL;
456 
457  width = cfile->hsize;
458  height = cfile->vsize;
459 
461  calc_maxspect(fd_width, fd_height, &width, &height);
462 
463  // copy from orig, resize
464 
465  if (!layer) {
466  // forced reload: get frame from clip, and set in mainw->fd_layer_orig
467  const char *img_ext;
468  if (framedraw->rfx->num_in_channels > 0 && !(framedraw->rfx->props & RFX_PROPS_MAY_RESIZE)) {
469  img_ext = LIVES_FILE_EXT_PRE;
470  } else {
471  img_ext = get_image_ext_for_type(cfile->img_type);
472  }
473 
475  if (!pull_frame(layer, img_ext, 0)) {
476  weed_plant_free(layer);
477  return NULL;
478  }
480  mainw->fd_layer_orig = layer;
481  } else {
482  if (mainw->fd_layer_orig && mainw->fd_layer_orig != layer) {
484  mainw->fd_layer_orig = layer;
485  }
486  }
487 
488  // copy orig layer to new layer
489  if (mainw->fd_layer) {
491  mainw->fd_layer = NULL;
492  }
493 
494  mainw->fd_layer = weed_layer_copy(NULL, layer);
495 
496  // resize to correct size
497  resize_layer(mainw->fd_layer, width, height, LIVES_INTERP_BEST,
498  LIVES_PAINTER_COLOR_PALETTE(capable->byte_order), 0);
499 
501 
502  // draw on the lives_painter
503 
504  switch (framedraw->type) {
507  if (framedraw->xstart_param->dp == 0) {
508  xstartf = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]));
509  xstartf = xstartf / (double)cfile->hsize * (double)width;
510  } else {
511  xstartf = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]));
512  xstartf = xstartf * (double)width;
513  }
514 
515  if (framedraw->xend_param->dp == 0) {
516  xendf = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]));
517  xendf = xendf / (double)cfile->hsize * (double)width;
518  } else {
519  xendf = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]));
520  xendf = xendf * (double)width;
521  }
522 
523  if (framedraw->ystart_param->dp == 0) {
524  ystartf = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]));
525  ystartf = ystartf / (double)cfile->vsize * (double)height;
526  } else {
527  ystartf = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]));
528  ystartf = ystartf * (double)height;
529  }
530 
531  if (framedraw->yend_param->dp == 0) {
532  yendf = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]));
533  yendf = yendf / (double)cfile->vsize * (double)height;
534  } else {
535  yendf = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]));
536  yendf = yendf * (double)height;
537  }
538 
539  if (framedraw->type == LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT) {
540  lives_painter_set_source_rgb(cr, 1., 0., 0.); // TODO - make colour configurable
541  lives_painter_rectangle(cr, xstartf - 1., ystartf - 1., xendf, yendf);
543  } else {
544  if (b1_held) {
545  lives_painter_set_source_rgb(cr, 1., 0., 0.); // TODO - make colour configurable
546  lives_painter_rectangle(cr, xstartf - 1., ystartf - 1., xendf - xstartf + 2., yendf - ystartf + 2.);
548  }
549  // create a mask which is only opaque within the clipping area
550  LiVESWidgetColor maskcol;
551  double opacity = lives_range_get_value(LIVES_RANGE(mainw->framedraw_opscale));
552  lives_color_button_get_color(LIVES_COLOR_BUTTON(mainw->framedraw_cbutton), &maskcol);
553  lives_painter_rectangle(cr, 0, 0, width, height);
554  lives_painter_rectangle(cr, xstartf, ystartf, xendf - xstartf + 1., yendf - ystartf + 1.);
555  lives_painter_set_source_rgba(cr, LIVES_WIDGET_COLOR_SCALE(maskcol.red), LIVES_WIDGET_COLOR_SCALE(maskcol.green),
556  LIVES_WIDGET_COLOR_SCALE(maskcol.blue), opacity);
557  lives_painter_set_fill_rule(cr, LIVES_PAINTER_FILL_RULE_EVEN_ODD);
558  lives_painter_fill(cr);
559  }
560  break;
561 
564  if (framedraw->type == LIVES_PARAM_SPECIAL_TYPE_SINGLEPOINT) {
565  if (framedraw->xstart_param->dp == 0) {
566  xstartf = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]));
567  xstartf = xstartf / (double)cfile->hsize * (double)width;
568  } else {
569  xstartf = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]));
570  xstartf *= (double)width;
571  }
572 
573  if (framedraw->ystart_param->dp == 0) {
574  ystartf = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]));
575  ystartf = ystartf / (double)cfile->vsize * (double)height;
576  } else {
577  ystartf = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]));
578  ystartf *= (double)height;
579  }
580  } else {
581  if (b1_held) {
582  xstartf = xcurrent * (double)width;
583  ystartf = ycurrent * (double)height;
584  } else {
585  double xpos, ypos;
586  double scale = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->scale_param->widgets[0]));
587  if (scale == 0.) break;
588 
589  if (framedraw->xstart_param->dp > 0)
590  xpos = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]));
591  else
592  xpos = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]))
593  / (double)cfile->hsize;
594  if (framedraw->ystart_param->dp > 0)
595  ypos = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]));
596  else
597  ypos = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]))
598  / (double)cfile->vsize;
599 
600  xstartf = 0.5;
601  ystartf = 0.5;
602 
603  if (xpos - xstartf / scale < 0.) xstartf = xpos * scale;
604  else if (xpos + xstartf / scale > 1.) xstartf = 1. - (1. - xpos) * scale;
605  if (ypos - ystartf / scale < 0.) ystartf = ypos * scale;
606  else if (ypos + ystartf / scale > 1.) ystartf = 1. - (1. - ypos) * scale;
607  xstartf *= (double)width;
608  ystartf *= (double)height;
609  }
610  }
611 
612  // draw a crosshair
613  lives_painter_set_source_rgb(cr, 1., 0., 0.); // TODO - make colour configurable
614 
615  lives_painter_move_to(cr, xstartf, ystartf - CROSSHAIR_SIZE);
616  lives_painter_line_to(cr, xstartf, ystartf + CROSSHAIR_SIZE);
617 
619 
620  lives_painter_move_to(cr, xstartf - CROSSHAIR_SIZE, ystartf);
621  lives_painter_line_to(cr, xstartf + CROSSHAIR_SIZE, ystartf);
622 
624  break;
625 
626  default:
627  break;
628  }
629 
631 
632  if (!mainw->multitrack)
633  redraw_framedraw_image(mainw->fd_layer);
634  else {
635  LiVESPixbuf *pixbuf;
638  palette = WEED_PALETTE_RGBA32;
639  } else {
640  palette = WEED_PALETTE_RGB24;
641  }
642 
645  weed_layer_get_height(mainw->fd_layer_orig), LIVES_INTERP_BEST, palette, 0);
646 
648  pixbuf = layer_to_pixbuf(mainw->fd_layer, TRUE, TRUE);
651  mainw->fd_layer = NULL;
652  if (pixbuf) {
653  if (mainw->multitrack->frame_pixbuf != mainw->imframe) {
654  if (mainw->multitrack->frame_pixbuf) lives_widget_object_unref(mainw->multitrack->frame_pixbuf);
655  }
656  // set frame_pixbuf, this gets painted in in expose_event
657  mainw->multitrack->frame_pixbuf = pixbuf;
659  lives_widget_queue_draw(mainw->multitrack->preview_eventbox);
661  mainw->multitrack->frame_pixbuf = NULL;
662  }
663  }
664 
665  lives_widget_queue_draw(fd_widget);
666  // update the widget
667  return mainw->fd_layer;
668 }
669 
670 
672  // load a preview of an rfx (rendered effect) in clip editor
673  weed_layer_t *layer;
674  FILE *infofile = NULL;
675  lives_alarm_t alarm_handle;
676  ticks_t timeout;
677  int tot_frames = 0;
678  int retval;
679  int current_file = mainw->current_file;
680 
681  const char *img_ext;
682 
687  //lives_widget_context_update();
688  }
689 
690  if (mainw->framedraw_frame == 0) mainw->framedraw_frame = 1;
691 
693 
694  clear_mainw_msg();
695  THREADVAR(write_failed) = FALSE;
696 
697  if (cfile->clip_type == CLIP_TYPE_FILE && cfile->fx_frame_pump && !cfile->pumper) {
698  // pull frames in background
700  -1, "iiibV", mainw->current_file,
701  cfile->undo_start, cfile->undo_end, FALSE, NULL);
702  }
703 
704  if (mainw->cancelled) {
705  if (cfile->pumper) {
707  weed_plant_free(cfile->pumper);
708  cfile->pumper = NULL;
709  }
711  return;
712  }
713 
714  // get message from back end processor
715  alarm_handle = lives_alarm_set(LIVES_LONGER_TIMEOUT);
716  while ((timeout = lives_alarm_check(alarm_handle)) > 0 && !(infofile = fopen(cfile->info_file, "r")) && !mainw->cancelled) {
717  // wait until we get at least 1 frame
718  //lives_widget_context_update();
719  lives_nanosleep(1000);
720  sched_yield();
721  }
722  lives_alarm_clear(alarm_handle);
723 
724  if (!timeout) {
726  return;
727  }
728 
729  if (mainw->cancelled) {
730  if (infofile) fclose(infofile);
732  if (cfile->pumper) {
734  weed_plant_free(cfile->pumper);
735  cfile->pumper = NULL;
736  }
737  return;
738  }
739 
740  do {
741  retval = 0;
742  lives_fgets(mainw->msg, MAINW_MSG_SIZE, infofile);
743  if (THREADVAR(read_failed)) {
744  // TODO : should check fd
745  THREADVAR(read_failed) = 0;
746  retval = do_read_failed_error_s_with_retry(cfile->info_file, NULL);
747  }
748  } while (retval == LIVES_RESPONSE_RETRY);
749 
750  fclose(infofile);
751 
752  if (lives_strncmp(mainw->msg, "completed", 9)) {
753  if (rfx->num_in_channels > 0) {
754  mainw->fd_max_frame = atoi(mainw->msg);
755  tot_frames = cfile->end;
756  } else {
757  int numtok = get_token_count(mainw->msg, '|');
758  if (numtok > 4) {
759  char **array = lives_strsplit(mainw->msg, "|", numtok);
760  mainw->fd_max_frame = atoi(array[0]);
761  cfile->hsize = atoi(array[1]);
762  cfile->vsize = atoi(array[2]);
763  cfile->fps = cfile->pb_fps = strtod(array[3], NULL);
764  if (cfile->fps == 0) cfile->fps = cfile->pb_fps = prefs->default_fps;
765  tot_frames = atoi(array[4]);
766  lives_strfreev(array);
767  }
768  }
769  } else {
770  tot_frames = mainw->fd_max_frame = cfile->end;
771  }
772 
773  if (!(rfx->props & RFX_PROPS_MAY_RESIZE)) {
775 
776  if (mainw->fd_max_frame > 0) {
777  int maxlen = calc_spin_button_width(1., (double)tot_frames, 0);
778  lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton), cfile->start, tot_frames);
782  if (rfx->num_in_channels == 0) {
783  cfile->frames = tot_frames;
784  }
785 
786  if (!(rfx->props & RFX_PROPS_MAY_RESIZE)) {
787  gtk_range_set_fill_level(GTK_RANGE(mainw->framedraw_scale), (double)mainw->fd_max_frame);
791  mainw->current_file = current_file;
792  return;
793  // *INDENT-OFF*
794  }}}}
795  // *INDENT-ON*
796 
798  if (rfx->num_in_channels > 0 && !(rfx->props & RFX_PROPS_MAY_RESIZE)) {
799  img_ext = LIVES_FILE_EXT_PRE;
800  } else {
801  img_ext = get_image_ext_for_type(cfile->img_type);
802  }
803  if (!pull_frame(layer, img_ext, 0)) {
804  weed_plant_free(layer);
805  } else {
806  if (mainw->fd_layer_orig && mainw->fd_layer_orig != layer)
808  mainw->fd_layer_orig = layer;
811  redraw_framedraw_image(mainw->fd_layer);
812  }
813  mainw->current_file = current_file;
814 }
815 
816 
817 // change cursor maybe when we enter or leave the framedraw window
818 
819 boolean on_framedraw_enter(LiVESWidget * widget, LiVESXEventCrossing * event, lives_special_framedraw_rect_t *framedraw) {
820  if (!framedraw && mainw->multitrack) {
821  framedraw = mainw->multitrack->framedraw;
822  if (!framedraw && mainw->multitrack->cursor_style == LIVES_CURSOR_NORMAL)
824  }
825 
826  if (!framedraw) return FALSE;
827  if (mainw->multitrack && (mainw->multitrack->track_index == -1 ||
828  mainw->multitrack->cursor_style != LIVES_CURSOR_NORMAL)) return FALSE;
829 
830  switch (framedraw->type) {
833  if (!mainw->multitrack) {
835  } else {
837  }
838  break;
839 
842  if (!mainw->multitrack) {
844  } else {
846  }
847  break;
848 
849  default:
850  break;
851  }
852  return FALSE;
853 }
854 
855 boolean on_framedraw_leave(LiVESWidget * widget, LiVESXEventCrossing * event, lives_special_framedraw_rect_t *framedraw) {
856  LiVESWidget *fd_widget;
857  if (!framedraw) return FALSE;
858 
859  if (mainw->multitrack) fd_widget = mainw->multitrack->preview_eventbox;
860  else fd_widget = mainw->framedraw;
861 
862  if (!LIVES_IS_WIDGET(fd_widget)) return FALSE;
863 
865  return FALSE;
866 }
867 
868 
869 // using these 3 functions, the user can draw on frames
870 
871 boolean on_framedraw_mouse_start(LiVESWidget * widget, LiVESXEventButton * event, lives_special_framedraw_rect_t *framedraw) {
872  // user clicked in the framedraw widget (or multitrack playback widget)
873  double xend, yend;
874 
875  int fd_height;
876  int fd_width;
877 
878  int width = cfile->hsize;
879  int height = cfile->vsize;
880 
881  int xstarti, ystarti;
882 
883  if (!framedraw && mainw->multitrack) framedraw = mainw->multitrack->framedraw;
884 
885  if (!framedraw) return FALSE;
886  if (mainw->multitrack && mainw->multitrack->track_index == -1) return FALSE;
887 
888  if (!framedraw && mainw->multitrack && event->button == 3) {
889  // right click brings up context menu
890  frame_context(widget, event, LIVES_INT_TO_POINTER(0));
891  }
892 
893  if (event->button != 1) return FALSE;
894 
895  b1_held = TRUE;
896 
898  widget, &xstarti, &ystarti);
899  xstarti -= widget_opts.border_width;
900 
901  if ((framedraw->type == LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT ||
903  (!mainw->multitrack || mainw->multitrack->cursor_style == 0)) {
904  if (!mainw->multitrack) {
906  } else {
908  }
909  }
910 
911  fd_width = lives_widget_get_allocation_width(widget);
912  fd_height = lives_widget_get_allocation_height(widget);
913 
914  calc_maxspect(fd_width, fd_height, &width, &height);
915 
916  xstart = (double)xstarti - (double)(fd_width - width) / 2.;
917  ystart = (double)ystarti - (double)(fd_height - height) / 2.;
918 
919  xstart /= (double)(width - 1);
920  ystart /= (double)(height - 1);
921 
922  xend = xcurrent = xstart;
923  yend = ycurrent = ystart;
924 
925  noupdate = TRUE;
926 
927  switch (framedraw->type) {
929  // current center is xinit, yinit
930  // ystart, xstart equal cursor (crosshair posn.)
931 
932  if (framedraw->xstart_param->dp > 0)
933  xinit = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]));
934  else
935  xinit = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]))
936  / (double)cfile->hsize;
937  if (framedraw->ystart_param->dp > 0)
938  yinit = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]));
939  else
940  yinit = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]))
941  / (double)cfile->vsize;
942  }
943  break;
944 
946  xend = yend = 0.;
947 
949  if (framedraw->xstart_param->dp > 0)
950  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), xstart);
951  else
952  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]),
953  (int)(xstart * (double)cfile->hsize + .5));
954  if (framedraw->xstart_param->dp > 0)
955  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), ystart);
956  else
957  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]),
958  (int)(ystart * (double)cfile->vsize + .5));
959 
960  if (framedraw->xend_param->dp > 0)
961  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]), xend);
962  else
963  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]), (int)(xend * (double)cfile->hsize + .5));
964  if (framedraw->xend_param->dp > 0)
965  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]), yend);
966  else
967  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]), (int)(yend * (double)cfile->vsize + .5));
968 
969  break;
970 
971  default:
972  break;
973  }
974 
975  if (mainw->framedraw_reset) {
977  }
978  if (mainw->framedraw_preview) {
980  }
981 
982  noupdate = FALSE;
983 
984  framedraw_redraw(framedraw, mainw->fd_layer_orig);
985 
986  return FALSE;
987 }
988 
989 boolean on_framedraw_mouse_update(LiVESWidget * widget, LiVESXEventMotion * event, lives_special_framedraw_rect_t *framedraw) {
990  // pointer moved in the framedraw widget
991  int xcurrenti, ycurrenti;
992 
993  int fd_width, fd_height, width, height;
994 
995  if (noupdate) return FALSE;
996 
997  if (!b1_held) return FALSE;
998 
999  if (!framedraw && mainw->multitrack) framedraw = mainw->multitrack->framedraw;
1000  if (!framedraw) return FALSE;
1001  if (mainw->multitrack && mainw->multitrack->track_index == -1) return FALSE;
1002 
1004  widget, &xcurrenti, &ycurrenti);
1005  xcurrenti -= widget_opts.border_width;
1006 
1007  width = cfile->hsize;
1008  height = cfile->vsize;
1009 
1010  fd_width = lives_widget_get_allocation_width(widget);
1011  fd_height = lives_widget_get_allocation_height(widget);
1012 
1013  calc_maxspect(fd_width, fd_height, &width, &height);
1014 
1015  xcurrent = (double)xcurrenti - (fd_width - width) / 2.;
1016  ycurrent = (double)ycurrenti - (fd_height - height) / 2.;
1017 
1018  xcurrent /= (double)(width - 1);
1019  ycurrent /= (double)(height - 1);
1020 
1021  noupdate = TRUE;
1022 
1023  switch (framedraw->type) {
1025  // end parameters provide a scale relative to the output channel
1026  double xscale, yscale;
1027 
1028  xscale = xcurrent - xstart;
1029  yscale = ycurrent - ystart;
1030 
1031  if (xscale > 0.) {
1032  if (framedraw->xend_param->dp > 0)
1033  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]), xscale);
1034  else
1035  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]),
1036  (int)(xscale * (double)cfile->hsize + .5));
1037  } else {
1038  if (framedraw->xstart_param->dp > 0) {
1039  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]), -xscale);
1040  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), xcurrent);
1041  } else {
1042  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]),
1043  (int)(-xscale * (double)cfile->hsize - .5));
1044  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]),
1045  (int)(xcurrent * (double)cfile->hsize + .5));
1046  }
1047  }
1048 
1049  if (yscale > 0.) {
1050  if (framedraw->yend_param->dp > 0)
1051  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]), yscale);
1052  else
1053  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]),
1054  (int)(yscale * (double)cfile->vsize + .5));
1055  } else {
1056  if (framedraw->xstart_param->dp > 0) {
1057  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]), -yscale);
1058  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), ycurrent);
1059  } else {
1060  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]),
1061  (int)(-yscale * (double)cfile->vsize - .5));
1062  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]),
1063  (int)(ycurrent * (double)cfile->vsize + .5));
1064  }
1065  }
1066  }
1067  break;
1068 
1070  // end parameters provide the absolute point, in output channel ratio
1071  if (xcurrent > xstart) {
1072  if (framedraw->xend_param->dp > 0)
1073  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]), xcurrent);
1074  else
1075  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]),
1076  (int)(xcurrent * (double)cfile->hsize + .5));
1077  } else {
1078  if (framedraw->xstart_param->dp > 0) {
1079  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]), xstart);
1080  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), xcurrent);
1081  } else {
1082  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]),
1083  (int)(xstart * (double)cfile->hsize + .5));
1084  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]),
1085  (int)(xcurrent * (double)cfile->hsize + .5));
1086  }
1087  }
1088 
1089  if (ycurrent > ystart) {
1090  if (framedraw->yend_param->dp > 0)
1091  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]), ycurrent);
1092  else
1093  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]),
1094  (int)(ycurrent * (double)cfile->vsize + .5));
1095  } else {
1096  if (framedraw->xstart_param->dp > 0) {
1097  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]), ystart);
1098  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), ycurrent);
1099  } else {
1100  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]),
1101  (int)(ystart * (double)cfile->vsize + .5));
1102  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]),
1103  (int)(ycurrent * (double)cfile->vsize + .5));
1104  }
1105  }
1106  break;
1107 
1109  // current center is xinit, yinit
1110  // ystart, xstart equal cursor (crosshair posn.)
1111  double offs_x, offs_y;
1112  double scale = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->scale_param->widgets[0]));
1113  if (scale == 0.) break;
1114  offs_x = (xstart - xcurrent) / scale;
1115  offs_y = (ystart - ycurrent) / scale;
1116 
1117  if (xinit + offs_x < .5 / scale) offs_x = .5 / scale - xinit;
1118  if (xinit + offs_x > 1. - .5 / scale) offs_x = 1. - .5 / scale - xinit;
1119  if (yinit + offs_y < .5 / scale) offs_y = .5 / scale - yinit;
1120  if (yinit + offs_y > 1. - .5 / scale) offs_y = 1. - .5 / scale - yinit;
1121 
1122  if (framedraw->xstart_param->dp > 0)
1123  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), xinit + offs_x);
1124  else
1125  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), (int)((xinit + offs_x)
1126  * (double)cfile->hsize + .5));
1127  if (framedraw->xstart_param->dp > 0)
1128  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), yinit + offs_y);
1129  else
1130  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), (int)((yinit + offs_y)
1131  * (double)cfile->vsize + .5));
1132  }
1133  break;
1134 
1135  default:
1136  break;
1137  }
1138 
1139 #if !GTK_CHECK_VERSION(3, 0, 0)
1141 #endif
1142 
1143  if (mainw->framedraw_reset) {
1145  }
1146  if (mainw->framedraw_preview) {
1148  }
1149 
1150  noupdate = FALSE;
1151  framedraw_redraw(framedraw, mainw->fd_layer_orig);
1152 
1153  return FALSE;
1154 }
1155 
1156 boolean on_framedraw_mouse_reset(LiVESWidget * widget, LiVESXEventButton * event, lives_special_framedraw_rect_t *framedraw) {
1157  // user released the mouse button in framedraw widget
1158  int xcurrenti, ycurrenti;
1159  int fd_width, fd_height, width, height;
1160 
1161  if (event->button != 1 || !b1_held) return FALSE;
1162 
1163  b1_held = FALSE;
1164 
1165  if (!framedraw && mainw->multitrack) framedraw = mainw->multitrack->framedraw;
1166  if (!framedraw) return FALSE;
1167  if (mainw->multitrack && mainw->multitrack->track_index == -1) return FALSE;
1168 
1170  widget, &xcurrenti, &ycurrenti);
1171  xcurrenti -= widget_opts.border_width;
1172 
1173  width = cfile->hsize;
1174  height = cfile->vsize;
1175 
1176  fd_width = lives_widget_get_allocation_width(widget);
1177  fd_height = lives_widget_get_allocation_height(widget);
1178 
1179  calc_maxspect(fd_width, fd_height, &width, &height);
1180 
1181  xcurrent = (double)xcurrenti - (fd_width - width) / 2.;
1182  ycurrent = (double)ycurrenti - (fd_height - height) / 2.;
1183 
1184  xcurrent /= (double)(width - 1);
1185  ycurrent /= (double)(height - 1);
1186 
1187  switch (framedraw->type) {
1190  if (!mainw->multitrack) {
1192  } else if (mainw->multitrack->cursor_style == 0) {
1194  }
1195  break;
1196 
1198  double offs_x, offs_y, scale, xend, yend;
1199  if (noupdate) break;
1200 
1201  scale = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->scale_param->widgets[0]));
1202  if (scale == 0.) break;
1203 
1204  if (framedraw->xstart_param->dp > 0)
1205  xend = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]));
1206  else
1207  xend = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]))
1208  / (double)cfile->hsize;
1209  if (framedraw->ystart_param->dp > 0)
1210  yend = lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]));
1211  else
1212  yend = (double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]))
1213  / (double)cfile->vsize;
1214 
1215  if (xend == xinit && yend == yinit && xcurrent == xstart && ycurrent == ystart) {
1218  xstart = 0.5;
1219  ystart = 0.5;
1220 
1221  if (xend - xstart / scale < 0.) xstart = xend * scale;
1222  else if (xend + xstart / scale > 1.) xstart = 1. - (1. - xend) * scale;
1223  if (yend - ystart / scale < 0.) ystart = yend * scale;
1224  else if (yend + ystart / scale > 1.) ystart = 1. - (1. - yend) * scale;
1225 
1226  offs_x = (xcurrent - xstart) / scale;
1227  offs_y = (ycurrent - ystart) / scale;
1228 
1229  if (framedraw->xstart_param->dp > 0)
1230  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), xend + offs_x);
1231  else
1232  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), (int)((xend + offs_x)
1233  * (double)cfile->hsize + .5));
1234  if (framedraw->xstart_param->dp > 0)
1235  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), yend + offs_y);
1236  else
1237  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), (int)((yend + offs_y)
1238  * cfile->vsize + .5));
1239  }
1240  }
1241  break;
1242 
1244  if (framedraw->xstart_param->dp > 0)
1245  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]), xstart);
1246  else
1247  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]),
1248  (int)(xstart * (double)cfile->hsize + .5));
1249  if (framedraw->xstart_param->dp > 0)
1250  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]), ystart);
1251  else
1252  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]),
1253  (int)(ystart * (double)cfile->vsize + .5));
1254  break;
1255 
1256  default:
1257  break;
1258  }
1259  framedraw_redraw(framedraw, mainw->fd_layer_orig);
1260  return FALSE;
1261 }
1262 
1263 boolean on_framedraw_scroll(LiVESWidget * widget, LiVESXEventScroll * event,
1264  lives_special_framedraw_rect_t *framedraw) {
1265  if (!framedraw && mainw->multitrack) framedraw = mainw->multitrack->framedraw;
1266  if (!framedraw) return FALSE;
1267  if (mainw->multitrack && mainw->multitrack->track_index == -1) return FALSE;
1268 
1269  if (framedraw->type == LIVES_PARAM_SPECIAL_TYPE_SCALEDPOINT) {
1270  LiVESSpinButton *spb = (LiVESSpinButton *)framedraw->scale_param->widgets[0];
1271  LiVESAdjustment *adj = lives_spin_button_get_adjustment(spb);
1272  double step = lives_adjustment_get_step_increment(adj);
1273  double scale = lives_spin_button_get_value(spb);
1274  if (lives_get_scroll_direction(event) == LIVES_SCROLL_UP) scale += step;
1275  if (lives_get_scroll_direction(event) == LIVES_SCROLL_DOWN) scale -= step;
1276  lives_spin_button_set_value(spb, scale);
1277  }
1278  return FALSE;
1279 }
1280 
1281 
1282 void after_framedraw_widget_changed(LiVESWidget * widget, lives_special_framedraw_rect_t *framedraw) {
1283  if (mainw->block_param_updates || noupdate) return;
1284 
1285  // redraw mask when spin values change
1286  framedraw_redraw(framedraw, mainw->fd_layer_orig);
1287  if (mainw->framedraw_reset) {
1289  }
1290  if (mainw->framedraw_preview) {
1292  }
1293 }
1294 
1295 
1296 void on_framedraw_reset_clicked(LiVESButton * button, lives_special_framedraw_rect_t *framedraw) {
1297  // reset to defaults
1298  if (fx_dialog[0]) {
1299  if (fx_dialog[0]->okbutton) lives_widget_set_sensitive(fx_dialog[0]->okbutton, FALSE);
1300  if (fx_dialog[0]->cancelbutton) lives_widget_set_sensitive(fx_dialog[0]->cancelbutton, FALSE);
1301  }
1302 
1303  noupdate = TRUE;
1304  if (framedraw->xend_param) {
1305  if (framedraw->xend_param->dp == 0)
1306  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]),
1307  (double)get_int_param(framedraw->xend_param->def));
1308  else
1309  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0]), get_double_param(framedraw->xend_param->def));
1310  }
1311  if (framedraw->yend_param) {
1312  if (framedraw->yend_param->dp == 0)
1313  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]),
1314  (double)get_int_param(framedraw->yend_param->def));
1315  else
1316  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0]), get_double_param(framedraw->yend_param->def));
1317  }
1318  if (framedraw->xstart_param) {
1319  if (framedraw->xstart_param->dp == 0)
1320  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]),
1321  (double)get_int_param(framedraw->xstart_param->def));
1322  else
1323  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0]),
1324  get_double_param(framedraw->xstart_param->def));
1325  }
1326  if (framedraw->ystart_param) {
1327  if (framedraw->ystart_param->dp == 0)
1328  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]),
1329  (double)get_int_param(framedraw->ystart_param->def));
1330  else
1331  lives_spin_button_set_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0]),
1332  get_double_param(framedraw->ystart_param->def));
1333  }
1334 
1335  if (mainw->framedraw_reset) {
1337  }
1338  if (mainw->framedraw_preview) {
1340  }
1341 
1342  // update widgets now
1343  //lives_widget_context_update();
1344 
1345  noupdate = FALSE;
1346 
1347  framedraw_redraw(framedraw, mainw->fd_layer_orig);
1348  if (fx_dialog[0]) {
1349  if (fx_dialog[0]->okbutton) lives_widget_set_sensitive(fx_dialog[0]->okbutton, TRUE);
1350  if (fx_dialog[0]->cancelbutton) lives_widget_set_sensitive(fx_dialog[0]->cancelbutton, TRUE);
1351  }
1352 }
lives_painter_line_to
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_line_to(lives_painter_t *cr, double x, double y)
Definition: widget-helper.c:533
mainwindow::framedraw_frame
int framedraw_frame
current displayed frame
Definition: mainwindow.h:1278
lives_painter_get_target
WIDGET_HELPER_GLOBAL_INLINE lives_painter_surface_t * lives_painter_get_target(lives_painter_t *cr)
Definition: widget-helper.c:711
widget_opts_t::packing_width
int packing_width
horizontal pixels between widgets
Definition: widget-helper.h:1410
clear_mainw_msg
void clear_mainw_msg(void)
Definition: utils.c:1435
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
lives_signal_connect
ulong lives_signal_connect(LiVESWidget *, const char *signal_name, ulong funcptr, livespointer data)
lives_color_button_get_color
WIDGET_HELPER_GLOBAL_INLINE LiVESWidgetColor * lives_color_button_get_color(LiVESColorButton *button, LiVESWidgetColor *color)
Definition: widget-helper.c:7077
framedraw_add_reset
void framedraw_add_reset(LiVESVBox *box, lives_special_framedraw_rect_t *framedraw)
add "reset values" button
Definition: framedraw.c:200
lives_special_framedraw_rect_t::yend_param
lives_param_t * yend_param
Definition: paramspecial.h:23
_palette::normal_back
LiVESWidgetColor normal_back
Definition: mainwindow.h:324
_palette::light_red
LiVESWidgetColor light_red
Definition: mainwindow.h:309
LIVES_CURSOR_NORMAL
@ LIVES_CURSOR_NORMAL
must be zero
Definition: widget-helper.h:1292
on_framedraw_scroll
boolean on_framedraw_scroll(LiVESWidget *widget, LiVESXEventScroll *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:1263
widget_opts_t::justify
LiVESJustification justify
justify for labels
Definition: widget-helper.h:1412
mainwindow::mgeom
lives_mgeometry_t * mgeom
multi-head support
Definition: mainwindow.h:1576
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
lives_set_cursor_style
void lives_set_cursor_style(lives_cursor_t cstyle, LiVESWidget *widget)
Definition: widget-helper.c:11950
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
clear_widget_bg
WIDGET_HELPER_GLOBAL_INLINE boolean clear_widget_bg(LiVESWidget *widget, lives_painter_surface_t *s)
Definition: widget-helper.c:11108
mainwindow::current_file
int current_file
Definition: mainwindow.h:727
LIVES_PARAM_SPECIAL_TYPE_SCALEDPOINT
@ LIVES_PARAM_SPECIAL_TYPE_SCALEDPOINT
type may be used in framedraw
Definition: plugins.h:525
framedraw_add_label
void framedraw_add_label(LiVESVBox *box)
add explanatory label
Definition: framedraw.c:189
MIN_PRE_Y
#define MIN_PRE_Y
Definition: framedraw.h:11
MAX_PRE_Y
#define MAX_PRE_Y
Definition: framedraw.h:14
_palette::style
int style
Definition: mainwindow.h:297
cfile
#define cfile
Definition: main.h:1833
lives_painter_set_source_rgb
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_source_rgb(lives_painter_t *cr, double red, double green, double blue)
Definition: widget-helper.c:604
lives_widget_hide
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
Definition: widget-helper.c:1514
effects.h
weed_layer_get_width
LIVES_GLOBAL_INLINE int weed_layer_get_width(weed_layer_t *layer)
Definition: colourspace.c:13941
lives_painter_set_fill_rule
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_fill_rule(lives_painter_t *cr, lives_painter_fill_rule_t fill_rule)
Definition: widget-helper.c:635
_palette::normal_fore
LiVESWidgetColor normal_fore
Definition: mainwindow.h:325
lives_rfx_t::params
lives_param_t * params
Definition: plugins.h:649
LIVES_JUSTIFY_DEFAULT
#define LIVES_JUSTIFY_DEFAULT
Definition: widget-helper.h:1289
framedraw_connect_spinbutton
void framedraw_connect_spinbutton(lives_special_framedraw_rect_t *framedraw, lives_rfx_t *rfx)
connect spinbutton to preview
Definition: framedraw.c:152
cvirtual.h
lives_special_framedraw_rect_t::rfx
lives_rfx_t * rfx
Definition: paramspecial.h:16
prefs
_prefs * prefs
Definition: preferences.h:847
after_framedraw_widget_changed
void after_framedraw_widget_changed(LiVESWidget *widget, lives_special_framedraw_rect_t *framedraw)
callback for widgets
Definition: framedraw.c:1282
virtual_to_images
frames_t virtual_to_images(int sfileno, frames_t sframe, frames_t eframe, boolean update_progress, LiVESPixbuf **pbr)
Definition: cvirtual.c:719
invalidate_preview
void invalidate_preview(lives_special_framedraw_rect_t *frame_draw)
Definition: framedraw.c:42
do_read_failed_error_s_with_retry
LiVESResponseType do_read_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4122
mainwindow::framedraw_cbutton
LiVESWidget * framedraw_cbutton
colour for mask
Definition: mainwindow.h:1270
LIVES_LONGER_TIMEOUT
#define LIVES_LONGER_TIMEOUT
Definition: mainwindow.h:44
lives_spin_button_get_adjustment
WIDGET_HELPER_GLOBAL_INLINE LiVESAdjustment * lives_spin_button_get_adjustment(LiVESSpinButton *button)
Definition: widget-helper.c:5099
lives_alarm_clear
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
_prefs::backend_sync
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
MIN_PRE_X
#define MIN_PRE_X
Definition: framedraw.h:10
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
mainwindow::framedraw_maskbox
LiVESWidget * framedraw_maskbox
box for opacity controls
Definition: mainwindow.h:1268
weed_layer_get_height
LIVES_GLOBAL_INLINE int weed_layer_get_height(weed_layer_t *layer)
Definition: colourspace.c:13953
get_token_count
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
fx_dialog
_fx_dialog * fx_dialog[2]
Definition: mainwindow.h:1851
LIVES_RFX_SOURCE_RFX
@ LIVES_RFX_SOURCE_RFX
Definition: plugins.h:513
mainwindow::imframe
LiVESPixbuf * imframe
Definition: mainwindow.h:1102
lives_widget_queue_draw
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw(LiVESWidget *widget)
Definition: widget-helper.c:1580
get_int_param
int get_int_param(void *value)
Definition: plugins.c:3079
weed_layer_nullify_pixel_data
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_nullify_pixel_data(weed_layer_t *layer)
Definition: colourspace.c:9753
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
lives_alarm_t
int lives_alarm_t
Definition: mainwindow.h:696
lives_nanosleep
#define lives_nanosleep(nanosec)
Definition: machinestate.h:307
lives_container_set_border_width
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_set_border_width(LiVESContainer *container, uint32_t width)
Definition: widget-helper.c:4947
ticks_t
int64_t ticks_t
Definition: main.h:97
lives_painter_set_source_surface
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_source_surface(lives_painter_t *cr, lives_painter_surface_t *surface, double x, double y)
Definition: widget-helper.c:339
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
TRUE
#define TRUE
Definition: videoplugin.h:59
lives_rfx_t::num_in_channels
int num_in_channels
Definition: plugins.h:630
on_framedraw_mouse_reset
boolean on_framedraw_mouse_reset(LiVESWidget *widget, LiVESXEventButton *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:1156
LIVES_PARAM_SPECIAL_TYPE_SINGLEPOINT
@ LIVES_PARAM_SPECIAL_TYPE_SINGLEPOINT
type may be used in framedraw
Definition: plugins.h:524
mainwindow::fd_layer_orig
weed_plant_t * fd_layer_orig
original layer uneffected
Definition: mainwindow.h:1275
LIVES_PARAM_SPECIAL_TYPE_RECT_DEMASK
@ LIVES_PARAM_SPECIAL_TYPE_RECT_DEMASK
type may be used in framedraw
Definition: plugins.h:522
_prefs::default_fps
double default_fps
Definition: preferences.h:173
mainwindow::fd_spin_func
ulong fd_spin_func
spinbutton for framedraw previews
Definition: mainwindow.h:1281
THREADVAR
#define THREADVAR(var)
Definition: machinestate.h:531
do_effect
boolean do_effect(lives_rfx_t *rfx, boolean is_preview)
defined as extern in paramwindow.c
Definition: effects.c:127
lives_rfx_t
Definition: plugins.h:625
mainwindow::cancelled
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
calc_spin_button_width
size_t calc_spin_button_width(double min, double max, int dp)
Definition: widget-helper.c:9384
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
on_framedraw_leave
boolean on_framedraw_leave(LiVESWidget *widget, LiVESXEventCrossing *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:855
callbacks.h
lives_painter_paint
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_paint(lives_painter_t *cr)
Definition: widget-helper.c:355
capable
capability * capable
Definition: main.h:627
lives_proc_thread_create
lives_proc_thread_t lives_proc_thread_create(lives_thread_attr_t attr, lives_funcptr_t func, int return_type, const char *args_fmt,...)
create the specific plant which defines a background task to be run
Definition: machinestate.c:1730
pull_frame
LIVES_GLOBAL_INLINE boolean pull_frame(weed_layer_t *layer, const char *image_ext, weed_timecode_t tc)
pull a frame from an external source into a layer the WEED_LEAF_CLIP and WEED_LEAF_FRAME leaves must ...
Definition: main.c:7500
CROSSHAIR_SIZE
#define CROSSHAIR_SIZE
pixel size for crosshair "arms"
Definition: framedraw.h:19
lives_rfx_t::props
uint32_t props
Definition: plugins.h:633
lives_special_framedraw_rect_t::scale_param
lives_param_t * scale_param
Definition: paramspecial.h:21
lives_painter_create_from_surface
WIDGET_HELPER_GLOBAL_INLINE lives_painter_t * lives_painter_create_from_surface(lives_painter_surface_t *target)
Definition: widget-helper.c:309
lives_painter_move_to
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_move_to(lives_painter_t *cr, double x, double y)
Definition: widget-helper.c:520
lives_adjustment_new
WIDGET_HELPER_GLOBAL_INLINE LiVESAdjustment * lives_adjustment_new(double value, double lower, double upper, double step_increment, double page_increment, double page_size)
Definition: widget-helper.c:3196
weed_layer_get_palette
LIVES_GLOBAL_INLINE int weed_layer_get_palette(weed_layer_t *layer)
Definition: colourspace.c:13977
lives_rfx_t::num_params
int num_params
Definition: plugins.h:644
mainwindow::play_image
LiVESWidget * play_image
Definition: mainwindow.h:946
mainwindow::msg
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
CLIP_TYPE_FILE
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
Definition: main.h:765
lives_spin_button_get_value
WIDGET_HELPER_GLOBAL_INLINE double lives_spin_button_get_value(LiVESSpinButton *button)
Definition: widget-helper.c:5083
on_framedraw_reset_clicked
void on_framedraw_reset_clicked(LiVESButton *button, lives_special_framedraw_rect_t *framedraw)
reset button
Definition: framedraw.c:1296
lives_standard_label_new
LiVESWidget * lives_standard_label_new(const char *text)
Definition: widget-helper.c:8601
interface.h
mainwindow::framedraw_opscale
LiVESWidget * framedraw_opscale
opacity
Definition: mainwindow.h:1269
lives_vbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_vbox_new(boolean homogeneous, int spacing)
Definition: widget-helper.c:3267
framedraw_redraw
weed_plant_t * framedraw_redraw(lives_special_framedraw_rect_t *framedraw, weed_layer_t *layer)
redraw when exposed/frame number changes
Definition: framedraw.c:423
lives_fgets
char * lives_fgets(char *s, int size, FILE *stream)
Definition: utils.c:368
lives_widget_get_parent
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_parent(LiVESWidget *widget)
Definition: widget-helper.c:4739
widget_opts_t::border_width
int border_width
border width in pixels
Definition: widget-helper.h:1416
lives_special_framedraw_rect_t::xend_param
lives_param_t * xend_param
Definition: paramspecial.h:22
get_double_param
double get_double_param(void *value)
Definition: plugins.c:3086
load_rfx_preview
void load_rfx_preview(lives_rfx_t *rfx)
rfx preview
Definition: framedraw.c:671
lives_widget_get_allocation_height
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_height(LiVESWidget *widget)
Definition: widget-helper.c:5470
widget_opts_t::monitor
int monitor
monitor we are displaying on
Definition: widget-helper.h:1437
CANCEL_NONE
@ CANCEL_NONE
no cancel
Definition: main.h:701
weed_palette_has_alpha
LIVES_GLOBAL_INLINE boolean weed_palette_has_alpha(int pal)
Definition: colourspace.c:1466
mainwindow::fd_max_frame
int fd_max_frame
max effected / generated frame
Definition: mainwindow.h:1279
mainwindow::fd_surface
lives_painter_surface_t * fd_surface
Definition: mainwindow.h:1273
LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT
@ LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT
type may be used in framedraw
Definition: plugins.h:523
widget_opts_t::packing_height
int packing_height
vertical pixels between widgets
Definition: widget-helper.h:1411
lives_range_get_value
WIDGET_HELPER_GLOBAL_INLINE double lives_range_get_value(LiVESRange *range)
Definition: widget-helper.c:5699
palette
_palette * palette
interface colour settings
Definition: main.c:101
MAX_PRE_X
#define MAX_PRE_X
Definition: framedraw.h:13
lives_hbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
Definition: widget-helper.c:3253
DEF_BUTTON_WIDTH
#define DEF_BUTTON_WIDTH
Definition: mainwindow.h:182
lives_special_framedraw_rect_t
Definition: paramspecial.h:15
lives_vseparator_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_vseparator_new(void)
Definition: widget-helper.c:3315
widget_opts_t::scale
double scale
scale factor for all sizes
Definition: widget-helper.h:1433
mainwindow::framedraw_preview
LiVESWidget * framedraw_preview
the 'redraw' button
Definition: mainwindow.h:1265
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
set_drawing_area_from_pixbuf
void set_drawing_area_from_pixbuf(LiVESWidget *widget, LiVESPixbuf *pixbuf, lives_painter_surface_t *surface)
Definition: main.c:5525
convert_layer_palette
boolean convert_layer_palette(weed_layer_t *layer, int outpl, int op_clamping)
Definition: colourspace.c:11945
weed_layer_t
weed_plant_t weed_layer_t
Definition: colourspace.h:71
LIVES_THRDATTR_NONE
#define LIVES_THRDATTR_NONE
Definition: machinestate.h:437
weed_layer_copy
weed_layer_t * weed_layer_copy(weed_layer_t *dlayer, weed_layer_t *slayer)
copy source layer slayer to dest layer dlayer
Definition: colourspace.c:13739
layer_to_lives_painter
lives_painter_t * layer_to_lives_painter(weed_layer_t *layer)
convert a weed layer to lives_painter (a.k.a cairo)
Definition: colourspace.c:13473
mainwindow::block_param_updates
boolean block_param_updates
block visual param changes from updating real values
Definition: mainwindow.h:1550
lives_widget_get_pointer
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_get_pointer(LiVESXDevice *device, LiVESWidget *widget, int *x, int *y)
Definition: widget-helper.c:7190
mainwindow::framedraw
LiVESWidget * framedraw
for the framedraw special widget - TODO - use a sub-struct
Definition: mainwindow.h:1263
lives_adjustment_get_step_increment
WIDGET_HELPER_GLOBAL_INLINE double lives_adjustment_get_step_increment(LiVESAdjustment *adj)
Definition: widget-helper.c:5562
framedraw_connect
void framedraw_connect(lives_special_framedraw_rect_t *framedraw, int width, int height, lives_rfx_t *rfx)
activate the image for clicks and draws
Definition: framedraw.c:165
lives_widget_set_sensitive
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_sensitive(LiVESWidget *widget, boolean state)
Definition: widget-helper.c:1477
LIVES_CURSOR_CROSSHAIR
@ LIVES_CURSOR_CROSSHAIR
Definition: widget-helper.h:1297
mainwindow::multitrack
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
lives_special_framedraw_rect_t::xstart_param
lives_param_t * xstart_param
Definition: paramspecial.h:19
CURRENT_CLIP_IS_VALID
#define CURRENT_CLIP_IS_VALID
Definition: main.h:809
lives_alarm_check
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
DEF_BUTTON_HEIGHT
#define DEF_BUTTON_HEIGHT
Definition: mainwindow.h:183
lives_entry_set_width_chars
WIDGET_HELPER_GLOBAL_INLINE boolean lives_entry_set_width_chars(LiVESEntry *entry, int nchars)
Definition: widget-helper.c:6223
mainwindow::framedraw_spinbutton
LiVESWidget * framedraw_spinbutton
the frame number button
Definition: mainwindow.h:1266
RFX_PROPS_MAY_RESIZE
#define RFX_PROPS_MAY_RESIZE
is a tool
Definition: plugins.h:635
main.h
LIVES_CURSOR_BUSY
@ LIVES_CURSOR_BUSY
Definition: widget-helper.h:1293
lives_rfx_t::source_type
lives_rfx_source_t source_type
Definition: plugins.h:650
lives_colRGBA64_t
Definition: main.h:322
lives_get_scroll_direction
WIDGET_HELPER_GLOBAL_INLINE LiVESScrollDirection lives_get_scroll_direction(LiVESXEventScroll *event)
Definition: widget-helper.c:8785
lives_layer_new_for_frame
LIVES_GLOBAL_INLINE weed_layer_t * lives_layer_new_for_frame(int clip, frames_t frame)
Definition: colourspace.c:9833
frame_context
boolean frame_context(LiVESWidget *widget, LiVESXEventButton *event, livespointer which)
Definition: callbacks.c:10909
lives_param_t::changed
boolean changed
Definition: plugins.h:597
mainw
mainwindow * mainw
Definition: main.c:103
get_image_ext_for_type
const char * get_image_ext_for_type(lives_img_type_t imgtype)
Definition: utils.c:3025
framedraw.h
lives_standard_hscale_new
LiVESWidget * lives_standard_hscale_new(LiVESAdjustment *adj)
Definition: widget-helper.c:10192
lives_standard_drawing_area_new
LiVESWidget * lives_standard_drawing_area_new(LiVESGuiCallback callback, lives_painter_surface_t **ppsurf)
Definition: widget-helper.c:8693
lives_widget_set_events
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_events(LiVESWidget *widget, int events)
Definition: widget-helper.c:4830
mainwindow::play_surface
lives_painter_surface_t * play_surface
Definition: mainwindow.h:950
mainwindow::did_rfx_preview
boolean did_rfx_preview
Definition: mainwindow.h:1056
resize_layer
boolean resize_layer(weed_layer_t *layer, int width, int height, LiVESInterpType interp, int opal_hint, int oclamp_hint)
resize a layer
Definition: colourspace.c:12537
lives_kill_subprocesses
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
lives_container_add
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_add(LiVESContainer *container, LiVESWidget *widget)
Definition: widget-helper.c:4929
on_framedraw_mouse_start
boolean on_framedraw_mouse_start(LiVESWidget *widget, LiVESXEventButton *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:871
mainwindow::fd_layer
weed_plant_t * fd_layer
framedraw preview layer
Definition: mainwindow.h:1276
lives_param_t::widgets
LiVESWidget * widgets[MAX_PARAM_WIDGETS]
TODO - change to LiVESWidget **widgets, terminated with a NULL.
Definition: plugins.h:594
lives_painter_to_layer
boolean lives_painter_to_layer(lives_painter_t *cr, weed_layer_t *layer)
convert a lives_painter_t (a.k.a) cairo_t to a weed layer
Definition: colourspace.c:13549
mainwindow::framedraw_scale
LiVESWidget * framedraw_scale
the slider
Definition: mainwindow.h:1267
lives_system
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
lives_mgeometry_t::mouse_device
LiVESXDevice * mouse_device
unused for gtk+ < 3.0.0
Definition: mainwindow.h:357
lives_widget_show_all
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
Definition: widget-helper.c:1523
weed_layer_free
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
Definition: colourspace.c:13883
lives_special_framedraw_rect_t::type
lives_param_special_t type
Definition: paramspecial.h:18
LIVES_CURSOR_TOP_LEFT_CORNER
@ LIVES_CURSOR_TOP_LEFT_CORNER
Definition: widget-helper.h:1298
lives_painter_stroke
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_stroke(lives_painter_t *cr)
Definition: widget-helper.c:382
lives_funcptr_t
void *(* lives_funcptr_t)(void *)
Definition: machinestate.h:378
widget_opts
widget_opts_t widget_opts
Definition: widget-helper.h:1442
lives_button_set_label
WIDGET_HELPER_GLOBAL_INLINE boolean lives_button_set_label(LiVESButton *button, const char *label)
Definition: widget-helper.c:4345
LIVES_FILE_EXT_PRE
#define LIVES_FILE_EXT_PRE
Definition: mainwindow.h:490
lives_standard_button_new_from_stock
LiVESWidget * lives_standard_button_new_from_stock(const char *stock_id, const char *label, int width, int height)
Definition: widget-helper.c:4215
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_range_set_value
WIDGET_HELPER_GLOBAL_INLINE boolean lives_range_set_value(LiVESRange *range, double value)
Definition: widget-helper.c:5663
lives_signal_handler_unblock
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_unblock(livespointer instance, unsigned long handler_id)
Definition: widget-helper.c:947
on_framedraw_enter
boolean on_framedraw_enter(LiVESWidget *widget, LiVESXEventCrossing *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:819
lives_rgba_col_new
WIDGET_HELPER_GLOBAL_INLINE lives_colRGBA64_t lives_rgba_col_new(int red, int green, int blue, int alpha)
Definition: widget-helper.c:12574
lives_painter_destroy
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_destroy(lives_painter_t *cr)
Definition: widget-helper.c:412
lives_nanosleep_until_nonzero
#define lives_nanosleep_until_nonzero(condition)
Definition: machinestate.h:310
check_filewrite_overwrites
boolean check_filewrite_overwrites(void)
Definition: paramspecial.c:617
LIVES_DEVNULL
#define LIVES_DEVNULL
Definition: mainwindow.h:592
lives_proc_thread_cancel
LIVES_GLOBAL_INLINE boolean lives_proc_thread_cancel(lives_proc_thread_t tinfo)
Definition: machinestate.c:1946
lives_painter_fill
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_fill(lives_painter_t *cr)
Definition: widget-helper.c:367
mainwindow::framedraw_reset
LiVESWidget * framedraw_reset
the 'redraw' button
Definition: mainwindow.h:1264
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
lives_widget_object_unref
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_object_unref(livespointer object)
decrease refcount by one: if refcount==0, object is destroyed
Definition: widget-helper.c:815
lives_painter_set_source_rgba
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_source_rgba(lives_painter_t *cr, double red, double green, double blue, double alpha)
Definition: widget-helper.c:619
lives_signal_handler_block
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_block(livespointer instance, unsigned long handler_id)
Definition: widget-helper.c:933
layer_to_pixbuf
LiVESPixbuf * layer_to_pixbuf(weed_layer_t *layer, boolean realpalette, boolean fordisplay)
Definition: colourspace.c:12210
mainwindow::fd_frame
LiVESWidget * fd_frame
surrounding frame widget
Definition: mainwindow.h:1271
lives_param_t::def
void * def
default values
Definition: plugins.h:581
_prefs::letterbox_mt
boolean letterbox_mt
playback with letterbox (multitrack)
Definition: preferences.h:363
FALSE
#define FALSE
Definition: videoplugin.h:60
lives_widget_get_allocation_width
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_width(LiVESWidget *widget)
Definition: widget-helper.c:5455
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
weed_palette_get_pixels_per_macropixel
LIVES_GLOBAL_INLINE int weed_palette_get_pixels_per_macropixel(int pal)
Definition: colourspace.c:1403
calc_maxspect
void calc_maxspect(int rwidth, int rheight, int *cwidth, int *cheight)
Definition: utils.c:2174
on_framedraw_mouse_update
boolean on_framedraw_mouse_update(LiVESWidget *widget, LiVESXEventMotion *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:989
DEF_MASK_OPACITY
#define DEF_MASK_OPACITY
Definition: framedraw.h:21
lives_painter_rectangle
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_rectangle(lives_painter_t *cr, double x, double y, double width, double height)
Definition: widget-helper.c:555
lives_alarm_set
lives_alarm_t lives_alarm_set(ticks_t ticks)
set alarm for now + delta ticks (10 nanosec) param ticks (10 nanoseconds) is the offset when we want ...
Definition: utils.c:1643
_
#define _(String)
Definition: support.h:44
STYLE_1
#define STYLE_1
turn on theming if set
Definition: mainwindow.h:299
lives_special_framedraw_rect_t::ystart_param
lives_param_t * ystart_param
Definition: paramspecial.h:20
mainwindow::error
boolean error
Definition: mainwindow.h:801
capability::byte_order
int byte_order
Definition: main.h:577
lives_event_box_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_event_box_new(void)
Definition: widget-helper.c:2284
lives_widget_show
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show(LiVESWidget *widget)
Definition: widget-helper.c:1505
lives_widget_context_update
boolean lives_widget_context_update(void)
Definition: widget-helper.c:11878
LIVES_CURSOR_BOTTOM_RIGHT_CORNER
@ LIVES_CURSOR_BOTTOM_RIGHT_CORNER
Definition: widget-helper.h:1299
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
MAINW_MSG_SIZE
#define MAINW_MSG_SIZE
mainw->msg bytesize
Definition: mainwindow.h:702
lives_standard_frame_new
LiVESWidget * lives_standard_frame_new(const char *labeltext, float xalign, boolean invis)
Definition: widget-helper.c:8732
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