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
16static double xstart, ystart;
17static double xcurrent, ycurrent;
18static double xinit, yinit;
19static volatile boolean b1_held;
20
21static volatile boolean noupdate = FALSE;
22
23static LiVESWidget *fbord_eventbox;
24
25
26static 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
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
61static 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
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
124static void framedraw_redraw_cb(LiVESWidget *widget, lives_special_framedraw_rect_t *framedraw) {
125 if (mainw->multitrack) return;
127}
128
129
130static 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
165void 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
189void 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
200void framedraw_add_reset(LiVESVBox *box, lives_special_framedraw_rect_t *framedraw) {
201 LiVESWidget *hbox_rst;
202
204
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
219static 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);
264
265 lives_painter_to_layer(cr, layer);
266 lives_widget_queue_draw(fd_widget);
267}
268
269
270static 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
279void 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);
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);
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
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
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);
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
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
691
693
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
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
819boolean 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
855boolean 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
871boolean 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
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 }
980 }
981
982 noupdate = FALSE;
983
985
986 return FALSE;
987}
988
989boolean 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;
1152
1153 return FALSE;
1154}
1155
1156boolean 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 }
1260 return FALSE;
1261}
1262
1263boolean 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
1283 if (mainw->block_param_updates || noupdate) return;
1284
1285 // redraw mask when spin values change
1287 if (mainw->framedraw_reset) {
1289 }
1290 if (mainw->framedraw_preview) {
1292 }
1293}
1294
1295
1296void 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
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}
boolean frame_context(LiVESWidget *widget, LiVESXEventButton *event, livespointer which)
Definition: callbacks.c:10909
LIVES_GLOBAL_INLINE weed_layer_t * lives_layer_new_for_frame(int clip, frames_t frame)
Definition: colourspace.c:9833
LiVESPixbuf * layer_to_pixbuf(weed_layer_t *layer, boolean realpalette, boolean fordisplay)
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
LIVES_GLOBAL_INLINE int weed_layer_get_height(weed_layer_t *layer)
boolean convert_layer_palette(weed_layer_t *layer, int outpl, int op_clamping)
lives_painter_t * layer_to_lives_painter(weed_layer_t *layer)
convert a weed layer to lives_painter (a.k.a cairo)
LIVES_GLOBAL_INLINE boolean weed_palette_has_alpha(int pal)
Definition: colourspace.c:1466
boolean resize_layer(weed_layer_t *layer, int width, int height, LiVESInterpType interp, int opal_hint, int oclamp_hint)
resize a layer
LIVES_GLOBAL_INLINE int weed_palette_get_pixels_per_macropixel(int pal)
Definition: colourspace.c:1403
LIVES_GLOBAL_INLINE int weed_layer_get_width(weed_layer_t *layer)
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_nullify_pixel_data(weed_layer_t *layer)
Definition: colourspace.c:9753
LIVES_GLOBAL_INLINE int weed_layer_get_palette(weed_layer_t *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
weed_layer_t * weed_layer_copy(weed_layer_t *dlayer, weed_layer_t *slayer)
copy source layer slayer to dest layer dlayer
weed_plant_t weed_layer_t
Definition: colourspace.h:71
frames_t virtual_to_images(int sfileno, frames_t sframe, frames_t eframe, boolean update_progress, LiVESPixbuf **pbr)
Definition: cvirtual.c:719
LiVESResponseType do_read_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4122
boolean do_effect(lives_rfx_t *rfx, boolean is_preview)
defined as extern in paramwindow.c
Definition: effects.c:127
void after_framedraw_widget_changed(LiVESWidget *widget, lives_special_framedraw_rect_t *framedraw)
callback for widgets
Definition: framedraw.c:1282
boolean on_framedraw_enter(LiVESWidget *widget, LiVESXEventCrossing *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:819
void framedraw_add_reset(LiVESVBox *box, lives_special_framedraw_rect_t *framedraw)
add "reset values" button
Definition: framedraw.c:200
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
boolean on_framedraw_mouse_start(LiVESWidget *widget, LiVESXEventButton *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:871
boolean on_framedraw_scroll(LiVESWidget *widget, LiVESXEventScroll *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:1263
void framedraw_connect_spinbutton(lives_special_framedraw_rect_t *framedraw, lives_rfx_t *rfx)
connect spinbutton to preview
Definition: framedraw.c:152
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
boolean on_framedraw_mouse_update(LiVESWidget *widget, LiVESXEventMotion *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:989
void framedraw_add_label(LiVESVBox *box)
add explanatory label
Definition: framedraw.c:189
boolean on_framedraw_mouse_reset(LiVESWidget *widget, LiVESXEventButton *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:1156
void invalidate_preview(lives_special_framedraw_rect_t *frame_draw)
Definition: framedraw.c:42
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
void load_rfx_preview(lives_rfx_t *rfx)
rfx preview
Definition: framedraw.c:671
void on_framedraw_reset_clicked(LiVESButton *button, lives_special_framedraw_rect_t *framedraw)
reset button
Definition: framedraw.c:1296
boolean on_framedraw_leave(LiVESWidget *widget, LiVESXEventCrossing *event, lives_special_framedraw_rect_t *framedraw)
Definition: framedraw.c:855
#define DEF_MASK_OPACITY
Definition: framedraw.h:21
#define MIN_PRE_X
Definition: framedraw.h:10
#define CROSSHAIR_SIZE
pixel size for crosshair "arms"
Definition: framedraw.h:19
#define MAX_PRE_X
Definition: framedraw.h:13
#define MAX_PRE_Y
Definition: framedraw.h:14
#define MIN_PRE_Y
Definition: framedraw.h:11
LIVES_GLOBAL_INLINE boolean lives_proc_thread_cancel(lives_proc_thread_t tinfo)
LIVES_GLOBAL_INLINE boolean lives_strncmp(const char *st1, const char *st2, size_t len)
returns FALSE if strings match
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
#define lives_nanosleep(nanosec)
Definition: machinestate.h:307
#define THREADVAR(var)
Definition: machinestate.h:531
#define lives_nanosleep_until_nonzero(condition)
Definition: machinestate.h:310
void *(* lives_funcptr_t)(void *)
Definition: machinestate.h:378
#define LIVES_THRDATTR_NONE
Definition: machinestate.h:437
void set_drawing_area_from_pixbuf(LiVESWidget *widget, LiVESPixbuf *pixbuf, lives_painter_surface_t *surface)
Definition: main.c:5525
_palette * palette
interface colour settings
Definition: main.c:101
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
mainwindow * mainw
Definition: main.c:103
void clear_mainw_msg(void)
Definition: utils.c:1435
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
char * lives_fgets(char *s, int size, FILE *stream)
Definition: utils.c:368
const char * get_image_ext_for_type(lives_img_type_t imgtype)
Definition: utils.c:3025
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
int64_t ticks_t
Definition: main.h:97
capability * capable
Definition: main.h:627
#define cfile
Definition: main.h:1833
#define CURRENT_CLIP_IS_VALID
Definition: main.h:809
void calc_maxspect(int rwidth, int rheight, int *cwidth, int *cheight)
Definition: utils.c:2174
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
Definition: main.h:765
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
@ CANCEL_NONE
no cancel
Definition: main.h:701
#define MAINW_MSG_SIZE
mainw->msg bytesize
Definition: mainwindow.h:702
#define DEF_BUTTON_HEIGHT
Definition: mainwindow.h:183
#define DEF_BUTTON_WIDTH
Definition: mainwindow.h:182
#define LIVES_LONGER_TIMEOUT
Definition: mainwindow.h:44
#define STYLE_1
turn on theming if set
Definition: mainwindow.h:299
_fx_dialog * fx_dialog[2]
Definition: mainwindow.h:1851
#define LIVES_FILE_EXT_PRE
Definition: mainwindow.h:490
#define LIVES_DEVNULL
Definition: mainwindow.h:592
int lives_alarm_t
Definition: mainwindow.h:696
boolean check_filewrite_overwrites(void)
Definition: paramspecial.c:617
void do_rfx_cleanup(lives_rfx_t *rfx)
Definition: plugins.c:2671
double get_double_param(void *value)
Definition: plugins.c:3086
int get_int_param(void *value)
Definition: plugins.c:3079
@ LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT
type may be used in framedraw
Definition: plugins.h:523
@ LIVES_PARAM_SPECIAL_TYPE_RECT_DEMASK
type may be used in framedraw
Definition: plugins.h:522
@ LIVES_PARAM_SPECIAL_TYPE_SCALEDPOINT
type may be used in framedraw
Definition: plugins.h:525
@ LIVES_PARAM_SPECIAL_TYPE_SINGLEPOINT
type may be used in framedraw
Definition: plugins.h:524
@ LIVES_RFX_SOURCE_RFX
Definition: plugins.h:513
#define RFX_PROPS_MAY_RESIZE
is a tool
Definition: plugins.h:635
_prefs * prefs
Definition: preferences.h:847
LiVESWidgetColor normal_fore
Definition: mainwindow.h:325
int style
Definition: mainwindow.h:297
LiVESWidgetColor light_red
Definition: mainwindow.h:309
LiVESWidgetColor normal_back
Definition: mainwindow.h:324
double default_fps
Definition: preferences.h:173
boolean letterbox_mt
playback with letterbox (multitrack)
Definition: preferences.h:363
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
int byte_order
Definition: main.h:577
LiVESXDevice * mouse_device
unused for gtk+ < 3.0.0
Definition: mainwindow.h:357
boolean changed
Definition: plugins.h:597
int dp
decimals, 0 for int and bool
Definition: plugins.h:575
LiVESWidget * widgets[MAX_PARAM_WIDGETS]
TODO - change to LiVESWidget **widgets, terminated with a NULL.
Definition: plugins.h:594
void * def
default values
Definition: plugins.h:581
int num_params
Definition: plugins.h:644
uint32_t props
Definition: plugins.h:633
lives_param_t * params
Definition: plugins.h:649
int num_in_channels
Definition: plugins.h:630
lives_rfx_source_t source_type
Definition: plugins.h:650
lives_param_special_t type
Definition: paramspecial.h:18
weed_plant_t * fd_layer
framedraw preview layer
Definition: mainwindow.h:1276
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
boolean block_param_updates
block visual param changes from updating real values
Definition: mainwindow.h:1550
lives_mgeometry_t * mgeom
multi-head support
Definition: mainwindow.h:1576
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
int current_file
Definition: mainwindow.h:727
LiVESPixbuf * imframe
Definition: mainwindow.h:1102
LiVESWidget * framedraw_preview
the 'redraw' button
Definition: mainwindow.h:1265
lives_painter_surface_t * fd_surface
Definition: mainwindow.h:1273
LiVESWidget * framedraw_cbutton
colour for mask
Definition: mainwindow.h:1270
LiVESWidget * framedraw_spinbutton
the frame number button
Definition: mainwindow.h:1266
LiVESWidget * framedraw_reset
the 'redraw' button
Definition: mainwindow.h:1264
LiVESWidget * fd_frame
surrounding frame widget
Definition: mainwindow.h:1271
boolean did_rfx_preview
Definition: mainwindow.h:1056
boolean error
Definition: mainwindow.h:801
LiVESWidget * framedraw_scale
the slider
Definition: mainwindow.h:1267
LiVESWidget * framedraw
for the framedraw special widget - TODO - use a sub-struct
Definition: mainwindow.h:1263
int framedraw_frame
current displayed frame
Definition: mainwindow.h:1278
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
weed_plant_t * fd_layer_orig
original layer uneffected
Definition: mainwindow.h:1275
lives_painter_surface_t * play_surface
Definition: mainwindow.h:950
LiVESWidget * framedraw_maskbox
box for opacity controls
Definition: mainwindow.h:1268
LiVESWidget * play_image
Definition: mainwindow.h:946
ulong fd_spin_func
spinbutton for framedraw previews
Definition: mainwindow.h:1281
int fd_max_frame
max effected / generated frame
Definition: mainwindow.h:1279
LiVESWidget * framedraw_opscale
opacity
Definition: mainwindow.h:1269
LiVESJustification justify
justify for labels
double scale
scale factor for all sizes
int packing_height
vertical pixels between widgets
int monitor
monitor we are displaying on
int packing_width
horizontal pixels between widgets
int border_width
border width in pixels
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
#define _(String)
Definition: support.h:44
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60
void lives_set_cursor_style(lives_cursor_t cstyle, LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_rectangle(lives_painter_t *cr, double x, double y, double width, double height)
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_width(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_value(LiVESSpinButton *button, double value)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_bg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
WIDGET_HELPER_GLOBAL_INLINE lives_painter_surface_t * lives_painter_get_target(lives_painter_t *cr)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_event_box_new(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_range_set_value(LiVESRange *range, double value)
WIDGET_HELPER_GLOBAL_INLINE LiVESAdjustment * lives_spin_button_get_adjustment(LiVESSpinButton *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_source_rgba(lives_painter_t *cr, double red, double green, double blue, double alpha)
WIDGET_HELPER_GLOBAL_INLINE LiVESScrollDirection lives_get_scroll_direction(LiVESXEventScroll *event)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_fill(lives_painter_t *cr)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidgetColor * lives_color_button_get_color(LiVESColorButton *button, LiVESWidgetColor *color)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_vbox_new(boolean homogeneous, int spacing)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_source_surface(lives_painter_t *cr, lives_painter_surface_t *surface, double x, double y)
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)
size_t calc_spin_button_width(double min, double max, int dp)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_pack_start(LiVESBox *box, LiVESWidget *child, boolean expand, boolean fill, uint32_t padding)
WIDGET_HELPER_GLOBAL_INLINE boolean clear_widget_bg(LiVESWidget *widget, lives_painter_surface_t *s)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_unblock(livespointer instance, unsigned long handler_id)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_events(LiVESWidget *widget, int events)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_fg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
LiVESWidget * lives_standard_button_new_from_stock(const char *stock_id, const char *label, int width, int height)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_sensitive(LiVESWidget *widget, boolean state)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_block(livespointer instance, unsigned long handler_id)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_object_unref(livespointer object)
decrease refcount by one: if refcount==0, object is destroyed
WIDGET_HELPER_GLOBAL_INLINE double lives_adjustment_get_step_increment(LiVESAdjustment *adj)
LiVESWidget * lives_standard_hscale_new(LiVESAdjustment *adj)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_set_border_width(LiVESContainer *container, uint32_t width)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_paint(lives_painter_t *cr)
WIDGET_HELPER_GLOBAL_INLINE int lives_spin_button_get_value_as_int(LiVESSpinButton *button)
WIDGET_HELPER_GLOBAL_INLINE LiVESAdjustment * lives_adjustment_new(double value, double lower, double upper, double step_increment, double page_increment, double page_size)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_get_pointer(LiVESXDevice *device, LiVESWidget *widget, int *x, int *y)
WIDGET_HELPER_GLOBAL_INLINE lives_colRGBA64_t lives_rgba_col_new(int red, int green, int blue, int alpha)
LiVESWidget * lives_standard_drawing_area_new(LiVESGuiCallback callback, lives_painter_surface_t **ppsurf)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_vseparator_new(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_add(LiVESContainer *container, LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_source_rgb(lives_painter_t *cr, double red, double green, double blue)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_no_show_all(LiVESWidget *widget, boolean set)
WIDGET_HELPER_GLOBAL_INLINE double lives_spin_button_get_value(LiVESSpinButton *button)
WIDGET_HELPER_GLOBAL_INLINE lives_painter_t * lives_painter_create_from_surface(lives_painter_surface_t *target)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE double lives_range_get_value(LiVESRange *range)
LiVESWidget * lives_standard_frame_new(const char *labeltext, float xalign, boolean invis)
boolean lives_widget_context_update(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_move_to(lives_painter_t *cr, double x, double y)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_fill_rule(lives_painter_t *cr, lives_painter_fill_rule_t fill_rule)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_destroy(lives_painter_t *cr)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_parent(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
LiVESWidget * lives_standard_label_new(const char *text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_entry_set_width_chars(LiVESEntry *entry, int nchars)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_line_to(lives_painter_t *cr, double x, double y)
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_height(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_size_request(LiVESWidget *widget, int width, int height)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_stroke(lives_painter_t *cr)
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)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_button_set_label(LiVESButton *button, const char *label)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_range(LiVESSpinButton *button, double min, double max)
@ LIVES_CURSOR_CROSSHAIR
@ LIVES_CURSOR_BOTTOM_RIGHT_CORNER
@ LIVES_CURSOR_NORMAL
must be zero
@ LIVES_CURSOR_TOP_LEFT_CORNER
@ LIVES_CURSOR_BUSY
ulong lives_signal_connect(LiVESWidget *, const char *signal_name, ulong funcptr, livespointer data)
widget_opts_t widget_opts
#define LIVES_JUSTIFY_DEFAULT