80#include "giw/giwvslider.h"
81#include "giw/giwled.h"
85#include "giw/giwtimeline.h"
92#ifndef WEED_AUDIO_LITTLE_ENDIAN
93#define WEED_AUDIO_LITTLE_ENDIAN 0
94#define WEED_AUDIO_BIG_ENDIAN 1
98static uint32_t event_list_get_byte_size(lives_mt *mt, weed_plant_t *event_list,
boolean nxprev,
int *num_events);
103static boolean mt_add_block_effect_idle(livespointer mt);
104static boolean mt_add_region_effect_idle(livespointer mt);
105static boolean mt_fx_edit_idle(livespointer mt);
107static void paint_lines(lives_mt *mt,
double currtime,
boolean unpaint, lives_painter_t *cr);
109static int *update_layout_map(weed_plant_t *event_list);
110static double *update_layout_map_audio(weed_plant_t *event_list);
112static boolean check_can_resetp(lives_mt *mt);
115static int renumbered_clips[
MAX_FILES + 1];
120static int xachans, xarate, xasamps, xse;
127static int dclick_time = 0;
129static boolean force_pertrack_audio;
130static int force_backing_tracks;
134static boolean pb_audio_needs_prerender;
135static weed_plant_t *pb_loop_event, *pb_filter_map, *pb_afilter_map;
137static boolean nb_ignore =
FALSE;
139static LiVESWidget *dummy_menuitem;
141static boolean doubleclick =
FALSE;
143static uint32_t last_press_time = 0;
144static int last_x = 0;
145static int last_y = 0;
147static boolean needs_clear;
149static LiVESList *pkg_list;
151static LiVESWidget *mainw_message_box;
152static LiVESWidget *mainw_msg_area;
153static LiVESWidget *mainw_msg_scrollbar;
154static LiVESAdjustment *mainw_msg_adj;
169static void on_delblock_activate(LiVESMenuItem *, livespointer mt);
178static void mt_render_vid_toggled(LiVESMenuItem *, livespointer mt);
179static void mt_render_aud_toggled(LiVESMenuItem *, livespointer mt);
180static void mt_norm_aud_toggled(LiVESMenuItem *, livespointer mt);
181static void mt_fplay_toggled(LiVESMenuItem *, livespointer mt);
184static void on_move_fx_changed(LiVESMenuItem *, livespointer mt);
185static void select_all_time(LiVESMenuItem *, livespointer mt);
186static void select_from_zero_time(LiVESMenuItem *, livespointer mt);
187static void select_to_end_time(LiVESMenuItem *, livespointer mt);
188static void select_all_vid(LiVESMenuItem *, livespointer mt);
189static void select_no_vid(LiVESMenuItem *, livespointer mt);
198static void mt_view_audio_toggled(LiVESMenuItem *, livespointer mt);
199static void mt_ign_ins_sel_toggled(LiVESMenuItem *, livespointer mt);
202static void mt_ac_audio_toggled(LiVESMenuItem *, livespointer mt);
206#define LIVES_AVOL_SCALE ((double)1000000.)
217 return clips_to_files[clip];
224 if (clips_to_files[i] == file)
return i;
232 return LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
237 return (lives_widget_object_get_data(track,
"blocks") == NULL);
241 double vol = (double)(LIVES_POINTER_TO_INT(lives_list_nth_data(mt->audio_vols, trackno)));
248 lives_list_nth(mt->audio_vols, trackno)->data = LIVES_INT_TO_POINTER(x);
266 if (!event_list)
return TRUE;
274 weed_set_int_value(event_list, WEED_LEAF_WIDTH,
mainw->
files[mt->render_file]->
hsize);
275 weed_set_int_value(event_list, WEED_LEAF_HEIGHT,
mainw->
files[mt->render_file]->
vsize);
276 weed_set_int_value(event_list, WEED_LEAF_AUDIO_CHANNELS,
mainw->
files[mt->render_file]->
achans);
277 weed_set_int_value(event_list, WEED_LEAF_AUDIO_RATE,
mainw->
files[mt->render_file]->
arate);
288 if (
prefs->
letterbox_mt) weed_set_boolean_value(event_list, WEED_LEAF_KEEP_ASPECT, WEED_TRUE);
289 else weed_set_boolean_value(event_list, WEED_LEAF_KEEP_ASPECT, WEED_FALSE);
291 if (mt && mt->audio_vols && mt->audio_draws) {
292 int natracks = lives_list_length(mt->audio_draws);
299 for (i = 0; i < natracks; i++) {
300 atracks[i] = i - mt->opts.back_audio_tracks;
305 if (mt->opts.gang_audio) navols = 1 + mt->opts.back_audio_tracks;
306 else navols = natracks;
308 avols = (
double *)
lives_malloc(navols *
sizeof(
double));
309 for (i = 0; i < navols; i++) {
317 int nvtracks = lives_list_length(mt->video_draws);
320 char **
const labels = (
char **)
lives_malloc(nvtracks *
sizeof(
char *));
322 for (i = 0; i < nvtracks; i++) {
324 const char *tname = (
const char *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
"track_name");
325 labels[i] = (
char *)tname;
337 if (!mem && fd < 0)
return TRUE;
344 while (!
THREADVAR(write_failed) && event) {
361 for (i = 0; i < nivs; i++) {
362 uievs[i] = (int64_t)(uint64_t)ievs[i];
372 weed_leaf_copy(event,
WEED_LEAF_HINT, event, WEED_LEAF_EVENT_TYPE);
395 if (++count == 100) {
405LiVESPixbuf *
make_thumb(lives_mt *mt,
int file,
int width,
int height,
frames_t frame, LiVESInterpType interp,
407 LiVESPixbuf *thumbnail = NULL, *pixbuf;
408 LiVESError *
error = NULL;
412 boolean tried_all =
FALSE;
413 boolean needs_idlefunc =
FALSE;
415 boolean did_backup =
FALSE;
417 int nframe, oframe = frame;
420 LIVES_WARN(
"Warning - make thumb for file -1");
424 if (width < 4 || height < 4)
return NULL;
426 if (mt) did_backup = mt->did_backup;
428 if (mt && mt->idlefunc > 0) {
429 needs_idlefunc =
TRUE;
445 width, height, LIVES_INTERP_FAST,
TRUE);
448 if (
error || !pixbuf) {
449 lives_error_free(
error);
450 if (mt && (needs_idlefunc || (!did_backup && mt->auto_changed))) {
460 }
else thumbnail = pixbuf;
463 if (tried_all) noblanks =
FALSE;
467 nframe = frame + sfile->
frames / 10.;
468 if (nframe == frame) nframe++;
469 if (nframe > sfile->
frames) {
480 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
494 LIVES_WARN(
"Warning - make thumb for file -1");
498 if (width < 2 || height < 2)
return NULL;
500 for (i = 1; i <= range; i++) {
502 nvframe = tframe - i;
505 if (tframe + i <= mainw->files[fileno]->frames && !
is_virtual_frame(fileno, tframe + i)) {
506 nvframe = tframe + i;
512 return make_thumb(mt, fileno, width, height, nvframe, LIVES_INTERP_FAST,
FALSE);
526static void mt_set_cursor_style(lives_mt *mt,
lives_cursor_t cstyle,
int width,
int height,
int clip,
int hsx,
int hsy) {
527 LiVESXCursor *cursor;
530 LiVESPixbuf *pixbuf = NULL;
531 LiVESPixbuf *thumbnail = NULL;
533 uint8_t *cpixels, *tpixels;
539 unsigned int cwidth, cheight;
541 int twidth = 0, twidth3, twidth4, trow;
544 register int i, j, k;
554 gdk_display_get_maximal_cursor_size(disp, &cwidth, &cheight);
557 cwidth = MAX_CURSOR_WIDTH;
560 if (width > cwidth) width = cwidth;
562 mt->cursor_style = cstyle;
565 if (sfile && sfile->
frames > 0) {
566 frame_start = mt->opts.ign_ins_sel ? 1 : sfile->
start;
567 frames_width = (double)(mt->opts.ign_ins_sel ? sfile->
frames : sfile->
end - sfile->
start + 1.);
574 if ((i + twidth) > width) twidth = width - i;
576 thumbnail =
make_thumb(mt, clip, twidth, height, frame_start + (
int)((
double)i / (
double)width * frames_width),
577 LIVES_INTERP_NORMAL,
FALSE);
586 twidth3 = twidth * 3;
587 for (j = 0; j < height; j++) {
588 for (k = 0; k < twidth3; k += 3) {
594 cpixels += (width - twidth) << 2;
597 twidth4 = twidth * 4;
598 for (j = 0; j < height; j++) {
601 cpixels += width << 2;
615 for (j = 0; j < height; j++) {
616 for (k = 0; k < width; k++) {
623 cpixels += (trow - width * 4);
630 for (j = 0; j < height; j++) {
631 for (k = 0; k < width; k++) {
638 cpixels += (trow - width * 4);
645 for (j = 0; j < height; j++) {
646 for (k = 0; k < width; k++) {
653 cpixels += (trow - width * 4);
672 int fd, i, vali, hdlsize;
685 i = LIVES_POINTER_TO_INT(clist->data);
693 hdlsize = strlen(sfile->
handle);
705static void upd_layout_maps(weed_plant_t *event_list) {
707 double *layout_map_audio;
711 layout_map_audio = update_layout_map_audio(event_list);
720static void renumber_from_backup_layout_numbering(lives_mt *mt) {
731 boolean gotvalid =
FALSE;
732 int fd, vari, clipn, offs, restart = 0;
739 upd_layout_maps(NULL);
753 if (vari > 511) vari = 511;
756 if (clipn < 0 || clipn >
MAX_FILES)
continue;
760 if (!gotvalid) restart = offs;
769 renumbered_clips[clipn] = offs;
782static void save_mt_autoback(lives_mt *mt) {
792 char *asave_file = lives_build_filename(
prefs->
workdir, fname, NULL);
795 boolean retval =
TRUE;
801 mt->auto_changed =
FALSE;
827 paint_lines(mt, mt->ptr_time,
FALSE, NULL);
835 if (!retval ||
THREADVAR(write_failed)) {
839 }
while (retval2 == LIVES_RESPONSE_RETRY);
845 gettimeofday(&otv, NULL);
847 d_print(
"Auto backup of timeline at %s\n", tmp);
852static void on_mt_backup_activate(LiVESMenuItem *menuitem, livespointer user_data) {
853 lives_mt *mt = (lives_mt *)user_data;
854 if (!mt->auto_changed)
return;
855 if (mt->idlefunc > 0) {
859 save_mt_autoback(mt);
866 lives_mt *mt = (lives_mt *)user_data;
868 if (!mt->idlefunc)
return FALSE;
873 if (!mt->auto_changed && mt->did_backup) {
885 if (mt->auto_back_time == 0) mt->auto_back_time = stime;
887 diff = stime - mt->auto_back_time;
891 save_mt_autoback(mt);
908 if (mt->idlefunc > 0)
return mt->idlefunc;
942 boolean recovered =
TRUE;
943 char *aload_file = NULL, *eload_file;
950 mt->auto_reloading =
TRUE;
952 mt->auto_reloading =
FALSE;
953 if (mt->event_list) {
958 save_mt_autoback(mt);
985 if (lives_file_test(uldir, LIVES_FILE_TEST_IS_DIR)) {
989 if (lives_file_test(eload_file, LIVES_FILE_TEST_EXISTS)) {
992 if (lives_file_test(aload_file, LIVES_FILE_TEST_EXISTS)) {
1011 boolean loaded =
TRUE;
1040 LiVESWidget *xeventbox;
1041 if (track_num < 0)
return (
_(
"Backing audio"));
1042 if (!is_audio) xeventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, track_num);
1043 else xeventbox = (LiVESWidget *)lives_list_nth_data(mt->audio_draws, track_num + mt->opts.back_audio_tracks);
1044 return lives_strdup((
char *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"track_name"));
1050 (mt->tl_max - mt->tl_min) + mt->tl_min;
1051 if (time < 0.) time = 0.;
1052 else if (time > mt->end_secs + 1. / mt->fps) time = mt->end_secs + 1. / mt->fps;
1058 weed_plant_t *wparam;
1059 weed_plant_t *inst = rfx->
source;
1068 for (j = 0; j < nvals; j++) {
1069 ign_array[j] = WEED_TRUE;
1071 weed_set_boolean_array(wparam, WEED_LEAF_IGNORE, nvals, ign_array);
1082static int get_track_height(lives_mt * mt) {
1083 LiVESWidget *eventbox;
1084 LiVESList *list = mt->video_draws;
1087 eventbox = (LiVESWidget *)list->data;
1088 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY)) == 0)
1097static boolean is_audio_eventbox(LiVESWidget * ebox) {
1098 return LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
"is_audio"));
1102static boolean add_to_thumb_cache(
int fnum,
frames_t frame,
frames_t range,
int height,
1103 LiVESPixbuf * pixbuf) {
1107 for (; list; list = list->next) {
1110 if (tce->
frame <= frame - range)
continue;
1111 if (tce->
frame <= frame + range)
return FALSE;
1117 xlist = lives_list_append(NULL, tce);
1118 xlist->data = (livespointer)tce;
1120 xlist->prev = list->prev;
1121 if (list->prev) list->prev->next = xlist;
1127 llist->next = xlist;
1128 xlist->prev = llist;
1137static LiVESPixbuf *get_from_thumb_cache(
int fnum,
frames_t frame,
frames_t range) {
1139 for (; list; list = list->next) {
1141 if (tcentry->
frame <= frame - range)
continue;
1142 if (tcentry->
frame >= frame + range)
return NULL;
1150 boolean has_some =
FALSE;
1151 for (; list; list = list->next) {
1154 if (tcentry->
frame < fromframe) {
1159 list->prev->next = NULL;
1167 if (freestart) lives_list_free(freestart);
1176static void draw_block(lives_mt * mt, lives_painter_t *cairo,
1177 lives_painter_surface_t *surf, track_rect * block,
int x1,
int x2) {
1179 lives_painter_t *cr;
1180 weed_event_t *
event = block->start_event, *nxevent = NULL;
1182 LiVESWidget *eventbox = block->eventbox;
1183 LiVESPixbuf *thumbnail = NULL;
1185 double tl_span = mt->tl_max - mt->tl_min;
1188 frames_t framenum, last_framenum = -1, range = 0;
1190 boolean needs_text =
TRUE;
1191 boolean is_audio =
FALSE;
1193 int offset_start, offset_end;
1196 int hidden = (int)LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY));
1200 if (mt->no_expose)
return;
1205 if (offset_startd >= mt->tl_max)
return;
1209 if ((x1 > 0 || x2 > 0) && offset_start > (x1 + x2))
return;
1216 if (offset_end < x1)
return;
1218 if (!surf) cr = cairo;
1225 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
1226 is_audio = is_audio_eventbox(eventbox);
1227 if (track < 0) is_audio =
TRUE;
1233 switch (block->state) {
1248 if (!is_audio && track > -1) {
1249 boolean in_cache =
FALSE;
1252 if (i > x2 - x1)
break;
1260 if (last_framenum == -1) {
1267 range = (xframenum - framenum) / 2;
1274 range = (framenum - xframenum) / 2;
1280 if (i + width >= 0) {
1293 if (!(thumbnail = get_from_thumb_cache(filenum, framenum, range))) {
1299 framenum, last_framenum == -1 ? 0
1300 : framenum - last_framenum);
1302 thumbnail =
make_thumb(mt, filenum, width, height,
1303 framenum, LIVES_INTERP_FAST,
FALSE);
1306 thumbnail =
make_thumb(mt, filenum, width, height,
1307 framenum, LIVES_INTERP_FAST,
FALSE);
1309 in_cache = add_to_thumb_cache(filenum, framenum, range, height, thumbnail);
1314 last_framenum = framenum;
1318 if (i + width > offset_end) {
1319 width = offset_end - i;
1327 if (i + width > offset_end) width = offset_end - i;
1334 mt->no_expose =
TRUE;
1337 mt->no_expose =
FALSE;
1354 const char *sfont =
"Sans";
1357 LingoLayout *layout;
1358 lives_painter_surface_t *surface;
1361 int text_start = offset_start + 2, text_end = offset_end;
1363 if (text_start < 2) text_start = 2;
1374 if (luma > 0.2) colr = &col_black;
1380 text_end - text_start, &height);
1382 lingo_painter_show_layout(cr, layout);
1392 mt->no_expose =
TRUE;
1394 mt->no_expose =
FALSE;
1425static void draw_aparams(lives_mt * mt, LiVESWidget * eventbox, lives_painter_t *cr, LiVESList * param_list,
1426 weed_plant_t *init_event,
1427 int startx,
int width) {
1434 weed_plant_t **in_params, *param, *ptmpl;
1435 weed_plant_t *filter, *inst, *deinit_event;
1437 weed_timecode_t tc, start_tc, end_tc;
1439 double tl_span = mt->tl_max - mt->tl_min;
1442 double vald, mind, maxd, *valds;
1446 int vali, mini, maxi, *valis;
1448 int offset_start, offset_end, startpos;
1453 void **pchainx = NULL;
1463 in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
1481 if (offset_start > startx) startpos = offset_start;
1482 else startpos = startx;
1484 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
1485 "layer_number")) + mt->opts.back_audio_tracks;
1490 pchainx = weed_get_voidptr_array(init_event, WEED_LEAF_IN_PARAMETERS, NULL);
1493 for (i = startpos; i < startx + width; i++) {
1496 if (tc >= end_tc)
break;
1502 pnum = LIVES_POINTER_TO_INT(plist->data);
1503 param = in_params[pnum];
1507 case WEED_PARAM_INTEGER:
1508 valis = weed_get_int_array(param, WEED_LEAF_VALUE, NULL);
1510 else vali = valis[0];
1511 mini = weed_get_int_value(ptmpl, WEED_LEAF_MIN, NULL);
1512 maxi = weed_get_int_value(ptmpl, WEED_LEAF_MAX, NULL);
1513 ratio = (double)(vali - mini) / (double)(maxi - mini);
1516 case WEED_PARAM_FLOAT:
1517 valds = weed_get_double_array(param, WEED_LEAF_VALUE, NULL);
1519 else vald = valds[0];
1520 mind = weed_get_double_value(ptmpl, WEED_LEAF_MIN, NULL);
1521 maxd = weed_get_double_value(ptmpl, WEED_LEAF_MAX, NULL);
1522 ratio = (vald - mind) / (maxd - mind);
1534 plist = plist->next;
1549static void redraw_eventbox(lives_mt * mt, LiVESWidget * eventbox) {
1550 if (!LIVES_IS_WIDGET_OBJECT(eventbox))
return;
1552 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"drawn", LIVES_INT_TO_POINTER(
FALSE));
1555 if (is_audio_eventbox(eventbox)) {
1557 LiVESWidget *xeventbox;
1559 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan0");
1560 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"drawn", LIVES_INT_TO_POINTER(
FALSE));
1563 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan1");
1564 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"drawn", LIVES_INT_TO_POINTER(
FALSE));
1572static EXPOSE_FN_DECL(expose_track_event, eventbox, user_data) {
1573 lives_painter_t *cr;
1575 lives_mt *mt = (lives_mt *)user_data;
1578 track_rect *sblock = NULL;
1582 lives_painter_surface_t *bgimage;
1584 int startx, starty, width, height;
1587 if (mt->no_expose)
return TRUE;
1590 if (event->count > 0) {
1593 startx =
event->area.x;
1594 starty =
event->area.y;
1595 width =
event->area.width;
1596 height =
event->area.height;
1598 startx = starty = 0;
1603 if (width == 0)
return FALSE;
1605 hidden = (int)LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY));
1607 LiVESWidget *label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label");
1613 idlefunc = mt->idlefunc;
1614 if (mt->idlefunc > 0) {
1621 bgimage = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"bgimg");
1624#if !GTK_CHECK_VERSION(3, 22, 0)
1631 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"drawn"))) {
1637 if (mt->block_selected && mt->block_selected->eventbox == eventbox) {
1638 draw_block(mt, cr, NULL, mt->block_selected, -1, -1);
1641 if (is_audio_eventbox(eventbox) && mt->avol_init_event && mt->opts.aparam_view_list)
1642 draw_aparams(mt, eventbox, cr, mt->opts.aparam_view_list, mt->avol_init_event, startx, width);
1673 if (mt->block_selected) {
1674 sblock = mt->block_selected;
1678 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
1681 draw_block(mt, NULL, bgimage, block, startx, width);
1682 block = block->next;
1686 mt->block_selected = sblock;
1691 }
else if (bgimage) {
1696 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"bgimg", (livespointer)bgimage);
1697 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"drawn", LIVES_INT_TO_POINTER(bgimage != NULL));
1699 if (bgimage)
goto draw1;
1710static char *mt_params_label(lives_mt * mt) {
1716 layer_name =
get_track_name(mt, mt->current_track, mt->aud_track_selected);
1718 ltext = lives_markup_escape_text(tmp, -1);
1720 }
else ltext = lives_strdup(fname);
1723 if (mt->framedraw) {
1724 char *someparms =
lives_big_and_bold(
_(
"<--- Some parameters can be altered by clicking / dragging in the Preview window"));
1725 char *tmp2 = lives_markup_escape_text(ltext, -1);
1748 weed_plant_t *deinit_event;
1752 double fx_start_time, fx_end_time;
1753 double cur_time = mt->ptr_time;
1757 boolean res =
FALSE;
1773 if (mt->fx_params_label) {
1785 fx_end_time - fx_start_time, 1. / mt->fps, 10. / mt->fps);
1795 ltext = mt_params_label(mt);
1819 if (!mt->sel_locked) {
1827static track_rect *get_block_from_time(LiVESWidget * eventbox,
double time, lives_mt * mt) {
1832 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
1838 mt->fps) > tc)
break;
1839 block = block->next;
1845static int track_to_channel(weed_plant_t *ievent,
int track) {
1854 int nc = 0, rpts, ntracks;
1859 if (ntracks == 0)
return -1;
1863 for (i = 0; i < ntracks; i++) {
1864 rpts = nc < i ? 1 : carray[i];
1865 if (in_tracks[i] + rpts > track) {
1878static boolean get_track_index(lives_mt * mt, weed_timecode_t tc) {
1884 int *clips, *in_tracks, numtracks;
1887 boolean retval =
FALSE;
1890 int opwidth, opheight;
1891 int track_index = mt->track_index;
1895 mt->track_index = -1;
1897 if (!event || !mt->play_width || !mt->play_height)
return retval;
1901 calc_maxspect(mt->play_width, mt->play_height, &opwidth, &opheight);
1903 clips = weed_get_int_array_counted(event,
WEED_LEAF_CLIPS, &numtracks);
1905 chindx = track_to_channel(mt->init_event, mt->current_track);
1907 if (mt->current_track < numtracks && clips[mt->current_track] < 1 &&
1908 (!mt->current_rfx || !mt->init_event || !mt->current_rfx->source || chindx == -1 ||
1910 if (track_index != -1 && mt->fx_box) {
1918 in_tracks = weed_get_int_array_counted(mt->init_event,
WEED_LEAF_IN_TRACKS, &num_in_tracks);
1919 if (num_in_tracks > 0) {
1920 for (i = 0; i < num_in_tracks; i++) {
1921 if (in_tracks[i] == mt->current_track) {
1922 mt->track_index = i;
1923 if (track_index == -1 && mt->fx_box) {
1933 if (track_index != -1 && mt->track_index == -1 && mt->fx_box) {
1942 LiVESWidget *labelbox, *label, *hbox, *dummy, *ahbox, *arrow, *eventbox, *oeventbox, *checkbutton = NULL;
1950 if (mt->current_track < 0) {
1976 for (list = mt->audio_draws; list; list = list->next, i++) {
1977 eventbox = (LiVESWidget *)list->data;
1978 if ((oeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"owner")))
1979 hidden = !LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(oeventbox),
"expanded"));
1980 if (hidden == 0) hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY));
1982 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox");
1983 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label");
1984 dummy = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"dummy");
1985 ahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"ahbox");
1986 hbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"hbox");
1987 arrow = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"arrow");
1988 if (mt->current_track == i - mt->opts.back_audio_tracks && (mt->current_track < 0 || mt->aud_track_selected)) {
2006 lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks") != NULL);
2008 lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks") != NULL);
2028 for (list = mt->video_draws; list; list = list->next, i++) {
2029 eventbox = (LiVESWidget *)list->data;
2030 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY));
2032 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox");
2033 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label");
2034 hbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"hbox");
2035 ahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"ahbox");
2036 arrow = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"arrow");
2037 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton");
2038 if (i == mt->current_track) {
2040 if (!mt->aud_track_selected) {
2057 lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks") != NULL);
2059 lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks") != NULL);
2093 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mt->select_track), FALSE);
2103 lives_widget_set_bg_color(labelbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
2104 lives_widget_set_fg_color(labelbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
2121else if (mt->current_rfx && mt->init_event && mt->poly_state ==
POLY_PARAMS &&
2124 boolean interp =
TRUE;
2129 xx = get_track_index(mt, tc);
2130 if (mt->track_index != -1) {
2131 for (i = 0; i < mt->current_rfx->num_params; i++) {
2135 if (mt->current_rfx->params[i].changed) {
2140 if (mt->current_track >= 0) {
2146 boolean aprev = mt->opts.fx_auto_preview;
2149 mt->current_rfx->needs_reinit =
FALSE;
2153 if (mt->current_rfx->needs_reinit) {
2155 mt->current_rfx->needs_reinit =
FALSE;
2158 mt->opts.fx_auto_preview = aprev;
2166static void show_track_info(lives_mt * mt, LiVESWidget * eventbox,
int track,
double timesecs) {
2168 track_rect *block = get_block_from_time(eventbox, timesecs, mt);
2173 (mt, (tmp = lives_markup_printf_escaped
2174 (
_(
"Current track: %s (layer %d)\n"),
2175 lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
2176 "track_name"), track)));
2178 if (track == -1)
add_context_label(mt, (tmp = (
_(
"Current track: Backing audio\n"))));
2180 lives_markup_printf_escaped(
_(
"Current track: Layer %d audio\n"), track)));
2198static boolean atrack_ebox_pressed(LiVESWidget * labelbox, LiVESXEventButton * event, livespointer user_data) {
2199 lives_mt *mt = (lives_mt *)user_data;
2200 int current_track = mt->current_track;
2202 mt->current_track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(labelbox),
"layer_number"));
2203 if (current_track != mt->current_track) mt->fm_edit_event = NULL;
2204 mt->aud_track_selected =
TRUE;
2206 show_track_info(mt, (LiVESWidget *)lives_list_nth_data(mt->audio_draws, mt->current_track + mt->opts.back_audio_tracks),
2207 mt->current_track, mt->ptr_time);
2212static boolean track_ebox_pressed(LiVESWidget * labelbox, LiVESXEventButton * event, livespointer user_data) {
2213 lives_mt *mt = (lives_mt *)user_data;
2214 int current_track = mt->current_track;
2216 mt->current_track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(labelbox),
"layer_number"));
2217 if (current_track != mt->current_track) mt->fm_edit_event = NULL;
2218 mt->aud_track_selected =
FALSE;
2220 show_track_info(mt, (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track), mt->current_track, mt->ptr_time);
2225static boolean on_mt_timeline_scroll(LiVESWidget * widget, LiVESXEventScroll * event, livespointer user_data) {
2227 lives_mt *mt = (lives_mt *)user_data;
2233 LiVESXModifierType kstate = (LiVESXModifierType)event->state;
2234 if ((kstate & LIVES_DEFAULT_MOD_MASK) == LIVES_CONTROL_MASK)
return on_mouse_scroll(widget, event, user_data);
2239 if (--cval < 0)
return FALSE;
2241 if (++cval >= mt->num_video_tracks)
return FALSE;
2250static int get_top_track_for(lives_mt * mt,
int track) {
2253 LiVESWidget *eventbox;
2256 int hidden, expanded;
2258 if (mt->opts.back_audio_tracks > 0 && !mt->audio_draws) mt->opts.back_audio_tracks = 0;
2259 if (
mainw->
files[mt->render_file]->
achans > 0 && mt->opts.back_audio_tracks > 0) {
2260 eventbox = (LiVESWidget *)mt->audio_draws->data;
2261 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY));
2264 expanded = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
2271 if (extras < 0)
return track;
2273 vdraw = lives_list_nth(mt->video_draws, track);
2274 eventbox = (LiVESWidget *)vdraw->data;
2275 expanded = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
2277 eventbox = (LiVESWidget *)(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack"));
2279 expanded = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
2285 if (extras < 0)
return track;
2287 vdraw = vdraw->prev;
2290 eventbox = (LiVESWidget *)vdraw->data;
2292 expanded = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
2295 eventbox = (LiVESWidget *)(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack"));
2297 expanded = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
2302 if (extras < 0)
break;
2303 vdraw = vdraw->prev;
2307 if (track < 0) track = 0;
2312static void redraw_all_event_boxes(lives_mt * mt) {
2315 slist = mt->audio_draws;
2317 redraw_eventbox(mt, (LiVESWidget *)slist->data);
2318 slist = slist->next;
2321 slist = mt->video_draws;
2323 redraw_eventbox(mt, (LiVESWidget *)slist->data);
2324 slist = slist->next;
2326 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
2330static boolean expose_paintlines(LiVESWidget * widget, lives_painter_t *cr, livespointer data) {
2331 int offset = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(widget),
2348 LiVESList *vdraws = mt->video_draws;
2349 LiVESList *table_children, *xlist;
2351 LiVESWidget *eventbox;
2355 LiVESWidget *checkbutton;
2356 LiVESWidget *labelbox;
2359 LiVESWidget *xeventbox, *aeventbox;
2361 LiVESWidgetColor col;
2378 if (top_track < 0) top_track = 0;
2379 if (top_track >= mt->num_video_tracks) top_track = mt->num_video_tracks - 1;
2381 mt->top_track = top_track;
2385 eventbox = (LiVESWidget *)vdraws->data;
2386 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY));
2388 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2390 aeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack"));
2393 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
HIDDEN_KEY));
2395 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2397 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"achan0");
2400 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY));
2402 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2405 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"achan1");
2408 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY));
2410 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2414 vdraws = vdraws->next;
2417 if (mt->timeline_table) {
2422 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mt->timeline_table),
"has_line", LIVES_INT_TO_POINTER(-1));
2426 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(mt->timeline_table), LIVES_WIDGET_EXPOSE_EVENT,
2427 LIVES_GUI_CALLBACK(expose_paintlines),
2435 if (mt->opts.back_audio_tracks > 0 && !mt->audio_draws) mt->opts.back_audio_tracks = 0;
2437 if (
mainw->
files[mt->render_file]->
achans > 0 && mt->opts.back_audio_tracks > 0) {
2439 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
HIDDEN_KEY)) == 0) {
2442 expanded = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"expanded"));
2444 label = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"label")));
2445 dummy = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"dummy")));
2446 arrow = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"arrow")));
2456 lives_table_attach(LIVES_TABLE(mt->timeline_table), dummy, 0, 2, 0, 1, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2457 lives_table_attach(LIVES_TABLE(mt->timeline_table), labelbox, 2, 6, 0, 1, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2458 lives_table_attach(LIVES_TABLE(mt->timeline_table), ahbox, 6, 7, 0, 1, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2460 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"labelbox", labelbox);
2461 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"ahbox", ahbox);
2462 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(ahbox),
"eventbox", (livespointer)mt->audio_draws->data);
2463 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(labelbox),
"layer_number", LIVES_INT_TO_POINTER(-1));
2466 LIVES_GUI_CALLBACK(atrack_ebox_pressed), (livespointer)mt);
2472 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL), (LiVESAttachOptions)(0), 0, 0);
2478 lives_signal_connect(LIVES_GUI_OBJECT(mt->audio_draws->data), LIVES_WIDGET_BUTTON_RELEASE_EVENT,
2483 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->audio_draws->data), LIVES_WIDGET_EXPOSE_EVENT,
2484 LIVES_GUI_CALLBACK(expose_track_event), (livespointer)mt);
2487 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"achan0");
2489 label = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"label")));
2495 lives_table_attach(LIVES_TABLE(mt->timeline_table), labelbox, 2, 6, 1, 2, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2497 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
2498 (LiVESAttachOptions)(0), 0, 0);
2505 LIVES_GUI_CALLBACK(mt_expose_audtrack_event),
2509 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"achan1");
2511 label = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"label")));
2517 lives_table_attach(LIVES_TABLE(mt->timeline_table), labelbox, 2, 6, 2, 3, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2519 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
2520 (LiVESAttachOptions)(0), 0, 0);
2527 LIVES_GUI_CALLBACK(mt_expose_audtrack_event),
2538 vdraws = lives_list_nth(mt->video_draws, top_track);
2542 while (vdraws && rows < prefs->max_disp_vtracks) {
2543 eventbox = (LiVESWidget *)vdraws->data;
2546 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2549 label = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label")));
2550 arrow = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"arrow")));
2551 checkbutton = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton")));
2560#if GTK_CHECK_VERSION(3, 0, 0)
2568 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(labelbox),
"layer_number",
2569 LIVES_INT_TO_POINTER(LIVES_POINTER_TO_INT
2570 (lives_widget_object_get_data
2571 (LIVES_WIDGET_OBJECT(eventbox),
"layer_number"))));
2579 rows, rows + 1, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2580 lives_table_attach(LIVES_TABLE(mt->timeline_table), ahbox, 6, 7, rows, rows + 1, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2582 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox", labelbox);
2583 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"hbox", hbox);
2584 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"ahbox", ahbox);
2585 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(ahbox),
"eventbox", eventbox);
2588 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL), (LiVESAttachOptions)(0), 0, 0);
2593 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
2596 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_MODE_CHANGED_SIGNAL,
2601 LIVES_GUI_CALLBACK(track_ebox_pressed), (livespointer)mt);
2605 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_EXPOSE_EVENT,
2606 LIVES_GUI_CALLBACK(expose_track_event), (livespointer)mt);
2619 if (mt->opts.pertrack_audio && lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded")) {
2621 aeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack"));
2623 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
2625 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2630 expanded = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"expanded"));
2632 label = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"label")));
2633 dummy = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"dummy")));
2634 arrow = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"arrow")));
2648 LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2650 LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2652 LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2654 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
"labelbox", labelbox);
2655 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
"hbox", hbox);
2656 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
"ahbox", ahbox);
2657 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(ahbox),
"eventbox", aeventbox);
2658 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(labelbox),
"layer_number",
2659 LIVES_INT_TO_POINTER(LIVES_POINTER_TO_INT
2660 (lives_widget_object_get_data
2661 (LIVES_WIDGET_OBJECT(eventbox),
"layer_number"))));
2664 LIVES_GUI_CALLBACK(atrack_ebox_pressed),
2672 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL), (LiVESAttachOptions)(0), 0, 0);
2682 lives_signal_sync_connect(LIVES_GUI_OBJECT(aeventbox), LIVES_WIDGET_EXPOSE_EVENT,
2683 LIVES_GUI_CALLBACK(expose_track_event), (livespointer)mt);
2689 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"achan0");
2690 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY))
2692 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2695 label = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"label")));
2709 labelbox, 2, 6, rows, rows + 1, LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2711 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
2712 (LiVESAttachOptions)(LIVES_FILL), 0, 0);
2714 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"labelbox", labelbox);
2715 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"hbox", hbox);
2720 LIVES_GUI_CALLBACK(mt_expose_audtrack_event),
2728 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"achan1");
2729 hidden = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY))
2731 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(hidden));
2734 label = (LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"label")));
2748 LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
2750 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
2751 (LiVESAttachOptions)(0), 0, 0);
2755 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"labelbox", labelbox);
2756 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"hbox", hbox);
2761 LIVES_GUI_CALLBACK(mt_expose_audtrack_event),
2770 vdraws = vdraws->next;
2777 (
double)(get_top_track_for(mt, mt->num_video_tracks - 1) +
2788 while (table_children) {
2789 LiVESWidget *child = (LiVESWidget *)table_children->data;
2791 table_children = table_children->next;
2794 if (xlist) lives_list_free(xlist);
2796 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
2801 mt->no_expose =
FALSE;
2808 LiVESWidget *eventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
"eventbox");
2809 LiVESWidget *arrow = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"arrow"), *new_arrow;
2810 lives_mt *mt = (lives_mt *)user_data;
2811 boolean expanded = !(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
2815 if (!mt->audio_draws || (!mt->opts.pertrack_audio && (mt->opts.back_audio_tracks == 0 ||
2816 eventbox != mt->audio_draws->data))) {
2817 track_ebox_pressed(eventbox, NULL, mt);
2821 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded", LIVES_INT_TO_POINTER(expanded));
2845 lives_mt *mt = (lives_mt *)user_data;
2851 lives_mt *mt = (lives_mt *)user_data;
2852 if (!mt->block_selected)
return;
2859static char *time_to_string(
double secs) {
2860 int hours, mins, rest;
2863 hours = secs / 3600;
2864 secs -= hours * 3600.;
2867 rest = (secs - ((int)secs) * 1.) * 100. + .5;
2868 secs = (int)secs * 1.;
2869 lives_snprintf(timestring,
TIMECODE_LENGTH,
"%02d:%02d:%02d.%02d", hours, mins, (
int)secs, rest);
2870 return lives_strdup(timestring);
2874static void update_timecodes(lives_mt * mt,
double dtime) {
2875 char *timestring = time_to_string(
QUANT_TIME(dtime));
2884static void set_fxlist_label(lives_mt * mt) {
2885 char *tname =
get_track_name(mt, mt->current_track, mt->aud_track_selected);
2893static void renumber_clips(
void) {
2904 boolean bad_header =
FALSE;
2906 renumbered_clips[0] = 0;
2913 for (cclip = 1; i <=
MAX_FILES; cclip++) {
2918 for (j = 0; j <
FN_KEYS - 1; j++) {
2925 if (LIVES_POINTER_TO_INT(clist->data) == i) {
2926 clist->data = LIVES_INT_TO_POINTER(cclip);
2929 clist = clist->next;
2940 renumbered_clips[i] = cclip;
2945 renumbered_clips[cclip] = cclip;
2946 if (i == cclip) i++;
2965static void rerenumber_clips(
const char *lfile, weed_plant_t *event_list) {
2979 upd_layout_maps(event_list);
2981 renumbered_clips[0] = 0;
2984 renumbered_clips[i] = 0;
2986 else lfps[i] =
cfile->fps;
2994 if (!
lives_strncmp((
char *)lmap->data, lfile, strlen(lfile))) {
2996 array = lives_strsplit((
char *)lmap->data,
"|", -1);
3000 rnc = atoi(array[1]);
3001 if (rnc < 0 || rnc >
MAX_FILES)
continue;
3002 renumbered_clips[rnc] = i;
3005 lfps[i] = strtod(array[3], NULL);
3007 lives_strfreev(array);
3026 LiVESWidget *clipbox = NULL;
3027 boolean was_neg =
FALSE;
3030 mt->file_selected = -1;
3035 if (!mt->was_undo_redo) {
3039 if (mt->clip_selected < 0) {
3041 mt->clip_selected = -mt->clip_selected;
3044 if (mt->clip_selected >= (len = lives_list_length(list)) && !was_neg) mt->clip_selected = 0;
3046 if (was_neg) mt->clip_selected--;
3048 if (mt->clip_selected < 0 || (was_neg && mt->clip_selected == 0)) mt->clip_selected = len - 1;
3050 if (mt->clip_selected < 0) {
3051 mt->file_selected = -1;
3052 lives_list_free(list);
3067 for (
int i = 0; i < len; i++) {
3068 clipbox = (LiVESWidget *)lives_list_nth_data(list, i);
3069 if (i == mt->clip_selected) {
3077 if (mt->current_track > -1) {
3092 lives_list_free(list);
3096boolean mt_prevclip(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3097 livespointer user_data) {
3098 lives_mt *mt = (lives_mt *)user_data;
3100 mt->clip_selected--;
3107boolean mt_nextclip(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3108 livespointer user_data) {
3109 lives_mt *mt = (lives_mt *)user_data;
3111 mt->clip_selected++;
3118static void set_time_scrollbar(lives_mt * mt) {
3119 double page = mt->tl_max - mt->tl_min;
3120 if (mt->end_secs == 0.) mt->end_secs =
DEF_TIME;
3122 if (mt->tl_max > mt->end_secs) mt->end_secs = mt->tl_max;
3124 lives_widget_object_freeze_notify(LIVES_WIDGET_OBJECT(mt->hadjustment));
3129 lives_widget_object_thaw_notify(LIVES_WIDGET_OBJECT(mt->hadjustment));
3135 double pos = mt->ptr_time;
3137 mt->end_secs = secs;
3140 giw_timeline_set_max_size(GIW_TIMELINE(mt->timeline), mt->end_secs);
3145 lives_ruler_set_range(LIVES_RULER(mt->timeline), mt->tl_min, mt->tl_max, mt->tl_min, mt->end_secs + 1. / mt->fps);
3148 if (!mt->sel_locked || mt->region_end < mt->end_secs + 1. / mt->fps) {
3152 set_time_scrollbar(mt);
3156 redraw_all_event_boxes(mt);
3160static weed_timecode_t set_play_position(lives_mt * mt) {
3162 boolean has_pb_loop_event =
FALSE;
3164#ifdef ENABLE_JACK_TRANSPORT
3170#ifdef ENABLE_JACK_TRANSPORT
3175 has_pb_loop_event =
TRUE;
3183 if (end_tc > 0) tc %= end_tc;
3184 mt->is_paused =
FALSE;
3193 mt->pb_unpaused_start_time = mt->ptr_time;
3195 mt->pb_start_time = mt->ptr_time;
3198#ifdef ENABLE_JACK_TRANSPORT
3207 if (!has_pb_loop_event) mt->pb_loop_event = mt->pb_start_event;
3221 weed_timecode_t curr_tc;
3223 double ptr_time = mt->ptr_time;
3232 boolean needs_idlefunc =
FALSE;
3233 boolean did_backup = mt->did_backup;
3234 static boolean lastblank =
TRUE;
3237 if (mt->no_frame_update)
return;
3241 if (mt->idlefunc > 0) {
3244 needs_idlefunc =
TRUE;
3247 if (!return_layer) {
3249 if (!mt->mt_frame_preview) {
3251 mt->mt_frame_preview =
TRUE;
3274#if GTK_CHECK_VERSION(3, 0, 0)
3275 if (!mt->frame_pixbuf || mt->frame_pixbuf !=
mainw->
imframe) {
3285#if GTK_CHECK_VERSION(3, 0, 0)
3288 mt->frame_pixbuf = NULL;
3296 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
3303 curr_tc = set_play_position(mt);
3307 if (mt->is_rendering && actual_frame <= mainw->files[mt->render_file]->frames) {
3312 weed_plant_t *live_inst = NULL;
3315 if (mt->event_list) {
3316 if (mt->pb_start_event) {
3317 cfile->next_event = mt->pb_start_event;
3334 if (mt->current_rfx && mt->init_event) {
3336 live_inst = (weed_plant_t *)mt->current_rfx->source;
3346 int key = atoi(keystr) + 1;
3354 if (mt->current_rfx->source) {
3358 for (
int i = 0; i < nparams; i++) {
3359 weed_leaf_dup(dst_params[i], src_params[i], WEED_LEAF_VALUE);
3362 mt->solo_inst = mt->current_rfx->source;
3364 mt->solo_inst = NULL;
3385 mt->preview_layer = -100000;
3386 mt->solo_inst = NULL;
3392 if (live_inst) mt->current_rfx->source = (
void *)live_inst;
3404 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
3410#if GTK_CHECK_VERSION(3, 0, 0)
3411 if (mt->frame_pixbuf && mt->frame_pixbuf !=
mainw->
imframe) {
3413 mt->frame_pixbuf = NULL;
3417 if (mt->frame_pixbuf && mt->frame_pixbuf ==
mainw->
imframe) {
3425 LiVESPixbuf *pixbuf = NULL;
3426 int pwidth, pheight, lb_width, lb_height;
3427 int cpal = WEED_PALETTE_RGB24, layer_palette;
3428 boolean was_letterboxed =
FALSE;
3434 pwidth = mt->play_width;
3435 pheight = mt->play_height;
3437 if (weed_get_boolean_value(
mainw->
frame_layer,
"letterboxed", NULL) == WEED_FALSE) {
3444 pheight = lb_height;
3446 LIVES_INTERP_BEST, cpal, 0))
3448 was_letterboxed =
TRUE;
3468#if GTK_CHECK_VERSION(3, 0, 0)
3470 mt->frame_pixbuf = pixbuf;
3484#if GTK_CHECK_VERSION(3, 0, 0)
3493 if (mt->frame_pixbuf && mt->frame_pixbuf !=
mainw->
imframe) {
3496 mt->frame_pixbuf = NULL;
3504 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
3510static void tc_to_rs(LiVESMenuItem * menuitem, livespointer user_data) {
3511 lives_mt *mt = (lives_mt *)user_data;
3512 mt->region_start = mt->ptr_time;
3517static void tc_to_re(LiVESMenuItem * menuitem, livespointer user_data) {
3518 lives_mt *mt = (lives_mt *)user_data;
3519 mt->region_end = mt->ptr_time;
3524static void rs_to_tc(LiVESMenuItem * menuitem, livespointer user_data) {
3525 lives_mt *mt = (lives_mt *)user_data;
3530static void re_to_tc(LiVESMenuItem * menuitem, livespointer user_data) {
3531 lives_mt *mt = (lives_mt *)user_data;
3538static void _mt_tl_move(lives_mt * mt,
double pos) {
3540 if (pos < 0.) pos = 0.;
3556 if (mt->is_paused) {
3557 mt->is_paused =
FALSE;
3563 if (mt->init_event && mt->poly_state ==
POLY_PARAMS && !mt->block_node_spin) {
3564 mt->block_tl_move =
TRUE;
3567 mt->block_tl_move =
FALSE;
3570 update_timecodes(mt, pos);
3578 if (mt->init_event) {
3582 mt->init_event = NULL;
3590 paint_lines(mt, pos,
TRUE, NULL);
3605boolean mt_tlfor(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3606 livespointer user_data) {
3607 lives_mt *mt = (lives_mt *)user_data;
3609 mt->fm_edit_event = NULL;
3615boolean mt_tlfor_frame(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3616 livespointer user_data) {
3617 lives_mt *mt = (lives_mt *)user_data;
3619 mt->fm_edit_event = NULL;
3625boolean mt_tlback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3626 livespointer user_data) {
3627 lives_mt *mt = (lives_mt *)user_data;
3629 mt->fm_edit_event = NULL;
3634boolean mt_tlback_frame(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3635 livespointer user_data) {
3636 lives_mt *mt = (lives_mt *)user_data;
3638 mt->fm_edit_event = NULL;
3644static void scroll_track_on_screen(lives_mt * mt,
int track) {
3645 if (track > mt->top_track) track = get_top_track_for(mt, track);
3651 lives_mt *mt = (lives_mt *)user_data;
3657static void mt_zoom(lives_mt * mt,
double scale) {
3663 double tl_span = (mt->tl_max - mt->tl_min) / 2.;
3667 tl_cur = mt->ptr_time;
3669 tl_cur = mt->tl_min + tl_span;
3673 mt->tl_min = tl_cur - tl_span * scale;
3674 mt->tl_max = tl_cur + tl_span * scale;
3676 if (mt->tl_min < 0.) {
3677 mt->tl_max -= mt->tl_min;
3684 if (mt->tl_min == mt->tl_max) mt->tl_max = mt->tl_min + 1. / mt->fps;
3687 giw_timeline_set_max_size(GIW_TIMELINE(mt->timeline), mt->tl_max);
3692 set_time_scrollbar(mt);
3696 redraw_all_event_boxes(mt);
3700static void scroll_time_by_scrollbar(LiVESHScrollbar * sbar, livespointer user_data) {
3701 lives_mt *mt = (lives_mt *)user_data;
3706 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
3710boolean mt_trdown(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3711 livespointer user_data) {
3712 lives_mt *mt = (lives_mt *)user_data;
3715 if (mt->current_track >= 0 && mt->opts.pertrack_audio && !mt->aud_track_selected) {
3716 LiVESWidget *eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
3717 mt->aud_track_selected = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
3718 if (!mt->aud_track_selected && mt->current_track == mt->num_video_tracks - 1)
return TRUE;
3720 if (mt->current_track == mt->num_video_tracks - 1)
return TRUE;
3721 mt->aud_track_selected =
FALSE;
3724 if (!mt->aud_track_selected || mt->current_track == -1) {
3725 if (mt->current_track > -1) mt->current_track++;
3728 LiVESList *llist = mt->video_draws;
3730 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(llist->data),
HIDDEN_KEY)) == 0) {
3731 mt->current_track = i;
3734 llist = llist->next;
3737 mt->current_track = i;
3740 mt->selected_init_event = NULL;
3741 scroll_track_on_screen(mt, mt->current_track);
3748boolean mt_trup(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
3749 livespointer user_data) {
3750 lives_mt *mt = (lives_mt *)user_data;
3751 if (mt->current_track == -1 || (mt->current_track == 0 && !mt->aud_track_selected && !mt->opts.show_audio))
return TRUE;
3754 if (mt->aud_track_selected) mt->aud_track_selected =
FALSE;
3756 mt->current_track--;
3757 if (mt->current_track >= 0 && mt->opts.pertrack_audio) {
3758 LiVESWidget *eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
3759 mt->aud_track_selected = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"));
3762 mt->selected_init_event = NULL;
3763 if (mt->current_track != -1) scroll_track_on_screen(mt, mt->current_track);
3785static void notebook_error(LiVESNotebook * nb, uint32_t tab,
lives_mt_nb_error_t err, lives_mt * mt) {
3789 mt->nb_label = NULL;
3795 mt->nb_label =
lives_standard_label_new(
_(
"\n\nPlease select a block\nin the timeline by\nright or double clicking on it.\n"));
3799 _(
"\n\nNo effect selected.\nSelect an effect in FX stack first to view its parameters.\n"));
3806 _(
"You must select two video tracks\nand a time region\nto apply transitions.\n\n"
3807 "Alternately, you can enable Autotransitions from the Effects menu\nbefore inserting clips into the timeline."));
3811 _(
"\n\nYou must select at least one video track\nand a time region\nto apply compositors.\n"));
3833static void fubar(lives_mt * mt) {
3840 mt->init_event = mt->selected_init_event;
3842 mt->track_index = -1;
3844 in_tracks = weed_get_int_array_counted(mt->init_event,
WEED_LEAF_IN_TRACKS, &num_in_tracks);
3845 if (num_in_tracks > 0) {
3847 for (i = 0; i < num_in_tracks; i++) {
3848 if (mt->current_track == in_tracks[i]) {
3849 mt->track_index = i;
3860 pchainx = weed_get_voidptr_array_counted(mt->init_event, WEED_LEAF_IN_PARAMETERS, &npch);
3862 pchain = (
void **)
lives_malloc((npch + 1) *
sizeof(
void *));
3863 for (i = 0; i < npch; i++) pchain[i] = pchainx[i];
3870static boolean notebook_page(LiVESWidget * nb, LiVESWidget * nbp, uint32_t tab, livespointer user_data) {
3875 lives_mt *mt = (lives_mt *)user_data;
3887 mt->nb_label = NULL;
3897 if (!mt->clip_labels) {
3905 if (!mt->block_selected && mt->poly_state !=
POLY_IN_OUT) {
3906 notebook_error(LIVES_NOTEBOOK(mt->nb), tab,
NB_ERROR_SEL, mt);
3917 if (!mt->block_selected && mt->poly_state !=
POLY_EFFECTS) {
3918 notebook_error(LIVES_NOTEBOOK(mt->nb), tab,
NB_ERROR_SEL, mt);
3925 if (lives_list_length(mt->selected_tracks) != 2 || mt->region_start == mt->region_end) {
3935 if (!mt->selected_tracks || mt->region_start == mt->region_end) {
3943 if (mt->poly_state !=
POLY_PARAMS && !mt->selected_init_event) {
3948 if (mt->selected_init_event && mt->poly_state !=
POLY_PARAMS) {
3973static void select_block(lives_mt * mt) {
3974 track_rect *block = mt->putative_block;
3980 LiVESWidget *eventbox = block->eventbox;
3982 if (!
mainw->
files[mt->render_file]->
achans || !mt->audio_draws || (mt->opts.back_audio_tracks == 0 ||
3983 eventbox != mt->audio_draws->data))
3984 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
3990 mt->block_selected = block;
3994 if (
mainw->
files[mt->render_file]->
achans == 0 || !mt->audio_draws || (mt->opts.back_audio_tracks == 0 ||
3995 eventbox != mt->audio_draws->data))
3996 add_context_label(mt, (tmp2 = lives_markup_printf_escaped(
_(
"Current track: %s (layer %d)\n"),
3997 lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"track_name"), track)));
4018 redraw_eventbox(mt, eventbox);
4021 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
4024 mt->context_time = -1.;
4034 pkg_list = lives_list_append(pkg_list, pkgstring);
4035 return lives_list_length(pkg_list);
4039 return strdup(lives_list_nth_data(pkg_list, pkgnum - 1));
4047static void populate_filter_box(
int ninchans, lives_mt * mt,
int pkgnum);
4049static boolean filter_ebox_pressed(LiVESWidget * eventbox, LiVESXEventButton * event, livespointer user_data) {
4050 lives_mt *mt = (lives_mt *)user_data;
4054 if (mt->is_rendering)
return FALSE;
4056 if ((pkgnum = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"pkgnum"))) != 0) {
4057 populate_filter_box(0, mt, pkgnum);
4061 mt->selected_filter = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"fxid"));
4063 if (event->type != LIVES_BUTTON_PRESS) {
4070 if (!mt->video_draws && !mt->audio_draws) {
4074 mt->hotspot_x = mt->hotspot_y = 0;
4082static boolean on_drag_filter_end(LiVESWidget * widget, LiVESXEventButton * event, livespointer user_data) {
4083 LiVESXWindow *window;
4084 LiVESWidget *eventbox = NULL, *oeventbox;
4085 LiVESWidget *labelbox;
4088 lives_mt *mt = (lives_mt *)user_data;
4089 double timesecs = 0.;
4090 int win_x, win_y, nins;
4095 mt->selected_filter = -1;
4102 mt->selected_filter = -1;
4108 mt->display, &win_x, &win_y);
4111 for (list = mt->audio_draws; list; list = list->next) {
4112 eventbox = (LiVESWidget *)list->data;
4113 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY)) != 0)
continue;
4114 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox");
4118 mt->timeline, &mt->sel_x, &mt->sel_y);
4121 tchan = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
4122 if ((oeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"owner")) != NULL) {
4123 eventbox = oeventbox;
4132 for (list = mt->video_draws; list; list = list->next) {
4133 eventbox = (LiVESWidget *)list->data;
4134 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY)) != 0)
continue;
4135 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox");
4136 ahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"ahbox");
4141 mt->timeline, &mt->sel_x, &mt->sel_y);
4144 tchan = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
4152 mt->selected_filter = -1;
4156 mt->current_fx = mt->selected_filter;
4157 mt->selected_filter = -1;
4161 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(dummy_menuitem),
"idx", LIVES_INT_TO_POINTER(mt->current_fx));
4181 block = get_block_from_time(eventbox, timesecs, mt);
4188 mt->putative_block = block;
4191 if (mt->current_track < 0) mt->aud_track_selected =
TRUE;
4192 else mt->aud_track_selected =
FALSE;
4198 mt->putative_block = NULL;
4200 }
else if (nins == 2) {
4202 if (lives_list_length(mt->selected_tracks) == 2 && mt->region_start != mt->region_end) {
4204 lives_timer_add_simple(0, mt_add_region_effect_idle, mt);
4206 }
else if (nins >= 1000000) {
4208 if (mt->selected_tracks && mt->region_start != mt->region_end) {
4210 lives_timer_add_simple(0, mt_add_region_effect_idle, mt);
4219static void add_to_listbox(lives_mt * mt, LiVESWidget * xeventbox,
char *fname,
boolean add_top) {
4247 lives_signal_sync_connect(LIVES_GUI_OBJECT(xeventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
4248 LIVES_GUI_CALLBACK(filter_ebox_pressed), (livespointer)mt);
4249 lives_signal_sync_connect(LIVES_GUI_OBJECT(xeventbox), LIVES_WIDGET_BUTTON_RELEASE_EVENT,
4250 LIVES_GUI_CALLBACK(on_drag_filter_end), (livespointer)mt);
4254static void populate_filter_box(
int ninchans, lives_mt * mt,
int pkgnum) {
4255 static int oxninchans = 0;
4257 LiVESWidget *eventbox = NULL, *xeventbox;
4258 char *fname, *pkgstring = NULL, *pkg_name = NULL, *catstring;
4268 LIVES_POLICY_AUTOMATIC, LIVES_POLICY_AUTOMATIC);
4279 if (!mt->block_selected && ninchans == 1)
return;
4281 if (mt->block_selected) eventbox = mt->block_selected->eventbox;
4284 ninchans = oxninchans;
4285 if (pkgnum == -1) pkgnum = 0;
4291 oxninchans = ninchans;
4297 for (i = 0; i < nfilts; i++) {
4301 int mandouts = 0, nouts = 0;
4302 weed_plant_t **ctmpls;
4305 (!
is_pure_audio(filter,
FALSE) && eventbox && is_audio_eventbox(eventbox)))
continue;
4312 for (j = 0; j < nouts; j++) {
4319 if (j < nouts)
continue;
4321 if ((nins == ninchans || (ninchans == 1000000 && nins >= ninchans)) && mandouts == 1) {
4327 if (pkg_name && strcmp(pkgstring, pkg_name)) {
4333 if (!pkg_name || !(*pkg_name)) {
4338 fname =
lives_strdup_printf(
_(
"%s from %s package (CLICK TO SHOW) ---->"), catstring, pkgstring);
4353 if (pkg_name && *pkg_name && !pkgstring) {
4363 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"fxid", LIVES_INT_TO_POINTER(sorted));
4364 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"pkgnum", LIVES_INT_TO_POINTER(pkgnum));
4368 add_to_listbox(mt, xeventbox, fname,
FALSE);
4376 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"fxid", LIVES_INT_TO_POINTER(0));
4377 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"pkgnum", LIVES_INT_TO_POINTER(-1));
4380 add_to_listbox(mt, xeventbox, fname,
TRUE);
4388static track_rect *mt_selblock(LiVESMenuItem * menuitem, livespointer user_data) {
4390 lives_mt *mt = (lives_mt *)user_data;
4391 LiVESWidget *eventbox;
4392 double timesecs = mt->ptr_time;
4393 boolean desel =
TRUE;
4395 if (mt->current_track == -1 || mt->aud_track_selected)
4396 eventbox = (LiVESWidget *)lives_list_nth_data(mt->audio_draws, mt->current_track + mt->opts.back_audio_tracks);
4397 else eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
4399 if (!menuitem)
return get_block_from_time(eventbox, timesecs, mt);
4401 mt->putative_block = get_block_from_time(eventbox, timesecs, mt);
4406 if (!desel) select_block((lives_mt *)user_data);
4408 return mt->putative_block;
4413 lives_mt *mt = (lives_mt *)user_data;
4415 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
4419void mt_zoom_in(LiVESMenuItem * menuitem, livespointer user_data) {
4420 lives_mt *mt = (lives_mt *)user_data;
4425 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
4430 lives_mt *mt = (lives_mt *)user_data;
4435 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
4439static void hpaned_position(LiVESWidgetObject *
object, livespointer pspec, livespointer user_data) {
4440 lives_mt *mt = (lives_mt *)user_data;
4445static void no_time_selected(lives_mt * mt) {
4453 lives_mt *mt = (lives_mt *)user_data;
4454 boolean has_region = (mt->region_start != mt->region_end);
4466 if ((((mt->region_start != mt->region_end && !has_region) || (mt->region_start == mt->region_end && has_region))) &&
4469 if (mt->selected_tracks) {
4471 if (mt->region_start != mt->region_end) {
4476 switch (lives_list_length(mt->selected_tracks)) {
4485 if (!mt->opts.pertrack_audio)
4500 if (mt->region_start == mt->region_end) no_time_selected(mt);
4507 lives_mt *mt = (lives_mt *)user_data;
4508 boolean has_region = (mt->region_start != mt->region_end);
4520 if ((((mt->region_start != mt->region_end && !has_region) || (mt->region_start == mt->region_end && has_region))) &&
4523 if (mt->selected_tracks) {
4525 if (mt->region_start != mt->region_end) {
4531 switch (lives_list_length(mt->selected_tracks)) {
4541 if (!mt->opts.pertrack_audio)
4556 if (mt->region_start == mt->region_end) no_time_selected(mt);
4562static boolean in_out_ebox_pressed(LiVESWidget * eventbox, LiVESXEventButton * event, livespointer user_data) {
4568 lives_mt *mt = (lives_mt *)user_data;
4572 if (mt->block_selected)
return FALSE;
4579 if (!mt->video_draws && !mt->audio_draws) {
4583 if (!mt->opts.ign_ins_sel) {
4584 width = (sfile->
end - sfile->
start + 1.) / sfile->
fps;
4589 if (width == 0)
return FALSE;
4590 width = width / (mt->tl_max - mt->tl_min) * (
double)ebwidth;
4591 if (width > ebwidth) width = ebwidth;
4592 if (width < 2) width = 2;
4593 height = get_track_height(mt);
4598 mt->hotspot_x = mt->hotspot_y = 0;
4605static void do_clip_context(lives_mt * mt, LiVESXEventButton * event,
lives_clip_t *sfile) {
4608 LiVESWidget *edit_start_end, *edit_clipedit, *close_clip, *show_clipinfo;
4625 lives_signal_sync_connect(LIVES_GUI_OBJECT(edit_clipedit), LIVES_WIDGET_ACTIVATE_SIGNAL,
4656static boolean clip_ebox_pressed(LiVESWidget * eventbox, LiVESXEventButton * event, livespointer user_data) {
4657 lives_mt *mt = (lives_mt *)user_data;
4664 if (!mt->is_ready)
return FALSE;
4668 if (event->type != LIVES_BUTTON_PRESS && !mt->is_rendering) {
4682 if (event->button == 3) {
4685 mt->timeline, &mt->sel_x, &mt->sel_y);
4689 do_clip_context(mt, event, sfile);
4694 if (!mt->video_draws && !mt->audio_draws) {
4698 if (!mt->opts.ign_ins_sel) {
4699 width = (sfile->
end - sfile->
start + 1.) / sfile->
fps;
4704 if (width == 0)
return FALSE;
4705 width = width / (mt->tl_max - mt->tl_min) * (
double)ebwidth;
4706 if (width > ebwidth) width = ebwidth;
4707 if (width < 2) width = 2;
4708 height = get_track_height(mt);
4711 mt->hotspot_x = mt->hotspot_y = 0;
4718static boolean on_drag_clip_end(LiVESWidget * widget, LiVESXEventButton * event, livespointer user_data) {
4719 lives_mt *mt = (lives_mt *)user_data;
4721 LiVESXWindow *window;
4722 LiVESWidget *eventbox;
4723 LiVESWidget *labelbox;
4726 double timesecs, osecs;
4735 if (mt->is_rendering)
return FALSE;
4739 osecs = mt->ptr_time;
4747 mt->display, &win_x, &win_y);
4749 if (
mainw->
files[mt->render_file]->
achans > 0 && mt->opts.back_audio_tracks > 0 &&
4750 LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
HIDDEN_KEY)) == 0) {
4751 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"labelbox");
4752 ahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
"ahbox");
4761 mt->timeline, &mt->sel_x, &mt->sel_y);
4764 mt->current_track = -1;
4769 if (!mt->is_paused) {
4774 if (timesecs > 0.) {
4792 for (LiVESList *list = mt->video_draws; list; list = list->next) {
4793 eventbox = (LiVESWidget *)list->data;
4795 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY)) != 0)
continue;
4797 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox");
4798 ahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"ahbox");
4804 mt->timeline, &mt->sel_x, &mt->sel_y);
4807 mt->current_track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
4808 mt->aud_track_selected =
FALSE;
4814 if (!mt->is_paused) {
4816 if (timesecs > 0.) {
4836static boolean on_clipbox_enter(LiVESWidget * widget, LiVESXEventCrossing * event, livespointer user_data) {
4837 lives_mt *mt = (lives_mt *)user_data;
4860 LIVES_KEY_m, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
4864 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->amixer_button), LIVES_WIDGET_CLICKED_SIGNAL,
4865 LIVES_GUI_CALLBACK(
amixer_show), (livespointer)mt);
4868 (tmp2 = H_(
"When active, all layers will be audible regardless of visibility")),
4869 &mt->opts.audio_bleedthru);
4882 mt->l_sel_arrow =
lives_arrow_new(LIVES_ARROW_LEFT, LIVES_SHADOW_OUT);
4891 mt->r_sel_arrow =
lives_arrow_new(LIVES_ARROW_RIGHT, LIVES_SHADOW_OUT);
4906 mt->spin_start_func = lives_signal_sync_connect_after(LIVES_GUI_OBJECT(mt->spinbutton_start), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
4910 mt->spin_end_func = lives_signal_sync_connect_after(LIVES_GUI_OBJECT(mt->spinbutton_end), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
4917 char *fname, *text, *tmp;
4947 const char *mtext = NULL;
4952 if (!mt->ins_label) {
4966static void on_insert_mode_changed(LiVESMenuItem * menuitem, livespointer user_data) {
4967 lives_mt *mt = (lives_mt *)user_data;
4971 if (menuitem == (LiVESMenuItem *)mt->ins_normal) {
4978static void on_mouse_mode_changed(LiVESMenuItem * menuitem, livespointer user_data) {
4979 lives_mt *mt = (lives_mt *)user_data;
4984 if (menuitem == (LiVESMenuItem *)mt->mm_move) {
4986 }
else if (menuitem == (LiVESMenuItem *)mt->mm_select) {
4992 if (!mt->ins_label) {
5014 const char *mtext = NULL;
5047static void on_grav_mode_changed(LiVESMenuItem * menuitem, livespointer user_data) {
5048 lives_mt *mt = (lives_mt *)user_data;
5052 if (menuitem == (LiVESMenuItem *)mt->grav_normal) {
5054 }
else if (menuitem == (LiVESMenuItem *)mt->grav_left) {
5056 }
else if (menuitem == (LiVESMenuItem *)mt->grav_right) {
5063static size_t estimate_space(lives_mt * mt,
int undo_type) {
5064 size_t needed =
sizeof(
mt_undo);
5066 switch (undo_type) {
5070 needed += event_list_get_byte_size(mt, mt->event_list,
FALSE, NULL);
5077static char *get_undo_text(
int action,
void *extra) {
5078 char *filtname, *ret;
5082 return (
_(
"Close gaps"));
5084 return (
_(
"Move block"));
5086 return (
_(
"Move audio block"));
5088 return (
_(
"Delete block"));
5090 return (
_(
"Delete audio block"));
5092 return (
_(
"Split tracks"));
5094 return (
_(
"Split block"));
5096 filtname = weed_get_string_value((weed_plant_t *)extra, WEED_LEAF_NAME, NULL);
5101 filtname = weed_get_string_value((weed_plant_t *)extra, WEED_LEAF_NAME, NULL);
5106 return (
_(
"Insert block"));
5108 return (
_(
"Insert gap"));
5110 return (
_(
"Insert audio block"));
5112 return (
_(
"Effect order change"));
5114 return lives_strdup(
"");
5118static void mt_set_undoable(lives_mt * mt,
int what,
void *extra,
boolean sensitive) {
5119 mt->undoable = sensitive;
5122 char *text = get_undo_text(what, extra);
5123 what_safe = lives_strdelimit(lives_strdup(text),
"_",
' ');
5124 lives_snprintf(mt->undo_text, 32,
_(
"_Undo %s"), what_safe);
5129 mt->undoable =
FALSE;
5130 lives_snprintf(mt->undo_text, 32,
"%s",
_(
"_Undo"));
5138static void mt_set_redoable(lives_mt * mt,
int what,
void *extra,
boolean sensitive) {
5139 mt->redoable = sensitive;
5142 char *text = get_undo_text(what, extra);
5143 what_safe = lives_strdelimit(lives_strdup(text),
"_",
' ');
5144 lives_snprintf(mt->redo_text, 32,
_(
"_Redo %s"), what_safe);
5148 mt->redoable =
FALSE;
5149 lives_snprintf(mt->redo_text, 32,
"%s",
_(
"_Redo"));
5159 size_t space_avail = (size_t)(
prefs->
mt_undo_buf * 1024 * 1024) - mt->undo_buffer_used;
5160 size_t space_freed = 0;
5162 LiVESList *xundo = mt->undos, *ulist;
5168 undo = (
mt_undo *)(xundo->data);
5170 if ((space_avail + space_freed) >= space_needed) {
5171 lives_memmove(mt->undo_mem, mt->undo_mem + space_freed, mt->undo_buffer_used - space_freed);
5172 ulist = lives_list_copy(lives_list_nth(mt->undos, count));
5173 if (ulist) ulist->prev = NULL;
5174 lives_list_free(mt->undos);
5177 ulist->data = (
unsigned char *)(ulist->data) - space_freed;
5178 ulist = ulist->next;
5180 mt->undo_buffer_used -= space_freed;
5181 if (mt->undo_offset > (len = lives_list_length(mt->undos))) {
5182 mt->undo_offset = len;
5184 mt_set_redoable(mt, ((
mt_undo *)(mt->undos->data))->action, NULL,
TRUE);
5188 xundo = xundo->next;
5190 mt->undo_buffer_used = 0;
5191 lives_list_free(mt->undos);
5193 mt->undo_offset = 0;
5200void mt_backup(lives_mt * mt,
int undo_type, weed_timecode_t tc) {
5203 size_t space_needed = 0;
5207 unsigned char *memblock, *omemblock;
5209 if (mt->did_backup)
return;
5212 mt->did_backup = mt->changed =
TRUE;
5218 if (!mt->undo_mem)
return;
5220 if (mt->undos && mt->undo_offset != 0) {
5223 if ((lives_list_length(mt->undos)) == mt->undo_offset) {
5225 mt->undo_buffer_used = 0;
5228 LiVESList *ulist = mt->undos;
5229 for (i = (
int)lives_list_length(mt->undos) - mt->undo_offset; --i > 0; ulist = ulist->next);
5231 memblock = (
unsigned char *)ulist->data;
5232 last_valid_undo = (
mt_undo *)memblock;
5233 memblock += last_valid_undo->
data_len;
5234 mt->undo_buffer_used = memblock - mt->undo_mem;
5236 ulist = ulist->next;
5237 ulist->prev->next = NULL;
5238 lives_list_free(ulist);
5243 mt->undo_offset = 0;
5250 switch (undo_type) {
5265 if ((space_needed = estimate_space(mt, undo_type) +
sizeof(
mt_undo)) >
5274 omemblock = memblock = (
unsigned char *)(mt->undo_mem + mt->undo_buffer_used +
sizeof(
mt_undo));
5276 undo->
data_len = memblock - omemblock;
5282 mt->undos = lives_list_append(mt->undos, mt->undo_mem + mt->undo_buffer_used);
5283 mt->undo_buffer_used += space_needed;
5290 lives_mt *mt = (lives_mt *)user_data;
5292 int which = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(menuitem),
"pnum"));
5295 mt->opts.aparam_view_list = lives_list_append(mt->opts.aparam_view_list, LIVES_INT_TO_POINTER(which));
5296 else mt->opts.aparam_view_list = lives_list_remove(mt->opts.aparam_view_list, LIVES_INT_TO_POINTER(which));
5297 for (list = mt->audio_draws; list; list = list->next) {
5303static void destroy_widget(LiVESWidget * widget, livespointer user_data) {
5310 LiVESWidget *menuitem;
5311 weed_plant_t *filter;
5317 if (mt->avol_fx == -1 || !mt->audio_draws) {
5328 if (mt->opts.aparam_view_list && !
mainw->
multi_opts.aparam_view_list) {
5329 lives_list_free(mt->opts.aparam_view_list);
5330 mt->opts.aparam_view_list = NULL;
5334 if (mt->opts.pertrack_audio) {
5355 mt->opts.aparam_view_list && lives_list_find(mt->opts.aparam_view_list, LIVES_INT_TO_POINTER(i)));
5358 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
"pnum", LIVES_INT_TO_POINTER(i));
5369static void apply_avol_filter(lives_mt * mt) {
5373 weed_plant_t *init_event = mt->avol_init_event, *new_end_event;
5374 weed_plant_t *deinit_event;
5375 weed_timecode_t new_tc;
5380 if (mt->opts.back_audio_tracks == 0 && !mt->opts.pertrack_audio)
return;
5384 if (!new_end_event) {
5387 if (mt->opts.aparam_view_list) {
5388 for (list = mt->audio_draws; list; list = list->next) {
5399 LiVESList *slist = lives_list_copy(mt->selected_tracks);
5401 weed_plant_t *old_mt_init = mt->init_event;
5403 double region_start = mt->region_start;
5404 double region_end = mt->region_end;
5406 boolean did_backup = mt->did_backup;
5407 int current_fx = mt->current_fx;
5409 mt->region_start = 0.;
5411 if (mt->selected_tracks) {
5412 lives_list_free(mt->selected_tracks);
5413 mt->selected_tracks = NULL;
5415 if (mt->opts.back_audio_tracks > 0) mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(-1));
5416 if (mt->opts.pertrack_audio) {
5417 for (i = 0; i < mt->num_video_tracks; i++) {
5418 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(i));
5421 mt->current_fx = mt->avol_fx;
5423 mt->did_backup =
TRUE;
5425 mt->did_backup = did_backup;
5426 mt->avol_init_event = mt->init_event;
5428 mt->region_start = region_start;
5429 mt->region_end = region_end;
5430 lives_list_free(mt->selected_tracks);
5431 mt->selected_tracks = lives_list_copy(slist);
5432 if (slist) lives_list_free(slist);
5433 mt->current_fx = current_fx;
5434 mt->init_event = old_mt_init;
5436 if (mt->opts.aparam_view_list) {
5437 for (list = mt->audio_draws; list; list = list->next) {
5450 if (mt->opts.aparam_view_list) {
5451 for (list = mt->audio_draws; list; list = list->next) {
5458static void set_audio_filter_channel_values(lives_mt * mt) {
5466 weed_plant_t **in_channels, **out_channels;
5468 int num_in, num_out;
5473 if (!mt->current_rfx || mt->current_fx == -1 || mt->current_fx != mt->avol_fx)
return;
5475 inst = (weed_plant_t *)mt->current_rfx->source;
5476 in_channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_IN_CHANNELS, &num_in);
5478 for (i = 0; i < num_in; i++) {
5479 weed_set_int_value(in_channels[i], WEED_LEAF_AUDIO_CHANNELS,
mainw->
files[mt->render_file]->
achans);
5480 weed_set_int_value(in_channels[i], WEED_LEAF_AUDIO_RATE,
mainw->
files[mt->render_file]->
arate);
5484 out_channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_OUT_CHANNELS, &num_out);
5486 for (i = 0; i < num_out; i++) {
5487 weed_set_int_value(out_channels[i], WEED_LEAF_AUDIO_CHANNELS,
mainw->
files[mt->render_file]->
achans);
5488 weed_set_int_value(out_channels[i], WEED_LEAF_AUDIO_RATE,
mainw->
files[mt->render_file]->
arate);
5500static char *mt_set_vals_string(
void) {
5504 else lives_snprintf(sendian, 128,
"%s",
_(
"signed "));
5510 _(
"Multitrack values set to %.3f fps, frame size %d x %d, audio channels %d, "
5511 "audio rate %d, audio sample size %d, %s.\n"),
5524 if (rwidth * rheight < 64) {
5531 width = (width >> 2) << 2;
5532 height = (height >> 2) << 2;
5534 mt->play_width = width;
5535 mt->play_height = height;
5540static weed_plant_t *load_event_list_inner(lives_mt * mt,
int fd,
boolean show_errors,
int *num_events,
5541 unsigned char **mem,
unsigned char *mem_end) {
5542 weed_plant_t *event, *eventprev = NULL;
5543 weed_plant_t *event_list;
5552 if (mt) mt->layout_set_properties =
FALSE;
5555 if (show_errors)
d_print(
_(
"invalid event list. Failed.\n"));
5559 if (show_errors && (!weed_plant_has_leaf(event_list, WEED_LEAF_FPS) ||
5560 (fps = weed_get_double_value(event_list, WEED_LEAF_FPS, NULL)) < 1. ||
5562 d_print(
_(
"event list has invalid fps. Failed.\n"));
5567 && weed_plant_has_leaf(event_list, WEED_LEAF_KEEP_ASPECT)) {
5568 boolean letterbox = weed_get_boolean_value(event_list, WEED_LEAF_KEEP_ASPECT, NULL);
5584 _(
"\nThis layout requires the set \"%s\"\nIn order to load it you must return to the Clip Editor, \n"
5585 "close the current set,\nthen load in the new set from the File menu.\n"),
5596 }
else if (mt && !show_errors && !mem)
return NULL;
5607 if (weed_plant_has_leaf(event_list, WEED_LEAF_WIDTH)) {
5608 int width = weed_get_int_value(event_list, WEED_LEAF_WIDTH, NULL);
5611 if (mt) mt->layout_set_properties =
TRUE;
5615 if (weed_plant_has_leaf(event_list, WEED_LEAF_HEIGHT)) {
5616 int height = weed_get_int_value(event_list, WEED_LEAF_HEIGHT, NULL);
5619 if (mt) mt->layout_set_properties =
TRUE;
5623 if (weed_plant_has_leaf(event_list, WEED_LEAF_AUDIO_CHANNELS)) {
5624 int achans = weed_get_int_value(event_list, WEED_LEAF_AUDIO_CHANNELS, NULL);
5625 if (achans >= 0 && mt) {
5628 _(
"\nThis layout has an invalid number of audio channels (%d) for LiVES.\n"
5629 "It cannot be loaded.\n"), achans);
5636 if (mt) mt->layout_set_properties =
TRUE;
5640 if (weed_plant_has_leaf(event_list, WEED_LEAF_AUDIO_RATE)) {
5641 int arate = weed_get_int_value(event_list, WEED_LEAF_AUDIO_RATE, NULL);
5644 if (mt) mt->layout_set_properties =
TRUE;
5650 if (asamps == 8 || asamps == 16) {
5652 if (mt) mt->layout_set_properties =
TRUE;
5662 if (asigned == WEED_TRUE) {
5669 if (mt) mt->layout_set_properties =
TRUE;
5681 if (mt) mt->layout_set_properties =
TRUE;
5687 if (mt) mt->layout_set_properties =
TRUE;
5716 if (mem && *mem >= mem_end)
break;
5725 event_id = (uint64_t)((weed_plant_t *)weed_get_voidptr_value(event,
WEED_LEAF_INIT_EVENT, NULL));
5731 if (eventprev) weed_set_voidptr_value(eventprev,
WEED_LEAF_NEXT, event);
5740 if (num_events)(*num_events)++;
5744 if (!mt)
return event_list;
5752 err = (
_(
"This layout was created using automatic gamma correction.\nFor compatibility, you may wish to"
5753 "enable this feature in Tools -> Preferences -> Effects, whilst editing and rendering the layout."));
5756 err = (
_(
"This layout was created without automatic gamma correction.\nFor compatibility, you may wish to"
5757 "disable this feature in Tools -> Preferences -> Effects, whilst editing and rendering the layout."));
5771 char *retval = NULL;
5781 load_event_list_inner(mt, -1,
TRUE, NULL, NULL, NULL);
5813 retval = mt_set_vals_string();
5820 mt->avol_init_event = NULL;
5821 }
else set_audio_filter_channel_values(mt);
5830 if (mt->undos) lives_list_free(mt->undos);
5832 mt->undo_buffer_used = 0;
5833 mt->undo_offset = 0;
5855 (LiVESCompareFunc)strcmp);
5870 if (mt->event_list) {
5872 mt->event_list = NULL;
5880 LiVESTextIter iter1, iter2;
5885 (LiVESTextMark *)markmap->next->data);
5890 markmap = markmap->next->next;
5948 }
while (resp == 2);
5953 if (resp == LIVES_RESPONSE_CANCEL) {
5960 if (resp == 1 && !exiting) {
5971 }
else if (mt && mt->event_list && (exiting || resp == 1)) {
5974 mt->event_list = NULL;
5987 LiVESList *slist = list;
5990 slist = slist->next;
5992 lives_list_free(list);
5997 lives_mt *mt = (lives_mt *)user_data;
6008static void set_mt_title(lives_mt * mt) {
6017static boolean timecode_string_validate(LiVESEntry * entry, lives_mt * mt) {
6022 double tl_range, pos;
6028 array = lives_strsplit(etext,
":", 3);
6031 lives_strfreev(array);
6035 hrs = atoi(array[0]);
6036 mins = atoi(array[1]);
6037 if (mins > 59) mins = 59;
6038 secs = lives_strtod(array[2], NULL);
6040 lives_strfreev(array);
6042 secs = secs + mins * 60. + hrs * 3600.;
6044 if (secs > mt->end_secs) {
6045 tl_range = mt->tl_max - mt->tl_min;
6048 mt->tl_min = secs - tl_range / 2;
6049 mt->tl_max = secs + tl_range / 2;
6051 if (mt->tl_max > mt->end_secs) {
6052 mt->tl_min -= (mt->tl_max - mt->end_secs);
6053 mt->tl_max = mt->end_secs;
6064 if (pos < 0.) pos = 0.;
6066 update_timecodes(mt, pos);
6072static void cmi_set_inactive(LiVESWidget * widget, livespointer data) {
6073 if (widget == data)
return;
6074 lives_widget_object_freeze_notify(LIVES_WIDGET_OBJECT(widget));
6076 lives_widget_object_thaw_notify(LIVES_WIDGET_OBJECT(widget));
6092static void mt_set_atrans_effect(LiVESMenuItem * menuitem, livespointer user_data) {
6093 lives_mt *mt = (lives_mt *)user_data;
6098 mt_set_autotrans(LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(menuitem),
"idx")));
6102static void after_timecode_changed(LiVESWidget * entry, LiVESXEventFocus * dir, livespointer user_data) {
6103 lives_mt *mt = (lives_mt *)user_data;
6106 if (!timecode_string_validate(LIVES_ENTRY(entry), mt)) {
6109 if (pos < 0.) pos = 0.;
6110 update_timecodes(mt, pos);
6115static char *get_tab_name(uint32_t tab) {
6118 return (
_(
"Clips"));
6120 return (
_(
"In/out"));
6122 return (
_(
"FX stack"));
6130 return (
_(
"Params."));
6134 return lives_strdup(
"");
6138static void set_child_grad(LiVESWidget * widget, livespointer data) {
6139 char *tmp = (
char *)data;
6142 "background-image", tmp);
6143 if (LIVES_IS_CONTAINER(widget))
6213#if GTK_CHECK_VERSION(3, 0, 0)
6222#if GTK_CHECK_VERSION(3, 0, 0)
6230#if GTK_CHECK_VERSION(3, 0, 0)
6249 "background-image",
"none");
6258 if (mt->hseparator2) {
6264 if (mt->hseparator2) {
6301 if (mt->ins_label) {
6338 && LIVES_IS_BIN(mt->fx_list_scroll) &&
lives_bin_get_child(LIVES_BIN(mt->fx_list_scroll)))
6345 if (mt->context_box && LIVES_IS_WIDGET_OBJECT(mt->context_box)) {
6356#if GTK_CHECK_VERSION(3, 16, 0)
6362 "background-image", tmp);
6377 if (mt->timeline_eb) {
6380 if (mt->timeline_reg) {
6384 if (mt->timeline_reg) {
6397#if !GTK_CHECK_VERSION(3, 0, 0)
6427 redraw_all_event_boxes(mt);
6431static void on_solo_check_toggled(LiVESWidget * widg, livespointer user_data) {
6432 lives_mt *mt = (lives_mt *)user_data;
6437static void multitrack_clear_marks(LiVESMenuItem * menuitem, livespointer user_data) {
6438 lives_mt *mt = (lives_mt *)user_data;
6439 lives_list_free(mt->tl_marks);
6440 mt->tl_marks = NULL;
6448lives_mt *
multitrack(weed_plant_t *event_list,
int orig_file,
double fps) {
6449 LiVESWidget *hseparator;
6450 LiVESWidget *menuitem;
6451 LiVESWidget *menuitem2;
6452 LiVESWidget *menuitem_menu;
6453 LiVESWidget *selcopy_menu;
6454#if LIVES_HAS_IMAGE_MENU_ITEM
6457 LiVESWidget *full_screen;
6459 LiVESWidget *show_mt_keys;
6460 LiVESWidget *view_mt_details;
6461 LiVESWidget *zoom_in;
6462 LiVESWidget *zoom_out;
6463 LiVESWidget *show_messages;
6464 LiVESWidget *scrollbar;
6467 LiVESWidget *ign_ins_sel;
6468 LiVESWidget *recent_submenu;
6469#ifdef ENABLE_DVD_GRAB
6470 LiVESWidget *vcd_dvd_submenu;
6473 LiVESWidget *device_submenu;
6476 LiVESWidget *open_loc_submenu;
6478 LiVESWidget *submenu;
6479 LiVESWidget *submenu2;
6482 LiVESWidget *submenu_menu;
6483 LiVESWidget *submenu_menuv;
6484 LiVESWidget *submenu_menua;
6485 LiVESWidget *submenu_menuvp = NULL;
6486 LiVESWidget *submenu_menuap = NULL;
6489 LiVESWidget *submenu_menurv;
6490 LiVESWidget *submenu_menura;
6491 LiVESWidget *submenu_menurvp = NULL;
6492 LiVESWidget *submenu_menurap = NULL;
6493 LiVESWidget *submenu_menu2av;
6494 LiVESWidget *submenu_menu2v;
6495 LiVESWidget *submenu_menu2a;
6496 LiVESWidget *submenu_menu3;
6498 LiVESWidget *show_frame_events;
6499 LiVESWidget *ccursor;
6501 LiVESWidget *show_manual;
6502 LiVESWidget *donate;
6503 LiVESWidget *email_author;
6504 LiVESWidget *report_bug;
6505 LiVESWidget *suggest_feature;
6506 LiVESWidget *help_translate;
6509 LiVESWidgetObject *vadjustment;
6510 LiVESAdjustment *spinbutton_adj;
6512 boolean in_menubar =
TRUE;
6514 char *cname, *tname, *msg;
6516 char *pkg, *xpkgv = NULL, *xpkga = NULL;
6517 const char *mtext = NULL;
6524 lives_mt *mt = (lives_mt *)
lives_calloc(1,
sizeof(lives_mt));
6534 mt->frame_pixbuf = NULL;
6536 mt->is_ready =
FALSE;
6537 mt->tl_marks = NULL;
6539 mt->timestring[0] = 0;
6542 mt->auto_back_time = 0;
6544 mt->playing_sel =
FALSE;
6546 mt->in_sensitise =
FALSE;
6552 if (!mt->undo_mem) {
6555 mt->undo_buffer_used = 0;
6557 mt->undo_offset = 0;
6565 mt->preview_layer = -1000000;
6567 mt->solo_inst = NULL;
6569 mt->apply_fx_button = NULL;
6570 mt->resetp_button = NULL;
6574 mt->file_selected = orig_file;
6576 mt->auto_changed = mt->changed =
FALSE;
6578 mt->was_undo_redo =
FALSE;
6580 mt->tl_mouse =
FALSE;
6582 mt->sel_locked =
FALSE;
6584 mt->clip_labels = NULL;
6586 mt->force_load_name = NULL;
6588 mt->dumlabel1 = mt->dumlabel2 = mt->tl_label = mt->timeline = mt->timeline_eb =
6589 mt->timeline_reg = NULL;
6591 mt->tl_surf = mt->tl_ev_surf = mt->tl_reg_surf = NULL;
6593 mt->play_width = mt->play_height = 0;
6598 mt->opts.aparam_view_list = lives_list_copy(
mainw->
multi_opts.aparam_view_list);
6600 mt->opts.move_effects =
TRUE;
6601 mt->opts.fx_auto_preview =
TRUE;
6602 mt->opts.snap_over =
FALSE;
6604 mt->opts.show_audio =
TRUE;
6605 mt->opts.ign_ins_sel =
FALSE;
6606 mt->opts.follow_playback =
TRUE;
6609 mt->opts.autocross_audio =
TRUE;
6610 mt->opts.render_vidp =
TRUE;
6611 mt->opts.render_audp =
TRUE;
6612 mt->opts.normalise_audp =
TRUE;
6613 mt->opts.aparam_view_list = NULL;
6614 mt->opts.hpaned_pos = mt->opts.vpaned_pos = -1;
6615 mt->opts.overlay_timecode =
TRUE;
6616 mt->opts.ptr_time = 0.;
6619 mt->opts.insert_audio =
TRUE;
6622 mt->opts.audio_bleedthru =
FALSE;
6623 mt->opts.gang_audio =
TRUE;
6624 mt->opts.back_audio_tracks = 1;
6626 if (force_pertrack_audio) mt->opts.pertrack_audio =
TRUE;
6627 force_pertrack_audio =
FALSE;
6629 mt->tl_fixed_length = 0.;
6631 mt->video_draws = NULL;
6632 mt->block_selected = NULL;
6633 mt->event_list = event_list;
6639 mt->hotspot_x = mt->hotspot_y = 0;
6640 mt->redraw_block =
FALSE;
6642 mt->region_start = mt->region_end = 0.;
6643 mt->region_updating =
FALSE;
6644 mt->is_rendering =
FALSE;
6645 mt->pr_audio =
FALSE;
6646 mt->selected_tracks = NULL;
6647 mt->mt_frame_preview =
FALSE;
6648 mt->current_rfx = NULL;
6649 mt->current_fx = -1;
6650 mt->putative_block = NULL;
6651 mt->specific_event = NULL;
6653 mt->block_tl_move =
FALSE;
6654 mt->block_node_spin =
FALSE;
6656 mt->is_atrans =
FALSE;
6662 mt->moving_block =
FALSE;
6664 mt->insert_start = mt->insert_end = -1;
6665 mt->insert_avel = 1.;
6667 mt->selected_init_event = mt->init_event = NULL;
6669 mt->auto_reloading =
FALSE;
6670 mt->fm_edit_event = NULL;
6672 mt->nb_label = NULL;
6673 mt->fx_list_box = NULL;
6674 mt->fx_list_scroll = NULL;
6675 mt->fx_list_label = NULL;
6677 mt->moving_fx = NULL;
6682 mt->did_backup =
FALSE;
6683 mt->framedraw = NULL;
6685 mt->audio_draws = NULL;
6686 mt->audio_vols = mt->audio_vols_back = NULL;
6688 mt->ignore_load_vals =
FALSE;
6690 mt->exact_preview = 0;
6692 mt->context_time = -1.;
6693 mt->use_context =
FALSE;
6695 mt->no_expose = mt->no_expose_frame =
TRUE;
6697 mt->is_paused =
FALSE;
6699 mt->pb_start_event = NULL;
6701 mt->aud_track_selected =
FALSE;
6703 mt->has_audio_file =
FALSE;
6705 mt->fx_params_label = NULL;
6708 mt->selected_filter = -1;
6714 mt->no_frame_update =
FALSE;
6720 }
else mt->avol_fx = -1;
6721 mt->avol_init_event = NULL;
6727 mt->user_arate = xarate;
6728 mt->user_achans = xachans;
6729 mt->user_asamps = xasamps;
6730 mt->user_signed_endian = xse;
6731 mt->opts.pertrack_audio = ptaud;
6732 mt->opts.back_audio_tracks = btaud;
6741 if (force_backing_tracks > mt->opts.back_audio_tracks) mt->opts.back_audio_tracks = force_backing_tracks;
6742 force_backing_tracks = 0;
6813#ifdef ENABLE_DVD_GRAB
6824 LIVES_INT_TO_POINTER(1));
6829#ifdef ENABLE_DVD_GRAB
6837 LIVES_INT_TO_POINTER(2));
6873 LIVES_KEY_w, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
6906 LIVES_KEY_s, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
6916 LIVES_KEY_d, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
6931 mt->ignore_load_vals);
6943 LIVES_KEY_q, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
6958 LIVES_KEY_u, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
6960#if LIVES_HAS_IMAGE_MENU_ITEM
6965 if (mt->undo_offset == lives_list_length(mt->undos)) mt_set_undoable(mt,
MT_UNDO_NONE, NULL,
FALSE);
6967 mt_undo *undo = (
mt_undo *)(lives_list_nth_data(mt->undos, lives_list_length(mt->undos) - mt->undo_offset - 1));
6971 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->undo), LIVES_WIDGET_ACTIVATE_SIGNAL,
6979 LIVES_KEY_z, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
6981#if LIVES_HAS_IMAGE_MENU_ITEM
6988 mt_undo *redo = (
mt_undo *)(lives_list_nth_data(mt->undos, lives_list_length(mt->undos) - mt->undo_offset));
6992 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->redo), LIVES_WIDGET_ACTIVATE_SIGNAL,
7001 LIVES_KEY_e, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7009 LIVES_KEY_x, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7016 LIVES_KEY_i, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7018 LIVES_KEY_i, LIVES_CONTROL_MASK, (LiVESAccelFlags)0);
7025 LIVES_KEY_i, LIVES_CONTROL_MASK,
7026 LIVES_ACCEL_VISIBLE);
7044 LIVES_KEY_j, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7052 LIVES_KEY_l, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7064 LIVES_KEY_j, (LIVES_CONTROL_MASK | LIVES_SHIFT_MASK),
7065 LIVES_ACCEL_VISIBLE);
7073 LIVES_KEY_l, (LIVES_CONTROL_MASK | LIVES_SHIFT_MASK),
7074 LIVES_ACCEL_VISIBLE);
7095 LIVES_KEY_p, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7100#if LIVES_HAS_IMAGE_MENU_ITEM
7107 LIVES_KEY_y, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7115 LIVES_KEY_q, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7117#if LIVES_HAS_IMAGE_MENU_ITEM
7125#if LIVES_HAS_IMAGE_MENU_ITEM
7133 LIVES_KEY_w, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7141 LIVES_KEY_f, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7147 LIVES_KEY_s, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7153 LIVES_KEY_o, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7159 LIVES_KEY_z, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7172 lives_signal_connect_after(LIVES_GUI_OBJECT(mt->move_fx), LIVES_WIDGET_TOGGLED_SIGNAL,
7173 LIVES_GUI_CALLBACK(on_move_fx_changed),
7185 mt->opts.autocross_audio);
7302 for (i = 0; i < num_filters; i++) {
7306 LiVESWidget *menuitem;
7307 char *fxname = NULL;
7316 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
"idx", LIVES_INT_TO_POINTER(sorted));
7325 if (!xpkgv || strcmp(pkg, xpkgv)) {
7346 submenu = submenu_menuvp;
7347 submenu2 = submenu_menurvp;
7349 xpkgv = lives_strdup(pkg);
7351 submenu = submenu_menuv;
7352 submenu2 = submenu_menurv;
7357 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
"idx", LIVES_INT_TO_POINTER(sorted));
7364 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
"idx", LIVES_INT_TO_POINTER(sorted));
7370 if (!xpkga || strcmp(pkg, xpkga)) {
7391 submenu = submenu_menuap;
7392 submenu2 = submenu_menurap;
7394 xpkga = lives_strdup(pkg);
7396 submenu = submenu_menua;
7397 submenu2 = submenu_menura;
7402 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
"idx", LIVES_INT_TO_POINTER(sorted));
7408 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
"idx", LIVES_INT_TO_POINTER(sorted));
7416 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
"idx", LIVES_INT_TO_POINTER(sorted));
7422 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem2),
"idx", LIVES_INT_TO_POINTER(sorted));
7424 lives_signal_sync_connect(LIVES_GUI_OBJECT(menuitem2), LIVES_WIDGET_ACTIVATE_SIGNAL,
7425 LIVES_GUI_CALLBACK(mt_set_atrans_effect), (livespointer)mt);
7449 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem2),
"idx", LIVES_INT_TO_POINTER(-1));
7452 lives_signal_sync_connect(LIVES_GUI_OBJECT(menuitem2), LIVES_WIDGET_ACTIVATE_SIGNAL,
7453 LIVES_GUI_CALLBACK(mt_set_atrans_effect),
7475 LIVES_KEY_b, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7483 LIVES_KEY_t, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7489 LIVES_KEY_t, (LiVESXModifierType)(LIVES_CONTROL_MASK | LIVES_SHIFT_MASK),
7490 LIVES_ACCEL_VISIBLE);
7501 LIVES_KEY_s, (LiVESXModifierType)LIVES_CONTROL_MASK,
7502 LIVES_ACCEL_VISIBLE);
7533 LIVES_GUI_CALLBACK(
remove_gaps), (livespointer)mt);
7536 LIVES_KEY_g, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7545 LIVES_KEY_f, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7558 lives_signal_sync_connect(LIVES_GUI_OBJECT(menuitem), LIVES_WIDGET_ACTIVATE_SIGNAL,
7565 LIVES_KEY_Space, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7571 LIVES_GUI_CALLBACK(select_all_vid), (livespointer)mt);
7577 LIVES_GUI_CALLBACK(select_no_vid), (livespointer)mt);
7583 LIVES_GUI_CALLBACK(select_all_time), (livespointer)mt);
7586 LIVES_KEY_a, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7592 LIVES_GUI_CALLBACK(select_from_zero_time), (livespointer)mt);
7598 LIVES_GUI_CALLBACK(select_to_end_time), (livespointer)mt);
7610 LIVES_GUI_CALLBACK(tc_to_rs), (livespointer)mt);
7616 LIVES_GUI_CALLBACK(tc_to_re), (livespointer)mt);
7622 LIVES_GUI_CALLBACK(rs_to_tc), (livespointer)mt);
7628 LIVES_GUI_CALLBACK(re_to_tc), (livespointer)mt);
7639 LIVES_GUI_CALLBACK(mt_selblock), (livespointer)mt);
7642 LIVES_KEY_Return, LIVES_CONTROL_MASK,
7643 LIVES_ACCEL_VISIBLE);
7683 LIVES_GUI_CALLBACK(on_mt_backup_activate), (livespointer)mt);
7690 LIVES_KEY_p, LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7692#if LIVES_HAS_IMAGE_MENU_ITEM
7697 lives_signal_sync_connect(LIVES_GUI_OBJECT(menuitem), LIVES_WIDGET_ACTIVATE_SIGNAL,
7713 LIVES_KEY_r, LIVES_CONTROL_MASK,
7714 LIVES_ACCEL_VISIBLE);
7755 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->show_info), LIVES_WIDGET_ACTIVATE_SIGNAL,
7765 LIVES_KEY_c, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7771 LIVES_KEY_n, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7779 LIVES_KEY_e, (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
7812 LIVES_KEY_c, (LiVESXModifierType)LIVES_CONTROL_MASK, LIVES_ACCEL_VISIBLE);
7818 LIVES_KEY_Plus, (LiVESXModifierType)LIVES_CONTROL_MASK,
7819 LIVES_ACCEL_VISIBLE);
7822 LIVES_KEY_Equal, (LiVESXModifierType)LIVES_CONTROL_MASK,
7823 (LiVESAccelFlags)0);
7829 LIVES_KEY_Minus, (LiVESXModifierType)LIVES_CONTROL_MASK,
7830 LIVES_ACCEL_VISIBLE);
7893 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->show_devopts), LIVES_WIDGET_ACTIVATE_SIGNAL,
7909 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->quit), LIVES_WIDGET_ACTIVATE_SIGNAL,
7911 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->load_vals), LIVES_WIDGET_ACTIVATE_SIGNAL,
7913 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->ac_audio_check), LIVES_WIDGET_ACTIVATE_SIGNAL,
7914 LIVES_GUI_CALLBACK(mt_ac_audio_toggled), (livespointer)mt);
7915 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->aload_subs), LIVES_WIDGET_ACTIVATE_SIGNAL,
7917 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->clipedit), LIVES_WIDGET_ACTIVATE_SIGNAL,
7929 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->view_events), LIVES_WIDGET_ACTIVATE_SIGNAL,
7931 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->view_sel_events), LIVES_WIDGET_ACTIVATE_SIGNAL,
7933 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->clear_marks), LIVES_WIDGET_ACTIVATE_SIGNAL,
7934 LIVES_GUI_CALLBACK(multitrack_clear_marks), (livespointer)mt);
7935 lives_signal_sync_connect(LIVES_GUI_OBJECT(view_mt_details), LIVES_WIDGET_ACTIVATE_SIGNAL,
7937 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->show_layout_errors), LIVES_WIDGET_ACTIVATE_SIGNAL,
7943 lives_signal_sync_connect(LIVES_GUI_OBJECT(show_messages), LIVES_WIDGET_ACTIVATE_SIGNAL,
7947 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->stop), LIVES_WIDGET_ACTIVATE_SIGNAL,
7949 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->rewind), LIVES_WIDGET_ACTIVATE_SIGNAL,
7951 mt->sepwin_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->sepwin), LIVES_WIDGET_ACTIVATE_SIGNAL,
7953 lives_signal_sync_connect(LIVES_GUI_OBJECT(full_screen), LIVES_WIDGET_ACTIVATE_SIGNAL,
7955 mt->loop_cont_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->loop_continue), LIVES_WIDGET_ACTIVATE_SIGNAL,
7957 mt->mute_audio_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->mute_audio), LIVES_WIDGET_ACTIVATE_SIGNAL,
7959 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->rename_track), LIVES_WIDGET_ACTIVATE_SIGNAL,
7967 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->render), LIVES_WIDGET_ACTIVATE_SIGNAL,
7971 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->jumpback), LIVES_WIDGET_ACTIVATE_SIGNAL,
7973 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->jumpnext), LIVES_WIDGET_ACTIVATE_SIGNAL,
7975 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->mark_jumpback), LIVES_WIDGET_ACTIVATE_SIGNAL,
7977 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->mark_jumpnext), LIVES_WIDGET_ACTIVATE_SIGNAL,
7980 LIVES_GUI_CALLBACK(on_delblock_activate), (livespointer)mt);
7981 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->save_event_list), LIVES_WIDGET_ACTIVATE_SIGNAL,
7983 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->load_event_list), LIVES_WIDGET_ACTIVATE_SIGNAL,
7985 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->clear_event_list), LIVES_WIDGET_ACTIVATE_SIGNAL,
7987 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->view_audio), LIVES_WIDGET_ACTIVATE_SIGNAL,
7988 LIVES_GUI_CALLBACK(mt_view_audio_toggled), (livespointer)mt);
7989 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->change_max_disp), LIVES_WIDGET_ACTIVATE_SIGNAL,
7991 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->render_vid), LIVES_WIDGET_ACTIVATE_SIGNAL,
7992 LIVES_GUI_CALLBACK(mt_render_vid_toggled), (livespointer)mt);
7993 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->render_aud), LIVES_WIDGET_ACTIVATE_SIGNAL,
7994 LIVES_GUI_CALLBACK(mt_render_aud_toggled), (livespointer)mt);
7995 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->normalise_aud), LIVES_WIDGET_ACTIVATE_SIGNAL,
7996 LIVES_GUI_CALLBACK(mt_norm_aud_toggled), (livespointer)mt);
7997 lives_signal_sync_connect(LIVES_GUI_OBJECT(ign_ins_sel), LIVES_WIDGET_ACTIVATE_SIGNAL,
7998 LIVES_GUI_CALLBACK(mt_ign_ins_sel_toggled), (livespointer)mt);
7999 lives_signal_sync_connect(LIVES_GUI_OBJECT(show_frame_events), LIVES_WIDGET_ACTIVATE_SIGNAL,
8001 lives_signal_sync_connect(LIVES_GUI_OBJECT(ccursor), LIVES_WIDGET_ACTIVATE_SIGNAL,
8003 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->follow_play), LIVES_WIDGET_ACTIVATE_SIGNAL,
8004 LIVES_GUI_CALLBACK(mt_fplay_toggled), (livespointer)mt);
8006 LIVES_GUI_CALLBACK(
mt_zoom_in), (livespointer)mt);
8008 LIVES_GUI_CALLBACK(
mt_zoom_out), (livespointer)mt);
8009 mt->seltrack_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->select_track), LIVES_WIDGET_ACTIVATE_SIGNAL,
8012 lives_signal_sync_connect(LIVES_GUI_OBJECT(show_manual), LIVES_WIDGET_ACTIVATE_SIGNAL,
8015 lives_signal_sync_connect(LIVES_GUI_OBJECT(email_author), LIVES_WIDGET_ACTIVATE_SIGNAL,
8018 lives_signal_sync_connect(LIVES_GUI_OBJECT(donate), LIVES_WIDGET_ACTIVATE_SIGNAL,
8021 lives_signal_sync_connect(LIVES_GUI_OBJECT(report_bug), LIVES_WIDGET_ACTIVATE_SIGNAL,
8024 lives_signal_sync_connect(LIVES_GUI_OBJECT(suggest_feature), LIVES_WIDGET_ACTIVATE_SIGNAL,
8027 lives_signal_sync_connect(LIVES_GUI_OBJECT(help_translate), LIVES_WIDGET_ACTIVATE_SIGNAL,
8030 lives_signal_sync_connect(LIVES_GUI_OBJECT(about), LIVES_WIDGET_ACTIVATE_SIGNAL,
8036 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->expl_missing), LIVES_WIDGET_ACTIVATE_SIGNAL,
8039 lives_signal_sync_connect(LIVES_GUI_OBJECT(show_mt_keys), LIVES_WIDGET_ACTIVATE_SIGNAL,
8041 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->fx_delete), LIVES_WIDGET_ACTIVATE_SIGNAL,
8049 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_mark_callback), (livespointer)mt, NULL));
8058 | LIVES_BUTTON_PRESS_MASK | LIVES_SCROLL_MASK | LIVES_SMOOTH_SCROLL_MASK);
8060 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->top_eventbox), LIVES_WIDGET_SCROLL_EVENT,
8118#if GTK_CHECK_VERSION(3, 16, 0)
8120 set_css_value_direct(LIVES_WIDGET(mt->timecode), LIVES_WIDGET_STATE_NORMAL,
"",
"border-top-left-radius",
"20px");
8121 set_css_value_direct(LIVES_WIDGET(mt->timecode), LIVES_WIDGET_STATE_NORMAL,
"",
"border-top-right-radius",
"20px");
8122 set_css_value_direct(LIVES_WIDGET(mt->timecode), LIVES_WIDGET_STATE_NORMAL,
"",
"border-bottom-right-radius",
"20px");
8123 set_css_value_direct(LIVES_WIDGET(mt->timecode), LIVES_WIDGET_STATE_NORMAL,
"",
"border-bottom-left-radius",
"20px");
8127 update_timecodes(mt, 0.);
8132 mt->tc_func = lives_signal_sync_connect_after(LIVES_WIDGET_OBJECT(mt->timecode), LIVES_WIDGET_FOCUS_OUT_EVENT,
8133 LIVES_GUI_CALLBACK(after_timecode_changed), (livespointer) mt);
8142 (tmp2 = (
_(
"Select whether video clips are inserted and moved with their audio or not"))),
8143 &mt->opts.insert_audio);
8159 (tmp2 = (
_(
"Select whether timeline selection snaps to overlap between selected tracks or not"))),
8160 &mt->opts.snap_over);
8215 mt->grav_normal_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->grav_normal), LIVES_WIDGET_TOGGLED_SIGNAL,
8216 LIVES_GUI_CALLBACK(on_grav_mode_changed), (livespointer)mt);
8221 mt->grav_left_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->grav_left), LIVES_WIDGET_TOGGLED_SIGNAL,
8222 LIVES_GUI_CALLBACK(on_grav_mode_changed), (livespointer)mt);
8227 mt->grav_right_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->grav_right), LIVES_WIDGET_TOGGLED_SIGNAL,
8228 LIVES_GUI_CALLBACK(on_grav_mode_changed), (livespointer)mt);
8236 mt->mm_label = NULL;
8255 mt->mm_move_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->mm_move), LIVES_WIDGET_TOGGLED_SIGNAL,
8256 LIVES_GUI_CALLBACK(on_mouse_mode_changed), (livespointer)mt);
8262 mt->mm_select_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->mm_select), LIVES_WIDGET_TOGGLED_SIGNAL,
8263 LIVES_GUI_CALLBACK(on_mouse_mode_changed), (livespointer)mt);
8273 mt->ins_label = NULL;
8288 mt->ins_normal_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->ins_normal), LIVES_WIDGET_TOGGLED_SIGNAL,
8289 LIVES_GUI_CALLBACK(on_insert_mode_changed),
8296 }
else mt->sep4 = NULL;
8312 LIVES_ORIENTATION_HORIZONTAL)) {
8342 mt->fd_frame = mt->preview_frame;
8345 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(mt->preview_eventbox), LIVES_WIDGET_CONFIGURE_EVENT,
8363 | LIVES_BUTTON_PRESS_MASK | LIVES_ENTER_NOTIFY_MASK | LIVES_SMOOTH_SCROLL_MASK | LIVES_SCROLL_MASK);
8365 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->preview_eventbox), LIVES_WIDGET_MOTION_NOTIFY_EVENT,
8367 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->preview_eventbox), LIVES_WIDGET_BUTTON_RELEASE_EVENT,
8369 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->preview_eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
8371 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->preview_eventbox), LIVES_WIDGET_ENTER_EVENT,
8373 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->preview_eventbox), LIVES_WIDGET_LEAVE_NOTIFY_EVENT,
8375 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->preview_eventbox), LIVES_WIDGET_SCROLL_EVENT,
8415 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->clip_scroll), LIVES_WIDGET_SCROLL_EVENT, LIVES_GUI_CALLBACK(
on_mouse_scroll),
8496 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->apply_fx_button), LIVES_WIDGET_CLICKED_SIGNAL,
8499 mt->node_adj = (LiVESWidgetObject *)
lives_adjustment_new(0., 0., 0., 1. / mt->fps, 10. / mt->fps, 0.);
8504 3, LIVES_BOX(hbox), NULL);
8508 lives_signal_connect_after(LIVES_GUI_OBJECT(mt->node_spinbutton), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
8520 (tmp = (
_(
"Preview only the selected effect"))));
8523 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(mt->solo_check), LIVES_WIDGET_TOGGLED_SIGNAL,
8524 LIVES_GUI_CALLBACK(on_solo_check_toggled), (livespointer)mt);
8530 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->resetp_button), LIVES_WIDGET_CLICKED_SIGNAL,
8537 -1, LIVES_BOX(hbox),
TRUE, NULL);
8542 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->del_node_button), LIVES_WIDGET_CLICKED_SIGNAL,
8547 -1, LIVES_BOX(hbox),
TRUE, NULL);
8552 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->next_node_button), LIVES_WIDGET_CLICKED_SIGNAL,
8557 -1, LIVES_BOX(hbox),
TRUE, NULL);
8563 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->prev_node_button), LIVES_WIDGET_CLICKED_SIGNAL,
8632 mt->check_avel_rev_func = lives_signal_connect_after(LIVES_GUI_OBJECT(mt->checkbutton_avel_reverse),
8639 LIVES_BOX(hbox), NULL);
8641 mt->spin_avel_func = lives_signal_connect_after(LIVES_GUI_OBJECT(mt->spinbutton_avel), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
8666 LIVES_GUI_CALLBACK(in_out_ebox_pressed), (livespointer)mt);
8668 LIVES_GUI_CALLBACK(on_drag_clip_end), (livespointer)mt);
8681 LIVES_BOX(mt->in_hbox), NULL);
8685 LIVES_BOX(mt->in_hbox),
8686 (tmp2 = (
_(
"Anchor the start point to the timeline"))));
8692 mt->spin_in_func = lives_signal_connect_after(LIVES_GUI_OBJECT(mt->spinbutton_in), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
8695 mt->check_start_func = lives_signal_connect_after(LIVES_GUI_OBJECT(mt->checkbutton_start_anchored),
8711 LIVES_GUI_CALLBACK(in_out_ebox_pressed), (livespointer)mt);
8713 LIVES_GUI_CALLBACK(on_drag_clip_end), (livespointer)mt);
8721 LIVES_BOX(mt->out_hbox), NULL);
8725 LIVES_BOX(mt->out_hbox),
8726 (tmp2 = (
_(
"Anchor the end point to the timeline"))));
8733 mt->spin_out_func = lives_signal_sync_connect_after(LIVES_GUI_OBJECT(mt->spinbutton_out), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
8736 mt->check_end_func = lives_signal_sync_connect_after(LIVES_GUI_OBJECT(mt->checkbutton_end_anchored),
8743 LIVES_GUI_CALLBACK(notebook_page), (livespointer)mt);
8753 mt->context_scroll = NULL;
8763 mt->sep_image = NULL;
8764 mt->hseparator2 = NULL;
8797 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->tlx_eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
8800 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->tlx_eventbox), LIVES_WIDGET_BUTTON_RELEASE_EVENT,
8804 | LIVES_BUTTON_PRESS_MASK);
8805 mt->mouse_mot1 = lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->tlx_eventbox), LIVES_WIDGET_MOTION_NOTIFY_EVENT,
8818#if GTK_CHECK_VERSION(3, 8, 0)
8819 gtk_widget_set_opacity(scrollbar, 0.);
8830 lives_signal_connect_after(LIVES_GUI_OBJECT(mt->scrollbar), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
8836 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->tl_eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
8843 | LIVES_BUTTON_PRESS_MASK | LIVES_SCROLL_MASK | LIVES_SMOOTH_SCROLL_MASK);
8844 mt->mouse_mot2 =
lives_signal_connect(LIVES_GUI_OBJECT(mt->tl_eventbox), LIVES_WIDGET_MOTION_NOTIFY_EVENT,
8850 LIVES_GUI_CALLBACK(on_mt_timeline_scroll), (livespointer)mt);
8869 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->time_scrollbar), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
8870 LIVES_GUI_CALLBACK(scroll_time_by_scrollbar), (livespointer)mt);
8872 mt->num_video_tracks = 0;
8874 mt->timeline_table = NULL;
8875 mt->timeline_eb = NULL;
8879 mt->auto_reloading =
TRUE;
8882 mt->auto_reloading =
FALSE;
8884 if (mt->event_list) {
8922 lives_signal_connect_after(LIVES_GUI_OBJECT(mt->msg_adj),
8923 LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
8925 (livespointer)mt->msg_area);
8929 (livespointer)mt->msg_adj);
8933 mt->msg_area = mt->msg_scrollbar = NULL;
8939 lives_accel_group_connect(LIVES_ACCEL_GROUP(mt->accel_group), LIVES_KEY_Page_Up, LIVES_CONTROL_MASK, (LiVESAccelFlags)0,
8940 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_prevclip), mt, NULL));
8941 lives_accel_group_connect(LIVES_ACCEL_GROUP(mt->accel_group), LIVES_KEY_Page_Down, LIVES_CONTROL_MASK, (LiVESAccelFlags)0,
8942 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_nextclip), mt, NULL));
8945 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_tlback), mt, NULL));
8947 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_tlfor), mt, NULL));
8952 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_tlfor_frame), mt, NULL));
8955 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_trup), mt, NULL));
8957 lives_cclosure_new(LIVES_GUI_CALLBACK(
mt_trdown), mt, NULL));
8962 if (mt->opts.mouse_mode ==
MOUSE_MODE_MOVE) on_mouse_mode_changed(LIVES_MENU_ITEM(mt->mm_move), (livespointer)mt);
8963 else if (mt->opts.mouse_mode ==
MOUSE_MODE_SELECT) on_mouse_mode_changed(LIVES_MENU_ITEM(mt->mm_select), (livespointer)mt);
8965 if (mt->opts.insert_mode ==
INSERT_MODE_NORMAL) on_insert_mode_changed(LIVES_MENU_ITEM(mt->ins_normal), (livespointer)mt);
8967 if (mt->opts.grav_mode ==
GRAV_MODE_NORMAL) on_grav_mode_changed(LIVES_MENU_ITEM(mt->grav_normal), (livespointer)mt);
8968 else if (mt->opts.grav_mode ==
GRAV_MODE_LEFT) on_grav_mode_changed(LIVES_MENU_ITEM(mt->grav_left), (livespointer)mt);
8969 else if (mt->opts.grav_mode ==
GRAV_MODE_RIGHT) on_grav_mode_changed(LIVES_MENU_ITEM(mt->grav_right), (livespointer)mt);
8978 mt->is_ready =
TRUE;
8997 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks"), *blocknext;
8999 LiVESWidget *label, *labelbox, *arrow, *ahbox, *xeventbox;
9000 lives_painter_surface_t *bgimg;
9003 blocknext = block->next;
9004 if (mt->block_selected == block) mt->block_selected = NULL;
9009 if ((bgimg = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"bgimg")) != NULL) {
9013 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label");
9014 arrow = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"arrow");
9017 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY)) == 0) {
9018 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox");
9019 ahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"ahbox");
9024 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan0");
9026 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"label");
9028 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY)) == 0) {
9029 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"labelbox");
9032 if ((bgimg = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"bgimg")) != NULL) {
9039 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan1");
9041 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"label");
9043 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY)) == 0) {
9044 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"labelbox");
9047 if ((bgimg = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"bgimg")) != NULL) {
9055 lives_free(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"track_name"));
9060static int *update_layout_map(weed_plant_t *event_list) {
9064 weed_plant_t *event;
9068 for (i = 1; i <=
MAX_FILES; i++) used_clips[i] = 0;
9070 if (!event_list)
return used_clips;
9077 int *clip_index = weed_get_int_array_counted(event,
WEED_LEAF_CLIPS, &numtracks);
9078 if (numtracks > 0) {
9079 int64_t *frame_index = weed_get_int64_array(event,
WEED_LEAF_FRAMES, NULL);
9080 for (
int i = 0; i < numtracks; i++) {
9081 if (clip_index[i] > 0 && (frame_index[i] > used_clips[clip_index[i]])) used_clips[clip_index[i]] = (int)frame_index[i];
9093static double *update_layout_map_audio(weed_plant_t *event_list) {
9097 weed_plant_t *event;
9117 if (!event_list)
return used_clips;
9122 avel[i] = neg_avel[i] = 0.;
9130 double *aseek_index;
9133 for (i = 0; i < numatracks; i += 2) {
9134 if (aclip_index[i + 1] > 0) {
9135 atrack = aclip_index[i];
9141 if (avel[atrack] != 0.) {
9143 last_aclip = last_aclips[atrack];
9144 if (aval > used_clips[last_aclip]) used_clips[last_aclip] = aval;
9146 aseek[atrack] = aseek_index[i];
9147 avel[atrack] = aseek_index[i + 1];
9149 last_aclips[atrack] = aclip_index[i + 1];
9156 if (neg_avel[atrack] != 0.) {
9158 last_aclip = neg_last_aclips[atrack];
9159 if (aval > used_clips[last_aclip]) used_clips[last_aclip] = aval;
9161 neg_aseek[atrack] = aseek_index[i];
9162 neg_avel[atrack] = aseek_index[i + 1];
9163 neg_atc[atrack] = tc;
9164 neg_last_aclips[atrack] = aclip_index[i + 1];
9183 double *layout_map_audio;
9184 boolean retval =
FALSE;
9190 if (mt && mt->event_list) {
9191 layout_map = update_layout_map(mt->event_list);
9192 layout_map_audio = update_layout_map_audio(mt->event_list);
9194 if (
layout_map[file] > 0 || layout_map_audio[file] > 0.) retval =
TRUE;
9207 double *layout_map_audio = NULL;
9209 boolean needs_idlefunc =
FALSE;
9210 boolean did_backup = mt->did_backup;
9216 if (mt->idlefunc > 0) {
9217 needs_idlefunc =
TRUE;
9222 if (mt->frame_pixbuf && mt->frame_pixbuf !=
mainw->
imframe) {
9224 mt->frame_pixbuf = NULL;
9229 int file_selected = mt->file_selected;
9231 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
9234 mt->file_selected = file_selected;
9237 if (mt->event_list) {
9251 mt->event_list = NULL;
9260 mt->undo_mem = NULL;
9268 if (
mainw->
files[i] && (
layout_map[i] != 0 || (layout_map_audio && layout_map_audio[i] != 0.))) {
9270 if (layout_map_audio)
9286 mt->no_expose = mt->no_expose_frame =
TRUE;
9287 mt->is_ready =
FALSE;
9290 mainw->
multi_opts.aparam_view_list = lives_list_copy(mt->opts.aparam_view_list);
9302 if (mt->undos) lives_list_free(mt->undos);
9304 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
9308 mt->event_list = NULL;
9313 if (mt->clip_labels) lives_list_free(mt->clip_labels);
9374 LIVES_ORIENTATION_HORIZONTAL)) {
9394 if (mt->mt_frame_preview) {
9416 if (mt->audio_vols) lives_list_free(mt->audio_vols);
9424 if (mt->video_draws) {
9425 for (i = 0; i < mt->num_video_tracks; i++) {
9428 lives_list_free(mt->video_draws);
9435 lives_list_free(mt->tl_marks);
9502 if (mt->file_selected != -1) {
9536 d_print(
_(
"====== Switched to Clip Edit mode ======\n"));
9544static void locate_avol_init_event(lives_mt * mt, weed_plant_t *event_list,
int avol_fx) {
9556 mt->avol_init_event = event;
9566static track_rect *add_block_start_point(LiVESWidget * eventbox, weed_timecode_t tc,
int filenum,
9567 weed_timecode_t offset_start, weed_plant_t *event,
boolean ordered) {
9577 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
9578 track_rect *new_block;
9581 if (block->start_event == event)
return NULL;
9582 if (!block->next)
break;
9585 new_block = (track_rect *)
lives_malloc(
sizeof(track_rect));
9588 new_block->next = new_block->prev = NULL;
9590 new_block->start_anchored = new_block->end_anchored =
FALSE;
9591 new_block->start_event = event;
9592 new_block->ordered = ordered;
9593 new_block->eventbox = eventbox;
9594 new_block->offset_start = offset_start;
9596 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last", (livespointer)new_block);
9602 block->prev->next = new_block;
9603 new_block->prev = block->prev;
9606 else lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks", (livespointer)new_block);
9607 new_block->next = block;
9608 block->prev = new_block;
9611 block->next = new_block;
9612 new_block->prev = block;
9617 if (!block) lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks", (livespointer)new_block);
9623static track_rect *add_block_end_point(LiVESWidget * eventbox, weed_plant_t *event) {
9625 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
9626 if (block) block->end_event = event;
9630static boolean on_tlreg_enter(LiVESWidget * widget, LiVESXEventCrossing * event, livespointer user_data) {
9631 lives_mt *mt = (lives_mt *)user_data;
9638static boolean on_tleb_enter(LiVESWidget * widget, LiVESXEventCrossing * event, livespointer user_data) {
9639 lives_mt *mt = (lives_mt *)user_data;
9649 renumbered_clips[i] = i;
9650 }
else renumbered_clips[i] = 0;
9655static void set_track_labels(lives_mt * mt) {
9665 if (nlabs < navs) navs = nlabs;
9667 for (i = 0; i < navs; i++) {
9669 if (nt < mt->num_video_tracks) {
9682 mt->avol_init_event = NULL;
9684 tlist = mt->audio_draws;
9686 while (mt->audio_draws) {
9688 mt->audio_draws = mt->audio_draws->next;
9691 lives_list_free(tlist);
9693 tlist = mt->video_draws;
9695 while (mt->video_draws) {
9697 mt->video_draws->data = NULL;
9698 mt->video_draws = mt->video_draws->next;
9701 lives_list_free(tlist);
9702 mt->num_video_tracks = 0;
9704 mt->tl_label = NULL;
9707 if (!mt->timeline_table) {
9710 LIVES_FILL, (LiVESAttachOptions)0, 0, 0);
9714 mt->current_track = 0;
9719 if (
mainw->
files[mt->render_file]->
achans > 0 && mt->opts.back_audio_tracks > 0) {
9728 mt->current_track = 0;
9729 mt->block_selected = NULL;
9731 if (!mt->timeline_eb) {
9733 mt->timeline = giw_timeline_new_with_adjustment(LIVES_ORIENTATION_HORIZONTAL, 0., 0., 1000000., 1000000.);
9734 giw_timeline_set_unit(GIW_TIMELINE(mt->timeline), GIW_TIME_UNIT_SMH);
9735 giw_timeline_set_mouse_policy(GIW_TIMELINE(mt->timeline), GIW_TIMELINE_MOUSE_DISABLED);
9745 LIVES_BUTTON_RELEASE_MASK | LIVES_BUTTON_PRESS_MASK | LIVES_ENTER_NOTIFY_MASK);
9748 LIVES_BUTTON_RELEASE_MASK | LIVES_BUTTON_PRESS_MASK | LIVES_ENTER_NOTIFY_MASK);
9749 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->timeline_eb), LIVES_WIDGET_ENTER_EVENT, LIVES_GUI_CALLBACK(on_tleb_enter),
9751 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->timeline_reg), LIVES_WIDGET_ENTER_EVENT, LIVES_GUI_CALLBACK(on_tlreg_enter),
9754 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->timeline), LIVES_WIDGET_MOTION_NOTIFY_EVENT,
9755 LIVES_GUI_CALLBACK(return_true), NULL);
9781 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->timeline_reg), LIVES_WIDGET_EXPOSE_EVENT,
9782 LIVES_GUI_CALLBACK(expose_timeline_reg_event), (livespointer)mt);
9788 lives_table_attach(LIVES_TABLE(mt->timeline_table_header), mt->dumlabel1, 0, 7, 0, 1,
9789 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
9790 (LiVESAttachOptions)(LIVES_FILL), 0, 0);
9793 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
9794 (LiVESAttachOptions)(LIVES_FILL), 0, 0);
9798 lives_table_attach(LIVES_TABLE(mt->timeline_table_header), mt->dumlabel2, 0, 7, 1, 2,
9799 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
9800 (LiVESAttachOptions)(LIVES_FILL), 0, 0);
9803 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
9804 (LiVESAttachOptions)(LIVES_FILL), 0, 0);
9807 if (mt->event_list) {
9808 LiVESWidget *audio_draw;
9811 weed_plant_t *event, *last_event = NULL, *next_frame_event;
9812 weed_timecode_t tc, last_tc;
9813 weed_timecode_t offset_start;
9814 weed_timecode_t block_marker_tc = -1;
9815 weed_timecode_t block_marker_uo_tc = -1;
9818 int64_t *frame_index, *new_frame_index;
9819 int *clip_index, *new_clip_index;
9820 int *block_marker_uo_tracks = NULL;
9821 int *aclips, *navals;
9822 int *block_marker_tracks = NULL;
9825 boolean forced_end =
FALSE;
9826 boolean ordered =
TRUE;
9827 boolean shown_audio_warn =
FALSE;
9829 int block_marker_uo_num_tracks = 0;
9832 int last_valid_frame;
9833 int block_marker_num_tracks = 0;
9834 int last_tracks = 1;
9847 maxval = mt->num_video_tracks - 1;
9849 for (j = 0; j < navs; j++) {
9850 if (navals[j] > maxval) maxval = navals[j];
9853 num_tracks = maxval + 1;
9855 if (num_tracks > mt->num_video_tracks) {
9856 for (j = mt->num_video_tracks; j < num_tracks; j++) {
9873 block_marker_uo_tracks = weed_get_int_array_counted(event,
WEED_LEAF_TRACKS, &block_marker_uo_num_tracks);
9878 maxval = mt->num_video_tracks - 1;
9880 for (j = 0; j < navs; j++) {
9881 if (navals[j] > maxval) maxval = navals[j];
9884 num_tracks = maxval + 1;
9886 if (num_tracks > mt->num_video_tracks) {
9887 for (j = mt->num_video_tracks; j < num_tracks; j++) {
9894 clip_index = weed_get_int_array_counted(event,
WEED_LEAF_CLIPS, &num_tracks);
9897 if (num_tracks < last_tracks) {
9898 for (j = num_tracks; j < last_tracks; j++) {
9900 if (tracks[j] > 0) {
9901 add_block_end_point(LIVES_WIDGET(lives_list_nth_data(mt->video_draws, j)), last_event);
9907 if (num_tracks > mt->num_video_tracks) {
9908 for (j = mt->num_video_tracks; j < num_tracks; j++) {
9913 last_tracks = num_tracks;
9915 new_frame_index = (int64_t *)
lives_malloc(num_tracks * 8);
9916 last_valid_frame = 0;
9918 for (j = 0; j < num_tracks; j++) {
9920 if (clip_index[j] > 0 && frame_index[j] > -1 && clip_index[j] <=
MAX_FILES &&
9921 renumbered_clips[clip_index[j]] > 0 && (frame_index[j] <=
9927 if ((tracks[j] != renumbered_clips[clip_index[j]]) || forced_end) {
9929 if (tracks[j] > 0) {
9931 add_block_end_point(LIVES_WIDGET(lives_list_nth_data(mt->video_draws, j)), last_event);
9933 if (clip_index[j] > 0) {
9939 add_block_start_point(LIVES_WIDGET(lives_list_nth_data(mt->video_draws, j)), tc,
9940 renumbered_clips[clip_index[j]], offset_start, event, ordered);
9942 tracks[j] = renumbered_clips[clip_index[j]];
9944 new_clip_index[j] = renumbered_clips[clip_index[j]];
9945 new_frame_index[j] = frame_index[j];
9946 last_valid_frame = j + 1;
9951 new_clip_index[j] = -1;
9952 new_frame_index[j] = 0;
9953 if (tracks[j] > 0) {
9955 add_block_end_point(LIVES_WIDGET(lives_list_nth_data(mt->video_draws, j)), last_event);
9961 if (last_valid_frame == 0) {
9966 *new_clip_index = -1;
9967 *new_frame_index = 0;
9970 if (last_valid_frame < num_tracks) {
9974 new_frame_index = (int64_t *)
lives_malloc(last_valid_frame * 8);
9975 for (j = 0; j < last_valid_frame; j++) {
9976 new_clip_index[j] = clip_index[j];
9977 new_frame_index[j] = frame_index[j];
9979 num_tracks = last_valid_frame;
9983 weed_set_int_array(event,
WEED_LEAF_CLIPS, num_tracks, new_clip_index);
9984 weed_set_int64_array(event,
WEED_LEAF_FRAMES, num_tracks, new_frame_index);
9995 for (i = 0; i < num_aclips; i += 2) {
9996 if (aclips[i + 1] > 0) {
9998 if (!shown_audio_warn) {
9999 shown_audio_warn =
TRUE;
10004 if (aclips[i] == -1) audio_draw = (LiVESWidget *)mt->audio_draws->data;
10005 else audio_draw = (LiVESWidget *)lives_list_nth_data(mt->audio_draws, aclips[i] + mt->opts.back_audio_tracks);
10006 if (avels[aclips[i] + 1] != 0.) {
10007 add_block_end_point(audio_draw, event);
10008 if (!forced_end && tracks[aclips[i]] > 0 && next_frame_event &&
get_next_frame_event(next_frame_event)) {
10009 add_block_end_point(LIVES_WIDGET(lives_list_nth_data(mt->video_draws, aclips[i])), last_event);
10013 avels[aclips[i] + 1] = aseeks[i + 1];
10016 if (avels[aclips[i] + 1] != 0.) {
10017 add_block_start_point(audio_draw, tc, renumbered_clips[aclips[i + 1]],
10019 if (!forced_end && tracks[aclips[i]] > 0 && next_frame_event &&
get_next_frame_event(next_frame_event)) {
10022 add_block_start_point(LIVES_WIDGET(lives_list_nth_data(mt->video_draws, aclips[i])), tc,
10023 new_clip_index[aclips[i]], offset_start, event, ordered);
10028 if (aclips[i + 1] > 0) aclips[i + 1] = renumbered_clips[aclips[i + 1]];
10038 slist = mt->audio_draws;
10039 for (i = mt->opts.back_audio_tracks + 1; --i > 0; slist = slist->next);
10040 for (; slist; slist = slist->next, i++) {
10043 audio_draw = (LiVESWidget *)slist->data;
10044 if (avels[i] != 0.) {
10047 block = add_block_end_point(audio_draw, event);
10050 offset_start = block->offset_start + (weed_timecode_t)((
double)(tc - last_tc) * avels[i] + .5);
10051 add_block_start_point(audio_draw, tc, -1, offset_start, event,
TRUE);
10056 if (!next_frame_event) {
10059 for (slist = mt->video_draws; slist; slist = slist->next) {
10060 if (tracks[j++] > 0) {
10061 add_block_end_point(LIVES_WIDGET(slist->data), event);
10065 for (slist = mt->audio_draws; slist; slist = slist->next) {
10067 add_block_end_point((LiVESWidget *)slist->data, event);
10070 last_event = event;
10080 if (mt->avol_fx != -1) locate_avol_init_event(mt, mt->event_list, mt->avol_fx);
10082 if (!mt->was_undo_redo && mt->avol_fx != -1 && mt->audio_draws) {
10083 apply_avol_filter(mt);
10088 if (mt->event_list) {
10090 if (mt->end_secs == 0.)
LIVES_WARN(
"got zero length event_list");
10092 if (mt->end_secs == 0.) mt->end_secs =
DEF_TIME;
10096 mt->tl_max = mt->end_secs;
10101 if (!mt->was_undo_redo) {
10102 set_track_labels(mt);
10104 if (mt->is_ready) {
10105 if (mt->current_track != 0) {
10106 mt->current_track = 0;
10109 if (mt->region_start != mt->region_end || mt->region_start != 0.) {
10110 mt->region_start = mt->region_end = 0.;
10115 }
else mt->was_undo_redo =
FALSE;
10125 LiVESWidget *eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, layer);
10126 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks"), *blocknext;
10128 LiVESWidget *checkbutton;
10129 LiVESWidget *label, *labelbox, *ahbox, *arrow;
10130 lives_painter_surface_t *bgimg;
10133 blocknext = block->next;
10134 if (mt->block_selected == block) mt->block_selected = NULL;
10139 if ((bgimg = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"bgimg")) != NULL) {
10143 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton");
10144 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label");
10145 arrow = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"arrow");
10147 mt->cb_list = lives_list_remove(mt->cb_list, (livespointer)checkbutton);
10152 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY)) == 0) {
10153 labelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"labelbox");
10154 ahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"ahbox");
10158 lives_free(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"track_name"));
10168 LiVESWidgetObject *adj;
10169 LiVESWidget *label, *dummy;
10170 LiVESWidget *arrow;
10171 LiVESWidget *eventbox;
10174 char *pname, *tname;
10182 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(audio_draw),
"blocks", (livespointer)NULL);
10183 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(audio_draw),
"block_last", (livespointer)NULL);
10184 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(audio_draw),
HIDDEN_KEY, LIVES_INT_TO_POINTER(0));
10185 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(audio_draw),
"expanded", LIVES_INT_TO_POINTER(
FALSE));
10186 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(audio_draw),
"bgimg", NULL);
10187 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(audio_draw),
"is_audio", LIVES_INT_TO_POINTER(
TRUE));
10191 mt->num_video_tracks : max_disp_vtracks));
10218 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(arrow),
"layer_number", LIVES_INT_TO_POINTER(track));
10219 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(audio_draw),
"layer_number", LIVES_INT_TO_POINTER(track));
10241 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"owner", audio_draw);
10243 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(0));
10244 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"bgimg", NULL);
10245 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"channel", LIVES_INT_TO_POINTER(i));
10250 if (!mt->was_undo_redo) {
10252 llen = lives_list_length(mt->audio_draws);
10256 }
else if (llen == 1) {
10257 if (mt->opts.back_audio_tracks > 0) {
10259 mt->audio_vols->data = LIVES_INT_TO_POINTER(vol);
10261 if (mt->opts.gang_audio) {
10262 vol = LIVES_POINTER_TO_INT(lives_list_nth_data(mt->audio_vols, 0));
10266 if (mt->opts.gang_audio) {
10267 vol = LIVES_POINTER_TO_INT(lives_list_nth_data(mt->audio_vols, mt->opts.back_audio_tracks));
10269 if (mt->opts.back_audio_tracks > 0) {
10278 if (!mt->was_undo_redo && mt->amixer && track >= 0) {
10280 LiVESWidget **ch_sliders;
10281 ulong *ch_slider_fns;
10285 nachans = lives_list_length(mt->audio_vols) + 1;
10287 ch_sliders = (LiVESWidget **)
lives_malloc(nachans *
sizeof(LiVESWidget *));
10291 for (i = 0; i < nachans - 1; i++) {
10292 if (!behind && i == mt->opts.back_audio_tracks) j++;
10293 ch_sliders[j] = mt->amixer->ch_sliders[i];
10294 ch_slider_fns[j] = mt->amixer->ch_slider_fns[i];
10301 mt->amixer->ch_sliders = ch_sliders;
10302 mt->amixer->ch_slider_fns = ch_slider_fns;
10306 mt->audio_draws = lives_list_prepend(mt->audio_draws, (livespointer)audio_draw);
10307 if (!mt->was_undo_redo) mt->audio_vols = lives_list_prepend(mt->audio_vols, LIVES_INT_TO_POINTER(vol));
10308 }
else if (behind) {
10309 mt->audio_draws = lives_list_append(mt->audio_draws, (livespointer)audio_draw);
10311 if (!mt->was_undo_redo) {
10319 mt->audio_vols = lives_list_append(mt->audio_vols, LIVES_INT_TO_POINTER(vol));
10322 mt->audio_draws = lives_list_insert(mt->audio_draws, (livespointer)audio_draw, mt->opts.back_audio_tracks);
10323 if (!mt->was_undo_redo) {
10324 mt->audio_vols = lives_list_insert(mt->audio_vols, LIVES_INT_TO_POINTER(vol), mt->opts.back_audio_tracks);
10337 for (i = mt->opts.back_audio_tracks + 1; i < nachans; i++) {
10338 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->amixer->ch_sliders[i]),
"label");
10345 adj = (LiVESWidgetObject *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->amixer->ch_sliders[i]),
"adj");
10346 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(adj),
"layer", LIVES_INT_TO_POINTER(i));
10355static void set_track_label(LiVESEventBox * xeventbox,
int tnum) {
10356 LiVESWidget *label = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"label"));
10357 const char *tname = (
const char *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"track_name");
10369 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(ebox),
"track_name", (livespointer)label);
10370 set_track_label(LIVES_EVENT_BOX(ebox), track);
10374static int add_video_track(lives_mt * mt,
boolean behind) {
10376 LiVESWidget *label;
10377 LiVESWidget *checkbutton;
10378 LiVESWidget *arrow;
10379 LiVESWidget *eventbox;
10380 LiVESWidget *aeventbox;
10386 if (mt->audio_draws && mt->audio_draws->data && mt->opts.back_audio_tracks > 0 &&
10387 LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
HIDDEN_KEY)) == 0) {
10388 max_disp_vtracks--;
10389 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
10393 mt->num_video_tracks++;
10401 checkbutton = giw_led_new();
10402 giw_led_enable_mouse(GIW_LED(checkbutton),
TRUE);
10407 mt->cb_list = lives_list_append(mt->cb_list, checkbutton);
10409 if (LIVES_IS_WIDGET(checkbutton)) {
10421 mt->num_video_tracks));
10424 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded", LIVES_INT_TO_POINTER(
FALSE));
10426 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks", (livespointer)NULL);
10427 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last", (livespointer)NULL);
10428 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
HIDDEN_KEY, LIVES_INT_TO_POINTER(0));
10429 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"bgimg", NULL);
10432 mt->num_video_tracks : max_disp_vtracks));
10440 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number", LIVES_INT_TO_POINTER(0));
10441 for (i = 0; i < mt->num_video_tracks - 1; i++) {
10443 LiVESWidget *xeventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, i);
10444 LiVESWidget *xcheckbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"checkbutton");
10445 LiVESWidget *xarrow = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"arrow");
10446 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"layer_number", LIVES_INT_TO_POINTER(i + 1));
10447 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xcheckbutton),
"layer_number", LIVES_INT_TO_POINTER(i + 1));
10448 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xarrow),
"layer_number", LIVES_INT_TO_POINTER(i + 1));
10449 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"is_audio", LIVES_INT_TO_POINTER(
FALSE));
10451 set_track_label(LIVES_EVENT_BOX(xeventbox), i + 1);
10453 if (mt->opts.pertrack_audio) {
10454 LiVESWidget *aeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"atrack");
10455 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
"layer_number", LIVES_INT_TO_POINTER(i + 1));
10456 xarrow = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"arrow");
10457 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xarrow),
"layer_number", LIVES_INT_TO_POINTER(i + 1));
10458 label = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"label");
10461 newtext =
lives_strdup_printf(
_(
" %s"), lives_widget_object_get_data(LIVES_WIDGET_OBJECT(aeventbox),
"track_name"));
10465 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
"is_audio", LIVES_INT_TO_POINTER(
TRUE));
10472 mt->video_draws = lives_list_prepend(mt->video_draws, (livespointer)eventbox);
10473 mt->current_track = 0;
10476 liste = mt->selected_tracks;
10478 liste->data = LIVES_INT_TO_POINTER(LIVES_POINTER_TO_INT(liste->data) + 1);
10479 liste = liste->next;
10483 mt->video_draws = lives_list_append(mt->video_draws, (livespointer)eventbox);
10484 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number", LIVES_INT_TO_POINTER(mt->num_video_tracks - 1));
10485 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(checkbutton),
"layer_number",
10486 LIVES_INT_TO_POINTER(mt->num_video_tracks - 1));
10487 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(arrow),
"layer_number", LIVES_INT_TO_POINTER(mt->num_video_tracks - 1));
10488 mt->current_track = mt->num_video_tracks - 1;
10493 lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"track_name"),
10494 LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
10495 "layer_number")))));
10503 if (mt->opts.pertrack_audio) {
10505 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
"owner", eventbox);
10506 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack", aeventbox);
10508 if (mt->avol_init_event) {
10513 if (!behind) scroll_track_on_screen(mt, 0);
10514 else scroll_track_on_screen(mt, mt->num_video_tracks - 1);
10518 if (!behind)
return 0;
10519 else return mt->num_video_tracks - 1;
10525 lives_mt *mt = (lives_mt *)user_data;
10527 tnum = add_video_track(mt,
TRUE);
10535 lives_mt *mt = (lives_mt *)user_data;
10537 tnum = add_video_track(mt,
FALSE);
10544 lives_mt *mt = (lives_mt *)user_data;
10545 if (!mt->selected_init_event)
return;
10554static boolean mt_fx_edit_idle(livespointer user_data) {
10560static void mt_avol_quick(LiVESMenuItem * menuitem, livespointer user_data) {
10561 lives_mt *mt = (lives_mt *)user_data;
10562 mt->selected_init_event = mt->avol_init_event;
10567static void rdrw_cb(LiVESMenuItem * menuitem, livespointer user_data) {
10568 lives_mt *mt = (lives_mt *)user_data;
10569 redraw_all_event_boxes(mt);
10576 LiVESWidget *edit_effect;
10577 LiVESWidget *delete_effect;
10580 weed_plant_t *filter;
10585 fhash = weed_get_string_value(mt->selected_init_event,
WEED_LEAF_FILTER, NULL);
10601 if (mt->selected_init_event != mt->avol_init_event) {
10619static boolean fx_ebox_pressed(LiVESWidget * eventbox, LiVESXEventButton * event, livespointer user_data) {
10620 lives_mt *mt = (lives_mt *)user_data;
10621 LiVESList *children, *xlist;
10622 weed_plant_t *osel = mt->selected_init_event;
10624 if (mt->is_rendering)
return FALSE;
10626 mt->selected_init_event = (weed_plant_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"init_event");
10628 if (event->type == LIVES_BUTTON2_PRESS) {
10630 mt->moving_fx = NULL;
10632 lives_timer_add_simple(0, mt_fx_edit_idle, mt);
10639 if (osel != mt->selected_init_event && osel != mt->avol_init_event) {
10640 switch (mt->fx_order) {
10647 mt->current_track,
FALSE);
10654 mt->selected_init_event = osel;
10664 mt->current_track,
TRUE);
10672 mt->did_backup =
FALSE;
10673 mt->selected_init_event = osel;
10675 mt->selected_init_event = NULL;
10700 LiVESWidget *child = (LiVESWidget *)children->data;
10701 if (child != eventbox) {
10708 children = children->next;
10710 if (xlist) lives_list_free(xlist);
10720static void set_clip_labels_variable(lives_mt * mt,
int i) {
10722 LiVESLabel *label1, *label2;
10725 if (!mt->clip_labels)
return;
10730 label1 = (LiVESLabel *)lives_list_nth_data(mt->clip_labels, i);
10731 label2 = (LiVESLabel *)lives_list_nth_data(mt->clip_labels, ++i);
10748 for (i = 0; i < mt->num_video_tracks; i++) {
10751 lives_list_free(mt->video_draws);
10752 mt->video_draws = NULL;
10753 mt->num_video_tracks = 0;
10756 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
10757 mt->selected_tracks = NULL;
10762 mt->audio_draws = NULL;
10763 if (mt->audio_vols) lives_list_free(mt->audio_vols);
10764 mt->audio_vols = NULL;
10769 mt->changed =
FALSE;
10786 }
else mt->avol_fx = -1;
10787 mt->avol_init_event = NULL;
10803 LiVESList *clist = mt->clip_labels, *clist_nnext;
10805 boolean removed =
FALSE;
10806 int neg = 0, i = 0;
10808 for (; list; i++) {
10809 list_next = list->next;
10812 clist_nnext = clist->next->next;
10813 if (clips_to_files[i] == file) {
10818 if (clist_nnext) clist_nnext->prev = clist->prev;
10819 if (clist->prev) clist->prev->next = clist_nnext;
10820 else mt->clip_labels = clist_nnext;
10821 clist->prev = clist->next->next = NULL;
10822 lives_list_free(clist);
10828 clips_to_files[i] = clips_to_files[i + neg];
10830 clist = clist_nnext;
10831 if (mt->file_selected == file) {
10836 if (olist) lives_list_free(olist);
10865 LiVESWidget *thumb_image = NULL;
10866 LiVESWidget *vbox, *hbox, *label;
10867 LiVESWidget *eventbox;
10869 LiVESPixbuf *thumbnail;
10879 int count = lives_list_length(mt->clip_labels) / 2;
10881 mt->clip_selected = -1;
10883 if (add) i = orig_file;
10885 while (add || cliplist) {
10886 if (add) i = orig_file;
10887 else i = LIVES_POINTER_TO_INT(cliplist->data);
10890 cliplist = cliplist->next;
10898 mt->file_selected = i;
10899 mt->clip_selected = count;
10900 renumbered_clips[i] = i;
10907 mt->nb_label = NULL;
10913 lives_widget_add_events(eventbox, LIVES_BUTTON_RELEASE_MASK | LIVES_BUTTON_PRESS_MASK | LIVES_ENTER_NOTIFY_MASK);
10914 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_ENTER_EVENT, LIVES_GUI_CALLBACK(on_clipbox_enter),
10917 clips_to_files[count] = i;
10942 mt->clip_labels = lives_list_append(mt->clip_labels, label);
10949 mt->clip_labels = lives_list_append(mt->clip_labels, label);
10953 set_clip_labels_variable(mt, i);
10956 mt->clip_labels = lives_list_append(mt->clip_labels, label);
10964 mt->clip_labels = lives_list_append(mt->clip_labels, label);
10971 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
10972 LIVES_GUI_CALLBACK(clip_ebox_pressed), (livespointer)mt);
10973 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_RELEASE_EVENT,
10974 LIVES_GUI_CALLBACK(on_drag_clip_end), (livespointer)mt);
10982 if (cliplist) cliplist = cliplist->next;
10987static void set_audio_mixer_vols(lives_mt * mt, weed_plant_t *elist) {
10990 int catracks, xtrack, xavol, natracks, navols;
10993 if (!atracks)
return;
10995 if (!avols)
return;
10997 catracks = lives_list_length(mt->audio_vols);
10998 for (
int i = 0; i < natracks; i++) {
10999 xtrack = atracks[i];
11000 if (xtrack < -mt->opts.back_audio_tracks)
continue;
11001 if (xtrack >= catracks - mt->opts.back_audio_tracks)
continue;
11004 if (xavol >= navols) {
11005 mt->opts.gang_audio =
TRUE;
11006 xavol = navols - 1;
11016 lives_mt *mt = (lives_mt *)data;
11030 xachans = xarate = xasamps = xse = 0;
11058 if (response == LIVES_RESPONSE_CANCEL) {
11088 xarate = xachans = xasamps = 0;
11089 xse =
cfile->signed_endian;
11156 force_pertrack_audio =
FALSE;
11157 force_backing_tracks = 0;
11161 rerenumber_clips(NULL, event_list);
11167 if (!qevent_list) {
11177 weed_set_double_value(event_list, WEED_LEAF_FPS,
cfile->fps);
11194 if (!multi->event_list) {
11196 multi->file_selected = orig_file;
11208 set_audio_mixer_vols(multi, multi->event_list);
11218 multi->file_selected = orig_file;
11238 if (multi->clip_labels) {
11243 scroll_track_on_screen(multi, 0);
11244 if (multi->nb_label) {
11250 if (
cfile->achans == 0) {
11251 multi->opts.pertrack_audio =
FALSE;
11265 if (multi->hseparator2) {
11270 if (!multi->opts.pertrack_audio) {
11292 mt_zoom(multi, 1.);
11305 redraw_all_event_boxes(multi);
11307 if (multi->opts.pertrack_audio) {
11317 multi->no_expose = multi->no_expose_frame =
FALSE;
11343 if (multi->opts.hpaned_pos != -1)
11349 LIVES_GUI_CALLBACK(hpaned_position), (livespointer)multi);
11361 d_print(
_(
"====== Switched to Multitrack mode ======\n"));
11372 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
11377 block = block->next;
11383static track_rect *get_block_before(LiVESWidget * eventbox,
double time,
boolean allow_cur) {
11389 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks"), *last_block = NULL;
11394 last_block = block;
11395 block = block->next;
11401static track_rect *get_block_after(LiVESWidget * eventbox,
double time,
boolean allow_cur) {
11407 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
11411 block = block->next;
11417track_rect *
move_block(lives_mt * mt, track_rect * block,
double timesecs,
int old_track,
int new_track) {
11418 weed_timecode_t new_start_tc, end_tc;
11421 ulong uid = block->uid;
11423 LiVESWidget *eventbox, *oeventbox;
11425 int clip, current_track = -1;
11427 boolean did_backup = mt->did_backup;
11428 boolean needs_idlefunc =
FALSE;
11430 if (mt->idlefunc > 0) {
11431 needs_idlefunc =
TRUE;
11439 if (is_audio_eventbox(block->eventbox) && (oeventbox =
11440 (LiVESWidget *)lives_widget_object_get_data
11441 (LIVES_WIDGET_OBJECT(block->eventbox),
"owner")) != NULL) {
11446 mt->block_selected = block;
11451 weed_plant_t *
event = NULL;
11452 weed_timecode_t tc = 0, tcnow;
11453 weed_timecode_t tclen = end_tc - start_tc;
11454 while (tc <= tclen) {
11457 if (old_track == new_track && tcnow >= start_tc && tcnow <= end_tc)
continue;
11460 if (new_track >= 0) {
11464 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
11474 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
11489 if (old_track > -1) {
11491 mt->insert_start = block->offset_start;
11497 mt->insert_end =
q_gint64(mt->insert_start + (end_tc - start_tc), mt->fps);
11500 mt->moving_block =
TRUE;
11501 mt->current_track = old_track;
11503 mt->block_selected = NULL;
11504 mt->current_track = new_track;
11514 mt->insert_avel = 1.;
11517 mt->insert_start = mt->insert_end = -1;
11524 if (mt->opts.move_effects)
update_filter_events(mt, mt->specific_event, start_tc, end_tc, old_track, new_start_tc,
11525 mt->current_track);
11528 mt->moving_block =
FALSE;
11529 mt->specific_event = NULL;
11531 if (new_track != -1) eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
11532 else eventbox = (LiVESWidget *)mt->audio_draws->data;
11533 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
11538 double oldr_start = mt->region_start;
11539 double oldr_end = mt->region_end;
11540 LiVESList *tracks_sel = NULL;
11541 track_rect *lblock;
11547 lblock = block->prev;
11553 lblock = block->next;
11558 mt->region_start = rstart;
11559 mt->region_end = rend;
11561 if (new_track > -1) {
11562 tracks_sel = lives_list_copy(mt->selected_tracks);
11563 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
11564 mt->selected_tracks = NULL;
11565 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(new_track));
11567 current_track = mt->current_track;
11568 mt->current_track = old_track;
11572 if (old_track > -1) {
11573 lives_list_free(mt->selected_tracks);
11574 mt->selected_tracks = lives_list_copy(tracks_sel);
11575 if (tracks_sel) lives_list_free(tracks_sel);
11576 }
else mt->current_track = current_track;
11577 mt->region_start = oldr_start;
11578 mt->region_end = oldr_end;
11583 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
11586 if (mt->avol_fx != -1 && (!block || !block->next) && mt->audio_draws &&
11588 apply_avol_filter(mt);
11595 mt->did_backup = did_backup;
11597 mt->did_backup =
TRUE;
11600 if (!did_backup && mt->framedraw && mt->current_rfx && mt->init_event &&
11604 get_track_index(mt, tc);
11608 if (block) block->uid = uid;
11611 mt->did_backup =
FALSE;
11612 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
11622 LiVESWidget *eventbox;
11629 for (list = mt->audio_draws; list; list = list->next) {
11630 eventbox = (LiVESWidget *)list->data;
11632 trec = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
11640 for (list = mt->video_draws; list; list = list->next) {
11641 eventbox = (LiVESWidget *)list->data;
11643 trec = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
11650 mt->block_selected = NULL;
11661static void _clear_context(lives_mt * mt) {
11664 if (mt->context_scroll) {
11674 LIVES_POLICY_AUTOMATIC);
11700 LiVESWidget *label;
11724 if (!mt->event_list || !
get_first_event(mt->event_list) || mt->tl_fixed_length > 0.)
return FALSE;
11728 if (end_secs > mt->end_secs) {
11733 redraw_all_event_boxes(mt);
11739static void set_in_out_spin_ranges(lives_mt * mt, weed_timecode_t start_tc, weed_timecode_t end_tc) {
11740 track_rect *block = mt->block_selected;
11741 weed_timecode_t min_tc = 0, max_tc = -1;
11745 out_start_range = in_val + 1. / mt->fps;
11746 double out_end_range, real_out_end_range;
11747 double in_end_range = out_val - 1. / mt->fps, real_in_start_range = in_start_range;
11750 int track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
11772 real_out_end_range = out_end_range;
11775 if (!block->end_anchored && max_tc > -1 &&
11779 if (!block->start_anchored && min_tc > -1 &&
11783 if (!block->start_anchored) out_end_range = real_out_end_range;
11784 if (!block->end_anchored) in_start_range = real_in_start_range;
11787 if (block->end_anchored && (out_val - in_val > out_start_range)) out_start_range = in_start_range + out_val - in_val;
11788 if (block->start_anchored && (out_end_range - out_val + in_val) < in_end_range) in_end_range = out_end_range - out_val + in_val;
11790 in_end_range =
lives_fix(in_end_range, 2);
11791 real_out_end_range =
lives_fix(real_out_end_range, 2);
11793 out_start_range =
lives_fix(out_start_range, 2);
11794 real_in_start_range =
lives_fix(real_in_start_range, 2);
11809static void update_in_image(lives_mt * mt) {
11810 LiVESPixbuf *thumb;
11811 track_rect *block = mt->block_selected;
11818 if (!mt->insurface)
return;
11821 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
11826 filenum = mt->file_selected;
11843static void update_out_image(lives_mt * mt, weed_timecode_t end_tc) {
11844 LiVESPixbuf *thumb;
11845 track_rect *block = mt->block_selected;
11852 if (!mt->outsurface)
return;
11855 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
11861 filenum = mt->file_selected;
11879 lives_mt *mt = (lives_mt *)user_data;
11880 track_rect *block = mt->block_selected;
11881 weed_timecode_t end_tc;
11883 if (!block)
return FALSE;
11884 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
11885 if (track < 0)
return FALSE;
11888 if (!mt->insurface || !mt->outsurface)
return TRUE;
11891 update_in_image(mt);
11892 update_out_image(mt, end_tc);
11898 lives_mt *mt = (lives_mt *)user_data;
11900 track_rect *block = mt->block_selected, *ablock = NULL;
11902 weed_plant_t *event;
11903 weed_plant_t *start_event = NULL, *event_next;
11905 weed_timecode_t new_start_tc, orig_start_tc, offset_end, tl_start;
11906 weed_timecode_t new_tl_tc;
11909 double avel = 1., aseek = 0.;
11912 boolean start_anchored;
11913 boolean needs_idlefunc =
FALSE;
11914 boolean did_backup = mt->did_backup;
11922 if (mt->idlefunc > 0) {
11923 needs_idlefunc =
TRUE;
11934 set_clip_labels_variable(mt, mt->file_selected);
11935 update_in_image(mt);
11940 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
11949 event = block->start_event;
11950 orig_start_tc = block->offset_start;
11951 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
11952 new_start_tc =
q_dbl(new_start, mt->fps);
11954 if (new_start_tc == orig_start_tc || !block->ordered) {
11956 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
11967 if (!mt->aud_track_selected) {
11968 if (mt->opts.pertrack_audio) {
11969 LiVESWidget *aeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"atrack"));
11972 start_anchored = block->start_anchored;
11974 LiVESWidget *eventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"owner"));
11977 start_anchored = ablock->start_anchored;
11982 start_anchored = block->start_anchored;
11987 if (!start_anchored) {
11988 if (new_start_tc > block->offset_start) {
11993 if ((
get_event_timecode(event) - tl_start) >= (new_start_tc - block->offset_start) / avel) {
12001 if (ablock->prev && ablock->prev->end_event == ablock->start_event) {
12009 ablock->start_event = event;
12010 ablock->offset_start = new_start_tc;
12012 if (block != ablock) {
12013 block->start_event = event;
12014 block->offset_start = new_start_tc;
12019 if (event == block->end_event) {
12020 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
12047 if (event == start_event) start_event = NULL;
12061 event = event_next;
12076 q_gint64(tl_start + (new_start_tc - ablock->offset_start) / avel, mt->fps),
12082 if (block != ablock) {
12085 block->offset_start = new_start_tc;
12090 event = block->start_event;
12093 start_event = event;
12103 event = start_event;
12118 block->eventbox, mt, block);
12126 mt->opts.insert_mode = insert_mode;
12129 offset_end = (new_start_tc = block->offset_start) + (weed_timecode_t)((double)(track >= 0) *
TICKS_PER_SECOND_DBL / mt->fps) +
12133 set_in_out_spin_ranges(mt, new_start_tc, offset_end);
12145 update_in_image(mt);
12146 if (start_anchored) update_out_image(mt, offset_end);
12147 update_in_image(mt);
12148 if (start_anchored) update_out_image(mt, offset_end);
12153 redraw_eventbox(mt, block->eventbox);
12154 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
12158 mt->auto_changed =
TRUE;
12175 lives_mt *mt = (lives_mt *)user_data;
12177 track_rect *block = mt->block_selected, *ablock = NULL;
12179 weed_timecode_t offset_end, orig_end_tc;
12180 weed_timecode_t new_end_tc, tl_end;
12181 weed_timecode_t new_tl_tc;
12183 weed_plant_t *event, *prevevent, *shortcut = NULL;
12184 weed_plant_t *start_event, *event_next, *init_event, *new_end_event;
12188 double aseek, avel = 1.;
12191 boolean end_anchored;
12192 boolean needs_idlefunc =
FALSE;
12193 boolean did_backup = mt->did_backup;
12203 if (mt->idlefunc > 0) {
12204 needs_idlefunc =
TRUE;
12211 sfile->
end = (int)new_end;
12212 set_clip_labels_variable(mt, mt->file_selected);
12213 update_out_image(mt, 0);
12216 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
12224 event = block->end_event;
12225 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
12231 if (!mt->aud_track_selected) {
12232 if (mt->opts.pertrack_audio) {
12233 LiVESWidget *aeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"atrack"));
12236 end_anchored = block->end_anchored;
12238 LiVESWidget *eventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"owner"));
12241 end_anchored = ablock->end_anchored;
12246 end_anchored = block->end_anchored;
12261 orig_end_tc = offset_end;
12263#ifdef DEBUG_BL_MOVE
12264 g_print(
"pt a %ld %ld %ld %.4f %ld %ld\n", block->offset_start,
get_event_timecode(block->end_event),
12272 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
12281 if (!end_anchored) {
12286#ifdef DEBUG_BL_MOVE
12287 g_print(
"new tl tc is %ld %ld %.4f %.4f\n", new_tl_tc, tl_end, new_end, start_val);
12289 if (tl_end > new_tl_tc) {
12296 if (!ablock->next || ablock->next->start_event != ablock->end_event)
12300 block->end_event = event;
12310 if (!new_end_event) {
12311 weed_plant_t *shortcut = ablock->end_event;
12313 q_gint64(new_tl_tc + (weed_timecode_t)((
double)(track >= 0) *
12316 ablock->end_event = shortcut;
12317 }
else ablock->end_event = new_end_event;
12323 start_event = block->end_event;
12332 if (event == start_event) start_event = NULL;
12337 if (init_event != mt->avol_init_event) {
12348 event = event_next;
12360 block->end_event,
TRUE);
12365 shortcut = last_frame_event;
12366 while (final_tc < new_tl_tc) {
12373 ablock->end_event,
TRUE);
12374 if (new_end_event == ablock->end_event) {
12381 if (!new_end_event) {
12382 if (!shortcut) shortcut = ablock->end_event;
12385 ablock->end_event = shortcut;
12386 }
else ablock->end_event = new_end_event;
12388 if (!ablock->next || ablock->next->start_event != ablock->end_event) {
12396 start_event = event;
12401 if (init_event != mt->avol_init_event) {
12407 event = start_event;
12416 weed_timecode_t offset_start;
12419 offset_end =
q_gint64((offset_start = block->offset_start + new_end_tc - orig_end_tc) +
12426 if (track >= 0)
insert_frames(filenum, offset_end, offset_start, tl_end +
12427 (weed_timecode_t)((
double)(track >= 0
12431 block->offset_start =
q_gint64(offset_start, mt->fps);
12442 mt->opts.insert_mode = insert_mode;
12446 new_end_tc = (block->offset_start + (weed_timecode_t)((
double)(track >= 0) *
TICKS_PER_SECOND_DBL / mt->fps) +
12449#ifdef DEBUG_BL_MOVE
12454 if (mt->avol_fx != -1 && mt->avol_init_event && mt->audio_draws &&
12455 mt->audio_draws->data && !block->next) {
12456 apply_avol_filter(mt);
12460 set_in_out_spin_ranges(mt, block->offset_start, new_end_tc);
12470 update_out_image(mt, new_end_tc);
12471 if (end_anchored) update_in_image(mt);
12474#ifdef DEBUG_BL_MOVE
12475 g_print(
"pt b %ld\n",
q_gint64(new_end_tc / avel, mt->fps));
12478 redraw_eventbox(mt, block->eventbox);
12479 if (ablock && ablock != block) redraw_eventbox(mt, block->eventbox);
12480 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
12484 mt->auto_changed =
TRUE;
12501 lives_mt *mt = (lives_mt *)user_data;
12502 track_rect *block = mt->block_selected;
12503 int track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
12538 if (!block->start_anchored || !block->end_anchored) {
12549 lives_mt *mt = (lives_mt *)user_data;
12550 track_rect *block = mt->block_selected;
12551 int track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
12555 weed_timecode_t new_end_tc, old_tl_tc, start_tc, new_tl_tc, min_tc;
12556 weed_plant_t *new_end_event, *new_start_event;
12557 double orig_end_val, orig_start_val;
12558 boolean was_adjusted =
FALSE;
12564 start_tc = block->offset_start;
12569 if (!block->end_anchored) {
12570 new_end_tc =
q_gint64(start_tc + ((orig_end_val =
12583 set_in_out_spin_ranges(mt, block->offset_start, new_end_tc);
12592 if (new_tl_tc != old_tl_tc) {
12593 weed_plant_t *shortcut;
12594 if (new_tl_tc > old_tl_tc) shortcut = block->end_event;
12595 else shortcut = block->start_event;
12596 if (!block->next || block->next->start_event != block->end_event)
remove_audio_for_track(block->end_event, -1);
12598 if (new_end_event == block->start_event)
return;
12599 block->end_event = new_end_event;
12601 if (!block->end_event) {
12606 if (!block->next || block->next->start_event != block->end_event)
12618 if (mt->avol_fx != -1 && !block->next) {
12619 apply_avol_filter(mt);
12623 redraw_eventbox(mt, block->eventbox);
12624 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
12637 if (new_tl_tc < min_tc) {
12640 new_tl_tc = min_tc;
12641 was_adjusted =
TRUE;
12646 if (was_adjusted || new_tl_tc != old_tl_tc) {
12647 weed_plant_t *shortcut;
12648 if (new_tl_tc > old_tl_tc) shortcut = block->start_event;
12650 if (block->prev) shortcut = block->prev->end_event;
12651 else shortcut = NULL;
12655 if (new_start_event == block->end_event)
return;
12657 if (!block->prev || block->start_event != block->prev->end_event)
remove_audio_for_track(block->start_event, -1);
12659 block->start_event = new_start_event;
12665 set_in_out_spin_ranges(mt, start_tc, new_end_tc);
12676 if (mt->avol_fx != -1 && !block->next) {
12677 apply_avol_filter(mt);
12684 lives_mt *mt = (lives_mt *)user_data;
12685 track_rect *block = mt->block_selected;
12686 weed_timecode_t offset_end;
12691 if (mt->current_track < 0) {
12695 offset_end = block->offset_start + (double)(mt->current_track >= 0 && !mt->aud_track_selected) *
12699 block->start_anchored = !block->start_anchored;
12701 set_in_out_spin_ranges(mt, block->offset_start, offset_end);
12711 if (mt->current_track >= 0 && mt->opts.pertrack_audio) {
12712 LiVESWidget *xeventbox;
12713 track_rect *xblock;
12716 if (mt->aud_track_selected) {
12717 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"owner");
12719 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"atrack");
12723 if (xblock) xblock->start_anchored = block->start_anchored;
12730 lives_mt *mt = (lives_mt *)user_data;
12731 track_rect *block = mt->block_selected;
12732 weed_timecode_t offset_end;
12737 if (mt->current_track < 0) {
12741 offset_end = block->offset_start + (double)(mt->current_track >= 0 && !mt->aud_track_selected) *
12745 block->end_anchored = !block->end_anchored;
12747 set_in_out_spin_ranges(mt, block->offset_start, offset_end);
12757 if (mt->current_track >= 0 && mt->opts.pertrack_audio) {
12758 LiVESWidget *xeventbox;
12759 track_rect *xblock;
12762 if (mt->aud_track_selected) {
12763 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"owner");
12765 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"atrack");
12769 if (xblock) xblock->end_anchored = block->end_anchored;
12775#define POLY_WIDTH_MARGIN 4
12778 LiVESPixbuf *thumb;
12780 weed_timecode_t offset_end = 0;
12781 weed_timecode_t tc;
12783 weed_plant_t *filter, *inst;
12784 weed_plant_t *frame_event, *filter_map = NULL;
12785 weed_plant_t *init_event;
12786 weed_plant_t *prev_fm_event, *next_fm_event, *shortcut;
12788 track_rect *block = mt->block_selected;
12790 void **init_events;
12792 int *in_tracks, *out_tracks;
12795 LiVESWidget *eventbox, *xeventbox, *yeventbox, *label, *vbox;
12798 double out_end_range;
12802 char *fname, *otrackname, *txt;
12804 boolean is_input, is_output;
12805 boolean has_effect =
FALSE;
12806 boolean has_params;
12807 boolean tab_set =
FALSE;
12808 boolean start_anchored, end_anchored;
12810 int num_in_tracks, num_out_tracks;
12811 int def_out_track = 0;
12819 int track, fromtrack;
12820 int frame_start, frame_end = 0;
12823 static int xxwidth = 0, xxheight = 0;
12827 if (mt->in_sensitise)
return;
12833 switch (mt->poly_state) {
12845 if (mt->framedraw) {
12847 mt->framedraw = NULL;
12849 if (mt->current_rfx) {
12853 mt->current_rfx = NULL;
12859 mt->fx_params_label = NULL;
12863 if (mt->mt_frame_preview) {
12883 mt->init_event = NULL;
12890 mt->selected_init_event = NULL;
12891 mt->fm_edit_event = NULL;
12892 mt->context_time = -1.;
12900 mt->fx_list_scroll = NULL;
12907 mt->fx_list_box = NULL;
12909 mt->nb_label = NULL;
12911 mt->poly_state = poly;
12913 if (mt->poly_state ==
POLY_NONE)
return;
12920 while (xxwidth < 1 || xxheight < 1) {
12940 mt->init_event = NULL;
12941 if (!block || block->ordered) {
12951 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
"layer_number"));
12953 offset_end = block->offset_start + (weed_timecode_t)((
double)(track >= 0) *
TICKS_PER_SECOND_DBL / mt->fps) +
12956 start_anchored = block->start_anchored;
12957 end_anchored = block->end_anchored;
12960 start_anchored = end_anchored =
FALSE;
12961 filenum = mt->file_selected;
12967 LiVESWidget *oeventbox;
12971 if (mt->context_time != -1. && mt->use_context) secs = mt->context_time;
12972 if (is_audio_eventbox(block->eventbox) &&
12973 (oeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(block->eventbox),
12976 block = get_block_from_time(oeventbox, secs, mt);
12983 filenum = mt->file_selected;
12990 filenum = mt->file_selected;
12996 if (mt->insurface) {
12997 thumb =
make_thumb(mt, filenum, width, height, frame_start, LIVES_INTERP_NORMAL,
FALSE);
13035 filenum = mt->file_selected;
13062 if (mt->outsurface) {
13063 thumb =
make_thumb(mt, filenum, width, height, frame_end, LIVES_INTERP_NORMAL,
FALSE);
13074 / mt->fps, out_end_range);
13076 if (!block->start_anchored || !block->end_anchored) {
13126 mt->init_event = NULL;
13136 if (mt->current_rfx) {
13159 get_track_index(mt, tc);
13161 mt->prev_fx_time = 0;
13166 mt->block_tl_move =
TRUE;
13168 mt->block_tl_move =
FALSE;
13175 add_context_label(mt,
_(
"NODES are points where parameters\nhave been set.\nNodes can be deleted."));
13191 mt->init_event = NULL;
13192 if (mt->current_track >= 0) eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
13193 else eventbox = (LiVESWidget *)mt->audio_draws->data;
13195 if (!eventbox)
break;
13197 secs = mt->ptr_time;
13198 if (mt->context_time != -1. && mt->use_context) secs = mt->context_time;
13200 block = get_block_from_time(eventbox, secs, mt);
13202 block = get_block_before(eventbox, secs,
FALSE);
13203 if (block) shortcut = block->end_event;
13204 else shortcut = NULL;
13205 }
else shortcut = block->start_event;
13218 set_css_value_direct(mt->fx_list_label, LIVES_WIDGET_STATE_NORMAL,
"",
"padding-top",
"10px");
13219 set_css_value_direct(mt->fx_list_label, LIVES_WIDGET_STATE_NORMAL,
"",
"padding-bottom",
"10px");
13238 for (i = 0; i < num_fx; i++) {
13239 init_event = (weed_plant_t *)init_events[i];
13244 if (num_in_tracks > 0) {
13245 for (j = 0; j < num_in_tracks; j++) {
13246 if (in_tracks[j] == mt->current_track) {
13248 }
else if (num_in_tracks == 2) fromtrack = in_tracks[j];
13254 if (num_out_tracks > 0) {
13255 def_out_track = out_tracks[0];
13256 for (j = 0; j < num_out_tracks; j++) {
13257 if (out_tracks[j] == mt->current_track) {
13265 if (!is_input && !is_output)
continue;
13278 }
else if (!is_output && num_out_tracks > 0) {
13279 if (def_out_track > -1) {
13280 yeventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, def_out_track);
13281 olayer = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(yeventbox),
"layer_number"));
13283 }
else otrackname = (
_(
"audio track"));
13286 }
else if (num_in_tracks == 2 && num_out_tracks > 0) {
13287 if (fromtrack > -1) {
13288 yeventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, fromtrack);
13289 olayer = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(yeventbox),
"layer_number"));
13291 }
else otrackname = (
_(
"audio track"));
13295 txt = lives_strdup(fname);
13298 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(xeventbox),
"init_event", (livespointer)init_event);
13314 if (init_event == mt->selected_init_event) {
13322 lives_signal_sync_connect(LIVES_GUI_OBJECT(xeventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
13323 LIVES_GUI_CALLBACK(fx_ebox_pressed), (livespointer)mt);
13348 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->prev_fm_button), LIVES_WIDGET_CLICKED_SIGNAL,
13358 mt->selected_init_event != NULL);
13360 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->fx_ibefore_button), LIVES_WIDGET_CLICKED_SIGNAL,
13369 mt->selected_init_event != NULL);
13371 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->fx_iafter_button), LIVES_WIDGET_CLICKED_SIGNAL,
13375 mt->fx_ibefore_button = mt->fx_iafter_button = NULL;
13386 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->next_fm_button), LIVES_WIDGET_CLICKED_SIGNAL,
13404 set_fxlist_label(mt);
13413 add_context_label(mt, (
_(
"Drag a compositor anywhere\non the timeline\nto apply it to the selected region.")));
13420 add_context_label(mt, (
_(
"Drag a transition anywhere\non the timeline\nto apply it to the selected region.")));
13433 mt->fx_list_scroll = NULL;
13435 if (mt->poly_state ==
POLY_COMP) nins = 1000000;
13436 populate_filter_box(nins, mt, 0);
13446static void mouse_select_start(LiVESWidget * widget, LiVESXEventButton * event, lives_mt * mt) {
13456 mt->timeline, &mt->sel_x, &mt->sel_y);
13458 mt->region_start = mt->region_end = mt->region_init = timesecs;
13460 mt->region_updating =
TRUE;
13462 mt->region_updating =
FALSE;
13465 mt->tl_eventbox, &mt->sel_x, &mt->sel_y);
13468 if (mt->sel_x < min_x) mt->sel_x = min_x;
13469 if (mt->sel_y < 0.) mt->sel_y = 0.;
13474 mt->tl_selecting =
TRUE;
13478static void mouse_select_end(LiVESWidget * widget, LiVESXEventButton * event, lives_mt * mt) {
13481 mt->tl_selecting =
FALSE;
13483 mt->timeline, &mt->sel_x, &mt->sel_y);
13490static void mouse_select_move(LiVESWidget * widget, LiVESXEventMotion * event, lives_mt * mt) {
13491 lives_painter_t *cr;
13493 LiVESWidget *xeventbox;
13494 LiVESWidget *checkbutton;
13497 int start_x, start_y, width, height;
13498 int current_track = mt->current_track;
13500 int rel_x, rel_y, min_x;
13501 int offs_y_start, offs_y_end, xheight;
13510 mt->tl_eventbox, &x, &y);
13513 if (x < min_x) x = min_x;
13514 if (y < 0.) y = 0.;
13519 if (x >= mt->sel_x) {
13520 start_x = mt->sel_x;
13521 width = x - mt->sel_x;
13524 width = mt->sel_x - x;
13526 if (y >= mt->sel_y) {
13527 start_y = mt->sel_y;
13528 height = y - mt->sel_y;
13531 height = mt->sel_y - y;
13534 if (start_x < 0) start_x = 0;
13535 if (start_y < 0) start_y = 0;
13543 for (i = 0; i < mt->num_video_tracks; i++) {
13544 xeventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, i);
13545 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
HIDDEN_KEY)) == 0) {
13547 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"checkbutton");
13549 if (start_y > (rel_y + xheight / 2) || (start_y + height) < (rel_y + xheight / 2)) {
13555 mt->current_track = current_track;
13560 if (giw_led_get_mode(GIW_LED(checkbutton))) {
13561 giw_led_set_mode(GIW_LED(checkbutton),
FALSE);
13562 mt->current_track = current_track;
13570 offs_y_end = xheight;
13572 if (start_y < rel_y + xheight) {
13573 offs_y_start = start_y - rel_y;
13577 if (start_y + height < rel_y + xheight) {
13578 offs_y_end = start_y - rel_y + height;
13594 mt->current_track = current_track;
13599 if (!giw_led_get_mode(GIW_LED(checkbutton))) {
13600 giw_led_set_mode(GIW_LED(checkbutton),
TRUE);
13601 mt->current_track = current_track;
13611 if (widget != mt->timeline_eb) {
13612 mt->region_updating =
TRUE;
13614 mt->region_updating =
FALSE;
13622 LiVESWidget *delete_block;
13623 LiVESWidget *split_here;
13624 LiVESWidget *list_fx_here;
13625 LiVESWidget *selblock;
13629 double block_start_time, block_end_time;
13640 LIVES_GUI_CALLBACK(
selblock_cb), (livespointer)mt);
13642 if (block->ordered) {
13650 if (mt->ptr_time < block_start_time || mt->ptr_time >= block_end_time)
13653 lives_signal_sync_connect(LIVES_GUI_OBJECT(split_here), LIVES_WIDGET_ACTIVATE_SIGNAL,
13663 if (is_audio_eventbox(block->eventbox) && mt->avol_init_event) {
13664 char *avol_fxname = weed_get_string_value(
get_weed_filter(mt->avol_fx), WEED_LEAF_NAME, NULL);
13672 LIVES_GUI_CALLBACK(mt_avol_quick), (livespointer)mt);
13698 LiVESWidget *insert_here, *avol;
13701 boolean has_something =
FALSE;
13702 boolean needs_idlefunc =
FALSE;
13703 boolean did_backup = mt->did_backup;
13707 if (mt->idlefunc > 0) {
13710 needs_idlefunc =
TRUE;
13713 mouse_select_end(NULL, event, mt);
13717 if (mt->file_selected > 0 && ((track < 0 && mainw->files[mt->file_selected]->achans > 0 &&
13732 has_something =
TRUE;
13735 if (mt->audio_draws && (track < 0 || mt->opts.pertrack_audio) && mt->event_list) {
13736 char *avol_fxname = weed_get_string_value(
get_weed_filter(mt->avol_fx), WEED_LEAF_NAME, NULL);
13744 LIVES_GUI_CALLBACK(mt_avol_quick),
13749 has_something =
TRUE;
13752 if (has_something) {
13763 LIVES_GUI_CALLBACK(rdrw_cb),
13767 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
13773boolean on_track_release(LiVESWidget * eventbox, LiVESXEventButton * event, livespointer user_data) {
13774 lives_mt *mt = (lives_mt *)user_data;
13775 weed_timecode_t tc, tcpp;
13777 LiVESWidget *xeventbox;
13778 LiVESWidget *oeventbox;
13779 LiVESWidget *xlabelbox;
13780 LiVESWidget *xahbox;
13781 LiVESXWindow *window;
13785 boolean got_track =
FALSE;
13786 boolean needs_idlefunc =
FALSE;
13787 boolean did_backup = mt->did_backup;
13793 int old_track = mt->current_track;
13799 if (mt->idlefunc > 0) {
13802 needs_idlefunc =
TRUE;
13814 mt->display, &win_x, &win_y);
13818 for (list = mt->audio_draws; list; list = list->next, i++) {
13819 xeventbox = (LiVESWidget *)list->data;
13820 oeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"owner");
13821 if (i >= mt->opts.back_audio_tracks &&
13822 !LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(oeventbox),
"expanded")))
continue;
13823 xlabelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"labelbox");
13824 xahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"ahbox");
13829 mt->aud_track_selected =
TRUE;
13836 for (list = mt->video_draws; list; list = list->next) {
13837 xeventbox = (LiVESWidget *)list->data;
13838 xlabelbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"labelbox");
13839 xahbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"ahbox");
13842 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"layer_number"));
13843 mt->aud_track_selected =
FALSE;
13851 mouse_select_end(eventbox, event, mt);
13853 mt->sel_y -= y + 2;
13855 if (mt->hotspot_x != 0 || mt->hotspot_y != 0) {
13856 LiVESXScreen *screen;
13861 mt->display, &screen, &abs_x, &abs_y, NULL);
13863 mt->display, screen, abs_x + mt->hotspot_x, abs_y + mt->hotspot_y - height / 2);
13864 mt->hotspot_x = mt->hotspot_y = 0;
13872 mt->putative_block = get_block_from_time(eventbox, timesecs, mt);
13874 mt->putative_block = NULL;
13875 doubleclick =
FALSE;
13876 goto track_rel_done;
13879 if (got_track && !mt->is_rendering && mt->putative_block && !
LIVES_IS_PLAYING &&
13880 event->button == 1) {
13881 weed_timecode_t start_tc;
13891 (LIVES_WIDGET(lives_list_nth_data(mt->video_draws, 0))));
13894 if ((track != mt->current_track || (tc - start_tc > (tcpp * 3 / 2)) || (start_tc - tc > (tcpp * 3 / 2))) &&
13895 ((old_track < 0 && track < 0) || (old_track >= 0 && track >= 0))) {
13896 move_block(mt, mt->putative_block, timesecs, old_track, track);
13897 mt->putative_block = NULL;
13911 mt->hotspot_x = mt->hotspot_y = 0;
13912 mt->putative_block = NULL;
13917 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
13926 lives_mt *mt = (lives_mt *)user_data;
13929 mouse_select_start(widget, event, mt);
13937 lives_mt *mt = (lives_mt *)user_data;
13940 mouse_select_end(widget, event, mt);
13948 lives_mt *mt = (lives_mt *)user_data;
13951 mouse_select_start(widget, event, mt);
13959 lives_mt *mt = (lives_mt *)user_data;
13962 mouse_select_end(widget, event, mt);
13969boolean on_track_click(LiVESWidget * eventbox, LiVESXEventButton * event, livespointer user_data) {
13970 lives_mt *mt = (lives_mt *)user_data;
13984 mt->aud_track_selected = is_audio_eventbox(eventbox);
13993 if (
mainw->
files[mt->render_file]->
achans == 0 || !mt->audio_draws || (mt->opts.back_audio_tracks == 0 ||
13994 eventbox != mt->audio_draws->data))
13995 track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
13997 block = mt->putative_block = get_block_from_time(eventbox, timesecs, mt);
14001 if (mt->opts.mouse_mode ==
MOUSE_MODE_SELECT && event->type == LIVES_BUTTON_PRESS) {
14002 mouse_select_start(eventbox, event, mt);
14007 doubleclick =
TRUE;
14011 if (event->button == 1) {
14013 mt->fm_edit_event = NULL;
14025 if (event->time != dclick_time) {
14026 show_track_info(mt, eventbox, track, timesecs);
14028 if (!is_audio_eventbox(eventbox))
14036 if (!mt->is_rendering) {
14037 double start_secs, end_secs;
14039 LiVESXScreen *screen;
14049 if (event->button == 1) {
14051 mt->putative_block = NULL;
14054 if (!is_audio_eventbox(eventbox))
14058 width = (width / (mt->tl_max - mt->tl_min) * (
double)ebwidth);
14059 if (width > ebwidth) width = ebwidth;
14060 if (width < 2) width = 2;
14062 mt->hotspot_x = x - (int)((ebwidth * ((
double)start_secs - mt->tl_min) / (mt->tl_max - mt->tl_min)) + .5);
14065 mt->display, &screen, &abs_x, &abs_y, NULL);
14067 mt->display, screen, abs_x - mt->hotspot_x, abs_y - y + height / 2);
14068 if (track >= 0 && !mt->aud_track_selected) {
14083 mt->putative_block = NULL;
14087 mt->current_track = track;
14092 mt->context_time = timesecs;
14095 mt->putative_block = block;
14112boolean on_track_move(LiVESWidget * widget, LiVESXEventMotion * event, livespointer user_data) {
14114 lives_mt *mt = (lives_mt *)user_data;
14116 if (mt->opts.mouse_mode ==
MOUSE_MODE_SELECT) mouse_select_move(widget, event, mt);
14123 lives_mt *mt = (lives_mt *)user_data;
14125 if (mt->opts.mouse_mode ==
MOUSE_MODE_SELECT) mouse_select_move(widget, event, mt);
14134 if (mt->redraw_block)
return;
14136 if (!mt->is_ready)
return;
14137 if ((xoffset = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"has_line"))) < 0)
return;
14141 if (xoffset < ebwidth) {
14146 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"has_line", LIVES_INT_TO_POINTER(-1));
14151 if (!mt->is_ready)
return;
14157static void paint_line(lives_mt * mt, LiVESWidget * eventbox,
int offset,
double currtime,
14158 lives_painter_t *cr) {
14159 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"has_line", LIVES_INT_TO_POINTER(offset));
14164static void paint_lines(lives_mt * mt,
double currtime,
boolean unpaint, lives_painter_t *cr) {
14168 if (!mt->is_ready)
return;
14174 if (currtime < mt->tl_min || currtime > mt->tl_max)
return;
14175 offset = (currtime - mt->tl_min) / (mt->tl_max - mt->tl_min) * (double)ebwidth;
14180 if (offset > off_x && offset < ebwidth + off_x) {
14181 paint_line(mt, mt->timeline_table, offset, currtime, cr);
14186static void _animate_multitrack(lives_mt * mt) {
14191 int offset, offset_old;
14194 update_timecodes(mt, currtime);
14196 offset = (currtime - mt->tl_min) / (mt->tl_max - mt->tl_min) * (double)ebwidth;
14198 / (mt->tl_max - mt->tl_min) * (double)ebwidth;
14202 if (offset == offset_old)
return;
14204 if (mt->opts.follow_playback) {
14205 if (currtime > (mt->tl_min + ((tl_page = mt->tl_max - mt->tl_min)) * .85) &&
14208 mt->tl_min += tl_page * .85;
14209 mt->tl_max += tl_page * .85;
14214 if ((offset < 0. && offset_old < 0.) || (offset > (
double)ebwidth && offset_old > (
double)ebwidth))
return;
14217 if (mt->redraw_block)
return;
14219 paint_lines(mt, currtime,
TRUE, NULL);
14230static boolean multitrack_end(LiVESMenuItem * menuitem, livespointer user_data) {
14231 lives_mt *mt = (lives_mt *)user_data;
14238 lives_mt *mt = (lives_mt *)user_data;
14239 if (mt->is_rendering)
return;
14240 multitrack_end(menuitem, user_data);
14245 lives_mt *mt = (lives_mt *)user_data;
14246 if (mt->is_rendering)
return;
14252 lives_mt *mt = (lives_mt *)user_data;
14253 if (mt->is_rendering)
return;
14254 mt->use_context =
TRUE;
14260 lives_mt *mt = (lives_mt *)user_data;
14261 if (mt->is_rendering)
return;
14267 lives_mt *mt = (lives_mt *)user_data;
14268 if (mt->is_rendering)
return;
14274 lives_mt *mt = (lives_mt *)user_data;
14276 if (mt->file_selected != -1) {
14285 lives_mt *mt = (lives_mt *)user_data;
14286 if (mt->is_rendering)
return;
14292 lives_mt *mt = (lives_mt *)user_data;
14293 if (mt->is_rendering)
return;
14294 mt->use_context =
TRUE;
14300 lives_mt *mt = (lives_mt *)user_data;
14301 if (mt->is_rendering)
return;
14302 on_delblock_activate(NULL, user_data);
14307 lives_mt *mt = (lives_mt *)user_data;
14309 mt->putative_block = NULL;
14314 lives_mt *mt = (lives_mt *)user_data;
14316 mt->context_time = -1.;
14323static void on_move_fx_changed(LiVESMenuItem * menuitem, livespointer user_data) {
14324 lives_mt *mt = (lives_mt *)user_data;
14325 mt->opts.move_effects = !mt->opts.move_effects;
14329static void select_all_time(LiVESMenuItem * menuitem, livespointer user_data) {
14330 lives_mt *mt = (lives_mt *)user_data;
14331 mt->region_start = 0.;
14337static void select_from_zero_time(LiVESMenuItem * menuitem, livespointer user_data) {
14338 lives_mt *mt = (lives_mt *)user_data;
14339 if (mt->region_start == 0. && mt->region_end == 0.) mt->region_end = mt->ptr_time;
14340 mt->region_start = 0.;
14345static void select_to_end_time(LiVESMenuItem * menuitem, livespointer user_data) {
14346 lives_mt *mt = (lives_mt *)user_data;
14347 if (mt->region_start == 0. && mt->region_end == 0.) mt->region_start = mt->ptr_time;
14353static void select_all_vid(LiVESMenuItem * menuitem, livespointer user_data) {
14354 lives_mt *mt = (lives_mt *)user_data;
14355 LiVESWidget *eventbox, *checkbutton;
14356 LiVESList *vdr = mt->video_draws;
14358 int current_track = mt->current_track;
14367 eventbox = (LiVESWidget *)vdr->data;
14368 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton");
14377 if (!giw_led_get_mode(GIW_LED(checkbutton))) giw_led_set_mode(GIW_LED(checkbutton),
TRUE);
14380 mt->current_track = i++;
14385 mt->current_track = current_track;
14389static void select_no_vid(LiVESMenuItem * menuitem, livespointer user_data) {
14390 lives_mt *mt = (lives_mt *)user_data;
14391 LiVESWidget *eventbox, *checkbutton;
14392 LiVESList *vdr = mt->video_draws;
14394 int current_track = mt->current_track;
14403 eventbox = (LiVESWidget *)vdr->data;
14404 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton");
14413 if (giw_led_get_mode(GIW_LED(checkbutton))) giw_led_set_mode(GIW_LED(checkbutton),
FALSE);
14416 mt->current_track = i++;
14421 mt->current_track = current_track;
14425static void mt_fplay_toggled(LiVESMenuItem * menuitem, livespointer user_data) {
14426 lives_mt *mt = (lives_mt *)user_data;
14427 mt->opts.follow_playback = !mt->opts.follow_playback;
14432static void mt_render_vid_toggled(LiVESMenuItem * menuitem, livespointer user_data) {
14433 lives_mt *mt = (lives_mt *)user_data;
14434 mt->opts.render_vidp = !mt->opts.render_vidp;
14439static void mt_render_aud_toggled(LiVESMenuItem * menuitem, livespointer user_data) {
14440 lives_mt *mt = (lives_mt *)user_data;
14441 mt->opts.render_audp = !mt->opts.render_audp;
14447static void mt_norm_aud_toggled(LiVESMenuItem * menuitem, livespointer user_data) {
14448 lives_mt *mt = (lives_mt *)user_data;
14449 mt->opts.normalise_audp = !mt->opts.normalise_audp;
14453static void mt_view_audio_toggled(LiVESMenuItem * menuitem, livespointer user_data) {
14454 lives_mt *mt = (lives_mt *)user_data;
14457 if (!mt->opts.show_audio) lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
HIDDEN_KEY,
14459 else lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mt->audio_draws->data),
HIDDEN_KEY, LIVES_INT_TO_POINTER(0));
14466static void mt_ign_ins_sel_toggled(LiVESMenuItem * menuitem, livespointer user_data) {
14467 lives_mt *mt = (lives_mt *)user_data;
14472static void remove_gaps_inner(LiVESMenuItem * menuitem, livespointer user_data,
boolean only_first) {
14473 lives_mt *mt = (lives_mt *)user_data;
14475 weed_timecode_t offset = 0;
14476 weed_timecode_t tc, new_tc, tc_last, new_tc_last, tc_first, block_tc;
14478 LiVESList *vsel = mt->selected_tracks;
14479 LiVESList *track_sel;
14481 LiVESWidget *eventbox;
14483 track_rect *block = NULL;
14485 boolean did_backup = mt->did_backup;
14486 boolean audio_done =
FALSE;
14487 boolean needs_idlefunc =
FALSE;
14492 if (mt->idlefunc > 0) {
14493 needs_idlefunc =
TRUE;
14504 while (vsel || (mt->current_track == -1 && !audio_done)) {
14506 if (mt->current_track > -1) {
14507 track = LIVES_POINTER_TO_INT(vsel->data);
14508 eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, track);
14511 eventbox = (LiVESWidget *)mt->audio_draws->data;
14521 if (new_tc > tc) tc = new_tc;
14529 if (new_tc_last < tc_last) tc_last = new_tc_last;
14547 while (tc <= tc_last) {
14552 if (new_tc > tc_last)
break;
14556 if (offset > 0) tc =
q_gint64(new_tc - offset, mt->fps);
14563 track_sel = mt->selected_tracks;
14564 mt->selected_tracks = NULL;
14566 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
14567 mt->selected_tracks = track_sel;
14568 if (only_first && offset == 0) offset = new_tc - tc;
14572 if (mt->current_track > -1) vsel = vsel->next;
14573 else audio_done =
TRUE;
14583 while (tc >= tc_first) {
14588 if (new_tc < tc_first)
break;
14595 if (offset > 0) tc =
q_gint64(new_tc - block_tc + offset, mt->fps);
14596 else tc =
q_gint64(tc - block_tc, mt->fps);
14603 track_sel = mt->selected_tracks;
14604 mt->selected_tracks = NULL;
14606 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
14607 mt->selected_tracks = track_sel;
14608 if (only_first && offset == 0) offset = tc - new_tc + block_tc;
14612 if (mt->current_track > -1) vsel = vsel->next;
14613 else audio_done =
TRUE;
14618 if (mt->avol_fx != -1 && (!block || !block->next) && mt->audio_draws
14620 apply_avol_filter(mt);
14624 mt->did_backup = did_backup;
14625 if (!did_backup && mt->framedraw && mt->current_rfx && mt->init_event
14629 get_track_index(mt, tc);
14633 mt->did_backup =
FALSE;
14634 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
14644 remove_gaps_inner(menuitem, user_data,
TRUE);
14649 remove_gaps_inner(menuitem, user_data,
FALSE);
14653static void split_block(lives_mt * mt, track_rect * block, weed_timecode_t tc,
int track,
boolean no_recurse) {
14654 weed_plant_t *
event = block->start_event;
14655 weed_plant_t *start_event = event;
14656 weed_plant_t *old_end_event = block->end_event;
14657 int frame = 0, clip;
14658 LiVESWidget *eventbox;
14659 track_rect *new_block;
14660 weed_timecode_t offset_start;
14661 double seek, new_seek, vel;
14665 if (!block)
return;
14667 mt->no_expose =
TRUE;
14674 eventbox = block->eventbox;
14676 if (!is_audio_eventbox(eventbox)) {
14679 LiVESWidget *aeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack"));
14681 track_rect *ablock = get_block_from_time(aeventbox, tc /
TICKS_PER_SECOND_DBL + 1. / mt->fps, mt);
14690 LiVESWidget *oeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"owner"));
14691 if (oeventbox) split_block(mt, get_block_from_time(oeventbox, tc /
TICKS_PER_SECOND_DBL - 1. / mt->fps, mt),
14697 event = block->end_event;
14703 if (block->ordered ||
14704 (is_audio_eventbox(eventbox))) offset_start = block->offset_start -
get_event_timecode(start_event)
14708 new_block = add_block_start_point(LIVES_WIDGET(eventbox), tc, clip, offset_start, event, block->ordered);
14709 new_block->end_event = old_end_event;
14711 mt->no_expose =
FALSE;
14713 redraw_eventbox(mt, eventbox);
14714 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
14718static void insgap_inner(lives_mt * mt,
int tnum,
boolean is_sel,
int passnm) {
14733 track_rect *sblock, *block, *ablock = NULL;
14734 LiVESWidget *eventbox;
14736 weed_plant_t *event, *new_event = NULL, *last_frame_event;
14737 weed_plant_t *init_event;
14738 weed_timecode_t tc, new_tc;
14739 weed_timecode_t start_tc, new_init_tc, init_tc;
14740 double aseek = 0., avel = 0., *audio_seeks;
14743 int clip, *clips, *new_clips;
14744 int64_t frame, *frames, *new_frames;
14745 int xnumclips, numclips, naclips;
14746 int aclip = 0, *audio_clips;
14747 int nintracks, *in_tracks;
14754 if (tnum >= 0) eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, tnum);
14755 else eventbox = (LiVESWidget *)mt->audio_draws->data;
14756 tc =
q_dbl(mt->region_start, mt->fps);
14757 sblock = get_block_from_time(eventbox, mt->region_start, mt);
14760 split_block(mt, sblock, tc, tnum,
FALSE);
14761 sblock = sblock->next;
14763 sblock = get_block_after(eventbox, mt->region_start,
FALSE);
14766 if (!sblock)
return;
14769 while (block->next) block = block->next;
14770 event = block->end_event;
14772 if (tnum >= 0 && mt->opts.pertrack_audio) {
14773 LiVESWidget *aeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack"));
14775 ablock = get_block_after(aeventbox, mt->region_start,
FALSE);
14777 while (ablock->next) ablock = ablock->next;
14778 event = ablock->end_event;
14801 clips = weed_get_int_array_counted(new_event,
WEED_LEAF_CLIPS, &numclips);
14802 xnumclips = numclips;
14803 if (numclips < tnum + 1) xnumclips = tnum + 1;
14810 for (i = 0; i < xnumclips; i++) {
14812 new_clips[i] = clip;
14813 new_frames[i] = frame;
14815 if (i < numclips) {
14816 new_clips[i] = clips[i];
14817 new_frames[i] = frames[i];
14825 weed_set_int_array(new_event,
WEED_LEAF_CLIPS, xnumclips, new_clips);
14844 for (i = 0; i < naclips; i += 2) {
14845 if (audio_clips[i] == tnum) {
14846 aclip = audio_clips[i + 1];
14847 aseek = audio_seeks[i];
14848 avel = audio_seeks[i + 1];
14858 if (mt->avol_fx != -1) {
14859 apply_avol_filter(mt);
14864 if (new_event != event) {
14867 if (event == ablock->end_event) ablock->end_event = new_event;
14868 else if (event == ablock->start_event) {
14869 ablock->start_event = new_event;
14873 if (event == block->end_event) block->end_event = new_event;
14874 else if (event == block->start_event) {
14875 block->start_event = new_event;
14876 if (block == sblock) {
14877 if (tnum < 0 || ablock) {
14878 if (ablock) block = ablock;
14879 if (block->prev && block->prev->end_event == event) {
14883 if (mt->avol_fx != -1) {
14884 apply_avol_filter(mt);
14888 redraw_eventbox(mt, eventbox);
14889 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
14892 block = block->prev;
14894 if (ablock && ablock->start_event == new_event) {
14895 ablock = ablock->prev;
14896 if (ablock && event == ablock->end_event) ablock->end_event = new_event;
14903 if (new_event == block->end_event)
event = block->start_event;
14904 else event = block->end_event;
14919 if (init_event == mt->avol_init_event) {
14928 if ((nintracks == 1 && in_tracks[0] != mt->current_track) || (nintracks == 2 && in_tracks[0] != mt->current_track &&
14929 in_tracks[1] != mt->current_track)) {
14934 for (i = 0; i < nintracks; i++) {
14935 slist = mt->selected_tracks;
14938 while (slist && !found) {
14939 if (LIVES_POINTER_TO_INT(slist->data) == in_tracks[i]) found =
TRUE;
14940 slist = slist->next;
14943 if (nintracks != 2 || notmatched > 0)
return;
14957 if (init_tc >= start_tc) {
14965 if (nintracks == 2) {
14967 if (init_tc >= start_tc && init_event != mt->avol_init_event)
14976 if (end_secs > mt->end_secs) {
14984 lives_mt *mt = (lives_mt *)user_data;
14985 LiVESList *slist = mt->selected_tracks;
14986 char *tstart, *tend;
14987 boolean did_backup = mt->did_backup;
14988 boolean needs_idlefunc =
FALSE;
14992 if (mt->idlefunc > 0) {
14993 needs_idlefunc =
TRUE;
15001 track = LIVES_POINTER_TO_INT(slist->data);
15002 insgap_inner(mt, track,
TRUE, 1);
15003 slist = slist->next;
15006 if (mt->opts.move_effects) {
15007 insgap_inner(mt, 0,
TRUE, 2);
15010 mt->did_backup = did_backup;
15013 tstart = time_to_string(
QUANT_TIME(mt->region_start));
15014 tend = time_to_string(
QUANT_TIME(mt->region_end));
15016 d_print(
_(
"Inserted gap in selected tracks from time %s to time %s\n"), tstart, tend);
15022 mt->did_backup =
FALSE;
15023 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
15030 lives_mt *mt = (lives_mt *)user_data;
15032 boolean did_backup = mt->did_backup;
15033 boolean needs_idlefunc =
FALSE;
15035 char *tstart, *tend;
15038 if (mt->idlefunc > 0) {
15039 needs_idlefunc =
TRUE;
15046 insgap_inner(mt, mt->current_track,
FALSE, 1);
15048 if (mt->opts.move_effects) {
15049 insgap_inner(mt, mt->current_track,
FALSE, 2);
15052 mt->did_backup = did_backup;
15055 tstart = time_to_string(
QUANT_TIME(mt->region_start));
15056 tend = time_to_string(
QUANT_TIME(mt->region_end));
15059 d_print(
_(
"Inserted gap in track %s from time %s to time %s\n"), tname, tstart, tend);
15066 mt->did_backup =
FALSE;
15067 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
15074 lives_mt *mt = (lives_mt *)user_data;
15076 mt_undo *last_undo = (
mt_undo *)lives_list_nth_data(mt->undos, lives_list_length(mt->undos) - 1 - mt->undo_offset);
15080 LiVESList *label_list = NULL;
15081 LiVESList *vlist, *llist;
15082 LiVESList *seltracks = NULL;
15083 LiVESList *aparam_view_list;
15085 LiVESWidget *checkbutton, *eventbox, *label;
15087 unsigned char *memblock, *omemblock, *mem_end;
15089 size_t space_avail = (size_t)(
prefs->
mt_undo_buf * 1024 * 1024) - mt->undo_buffer_used;
15090 size_t space_needed;
15098 boolean block_is_selected =
FALSE;
15099 boolean avoid_fx_list =
FALSE;
15108 if (!mt->undo_mem)
return;
15110 if (mt->idlefunc > 0) {
15117 mt->was_undo_redo =
TRUE;
15118 ptr_time = mt->ptr_time;
15120 if (mt->block_selected) block_is_selected =
TRUE;
15123 if (mt->undo_offset == 0) {
15125 if ((space_needed = estimate_space(mt, last_undo->
action) +
sizeof(
mt_undo)) > space_avail) {
15135 new_redo = (
mt_undo *)(mt->undo_mem + mt->undo_buffer_used);
15138 omemblock = memblock = (
unsigned char *)new_redo +
sizeof(
mt_undo);
15140 new_redo->
data_len = memblock - omemblock;
15142 mt->undo_buffer_used += space_needed;
15143 mt->undos = lives_list_append(mt->undos, new_redo);
15147 current_track = mt->current_track;
15148 end_secs = mt->end_secs;
15149 num_tracks = mt->num_video_tracks;
15150 clip_sel = mt->clip_selected;
15152 seltracks = lives_list_copy(mt->selected_tracks);
15154 vlist = mt->video_draws;
15156 eventbox = LIVES_WIDGET(vlist->data);
15157 label = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label"));
15159 label_list = lives_list_append(label_list, txt);
15160 vlist = vlist->next;
15163 aparam_view_list = lives_list_copy(mt->opts.aparam_view_list);
15164 avol_fx = mt->avol_fx;
15167 mt->no_expose =
TRUE;
15170 last_undo = (
mt_undo *)lives_list_nth_data(mt->undos, lives_list_length(mt->undos) - 1 - mt->undo_offset);
15171 memblock = (
unsigned char *)(last_undo) +
sizeof(
mt_undo);
15173 mt->event_list = load_event_list_inner(mt, -1,
FALSE, NULL, &memblock, mem_end);
15177 mt->event_list = NULL;
15182 mt->event_list = NULL;
15185 for (i = 0; i < mt->num_video_tracks; i++) {
15188 lives_list_free(mt->video_draws);
15189 mt->video_draws = NULL;
15190 mt->num_video_tracks = 0;
15193 mt->audio_draws = NULL;
15195 mt->fm_edit_event = NULL;
15196 mt->init_event = NULL;
15197 mt->selected_init_event = NULL;
15198 mt->specific_event = NULL;
15199 mt->avol_init_event = NULL;
15203 if (mt->avol_fx == -1) mt->avol_fx = avol_fx;
15204 if (mt->avol_fx != -1) mt->opts.aparam_view_list = lives_list_copy(aparam_view_list);
15205 if (aparam_view_list) lives_list_free(aparam_view_list);
15210 for (i = mt->num_video_tracks; i < num_tracks; i++) {
15214 mt->clip_selected = clip_sel;
15217 vlist = mt->video_draws;
15218 llist = label_list;
15220 eventbox = LIVES_WIDGET(vlist->data);
15221 label = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label"));
15225 vlist = vlist->next;
15226 llist = llist->next;
15228 lives_list_free(label_list);
15232 mt->selected_tracks = lives_list_copy(seltracks);
15233 slist = mt->selected_tracks;
15235 eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, LIVES_POINTER_TO_INT(slist->data));
15236 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton");
15243 giw_led_set_mode(GIW_LED(checkbutton),
TRUE);
15246 slist = slist->next;
15248 if (seltracks) lives_list_free(seltracks);
15250 mt->current_track = current_track;
15255 mt->no_expose =
FALSE;
15259 if (mt->undo_offset == lives_list_length(mt->undos)) mt_set_undoable(mt,
MT_UNDO_NONE, NULL,
FALSE);
15261 mt_undo *undo = (
mt_undo *)(lives_list_nth_data(mt->undos, lives_list_length(mt->undos) - mt->undo_offset - 1));
15268 utxt = lives_utf8_strdown((tmp = get_undo_text(last_undo->
action, last_undo->
extra)), -1);
15274 if (last_undo->
action <= 1024 && block_is_selected) mt_selblock(LIVES_MENU_ITEM(mt->seldesel_menuitem), (livespointer)mt);
15280 avoid_fx_list =
TRUE;
15299 lives_mt *mt = (lives_mt *)user_data;
15301 mt_undo *last_redo = (
mt_undo *)lives_list_nth_data(mt->undos, lives_list_length(mt->undos) + 1 - mt->undo_offset);
15303 LiVESWidget *checkbutton, *eventbox, *label;
15306 LiVESList *label_list = NULL;
15307 LiVESList *vlist, *llist;
15308 LiVESList *seltracks = NULL;
15309 LiVESList *aparam_view_list;
15311 unsigned char *memblock, *mem_end;
15326 if (!mt->undo_mem)
return;
15328 if (mt->idlefunc > 0) {
15337 mt->was_undo_redo =
TRUE;
15338 ptr_time = mt->ptr_time;
15341 current_track = mt->current_track;
15342 end_secs = mt->end_secs;
15343 num_tracks = mt->num_video_tracks;
15344 clip_sel = mt->clip_selected;
15346 seltracks = lives_list_copy(mt->selected_tracks);
15348 vlist = mt->video_draws;
15350 eventbox = LIVES_WIDGET(vlist->data);
15351 label = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label"));
15353 label_list = lives_list_append(label_list, txt);
15354 vlist = vlist->next;
15357 aparam_view_list = lives_list_copy(mt->opts.aparam_view_list);
15358 avol_fx = mt->avol_fx;
15361 mt->no_expose =
TRUE;
15365 memblock = (
unsigned char *)(last_redo) +
sizeof(
mt_undo);
15367 mt->event_list = load_event_list_inner(mt, -1,
FALSE, NULL, &memblock, mem_end);
15370 mt->event_list = NULL;
15375 mt->event_list = NULL;
15378 for (i = 0; i < mt->num_video_tracks; i++) {
15381 lives_list_free(mt->video_draws);
15382 mt->video_draws = NULL;
15383 mt->num_video_tracks = 0;
15386 mt->audio_draws = NULL;
15388 mt->fm_edit_event = NULL;
15389 mt->init_event = NULL;
15390 mt->selected_init_event = NULL;
15391 mt->specific_event = NULL;
15392 mt->avol_init_event = NULL;
15396 if (mt->avol_fx == avol_fx) {
15397 mt->opts.aparam_view_list = lives_list_copy(aparam_view_list);
15399 if (aparam_view_list) lives_list_free(aparam_view_list);
15404 for (i = mt->num_video_tracks; i < num_tracks; i++) {
15408 mt->clip_selected = clip_sel;
15411 vlist = mt->video_draws;
15412 llist = label_list;
15414 eventbox = LIVES_WIDGET(vlist->data);
15415 label = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"label"));
15419 vlist = vlist->next;
15420 llist = llist->next;
15422 lives_list_free(label_list);
15426 mt->selected_tracks = lives_list_copy(seltracks);
15427 slist = mt->selected_tracks;
15429 eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, LIVES_POINTER_TO_INT(slist->data));
15430 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton");
15437 giw_led_set_mode(GIW_LED(checkbutton),
TRUE);
15440 slist = slist->next;
15442 if (seltracks) lives_list_free(seltracks);
15444 mt->current_track = current_track;
15449 mt->no_expose =
FALSE;
15455 mt_undo *redo = (
mt_undo *)(lives_list_nth_data(mt->undos, lives_list_length(mt->undos) - mt->undo_offset));
15458 last_redo = (
mt_undo *)lives_list_nth_data(mt->undos, lives_list_length(mt->undos) - 1 - mt->undo_offset);
15473 utxt = lives_utf8_strdown((tmp = get_undo_text(last_redo->
action, last_redo->
extra)), -1);
15492 lives_mt *mt = (lives_mt *)user_data;
15494 uint32_t bsize = 0;
15496 int num_events = 0;
15501 lives_snprintf(buff, 512,
"\n Event List");
15506 lives_snprintf(buff, 512,
"\n %.3f%s", mt->fps, rfile->
ratio_fps ?
"..." :
"");
15508 lives_snprintf(buff, 512,
"%s",
_(
"\n (variable)"));
15514 lives_snprintf(buff, 512,
"\n %dx%d", rfile->
hsize, rfile->
vsize);
15517 if (mt->event_list) {
15518 bsize = event_list_get_byte_size(mt, mt->event_list,
TRUE, &num_events);
15522 lives_snprintf(buff, 512,
"\n %d", (
frames_t)(mt->fps * time));
15525 lives_snprintf(buff, 512,
_(
"\n %.3f sec"), time);
15529 lives_snprintf(buff, 512,
_(
"\n %d bytes\n%d events"), bsize, num_events);
15544static void add_effect_inner(lives_mt * mt,
int num_in_tracks,
int *in_tracks,
int num_out_tracks,
int *out_tracks,
15545 weed_plant_t *start_event, weed_plant_t *end_event) {
15546 void **init_events;
15551 double timesecs = mt->ptr_time;
15559 boolean has_params;
15562 mt->track_index = -1;
15563 for (
int i = 0; i < num_in_tracks; i++) {
15564 if (mt->current_track == in_tracks[i]) {
15565 mt->track_index = i;
15622 if (mt->current_fx == mt->avol_fx)
return;
15624 if (mt->avol_fx != -1) {
15625 apply_avol_filter(mt);
15628 if (mt->is_atrans)
return;
15630 get_track_index(mt, tc);
15632 if (mt->track_index > -1) {
15653 weed_timecode_t tc;
15654 weed_plant_t *shortcut = NULL;
15655 weed_timecode_t tl =
q_dbl(1. / fps, fps);
15656 int blank_clip = -1;
15657 int64_t blank_frame = 0;
15662 for (; tc <= end_tc; tc =
q_gint64(tc + tl, fps)) {
15665 weed_set_double_value(event_list, WEED_LEAF_FPS, fps);
15671 lives_mt *mt = (lives_mt *)user_data;
15675 weed_plant_t *start_event;
15676 weed_plant_t *end_event;
15677 weed_plant_t *last_frame_event = NULL;
15681 weed_timecode_t last_frame_tc = 0;
15684 char *tname, *track_desc;
15686 char *tstart, *tend;
15688 boolean did_backup = mt->did_backup;
15689 boolean needs_idlefunc =
FALSE;
15691 int numtracks = lives_list_length(mt->selected_tracks);
15692 int tcount = 0, tlast = -1000000, tsmall = -1, ctrack;
15696 if (mt->idlefunc > 0) {
15697 needs_idlefunc =
TRUE;
15703 while (tcount < numtracks) {
15705 llist = mt->selected_tracks;
15707 ctrack = LIVES_POINTER_TO_INT(llist->data);
15708 if ((tsmall == -1000000 || ctrack < tsmall) && ctrack > tlast) tsmall = ctrack;
15709 llist = llist->next;
15711 tracks[tcount++] = tlast = tsmall;
15715 if (mt->event_list &&
15721 if (menuitem) mt->current_fx = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(menuitem),
"idx"));
15726 add_effect_inner(mt, numtracks, tracks, 1, &tracks[0], start_event, end_event);
15728 if (!menuitem && !mt->is_atrans) {
15730 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
15741 switch (numtracks) {
15756 track_desc = (
_(
"selected tracks"));
15764 d_print(
_(
"Added %s %s to %s from time %s to time %s\n"), tname, filter_name, track_desc, tstart, tend);
15773 mt->did_backup =
FALSE;
15774 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
15780static boolean mt_add_region_effect_idle(livespointer user_data) {
15788 lives_mt *mt = (lives_mt *)user_data;
15789 weed_plant_t *start_event = mt->block_selected->start_event;
15790 weed_plant_t *end_event = mt->block_selected->end_event;
15794 char *tstart, *tend;
15796 int selected_track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mt->block_selected->eventbox),
15798 boolean did_backup = mt->did_backup;
15799 boolean needs_idlefunc =
FALSE;
15801 if (mt->idlefunc > 0) {
15802 needs_idlefunc =
TRUE;
15807 if (menuitem) mt->current_fx
15808 = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(menuitem),
"idx"));
15811 add_effect_inner(mt, 1, &selected_track, 1, &selected_track, start_event, end_event);
15818 d_print(
_(
"Added effect %s to track %s from time %s to time %s\n"), filter_name,
15819 (tmp =
get_track_name(mt, selected_track, mt->aud_track_selected)),
15828 mt->did_backup =
FALSE;
15829 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
15835static boolean mt_add_block_effect_idle(livespointer user_data) {
15844 lives_mt *mt = (lives_mt *)user_data;
15850 lives_mt *mt = (lives_mt *)user_data;
15852 weed_timecode_t start_tc, end_tc;
15854 weed_plant_t *deinit_event, *init_event = mt->selected_init_event;
15858 char *fhash, *filter_name;
15859 char *tname, *track_desc;
15861 char *tstart, *tend;
15863 boolean did_backup = mt->did_backup;
15864 boolean needs_idlefunc =
FALSE;
15868 if (!mt->selected_init_event)
return;
15870 if (mt->is_rendering)
return;
15872 if (mt->idlefunc > 0) {
15873 needs_idlefunc =
TRUE;
15890 switch (numtracks) {
15905 track_desc = (
_(
"selected tracks"));
15919 d_print(
_(
"Deleted %s %s from %s from time %s to time %s\n"), tname, filter_name, track_desc, tstart, tend);
15926 mt->selected_init_event = NULL;
15927 mt->current_fx = -1;
15933 mt->did_backup =
FALSE;
15934 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
15944 weed_timecode_t start_tc, end_tc;
15946 LiVESWidget *eventbox;
15951 if (mt->current_track > -1 &&
15952 !mt->aud_track_selected) eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
15954 eventbox = (LiVESWidget *)lives_list_nth_data(mt->audio_draws, mt->current_track + mt->opts.back_audio_tracks);
15957 block = get_block_from_time(eventbox, secs, mt);
15962 secs -= 1. / mt->fps;
15967 secs += 1. / mt->fps;
15974 block = get_block_before(eventbox, secs,
TRUE);
15975 if (!block) secs = 0.;
15982 block = get_block_after(eventbox, secs,
FALSE);
15983 if (!block)
return;
15988 if (secs < 0.) secs = 0.;
15990 mt->fm_edit_event = NULL;
15996 lives_mt *mt = (lives_mt *)user_data;
16002 lives_mt *mt = (lives_mt *)user_data;
16008 LiVESList *tl_marks = mt->tl_marks;
16009 double time = -1., marktime = -1.;
16014 if (time > ptr_time)
break;
16015 if (marktime == time)
continue;
16017 tl_marks = tl_marks->next;
16026 lives_mt *mt = (lives_mt *)user_data;
16032 lives_mt *mt = (lives_mt *)user_data;
16038 lives_mt *mt = (lives_mt *)user_data;
16040 LiVESWidget *xeventbox;
16046 if (mt->current_track < 0)
return;
16048 xeventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
16050 cname = (
char *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(xeventbox),
"track_name");
16056 if (response == LIVES_RESPONSE_CANCEL)
return;
16067 set_track_label(LIVES_EVENT_BOX(xeventbox), mt->current_track);
16072 lives_mt *mt = (lives_mt *)user_data;
16073 mt->current_track = -1;
16079 lives_mt *mt = (lives_mt *)user_data;
16083 boolean had_audio =
FALSE;
16084 boolean post_reset_ba =
FALSE;
16085 boolean post_reset_ca =
FALSE;
16086 boolean retval =
FALSE;
16098 if (mt->idlefunc > 0) {
16105 mt->pr_audio =
TRUE;
16106 had_audio = mt->has_audio_file;
16117 mt->has_audio_file =
TRUE;
16119 mt->pr_audio =
FALSE;
16128 mt->is_rendering =
TRUE;
16137 if (mt->opts.normalise_audp) {
16144 boolean has_backing_audio =
FALSE;
16145 boolean has_channel_audio =
FALSE;
16148 list = mt->audio_draws;
16149 if (mt->opts.back_audio_tracks >= 1) {
16151 for (i = 0; i < mt->opts.back_audio_tracks; list = list->next, i++) {
16154 has_backing_audio =
TRUE;
16159 list = mt->audio_draws;
16160 for (i = mt->opts.back_audio_tracks + 1; --i > 0; list = list->next);
16161 for (; list; list = list->next, i++) {
16165 has_channel_audio =
TRUE;
16172 if (has_backing_audio && !has_channel_audio) {
16177 list = mt->audio_draws;
16178 for (i = 0; i < mt->opts.back_audio_tracks; i++, list = list->next) {
16181 has_backing_audio =
FALSE;
16187 if (has_backing_audio) {
16188 post_reset_ba =
TRUE;
16189 list = mt->audio_draws;
16190 for (i = 0; i < mt->opts.back_audio_tracks; i++, list = list->next) {
16197 if (!has_backing_audio && has_channel_audio) {
16202 list = mt->audio_draws;
16203 for (i = mt->opts.back_audio_tracks + 1; --i > 0; list = list->next);
16207 has_channel_audio =
FALSE;
16212 if (has_channel_audio) {
16213 post_reset_ca =
TRUE;
16214 list = mt->audio_draws;
16215 for (i = 0; i < mt->opts.back_audio_tracks; i++, list = list->next);
16217 for (; list; list = list->next) {
16229 if (mt->pr_audio) {
16230 mt->pr_audio =
FALSE;
16250 mt->is_rendering =
FALSE;
16257 if (post_reset_ba) {
16259 for (i = 0; i < mt->opts.back_audio_tracks; i++) {
16260 if (!
is_empty_track(LIVES_WIDGET_OBJECT(lives_list_nth_data(mt->audio_draws, i)))) {
16267 if (post_reset_ca) {
16269 list = mt->audio_draws;
16270 for (i = 0; i < mt->opts.back_audio_tracks; i++, list = list->next);
16272 for (; list; list = list->next) {
16297 cfile->arate = arate;
16298 cfile->arps = arps;
16299 cfile->asampsize = asampsize;
16301 cfile->achans = achans;
16302 cfile->signed_endian = signed_endian;
16313 if (multitrack_end(menuitem, user_data))
return TRUE;
16328 mt->is_rendering =
FALSE;
16331 if (mt->pr_audio) {
16335 mt->has_audio_file = had_audio;
16359 lives_mt *mt = (lives_mt *)user_data;
16368 int track, weed_timecode_t new_start_tc,
int new_track) {
16392 LiVESList *moved_events = NULL;
16394 weed_plant_t *event, *event_next;
16395 weed_plant_t *init_event, *deinit_event;
16397 weed_timecode_t last_frame_tc = 0, event_tc;
16400 boolean leave_event;
16421 if (event == mt->avol_init_event) {
16422 event = event_next;
16425 if (mt->opts.move_effects && mt->moving_block) {
16436 if (lives_list_index(moved_events, event) == -1) {
16443 for (i = 0; i < num_tracks; i++) {
16445 if (out_tracks[i] == track) out_tracks[i] = new_track;
16452 if (new_start_tc < start_tc) {
16457 deinit_event, mt->fps,
TRUE);
16458 if (event == first_event) first_event = NULL;
16460 }
else if (new_start_tc > start_tc) {
16464 deinit_event, mt->fps,
TRUE);
16466 if (event == first_event) first_event = NULL;
16470 moved_events = lives_list_prepend(moved_events, event);
16475 if (lives_list_index(moved_events, event) == -1 && event != mt->avol_init_event) {
16479 if (in_tracks[0] == track || (nins == 2 && in_tracks[1] == track)) {
16490 if (event == first_event) first_event = NULL;
16496 if (event == first_event) first_event = NULL;
16504 leave_event =
TRUE;
16507 if (mt->opts.move_effects && mt->moving_block) {
16511 if (init_event != mt->avol_init_event &&
16512 (event_tc > last_frame_tc ||
16513 (lives_list_index(moved_events, init_event) == -1 &&
16518 if (event_tc <= last_frame_tc) {
16520 if (in_tracks[0] == track || (nins == 2 && in_tracks[1] == track)) {
16521 leave_event =
FALSE;
16524 }
else leave_event =
FALSE;
16544 event = event_next;
16548 if (moved_events) lives_list_free(moved_events);
16554 lives_mt *mt = (lives_mt *)user_data;
16556 weed_timecode_t tc;
16558 double timesecs = mt->ptr_time;
16560 boolean did_backup = mt->did_backup;
16561 boolean needs_idlefunc =
FALSE;
16563 if (!mt->putative_block)
return;
16565 if (mt->idlefunc > 0) {
16566 needs_idlefunc =
TRUE;
16571 if (mt->context_time != -1. && mt->use_context) {
16572 timesecs = mt->context_time;
16573 mt->context_time = -1.;
16574 mt->use_context =
FALSE;
16581 split_block(mt, mt->putative_block, tc, mt->current_track,
FALSE);
16584 mt->did_backup =
FALSE;
16585 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
16593 lives_mt *mt = (lives_mt *)user_data;
16594 double timesecs = mt->ptr_time;
16595 boolean did_backup = mt->did_backup;
16596 boolean needs_idlefunc =
FALSE;
16597 weed_timecode_t tc;
16598 LiVESWidget *eventbox;
16601 if (mt->idlefunc > 0) {
16602 needs_idlefunc =
TRUE;
16609 if (mt->current_track == -1) eventbox = (LiVESWidget *)mt->audio_draws->data;
16610 else eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
16612 block = get_block_from_time(eventbox, timesecs, mt);
16616 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
16622 split_block(mt, block, tc, mt->current_track,
FALSE);
16625 mt->did_backup =
FALSE;
16626 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
16634 lives_mt *mt = (lives_mt *)user_data;
16635 LiVESList *selt = mt->selected_tracks;
16636 LiVESWidget *eventbox;
16639 double timesecs = mt->ptr_time;
16640 boolean did_backup = mt->did_backup;
16641 boolean needs_idlefunc =
FALSE;
16643 if (!mt->selected_tracks)
return;
16645 if (mt->idlefunc > 0) {
16646 needs_idlefunc =
TRUE;
16654 track = LIVES_POINTER_TO_INT(selt->data);
16655 eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, track);
16656 block = get_block_from_time(eventbox, timesecs, mt);
16662 mt->did_backup =
FALSE;
16663 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
16669static void on_delblock_activate(LiVESMenuItem * menuitem, livespointer user_data) {
16670 lives_mt *mt = (lives_mt *)user_data;
16671 weed_timecode_t start_tc, end_tc;
16672 weed_plant_t *first_event;
16673 weed_plant_t *event, *prevevent;
16675 track_rect *block, *blockprev, *blocknext;
16677 LiVESWidget *eventbox, *aeventbox;
16680 char *tstart, *tend;
16682 boolean done =
FALSE;
16683 boolean did_backup = mt->did_backup;
16684 boolean needs_idlefunc =
FALSE;
16688 if (mt->is_rendering)
return;
16690 if (mt->idlefunc > 0) {
16691 needs_idlefunc =
TRUE;
16696 mt->context_time = -1.;
16701 if (!mt->block_selected) mt->block_selected = mt->putative_block;
16702 block = mt->block_selected;
16703 eventbox = block->eventbox;
16705 if (mt->current_track != -1) track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
16709 if ((aeventbox = LIVES_WIDGET(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack"))) != NULL) {
16710 int current_track = mt->current_track;
16711 mt->current_track = track;
16713 if (mt->block_selected) on_delblock_activate(NULL, user_data);
16714 mt->block_selected = block;
16715 mt->current_track = current_track;
16728 event = block->end_event;
16730 if (mt->current_track != -1 && !is_audio_eventbox(eventbox)) {
16732 while (event && !done) {
16734 if (event == block->start_event) done =
TRUE;
16736 if (!done)
event = prevevent;
16746 if (block->prev && block->start_event == block->prev->end_event) {
16755 if ((blockprev = block->prev) != NULL) blockprev->next = block->next;
16756 else lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks", (livespointer)block->next);
16757 if ((blocknext = block->next) != NULL) blocknext->prev = blockprev;
16759 if (block == mt->block_selected) mt->block_selected = NULL;
16763 if (
cfile->achans > 0 && mt->audio_draws && mt->opts.back_audio_tracks > 0 && eventbox == mt->audio_draws->data &&
16764 LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"))) {
16765 LiVESWidget *xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan0");
16767 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan1");
16776 if (mt->current_track != -1 && !is_audio_eventbox(eventbox)) {
16777 d_print(
_(
"Deleted frames from time %s to time %s on track %s\n"), tstart, tend, tmp);
16779 d_print(
_(
"Deleted audio from time %s to time %s on track %s\n"), tstart, tend, tmp);
16789 double oldr_start = mt->region_start;
16790 double oldr_end = mt->region_end;
16791 LiVESList *tracks_sel = NULL;
16792 if (mt->current_track != -1) {
16793 tracks_sel = lives_list_copy(mt->selected_tracks);
16794 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
16795 mt->selected_tracks = NULL;
16796 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(mt->current_track));
16801 mt->region_end = mt->end_secs;
16803 mt->region_start = 0.;
16808 if (mt->current_track > -1) {
16809 lives_list_free(mt->selected_tracks);
16810 mt->selected_tracks = lives_list_copy(tracks_sel);
16811 if (tracks_sel) lives_list_free(tracks_sel);
16813 mt->region_start = oldr_start;
16814 mt->region_end = oldr_end;
16820 if (!mt->opts.move_effects || !mt->moving_block) {
16822 if (mt->block_selected == block) {
16823 mt->block_selected = NULL;
16831 if ((!mt->moving_block || !
get_first_frame_event(mt->event_list)) && mt->avol_fx != -1 && !blocknext &&
16833 apply_avol_filter(mt);
16836 if (!did_backup && mt->framedraw && mt->current_rfx && mt->init_event &&
16840 get_track_index(mt, tc);
16843 if (!mt->moving_block) {
16844 redraw_eventbox(mt, eventbox);
16845 paint_lines(mt, mt->ptr_time,
TRUE, NULL);
16850 mt->did_backup =
FALSE;
16851 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
16855 if (!mt->moving_block) {
16864 lives_mt *mt = (lives_mt *)user_data;
16872 lives_mt *mt = (lives_mt *)user_data;
16873 LiVESWidget *eventbox;
16874 LiVESWidget *checkbutton;
16880 if (mt->current_track == -1)
return;
16882 eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
16883 checkbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"checkbutton");
16889 if (lives_list_index(mt->selected_tracks, LIVES_INT_TO_POINTER(mt->current_track)) == -1)
16890 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(mt->current_track));
16893 if (lives_list_index(mt->selected_tracks, LIVES_INT_TO_POINTER(mt->current_track)) != -1)
16894 mt->selected_tracks = lives_list_remove(mt->selected_tracks, LIVES_INT_TO_POINTER(mt->current_track));
16907 if (giw_led_get_mode(GIW_LED(checkbutton)) != mi_state) {
16909 giw_led_set_mode(GIW_LED(checkbutton), mi_state);
16922 if (mt->selected_tracks) {
16927 if (mt->region_start != mt->region_end) {
16934 switch (lives_list_length(mt->selected_tracks)) {
16944 if (!mt->opts.pertrack_audio)
16963 int track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(checkbutton),
"layer_number"));
16964 lives_mt *mt = (lives_mt *)user_data;
16968 mt->current_track = track;
16970 if (track > -1) mt->aud_track_selected =
FALSE;
16971 else mt->aud_track_selected =
TRUE;
17021#ifdef ENABLE_DVD_GRAB
17041 if (mt->block_selected) {
17053 LiVESWidget *eventbox = NULL;
17055 if (mt->in_sensitise)
return;
17056 mt->in_sensitise =
TRUE;
17067 if (mt->avol_init_event && mt->opts.pertrack_audio &&
mainw->
files[mt->render_file]->
achans > 0)
17091#ifdef ENABLE_DVD_GRAB
17109 if (mt->selected_init_event) {
17114 if (mt->checkbutton_avel_reverse) {
17117 if (mt->block_selected && (!mt->block_selected->start_anchored ||
17119 (LIVES_TOGGLE_BUTTON(mt->checkbutton_avel_reverse))) {
17127 if (mt->file_selected > -1) {
17136 if (mt->video_draws &&
17137 mt->current_track > -1) eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
17138 else if (mt->audio_draws) eventbox = (LiVESWidget *)mt->audio_draws->data;
17145 if (mt->tl_marks) {
17152 if (mt->block_selected) {
17154 if (mt->poly_state ==
POLY_IN_OUT && mt->block_selected->ordered) {
17155 weed_timecode_t offset_end = mt->block_selected->offset_start + (weed_timecode_t)(
TICKS_PER_SECOND_DBL / mt->fps) +
17158 set_in_out_spin_ranges(mt, mt->block_selected->offset_start, offset_end);
17171 if (mt->region_end > mt->region_start && mt->event_list &&
get_first_event(mt->event_list)) {
17172 if (mt->selected_tracks) {
17178 if (mt->selected_tracks && mt->region_end != mt->region_start) {
17179 switch (lives_list_length(mt->selected_tracks)) {
17187 if (!mt->opts.pertrack_audio)
17202 mt->in_sensitise =
FALSE;
17207 LiVESWidget *tmp_img = NULL;
17208 static LiVESWidgetClosure *freeze_closure = NULL;
17210 if (!freeze_closure) freeze_closure = lives_cclosure_new(LIVES_GUI_CALLBACK(
freeze_callback), NULL, NULL);
17213#if GTK_CHECK_VERSION(2, 6, 0)
17223 lives_signal_sync_connect(LIVES_GUI_OBJECT(mt->playall), LIVES_WIDGET_ACTIVATE_SIGNAL,
17226 lives_signal_sync_connect(LIVES_GUI_OBJECT(
mainw->
m_playbutton), LIVES_WIDGET_CLICKED_SIGNAL,
17229 (LiVESXModifierType)LIVES_CONTROL_MASK,
17230 (LiVESAccelFlags)0, freeze_closure);
17242 freeze_closure = NULL;
17252 lives_mt *mt = (lives_mt *)user_data;
17262 pb_loop_event = mt->pb_loop_event;
17269 if (mt->mt_frame_preview) {
17293 mt->no_frame_update =
FALSE;
17297 if (mt->opts.follow_playback) {
17298 double currtime = mt->ptr_time;
17299 if (currtime > mt->tl_max || currtime < mt->tl_min) {
17305 mt->is_paused =
TRUE;
17306 if ((curtime = mt->ptr_time) > 0.) {
17310 paint_lines(mt, curtime,
TRUE, NULL);
17311 mt->no_frame_update =
FALSE;
17317 if (!mt->is_rendering) {
17319 if (mt->init_event) {
17331 if (mt->ptr_time > 0.) {
17339 if (mt->is_paused) mt->pb_loop_event = pb_loop_event;
17341 paint_lines(mt, mt->ptr_time,
FALSE, NULL);
17346 LiVESWidget *old_context_scroll = mt->context_scroll;
17347 boolean needs_idlefunc =
FALSE;
17350 mt->no_expose_frame =
TRUE;
17351 mt->no_frame_update =
TRUE;
17353 if (mt->idlefunc > 0) {
17356 needs_idlefunc =
TRUE;
17362 if (mt->context_scroll) {
17365 mt->context_scroll = NULL;
17378 if (mt->opts.follow_playback) {
17379 double currtime = mt->ptr_time;
17380 if (currtime > mt->tl_max || currtime < mt->tl_min) {
17381 double page = mt->tl_max - mt->tl_min;
17382 mt->tl_min = currtime - page * .25;
17383 mt->tl_max = currtime + page * .75;
17390 needs_clear =
FALSE;
17393 if (mt->is_rendering) {
17395 boolean had_audio = mt->has_audio_file;
17396 mt->pb_start_event = NULL;
17397 mt->has_audio_file =
TRUE;
17400 mt->has_audio_file = had_audio;
17402 if (mt->event_list) {
17404 set_play_position(mt);
17408 if (mt->playing_sel)
17411 else if (mt->is_paused) mt->pb_loop_event = pb_loop_event;
17422 if (mt->context_scroll)
17425 mt->context_scroll = old_context_scroll;
17426 if (mt->context_scroll)
17434 if (mt->context_scroll)
17440 if (!mt->is_rendering) {
17442 if (needs_idlefunc) mt->idlefunc =
mt_idle_add(mt);
17445 mt->no_expose_frame =
FALSE;
17452 lives_mt *mt = (lives_mt *)user_data;
17454 ptr_time = mt->ptr_time;
17456 if (ptr_time < mt->region_start || ptr_time >= mt->region_end) {
17462 mt->playing_sel =
TRUE;
17467 if (!mt->is_paused) {
17468 mt->playing_sel =
FALSE;
17474 lives_mt *mt = (lives_mt *)user_data;
17481 lives_mt *mt = (lives_mt *)user_data;
17484 double secs = mt->ptr_time;
17486 LiVESWidget *eventbox;
17491 boolean did_backup = mt->did_backup;
17492 boolean needs_idlefunc =
FALSE;
17500 if (mt->idlefunc > 0) {
17501 needs_idlefunc =
TRUE;
17506 if (mt->context_time != -1. && mt->use_context) {
17507 secs = mt->context_time;
17508 mt->context_time = -1.;
17509 mt->use_context =
FALSE;
17512 eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, mt->current_track);
17514 if (mt->opts.ign_ins_sel) {
17520 if (mt->insert_start != -1) {
17522 ins_start = mt->insert_start;
17523 ins_end = mt->insert_end;
17528 weed_plant_t *
event = NULL;
17529 weed_timecode_t tc = 0, tcnow;
17530 weed_timecode_t tclen = ins_end - ins_start;
17532 while (tc <= tclen) {
17540 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
17551 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
17553 if (block && (mt->opts.grav_mode ==
GRAV_MODE_LEFT || (block->next
17555 !(did_backup || mt->moving_block)) {
17556 double oldr_start = mt->region_start;
17557 double oldr_end = mt->region_end;
17558 LiVESList *tracks_sel;
17559 track_rect *selblock = NULL;
17560 if (mt->block_selected != block) selblock = mt->block_selected;
17561 tracks_sel = lives_list_copy(mt->selected_tracks);
17562 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
17563 mt->selected_tracks = NULL;
17564 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(mt->current_track));
17568 else mt->region_start = 0.;
17576 lives_list_free(mt->selected_tracks);
17577 mt->selected_tracks = lives_list_copy(tracks_sel);
17578 if (tracks_sel) lives_list_free(tracks_sel);
17579 mt->region_start = oldr_start;
17580 mt->region_end = oldr_end;
17582 if (selblock) mt->block_selected = selblock;
17586 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
17589 if (mt->avol_fx != -1 && block && !block->next &&
get_first_event(mt->event_list)) {
17590 apply_avol_filter(mt);
17596 mt->did_backup = did_backup;
17598 mt->did_backup =
TRUE;
17602 lives_painter_surface_t *bgimage = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
17610 if (!did_backup && mt->framedraw && mt->current_rfx && mt->init_event &&
17615 get_track_index(mt, tc);
17624 mt->did_backup =
FALSE;
17625 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
17633 lives_mt *mt = (lives_mt *)user_data;
17636 double secs = mt->ptr_time;
17637 double tstart, tend;
17639 LiVESWidget *eventbox = (LiVESWidget *)mt->audio_draws->data;
17644 boolean did_backup = mt->did_backup;
17645 boolean needs_idlefunc =
FALSE;
17650 char *istart, *iend;
17654 if (mt->current_track != -1 || sfile->
achans == 0)
return FALSE;
17656 if (mt->idlefunc > 0) {
17657 needs_idlefunc =
TRUE;
17662 if (mt->context_time != -1. && mt->use_context) {
17663 secs = mt->context_time;
17664 mt->context_time = -1.;
17665 mt->use_context =
FALSE;
17668 if (sfile->
frames == 0 || mt->opts.ign_ins_sel) {
17675 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
17684 if (mt->insert_start != -1) {
17685 ins_start = mt->insert_start;
17686 ins_end = mt->insert_end;
17694 weed_plant_t *
event = NULL;
17695 weed_timecode_t tc = 0, tcnow;
17696 weed_timecode_t tclen = ins_end - ins_start;
17700 while (tc <= tclen) {
17709 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
17720 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
17724 && !(did_backup || mt->moving_block)) {
17725 double oldr_start = mt->region_start;
17726 double oldr_end = mt->region_end;
17727 LiVESList *tracks_sel;
17728 track_rect *selblock = NULL;
17729 if (mt->block_selected != block) selblock = mt->block_selected;
17730 tracks_sel = lives_list_copy(mt->selected_tracks);
17731 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
17732 mt->selected_tracks = NULL;
17733 mt->current_track = -1;
17737 else mt->region_start = 0.;
17745 lives_list_free(mt->selected_tracks);
17746 mt->selected_tracks = lives_list_copy(tracks_sel);
17747 if (tracks_sel) lives_list_free(tracks_sel);
17748 mt->region_start = oldr_start;
17749 mt->region_end = oldr_end;
17750 if (selblock) mt->block_selected = selblock;
17753 mt->did_backup = did_backup;
17760 d_print(
_(
"Inserted audio %.4f to %.4f from clip %s into backing audio from time %s to time %s\n"),
17768 lives_painter_surface_t *bgimage = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
17775 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"expanded"))) {
17776 LiVESWidget *xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan0");
17778 xeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"achan1");
17784 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
17787 if (mt->avol_fx != -1 && block && !block->next &&
get_first_event(mt->event_list)) {
17788 apply_avol_filter(mt);
17794 if (!did_backup && mt->framedraw && mt->current_rfx && mt->init_event &&
17798 get_track_index(mt, tc);
17802 mt->did_backup =
FALSE;
17803 if (needs_idlefunc || (!did_backup && mt->auto_changed)) mt->idlefunc =
mt_idle_add(mt);
17810void insert_frames(
int filenum, weed_timecode_t offset_start, weed_timecode_t offset_end, weed_timecode_t tc,
17811 lives_direction_t direction, LiVESWidget * eventbox, lives_mt * mt, track_rect * in_block) {
17831 weed_timecode_t last_tc = 0, offset_start_tc, start_tc, last_offset;
17832 weed_timecode_t orig_st = offset_start, orig_end = offset_end;
17834 int *clips = NULL, *rep_clips;
17835 int64_t *frames = NULL, *rep_frames;
17836 weed_plant_t *last_frame_event = NULL;
17837 weed_plant_t *event, *shortcut1 = NULL, *shortcut2 = NULL;
17838 track_rect *new_block = NULL;
17840 LiVESWidget *aeventbox = NULL;
17845 boolean isfirst =
TRUE;
17848 int track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
17857 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last", (livespointer)NULL);
17858 if ((aeventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"atrack")) != NULL)
17859 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(aeventbox),
"block_last", (livespointer)NULL);
17861 last_offset = offset_start_tc =
q_gint64(offset_start, mt->fps);
17862 offset_end =
q_gint64(offset_end, mt->fps);
17871 q_gint64(start_tc - 1. / mt->fps, mt->fps), mt->fps);
17876 if (
cfile->fps != mt->fps && !
cfile->event_list) {
17878 cfile->undo1_dbl = mt->fps;
17885 (offset_start =
q_gint64(last_tc - start_tc + offset_start_tc, mt->fps)) < offset_end)
17887 (offset_start =
q_gint64(last_tc + offset_start_tc - start_tc, mt->fps)) >= offset_end)) {
17889 clips = rep_clips = NULL;
17890 frames = rep_frames = NULL;
17894 clips = weed_get_int_array_counted(event,
WEED_LEAF_CLIPS, &numframes);
17901 if (numframes <= track) {
17906 for (i = 0; i < track; i++) {
17907 if (i < numframes) {
17908 rep_clips[i] = clips[i];
17909 rep_frames[i] = frames[i];
17915 numframes = track + 1;
17918 if (!in_block && new_block) {
17928 rep_frames = frames;
17933 if (rep_clips != clips && rep_clips)
lives_free(rep_clips);
17934 if (rep_frames != frames && rep_frames)
lives_free(rep_frames);
17939 last_offset = offset_start;
17946 rep_clips[track] = filenum;
17947 rep_frames[track] = frame;
17950 if (!mt->event_list) {
17954 mt->event_list =
insert_frame_event_at(mt->event_list, last_tc, numframes, rep_clips, rep_frames, &shortcut1);
17956 if (rep_clips != clips && rep_clips)
lives_free(rep_clips);
17957 if (rep_frames != frames && rep_frames)
lives_free(rep_frames);
17962 new_block = add_block_start_point(eventbox, last_tc, filenum, offset_start, shortcut1,
TRUE);
17964 if (
cfile->achans > 0 && sfile->
achans > 0 && mt->opts.insert_audio) {
17967 aseek = ((double)frame - 1.) / sfile->
fps;
17970 add_block_start_point(aeventbox, last_tc, filenum, offset_start, shortcut1,
TRUE);
17972 weed_plant_t *nframe;
17976 nframe = shortcut1;
17990 last_tc =
q_gint64(last_tc, mt->fps);
17992 if (last_tc < TICKS_PER_SECOND_DBL / mt->fps) {
17996 last_tc =
q_gint64(last_tc, mt->fps);
18006 if (in_block) lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last", (livespointer)in_block);
18007 add_block_end_point(eventbox, shortcut1);
18009 if (
cfile->achans > 0 && sfile->
achans > 0 && mt->opts.insert_audio && mt->opts.pertrack_audio) {
18013 }
else shortcut1 = shortcut2;
18015 add_block_end_point(aeventbox, shortcut1);
18017 }
else if (in_block) {
18018 in_block->offset_start = last_offset;
18019 in_block->start_event = shortcut1;
18020 if (
cfile->achans > 0 && sfile->
achans > 0 && mt->opts.insert_audio && mt->opts.pertrack_audio) {
18024 }
else shortcut1 = shortcut2;
18029 mt->last_direction = direction;
18031 if (mt->event_list) {
18032 weed_set_double_value(mt->event_list, WEED_LEAF_FPS,
mainw->
files[render_file]->
fps);
18036 char *tmp, *tmp1, *istart, *iend;
18038 istart = time_to_string(
QUANT_TICKS((orig_st + start_tc)));
18039 iend = time_to_string(
QUANT_TICKS((orig_end + start_tc)));
18041 d_print(
_(
"Inserted frames %d to %d from clip %s into track %s from time %s to time %s\n"),
18051 if (end_secs > mt->end_secs) {
18059void insert_audio(
int filenum, weed_timecode_t offset_start, weed_timecode_t offset_end, weed_timecode_t tc,
18061 lives_mt * mt, track_rect * in_block) {
18064 weed_timecode_t start_tc =
q_gint64(tc, mt->fps);
18065 weed_timecode_t end_tc =
q_gint64(start_tc + offset_end - offset_start, mt->fps);
18066 weed_plant_t *last_frame_event;
18068 weed_plant_t *shortcut = NULL;
18069 weed_plant_t *frame_event;
18073 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last", (livespointer)NULL);
18076 weed_timecode_t tmp_tc = offset_end;
18077 offset_end = offset_start;
18078 offset_start = tmp_tc;
18082 if ((block = get_block_from_time((LiVESWidget *)mt->audio_draws->data, start_tc /
TICKS_PER_SECOND_DBL, mt)) != NULL &&
18090 if (block) shortcut = block->end_event;
18101 offset_start = offset_start - offset_end + offset_end * mt->insert_avel;
18104 add_block_start_point((LiVESWidget *)mt->audio_draws->data, start_tc, filenum, offset_start, frame_event,
TRUE);
18110 add_block_end_point((LiVESWidget *)mt->audio_draws->data, frame_event);
18111 }
else add_block_end_point((LiVESWidget *)mt->audio_draws->data, block->start_event);
18114 if (end_secs > mt->end_secs) {
18123 lives_mt *mt = (lives_mt *)user_data;
18124 LiVESWidget *elist_dialog;
18138 lives_mt *mt = (lives_mt *)user_data;
18139 LiVESWidget *elist_dialog;
18160 lives_painter_t *cr;
18167 if (mt->region_start == mt->region_end) {
18183 if (mt->region_start < mt->region_end) {
18184 start = mt->region_start;
18185 end = mt->region_end;
18187 start = mt->region_end;
18188 end = mt->region_start;
18191 if (mt->region_start == mt->region_end) {
18223static EXPOSE_FN_DECL(expose_timeline_reg_event, timeline, user_data) {
18224 lives_mt *mt = (lives_mt *)user_data;
18225 LiVESList *tl_marks = mt->tl_marks;
18232 if (mt->no_expose)
return TRUE;
18233 if (event && event->count > 0)
return FALSE;
18242 time = strtod((
char *)tl_marks->data, NULL);
18244 offset = (time - mt->tl_min) / (mt->tl_max - mt->tl_min) * (double)ebwidth;
18250 tl_marks = tl_marks->next;
18255 paint_lines(mt, mt->ptr_time,
FALSE, NULL);
18262static void draw_soundwave(LiVESWidget * ebox, lives_painter_surface_t *surf,
int chnum, lives_mt * mt) {
18263 weed_plant_t *event;
18264 weed_timecode_t tc;
18268 LiVESWidget *eventbox = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
"owner");
18270 track_rect *block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
18274 double offset_startd, offset_endd;
18275 double tl_span = mt->tl_max - mt->tl_min;
18280 int offset_start, offset_end;
18283 int track = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"layer_number"));
18291 event = block->start_event;
18295 if (offset_startd > mt->tl_max) {
18300 offset_start = (int)((offset_startd - mt->tl_min) / tl_span * width + .5);
18301 if (offset_start < 0) offset_start = 0;
18304 if (offset_endd < mt->tl_min) {
18305 block = block->next;
18308 if (offset_endd > mt->tl_max) offset_endd = mt->tl_max;
18309 offset_end = (offset_endd - mt->tl_min) / tl_span * width;
18328 if (fnum != aofile) {
18330 if (afd != -1) close(afd);
18337 for (
int i = offset_start; i <= offset_end; i++) {
18338 secs = (double)i / (
double)width * tl_span + mt->tl_min;
18339 secs -= offset_startd;
18340 secs = secs * vel + seek;
18354 block = block->next;
18369static EXPOSE_FN_DECL(mt_expose_audtrack_event, ebox, user_data) {
18370 lives_mt *mt = (lives_mt *)user_data;
18372 lives_painter_surface_t *bgimage;
18374 int startx, starty, width, height;
18378 if (mt->no_expose)
return TRUE;
18381 if (event->count > 0) {
18384 startx =
event->area.x;
18385 starty =
event->area.y;
18386 width =
event->area.width;
18387 height =
event->area.height;
18389 startx = starty = 0;
18394 if (width == 0)
return FALSE;
18396 hidden = (int)LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
HIDDEN_KEY));
18403#if !GTK_CHECK_VERSION(3, 22, 0)
18407 bgimage = (lives_painter_surface_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
"bgimg");
18409 if (LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
"drawn"))) {
18438 channum = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(ebox),
"channel"));
18441 draw_soundwave(ebox, bgimage, channum, mt);
18442 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(ebox),
"drawn", LIVES_INT_TO_POINTER(
TRUE));
18444 }
else if (bgimage) {
18449 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(ebox),
"bgimg", bgimage);
18461 lives_mt *mt = (lives_mt *)user_data;
18471 if (!mt->region_updating) {
18472 if (mt->tl_mouse) {
18473 mt->fm_edit_event = NULL;
18479 if (!mt->sel_locked) {
18480 if (pos > mt->region_init) {
18481 mt->region_start = mt->region_init;
18482 mt->region_end = pos;
18484 mt->region_start = pos;
18485 mt->region_end = mt->region_init;
18492 if (mt->opts.mouse_mode ==
MOUSE_MODE_SELECT && mt->tl_selecting && event) mouse_select_move(widget, event, mt);
18501 int numclips, layer;
18504 if (!event || !sel)
return FALSE;
18506 clips = weed_get_int_array_counted(event,
WEED_LEAF_CLIPS, &numclips);
18508 if (!numclips)
return FALSE;
18513 layer = LIVES_POINTER_TO_INT(sel->data);
18514 if (layer >= numclips || clips[layer] < 1 || frames[layer] < 1) {
18529 weed_plant_t *event;
18530 weed_timecode_t tc;
18532 if (!mt->selected_tracks || !mt->event_list) {
18533 mt->region_start = mt->region_end = 0.;
18540 while (
all_present(event, mt->selected_tracks)) {
18550 while (event && !
all_present(event, mt->selected_tracks)) {
18554 if (!event) mt->region_start = 0.;
18560 while (
all_present(event, mt->selected_tracks)) {
18570 while (event && !
all_present(event, mt->selected_tracks)) {
18574 if (!event) mt->region_end = 0.;
18585 if (mt->region_start == mt->region_end || mt->did_backup)
return;
18587 msg =
lives_strdup_printf(
_(
"Time region %.3f to %.3f\nselected.\n"), mt->region_start, mt->region_end);
18590 if (!mt->selected_tracks) {
18591 msg =
lives_strdup_printf(
_(
"select one or more tracks\nto create a region.\n"), lives_list_length(mt->selected_tracks));
18593 int llen = lives_list_length(mt->selected_tracks);
18608 add_context_label(mt, (
_(
"\n\nEffects are applied in order from top to bottom.\n")));
18617 add_context_label(mt, (
_(
"You can select an effect,\nthen use the INSERT BEFORE")));
18624 lives_mt *mt = (lives_mt *)user_data;
18626 double pos = mt->region_end;
18634 mt->tl_mouse =
FALSE;
18636 if (eventbox != mt->timeline_reg || mt->sel_locked) {
18640 if (event) mt->region_updating =
FALSE;
18642 if (mt->region_start == mt->region_end && eventbox == mt->timeline_reg) {
18643 mt->region_start = mt->region_end = 0;
18655 no_time_selected(mt);
18658 if ((mt->region_end != mt->region_start) && eventbox == mt->timeline_reg) {
18660 if (mt->region_end < mt->region_start) {
18661 mt->region_start -= mt->region_end;
18662 mt->region_end += mt->region_start;
18663 mt->region_start = mt->region_end - mt->region_start;
18665 if (mt->region_end > mt->region_start && mt->event_list &&
get_first_event(mt->event_list)) {
18666 if (mt->selected_tracks) {
18687 if (eventbox != mt->timeline_reg)
mt_tl_move(mt, pos);
18694 if (mt->init_event && mt->poly_state ==
POLY_PARAMS)
18702 pos = mt->ptr_time;
18708 if (mt->opts.mouse_mode ==
MOUSE_MODE_SELECT && event) mouse_select_end(eventbox, event, mt);
18710 if (mt->selected_tracks && mt->region_end != mt->region_start) {
18712 switch (lives_list_length(mt->selected_tracks)) {
18718 if (!mt->opts.pertrack_audio)
18740 lives_mt *mt = (lives_mt *)user_data;
18742 LiVESXModifierType modmask;
18743 LiVESXDevice *device;
18756 if (widget == mt->timeline_reg && !mt->sel_locked) {
18757 mt->region_start = mt->region_end = mt->region_init = pos;
18759 mt->region_updating =
TRUE;
18765 if (event->button == 1) {
18766 if (widget == mt->timeline_eb) {
18767 mt->fm_edit_event = NULL;
18769 mt->tl_mouse =
TRUE;
18772 if (widget == mt->timeline) {
18773 mt->fm_edit_event = NULL;
18777 if (mt->opts.mouse_mode ==
MOUSE_MODE_SELECT) mouse_select_start(widget, event, mt);
18784weed_plant_t *
get_prev_fm(lives_mt * mt,
int current_track, weed_plant_t *event) {
18785 weed_plant_t *event2, *event3, *eventx;
18787 if (!event)
return NULL;
18791 if (!eventx)
return NULL;
18799 if (!event2)
return NULL;
18804 event = event2 = event3;
18814 if (!event2)
return NULL;
18823 if (!event3)
break;
18827 if (!event2)
break;
18838weed_plant_t *
get_next_fm(lives_mt * mt,
int current_track, weed_plant_t *event) {
18839 weed_plant_t *event2, *event3;
18841 if (!event)
return NULL;
18844 if (!event3)
return NULL;
18850 if (!event)
return NULL;
18861static void add_mark_at(lives_mt * mt,
double time) {
18862 lives_painter_t *cr;
18868 mt->tl_marks = lives_list_append(mt->tl_marks, tstring);
18883boolean mt_mark_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
18884 livespointer user_data) {
18885 lives_mt *mt = (lives_mt *)user_data;
18890 cur_time = mt->ptr_time;
18892 add_mark_at(mt, cur_time);
18898 livespointer user_data) {
18899 lives_mt *mt = (lives_mt *)user_data;
18901 mt->opts.overlay_timecode = !mt->opts.overlay_timecode;
18908 lives_mt *mt = (lives_mt *)user_data;
18921 lives_mt *mt = (lives_mt *)user_data;
18934 lives_mt *mt = (lives_mt *)user_data;
18935 weed_timecode_t tc;
18936 double secs = mt->ptr_time;
18938 weed_plant_t *event;
18942 event =
get_prev_fm(mt, mt->current_track, event);
18951 lives_mt *mt = (lives_mt *)user_data;
18952 weed_timecode_t tc;
18953 weed_plant_t *event;
18954 double secs = mt->ptr_time;
18959 event =
get_next_fm(mt, mt->current_track, event);
18967static weed_timecode_t get_prev_node_tc(lives_mt * mt, weed_timecode_t tc) {
18969 weed_timecode_t prev_tc = -1;
18970 weed_plant_t *event;
18971 weed_timecode_t ev_tc;
18973 if (!pchain)
return tc;
18975 for (
int i = 0; i < num_params; i++) {
18976 event = (weed_plant_t *)pchain[i];
18978 if (ev_tc > prev_tc) prev_tc = ev_tc;
18986static weed_timecode_t get_next_node_tc(lives_mt * mt, weed_timecode_t tc) {
18988 weed_timecode_t next_tc = -1;
18989 weed_plant_t *event;
18990 weed_timecode_t ev_tc;
18992 if (!pchain)
return tc;
18994 for (
int i = 0; i < num_params; i++) {
18995 event = (weed_plant_t *)pchain[i];
18999 if (next_tc == -1 || ev_tc < next_tc) next_tc = ev_tc;
19006static boolean is_node_tc(lives_mt * mt, weed_timecode_t tc) {
19008 weed_plant_t *event;
19009 weed_timecode_t ev_tc;
19011 for (
int i = 0; i < num_params; i++) {
19012 event = (weed_plant_t *)pchain[i];
19025 lives_mt *mt = (lives_mt *)user_data;
19028 weed_timecode_t tc =
q_gint64(otc, mt->fps);
19029 weed_timecode_t pn_tc, nn_tc;
19031 boolean auto_prev = mt->opts.fx_auto_preview;
19035 if (!mt->block_tl_move) {
19037 mt->block_node_spin =
TRUE;
19038 if (mt->current_track >= 0 && (mt->opts.fx_auto_preview ||
mainw->
play_window))
19039 mt->no_frame_update =
TRUE;
19041 mt->no_frame_update =
FALSE;
19042 mt->block_node_spin =
FALSE;
19045 if (mt->prev_fx_time == 0. || tc == init_tc) {
19053 get_track_index(mt, tc);
19055 mt->opts.fx_auto_preview =
FALSE;
19056 mt->current_rfx->needs_reinit =
FALSE;
19060 if (mt->current_rfx->needs_reinit) {
19061 mt->current_rfx->needs_reinit =
FALSE;
19065 mt->opts.fx_auto_preview = auto_prev;
19068 pn_tc = get_prev_node_tc(mt, tc);
19069 nn_tc = get_next_node_tc(mt, tc);
19077 if (is_node_tc(mt, tc)) {
19084 if (mt->current_track >= 0) {
19092static boolean check_can_resetp(lives_mt * mt) {
19094 boolean can_reset =
FALSE;
19102 if (mt->init_event) {
19104 int *in_tracks = weed_get_int_array_counted(mt->init_event,
WEED_LEAF_IN_TRACKS, &num_in_tracks);
19106 for (i = 0; i < num_in_tracks; i++) {
19107 if (in_tracks[i] == mt->current_track) {
19108 mt->track_index = i;
19115 for (i = 0; i < nparams; i++) {
19120 if (!weed_leaf_elements_equate(in_params[i], WEED_LEAF_VALUE, def_params[i], WEED_LEAF_VALUE, mt->track_index)) {
19125 if (!weed_leaf_elements_equate(in_params[i], WEED_LEAF_VALUE, def_params[i], WEED_LEAF_VALUE, -1)) {
19132 for (i = 0; i < ninpar; i++) {
19133 weed_plant_free(def_params[i]);
19141 lives_mt *mt = (lives_mt *)user_data;
19143 boolean can_apply =
FALSE;
19144 boolean aprev = mt->opts.fx_auto_preview;
19152 if (mt->init_event) {
19154 int *in_tracks = weed_get_int_array_counted(mt->init_event,
WEED_LEAF_IN_TRACKS, &num_in_tracks);
19155 if (num_in_tracks > 0) {
19156 for (i = 0; i < num_in_tracks; i++) {
19157 if (in_tracks[i] == mt->current_track) {
19158 mt->track_index = i;
19166 for (i = 0; i < nparams; i++) {
19171 if (!weed_leaf_elements_equate(in_params[i], WEED_LEAF_VALUE, def_params[i], WEED_LEAF_VALUE, mt->track_index)) {
19172 weed_leaf_dup_nth(in_params[i], def_params[i], WEED_LEAF_VALUE, mt->track_index);
19174 mt->current_rfx->params[i].changed =
TRUE;
19177 if (!weed_leaf_elements_equate(in_params[i], WEED_LEAF_VALUE, def_params[i], WEED_LEAF_VALUE, -1)) {
19178 weed_leaf_dup(in_params[i], def_params[i], WEED_LEAF_VALUE);
19179 mt->current_rfx->params[i].changed =
TRUE;
19183 weed_plant_free(def_params[i]);
19188 mt->opts.fx_auto_preview =
FALSE;
19190 mt->current_rfx->needs_reinit =
FALSE;
19194 if (mt->current_rfx->needs_reinit) {
19196 mt->current_rfx->needs_reinit =
FALSE;
19199 mt->opts.fx_auto_preview = aprev;
19208 lives_mt *mt = (lives_mt *)user_data;
19213 weed_timecode_t next_tc = get_next_node_tc(mt, tc);
19222 lives_mt *mt = (lives_mt *)user_data;
19227 weed_timecode_t prev_tc = get_prev_node_tc(mt, tc);
19236 lives_mt *mt = (lives_mt *)user_data;
19240 weed_plant_t **in_params = weed_get_plantptr_array((weed_plant_t *)mt->current_rfx->source, WEED_LEAF_IN_PARAMETERS, &
error);
19242 weed_plant_t *event;
19243 weed_plant_t *prev_pchange, *next_pchange;
19245 weed_timecode_t ev_tc;
19255 if (mt->idlefunc > 0) {
19262 for (i = 0; i < num_params; i++) {
19263 event = (weed_plant_t *)pchain[i];
19270 if (event != pchain[i]) {
19276 weed_plant_t *param = in_params[i];
19280 }
else weed_leaf_copy(event, WEED_LEAF_VALUE, paramtmpl, WEED_LEAF_DEFAULT);
19291 if (mt->current_fx == mt->avol_fx && mt->avol_init_event && mt->opts.aparam_view_list) {
19292 LiVESList *slist = mt->audio_draws;
19295 slist = slist->next;
19301 d_print(
_(
"Removed parameter values for effect %s at time %s\n"), filter_name, mt->timestring);
19303 mt->block_tl_move =
TRUE;
19305 mt->block_tl_move =
FALSE;
19307 if (mt->current_track >= 0) {
19313 if (!mt->auto_changed) mt->auto_changed =
TRUE;
19317 mt->changed =
TRUE;
19326 if (mt->fm_edit_event == old_event) {
19328 mt->fm_edit_event = new_event;
19330 if (mt->init_event == old_event) {
19332 mt->init_event = new_event;
19334 if (mt->selected_init_event == old_event) {
19336 mt->selected_init_event = new_event;
19338 if (mt->avol_init_event == old_event) {
19340 mt->avol_init_event = new_event;
19342 if (mt->specific_event == old_event) {
19344 mt->specific_event = new_event;
19349static void combine_ign(weed_plant_t *xnew, weed_plant_t *xold) {
19350 int num, numo, *nign, *oign, i;
19353 oign = weed_get_boolean_array_counted(xold, WEED_LEAF_IGNORE, &numo);
19355 nign = weed_get_boolean_array_counted(xnew, WEED_LEAF_IGNORE, &num);
19356 for (i = 0; i < num; i++)
if (i >= numo || oign[i] == WEED_FALSE) nign[i] = WEED_FALSE;
19357 weed_set_boolean_array(xnew, WEED_LEAF_IGNORE, num, nign);
19363static void add_to_pchain(weed_plant_t *event_list, weed_plant_t *init_event, weed_plant_t *pchange,
int index,
19364 weed_timecode_t tc) {
19365 weed_plant_t *
event = (weed_plant_t *)pchain[index];
19366 weed_plant_t *last_event = NULL;
19370 last_event = event;
19379 if (event == pchain[index]) weed_leaf_delete(pchange, WEED_LEAF_IGNORE);
19380 if (weed_plant_has_leaf(pchange, WEED_LEAF_IGNORE)) combine_ign(pchange, event);
19391 void **in_params = weed_get_voidptr_array_counted(init_event, WEED_LEAF_IN_PARAMETERS, &numin);
19392 in_params[index] = pchain[index] = (
void *)pchange;
19393 weed_set_voidptr_array(init_event, WEED_LEAF_IN_PARAMETERS, numin, in_params);
19402 static boolean norecurse =
FALSE;
19403 if (norecurse)
return;
19407 if (mt->opts.fx_auto_preview) {
19412 if (mt->apply_fx_button) {
19413 int nparams = mt->current_rfx->num_params;
19416 for (
int i = 0; i < nparams; i++) {
19417 if (mt->current_rfx->params[i].changed) {
19431 lives_mt *mt = (lives_mt *)user_data;
19433 weed_plant_t *inst = (weed_plant_t *)mt->current_rfx->source;
19434 weed_plant_t *param, *pchange, *at_event;
19443 char *tname, *track_desc;
19445 boolean has_multi =
FALSE;
19446 boolean was_changed =
FALSE;
19447 boolean needs_idlefunc =
FALSE;
19448 boolean did_backup = mt->did_backup;
19455 LiVESWidget *textwidget = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(
mainw->
textwidget_focus),
19459 if (mt->framedraw) {
19465 if (mt->idlefunc > 0) {
19466 needs_idlefunc =
TRUE;
19475 if (!mt->current_rfx->params[i].changed)
continue;
19476 pchange = weed_plant_new(WEED_PLANT_EVENT);
19477 weed_set_int_value(pchange, WEED_LEAF_EVENT_TYPE, WEED_EVENT_TYPE_PARAM_CHANGE);
19478 weed_set_int64_value(pchange, WEED_LEAF_TIMECODE, tc);
19483 if (weed_plant_has_leaf(param, WEED_LEAF_IGNORE)) {
19486 int *ign = weed_get_boolean_array_counted(param, WEED_LEAF_IGNORE, &num_vals);
19487 weed_set_boolean_array(pchange, WEED_LEAF_IGNORE, num_vals, ign);
19488 for (j = 0; j < num_vals; j++) {
19489 if (ign[j] == WEED_FALSE) {
19490 was_changed =
TRUE;
19491 ign[j] = WEED_TRUE;
19495 weed_set_boolean_array(param, WEED_LEAF_IGNORE, num_vals, ign);
19498 }
else was_changed =
TRUE;
19500 weed_leaf_copy(pchange, WEED_LEAF_VALUE, param, WEED_LEAF_VALUE);
19508 add_to_pchain(mt->event_list, mt->init_event, pchange, i, tc);
19514 if (!was_changed) {
19515 if (needs_idlefunc || (!did_backup && mt->auto_changed))
19524 nparams = mt->current_rfx->num_params;
19525 for (i = 0; i < nparams; i++) mt->current_rfx->params[i].changed =
FALSE;
19527 switch (numtracks) {
19545 }
else track_desc = (
_(
"selected tracks"));
19549 if (mt->current_fx == mt->avol_fx) {
19551 tname = (
_(
"audio"));
19554 d_print(
_(
"Set parameter values for %s %s on %s at time %s\n"), tname, filter_name, track_desc, mt->timestring);
19561 if (mt->current_fx == mt->avol_fx && mt->avol_init_event && mt->opts.aparam_view_list) {
19562 LiVESList *slist = mt->audio_draws;
19565 slist = slist->next;
19569 if (mt->current_track >= 0) {
19573 if (!mt->auto_changed) mt->auto_changed =
TRUE;
19577 mt->changed =
TRUE;
19581static int free_tt_key;
19582static int elist_errors;
19598 LiVESList *lmap = NULL;
19600 uint64_t unique_id;
19613 boolean err =
FALSE;
19615 if (!lives_file_test(lmap_name, LIVES_FILE_TEST_EXISTS)) {
19659 lmap_entry->
handle = handle;
19661 lmap_entry->
name = name;
19662 lmap_entry->
list = NULL;
19673 for (i = 0; i < nm; i++) {
19687 lmap_entry->
list = lives_list_append(lmap_entry->
list, lives_strdup(
string));
19688 array = lives_strsplit(
string,
"|", -1);
19691 lives_strfreev(array);
19695 lmap = lives_list_append(lmap, lmap_entry);
19707 }
while (retval == LIVES_RESPONSE_RETRY);
19743 LiVESList *map, *map_next;
19746 char *map_name = NULL, *ldir = NULL;
19753 boolean written =
FALSE;
19755 boolean write_to_file =
TRUE;
19766 if (!file) write_to_file =
FALSE;
19772 else ldir = lives_strdup(dir);
19795 map_next = map->next;
19797 char **array = lives_strsplit((
char *)map->data,
"|", -1);
19798 if ((file && !strcmp(array[0], file)) || (!file && !dir &&
19799 !lives_file_test(array[0], LIVES_FILE_TEST_EXISTS))) {
19805 lives_strfreev(array);
19811 if (file && ((lmap && lmap[i] != 0) || (lmap_audio && lmap_audio[i] != 0.))) {
19812 if (lmap) max_frame = lmap[i];
19813 else max_frame = 0;
19814 if (lmap_audio) max_atime = lmap_audio[i];
19815 else max_atime = 0.;
19832 len = lives_list_length(map);
19836 len = strlen(
string);
19853 }
while (retval == LIVES_RESPONSE_RETRY);
19855 if (write_to_file && retval != LIVES_RESPONSE_CANCEL) {
19859 if (size <= 0 || !written) {
19870 if (write_to_file) {
19877void add_markers(lives_mt * mt, weed_plant_t *event_list,
boolean add_block_ids) {
19889 LiVESList *track_blocks = NULL;
19890 LiVESList *tlist = mt->video_draws;
19893 weed_timecode_t tc;
19894 LiVESWidget *eventbox;
19895 weed_plant_t *event;
19899 eventbox = (LiVESWidget *)tlist->data;
19900 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
19901 track_blocks = lives_list_append(track_blocks, (livespointer)block);
19902 tlist = tlist->next;
19910 blist = track_blocks;
19913 block = (track_rect *)blist->data;
19922 if (mt->audio_draws && lives_list_length(mt->audio_draws) >= track + mt->opts.back_audio_tracks) {
19925 LIVES_INT_TO_POINTER(-track - mt->opts.back_audio_tracks - 1));
19928 if (!block->ordered) {
19931 if (event == block->end_event) blist->data = block->next;
19934 blist = blist->next;
19940 if (track_blocks) lives_list_free(track_blocks);
19950 boolean needs_idlefunc =
FALSE;
19952 if (mt && mt->idlefunc > 0) {
19955 needs_idlefunc =
TRUE;
19964 if (response == LIVES_RESPONSE_CANCEL) {
19967 if (needs_idlefunc) {
19983 if (!mt->auto_changed) mt->auto_changed =
TRUE;
19999 lives_mt *mt = (lives_mt *)user_data;
20005 double *layout_map_audio;
20007 LiVESWidget *ar_checkbutton;
20010 weed_plant_t *event_list;
20020 boolean retval =
TRUE;
20022 boolean needs_idlefunc =
FALSE;
20023 boolean did_backup;
20032 did_backup = mt->did_backup;
20034 event_list = mt->event_list;
20035 layout_name = mt->layout_name;
20040 layout_map_audio = update_layout_map_audio(event_list);
20062 if (mt && mt->idlefunc > 0) {
20065 needs_idlefunc =
TRUE;
20075 if (needs_idlefunc) {
20084 if ((needs_idlefunc || (!did_backup && mt->auto_changed))) {
20100 lives_signal_sync_connect(LIVES_GUI_OBJECT(ar_checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
20106 if (!(*layout_name)) esave_file =
choose_file(esave_dir, NULL, filt, LIVES_FILE_CHOOSER_ACTION_SAVE, NULL, hbox);
20107 else esave_file =
choose_file(esave_dir, layout_name, filt, LIVES_FILE_CHOOSER_ACTION_SAVE, NULL, hbox);
20114 esave_dir =
get_dir(esave_file);
20134 if (needs_idlefunc || (!did_backup && mt->auto_changed)) {
20143 lives_snprintf(xlayout_name,
PATH_MAX,
"%s", esave_file);
20162 if (!retval || fd < 0) {
20164 if (retval2 == LIVES_RESPONSE_CANCEL) {
20166 if (needs_idlefunc) {
20178 }
while (retval2 == LIVES_RESPONSE_RETRY);
20180 if (retval2 != LIVES_RESPONSE_CANCEL) {
20182 d_print(
_(
"Saved layout to %s\n"), esave_file);
20188 if (mt) mt->changed =
FALSE;
20208 mt->auto_changed =
FALSE;
20218static char *rec_error_add(
char *ebuf,
char *msg,
int num, weed_timecode_t tc) {
20227 if (tc == -1) xnew = lives_strdup(msg);
20232 tmp = lives_strconcat(ebuf, xnew, NULL);
20234#ifndef SILENT_EVENT_LIST_LOAD
20235 lives_printerr(
"Rec error: %s", xnew);
20244static int get_next_tt_key(
ttable * trans_table) {
20247 if (trans_table[i].in == 0)
return i;
20255 if (normal && trans_table[i].in == in)
return trans_table[i].
out;
20258 if (!normal && (uint64_t)trans_table[i].out == in)
return (
void *)trans_table[i].
in;
20259 if (!trans_table[i].out)
return NULL;
20265static void **remove_nulls_from_filter_map(
void **init_events,
int *num_events) {
20269 int num_nulls = 0, i, j = 0;
20270 void **new_init_events;
20272 if (*num_events == 1)
return init_events;
20274 for (i = 0; i < *num_events; i++)
if (!init_events[i]) num_nulls++;
20275 if (num_nulls == 0)
return init_events;
20277 *num_events -= num_nulls;
20279 if (*num_events == 0) new_init_events = NULL;
20281 else new_init_events = (
void **)
lives_malloc((*num_events) *
sizeof(
void *));
20283 for (i = 0; i < *num_events + num_nulls; i++)
if (init_events[i]) new_init_events[j++] = init_events[i];
20287 if (*num_events == 0) *num_events = 1;
20289 return new_init_events;
20294 weed_plant_t *ito,
int track,
boolean after) {
20297 void **events_before = NULL;
20298 void **events_after = NULL;
20299 int num_before = 0, j1;
20300 int num_after = 0, j2;
20302 void **init_events, **new_init_events;
20305 while (event != deinit_event) {
20311 if (!events_before && !events_after) {
20313 for (i = 0; i < num_inits; i++) {
20314 if (init_events[i] == ifrom)
continue;
20317 if (init_events[i] == ito) {
20318 num_before = j - 1 + after;
20322 num_after = j - after;
20323 if (num_before > 0) events_before = (
void **)
lives_malloc(num_before *
sizeof(
void *));
20324 if (num_after > 0) events_after = (
void **)
lives_malloc(num_after *
sizeof(
void *));
20326 for (i = 0; i < num_inits; i++) {
20328 if (init_events[i] == ifrom)
continue;
20329 if (j1 < num_before) {
20330 events_before[j1] = init_events[i];
20333 events_after[j2] = init_events[i];
20340 for (i = 0; i < num_inits; i++) {
20341 if (init_events[i] == ifrom)
continue;
20343 if (!got_after &&
init_event_in_list(events_after, num_after, (weed_plant_t *)init_events[i])) got_after =
TRUE;
20344 if (got_after &&
init_event_in_list(events_before, num_before, (weed_plant_t *)init_events[i])) {
20346 if (events_before)
lives_free(events_before);
20351 new_init_events = (
void **)
lives_malloc(num_inits *
sizeof(
void *));
20354 for (i = 0; i < num_inits; i++) {
20355 if (init_events[i] == ifrom)
continue;
20356 if ((
init_event_in_list(events_before, num_before, (weed_plant_t *)init_events[i]) ||
20359 new_init_events[j] = init_events[i];
20363 new_init_events[j] = ifrom;
20368 new_init_events[j] = init_events[i];
20372 if (j < num_inits) new_init_events[j] = ifrom;
20379 if (events_before)
lives_free(events_before);
20387 int i1, i2, num_events1, num_events2;
20388 void **inits1, **inits2;
20410 if (!inits1 && !inits2)
return TRUE;
20414 for (i1 = 0; i1 < num_events1; i1++) {
20435 if (i2 >= num_events2) {
20444 if (i2 < num_events2) {
20453 if (inits1[i1] != inits2[i2]) {
20462 if (i2 < num_events2) {
20467 for (; i2 < num_events2; i2++) {
20488static char *filter_map_check(
ttable * trans_table, weed_plant_t *filter_map, weed_timecode_t deinit_tc,
20489 weed_timecode_t fm_tc,
char *ebuf) {
20490 int num_init_events;
20491 void **copy_events, **pinit_events;
20493 uint64_t *init_events;
20500 if (num_init_events == 1 && weed_get_int64_value(filter_map,
WEED_LEAF_INIT_EVENTS, NULL) == 0)
return ebuf;
20503 if (num_init_events == 1 && !weed_get_voidptr_value(filter_map,
WEED_LEAF_INIT_EVENTS, NULL))
return ebuf;
20505 init_events = (uint64_t *)
lives_malloc(num_init_events *
sizeof(uint64_t));
20506 for (i = 0; i < num_init_events; i++) init_events[i] = (uint64_t)pinit_events[i];
20510 copy_events = (
void **)
lives_malloc(num_init_events *
sizeof(weed_plant_t *));
20511 for (i = 0; i < num_init_events; i++) {
20514 copy_events[i] = NULL;
20515 ebuf = rec_error_add(ebuf,
"Filter_map points to invalid filter_init", -1, fm_tc);
20518 if (num_init_events > 1) copy_events = remove_nulls_from_filter_map(copy_events, &num_init_events);
20526static char *add_filter_deinits(weed_plant_t *event_list,
ttable * trans_table,
void ***pchains,
20527 weed_timecode_t tc,
char *ebuf) {
20529 int i, j, num_params;
20532 weed_plant_t *init_event, *event;
20533 void **in_pchanges;
20536 if (!trans_table[i].out)
continue;
20537 if (trans_table[i].in != 0) {
20543 if ((num_params = weed_leaf_num_elements(init_event, WEED_LEAF_IN_PARAMETERS)) > 0) {
20544 in_pchanges = (
void **)
lives_malloc(num_params *
sizeof(
void *));
20545 for (j = 0; j < num_params; j++) {
20547 in_pchanges[j] = (weed_plant_t *)pchains[i][j];
20548 else in_pchanges[j] = NULL;
20550 weed_set_voidptr_array(event, WEED_LEAF_IN_PARAMETERS, num_params, in_pchanges);
20556 ebuf = rec_error_add(ebuf,
"Added missing filter_deinit", -1, tc);
20563static char *add_null_filter_map(weed_plant_t *event_list, weed_plant_t *last_fm, weed_timecode_t tc,
char *ebuf) {
20573 ebuf = rec_error_add(ebuf,
"Added missing empty filter_map", -1, tc);
20578static weed_plant_t *duplicate_frame_at(weed_plant_t *event_list, weed_plant_t *src_frame, weed_timecode_t tc) {
20584 clips = weed_get_int_array_counted(src_frame,
WEED_LEAF_CLIPS, &numframes);
20585 if (!numframes)
return src_frame;
20597static LiVESList *atrack_list;
20599static void add_atrack_to_list(
int track,
int clip) {
20601 LiVESList *alist = atrack_list;
20606 entry = (
char *)alist->data;
20607 array = lives_strsplit(entry,
"|", -1);
20608 if (atoi(array[0]) == track) {
20611 lives_strfreev(array);
20614 lives_strfreev(array);
20615 alist = alist->next;
20621static void remove_atrack_from_list(
int track) {
20623 LiVESList *alist = atrack_list, *alist_next;
20628 alist_next = alist->next;
20629 entry = (
char *)alist->data;
20630 array = lives_strsplit(entry,
"|", -1);
20631 if (atoi(array[0]) == track) {
20632 atrack_list = lives_list_remove(atrack_list, entry);
20633 lives_strfreev(array);
20637 lives_strfreev(array);
20638 alist = alist_next;
20643static char *add_missing_atrack_closers(weed_plant_t *event_list,
double fps,
char *ebuf) {
20644 LiVESList *alist = atrack_list;
20652 weed_plant_t *last_frame;
20654 weed_timecode_t tc;
20656 if (!atrack_list)
return ebuf;
20658 num_atracks = lives_list_length(atrack_list) * 2;
20667 weed_plant_t *shortcut = last_frame;
20672 entry = (
char *)alist->data;
20673 array = lives_strsplit(entry,
"|", -1);
20674 aclips[i] = atoi(array[0]);
20675 aclips[i + 1] = atoi(array[1]);
20677 aseeks[i + 1] = 0.;
20678 lives_strfreev(array);
20679 if (aclips[i] >= 0) ebuf = rec_error_add(ebuf,
"Added missing audio closure", aclips[i], tc);
20680 else ebuf = rec_error_add(ebuf,
"Added missing audio closure to backing track", -aclips[i], tc);
20682 alist = alist->next;
20697static int64_t *get_int64_array_convert(weed_plant_t *plant,
const char *key) {
20698 if (weed_leaf_seed_type(plant, key) == WEED_SEED_INT) {
20700 int *ivals = weed_get_int_array_counted(plant, key, &nvals);
20701 if (!nvals)
return NULL;
20703 for (
int i = 0; i < nvals; i++) i64vals[i] = (int64_t)ivals[i];
20705 weed_leaf_delete(plant, key);
20706 weed_set_int64_array(plant, key, nvals, i64vals);
20709 return weed_get_int64_array(plant, key, NULL);
20722 weed_plant_t **ptmpls;
20723 weed_plant_t **ctmpls;
20726 weed_plant_t *shortcut = NULL;
20727 weed_plant_t *last_frame_event;
20728 weed_plant_t *last_filter_map = NULL;
20729 weed_plant_t *filter = NULL;
20730 weed_plant_t *last_event;
20732 weed_timecode_t tc = 0, last_tc = 0;
20733 weed_timecode_t last_frame_tc = -1;
20734 weed_timecode_t last_deinit_tc = -1;
20735 weed_timecode_t last_filter_map_tc = -1;
20736 weed_timecode_t cur_tc = 0;
20738 char *ebuf = lives_strdup(
"");
20741 char *bit1 = lives_strdup(
""), *bit2 = NULL, *bit3 = lives_strdup(
"."), *msg;
20742 int64_t *frame_index, *new_frame_index;
20744 int *clip_index, *aclip_index, *new_aclip_index;
20745 int *new_clip_index;
20747 int i, idx, filter_idx, j;
20749 int num_ctmpls, num_inct, num_outct;
20751 int num_init_events;
20753 int num_tracks, num_atracks;
20754 int last_valid_frame;
20757 int api_version = 100;
20760 boolean check_filter_map =
FALSE;
20761 boolean was_deleted =
FALSE;
20763 boolean missing_clips =
FALSE, missing_frames =
FALSE;
20764 boolean has_event_type;
20767 void **new_init_events;
20768 void **in_pchanges;
20772 double *aseek_index, *new_aseek_index;
20776 uint64_t *init_events;
20780 if (weed_plant_has_leaf(event_list, WEED_LEAF_FPS)) fps = weed_get_double_value(event_list, WEED_LEAF_FPS, NULL);
20784 if (mt) mt->layout_prompt =
FALSE;
20787 trans_table[i].
in = 0;
20788 trans_table[i].
out = NULL;
20793 atrack_list = NULL;
20796 was_deleted =
FALSE;
20798 if (!weed_plant_has_leaf(event, WEED_LEAF_TIMECODE)) {
20799 ebuf = rec_error_add(ebuf,
"Event has no timecode", weed_get_plant_type(event), -1);
20801 event = event_next;
20807 weed_set_int64_value(event, WEED_LEAF_TIMECODE, tc);
20813 if (weed_get_plant_type(event) != WEED_PLANT_EVENT) {
20814 ebuf = rec_error_add(ebuf,
"Invalid plant type", weed_get_plant_type(event), tc);
20816 event = event_next;
20819 if (tc < last_tc) {
20820 break_me(
"oo event in event_list_rectify");
20821 ebuf = rec_error_add(ebuf,
"Out of order event", -1, tc);
20823 event = event_next;
20826 has_event_type =
TRUE;
20827 if (!weed_plant_has_leaf(event, WEED_LEAF_EVENT_TYPE)) {
20828 has_event_type =
FALSE;
20829 if (api_version < 122) {
20831 weed_leaf_copy(event, WEED_LEAF_EVENT_TYPE, event,
WEED_LEAF_HINT);
20833 has_event_type =
TRUE;
20837 if (!has_event_type) {
20838 ebuf = rec_error_add(ebuf,
"Event has no event_type", weed_get_plant_type(event), tc);
20840 event = event_next;
20846 switch (event_type) {
20847 case WEED_EVENT_TYPE_FILTER_INIT:
20849 g_print(
"\n\ngot filter init %p\n", event);
20853 ebuf = rec_error_add(ebuf,
"Filter_init missing event_id", -1, tc);
20861 ebuf = rec_error_add(ebuf,
"Filter_init missing filter", -1, tc);
20863 was_deleted =
TRUE;
20868 if (weed_plant_has_leaf(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES)) {
20870 ebuf = rec_error_add(ebuf,
"Filter_init missing filter", -1, tc);
20872 was_deleted =
TRUE;
20874 num_ctmpls = weed_leaf_num_elements(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES);
20876 if (num_ctmpls != num_inct) {
20877 ebuf = rec_error_add(ebuf,
"Filter_init has invalid in_count", -1, tc);
20879 was_deleted =
TRUE;
20882 ctmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES, NULL);
20883 for (i = 0; i < num_ctmpls; i++) {
20886 ebuf = rec_error_add(ebuf,
"Filter_init disables a non-optional in channel", i, tc);
20888 was_deleted =
TRUE;
20890 if (thisct > 1 && (!weed_plant_has_leaf(ctmpls[i], WEED_LEAF_MAX_REPEATS) ||
20891 (weed_get_int_value(ctmpls[i], WEED_LEAF_MAX_REPEATS, NULL) > 0 &&
20892 weed_get_int_value(ctmpls[i], WEED_LEAF_MAX_REPEATS, NULL) < thisct))) {
20893 ebuf = rec_error_add(ebuf,
"Filter_init has too many repeats of in channel", i, tc);
20895 was_deleted =
TRUE;
20903 if (!was_deleted) {
20904 num_ctmpls = weed_leaf_num_elements(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES);
20906 if (num_ctmpls != num_outct) {
20907 ebuf = rec_error_add(ebuf,
"Filter_init has invalid out_count", -1, tc);
20909 was_deleted =
TRUE;
20912 ctmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, NULL);
20913 for (i = 0; i < num_ctmpls; i++) {
20916 ebuf = rec_error_add(ebuf,
"Filter_init disables a non-optional out channel", i, tc);
20918 was_deleted =
TRUE;
20920 if (thisct > 1 && (!weed_plant_has_leaf(ctmpls[i], WEED_LEAF_MAX_REPEATS) ||
20921 (weed_get_int_value(ctmpls[i], WEED_LEAF_MAX_REPEATS, NULL) > 0 &&
20922 weed_get_int_value(ctmpls[i], WEED_LEAF_MAX_REPEATS, NULL) < thisct))) {
20923 ebuf = rec_error_add(ebuf,
"Filter_init has too many repeats of out channel", i, tc);
20925 was_deleted =
TRUE;
20930 for (i = 0; i < ntracks; i++) {
20933 if (mt && !mt->opts.pertrack_audio) {
20935 mt->opts.pertrack_audio =
TRUE;
20936 }
else force_pertrack_audio =
TRUE;
20939 if (trax[i] == -1) {
20941 if (mt && mt->opts.back_audio_tracks == 0) {
20942 mt->opts.back_audio_tracks = 1;
20943 ebuf = rec_error_add(ebuf,
"Adding backing audio", -1, tc);
20944 }
else force_backing_tracks = 1;
20950 for (i = 0; i < ntracks; i++) {
20953 if (mt && !mt->opts.pertrack_audio) {
20955 mt->opts.pertrack_audio =
TRUE;
20956 }
else force_pertrack_audio =
TRUE;
20958 if (trax[i] == -1) {
20960 if (mt && mt->opts.back_audio_tracks == 0) {
20961 mt->opts.back_audio_tracks = 1;
20962 }
else force_backing_tracks = 1;
20970 if (mt && mt->avol_fx == -1) {
20974 if (LIVES_POINTER_TO_INT(clist->data) == filter_idx) {
20975 mt->avol_fx = filter_idx;
20976 mt->avol_init_event = event;
20979 clist = clist->next;
20987 lives_printerr(
"Layout contains unknown filter %s\n", filter_hash);
20988 ebuf = rec_error_add(ebuf,
"Layout contains unknown filter", -1, tc);
20990 was_deleted =
TRUE;
20991 if (mt) mt->layout_prompt =
TRUE;
20994 if (!was_deleted) {
20996 if (host_tag == -1) {
21008 event_id = (uint64_t)((weed_plant_t *)weed_get_voidptr_value(event,
WEED_LEAF_EVENT_ID, NULL));
21011 trans_table[idx].
out = event;
21013 g_print(
"adding lookup %"PRIu64" -> %p\n", event_id, event);
21017 if (weed_plant_has_leaf(event, WEED_LEAF_IN_PARAMETERS)) {
21018 num_params = weed_leaf_num_elements(event, WEED_LEAF_IN_PARAMETERS);
21019 pchains[idx] = (
void **)
lives_malloc((num_params + 1) *
sizeof(
void *));
21020 in_pchanges = (
void **)
lives_malloc(num_params *
sizeof(
void *));
21021 for (i = 0; i < num_params; i++) {
21022 pchains[idx][i] = event;
21023 in_pchanges[i] = NULL;
21025 pchains[idx][i] = NULL;
21027 weed_leaf_delete(event, WEED_LEAF_IN_PARAMETERS);
21028 weed_set_voidptr_array(event, WEED_LEAF_IN_PARAMETERS, num_params, in_pchanges);
21035 case WEED_EVENT_TYPE_FILTER_DEINIT:
21039 ebuf = rec_error_add(ebuf,
"Filter_deinit missing init_event", -1, tc);
21041 was_deleted =
TRUE;
21046 event_id = (uint64_t)((weed_plant_t *)weed_get_voidptr_value(event,
WEED_LEAF_INIT_EVENT, NULL));
21049 g_print(
"looking for %"PRIu64" in ttable\n", event_id);
21054 ebuf = rec_error_add(ebuf,
"Filter_deinit has invalid init_event", -1, tc);
21056 was_deleted =
TRUE;
21061 host_tag_s = weed_get_string_value((weed_plant_t *)init_event,
WEED_LEAF_HOST_TAG, NULL);
21062 host_tag = atoi(host_tag_s);
21065 if (idx < free_tt_key) free_tt_key = idx;
21068 check_filter_map =
TRUE;
21069 last_deinit_tc = tc;
21071 filter_hash = weed_get_string_value((weed_plant_t *)init_event,
WEED_LEAF_FILTER, NULL);
21073 if ((num_params = weed_leaf_num_elements((weed_plant_t *)init_event, WEED_LEAF_IN_PARAMETERS)) > 0) {
21074 in_pchanges = (
void **)
lives_malloc(num_params *
sizeof(
void *));
21075 for (i = 0; i < num_params; i++) {
21077 in_pchanges[i] = (weed_plant_t *)pchains[idx][i];
21078 else in_pchanges[i] = NULL;
21080 weed_leaf_delete(event, WEED_LEAF_IN_PARAMETERS);
21081 weed_set_voidptr_array(event, WEED_LEAF_IN_PARAMETERS, num_params, in_pchanges);
21090 case WEED_EVENT_TYPE_FILTER_MAP:
21098 init_events = (uint64_t *)
lives_malloc(num_init_events *
sizeof(uint64_t));
21099 for (i = 0; i < num_init_events; i++) init_events[i] = (uint64_t)pinit_events[i];
21103 new_init_events = (
void **)
lives_malloc(num_init_events *
sizeof(
void *));
21104 for (i = 0; i < num_init_events; i++) {
21105 event_id = (uint64_t)init_events[i];
21106 if (event_id != 0) {
21109 g_print(
"looking for %"PRIu64" in ttable, got %p\n", event_id, init_event);
21112 ebuf = rec_error_add(ebuf,
"Filter_map has invalid init_event", -1, tc);
21113 new_init_events[i] = NULL;
21114 }
else new_init_events[i] = init_event;
21115 }
else new_init_events[i] = NULL;
21117 new_init_events = remove_nulls_from_filter_map(new_init_events, &num_init_events);
21125 for (i = 0; i < num_init_events; i++) {
21137 if (last_filter_map) {
21141 was_deleted =
TRUE;
21146 was_deleted =
TRUE;
21148 if (!was_deleted) last_filter_map = event;
21151 case WEED_EVENT_TYPE_PARAM_CHANGE:
21153 ebuf = rec_error_add(ebuf,
"Param_change has no index", -1, tc);
21155 was_deleted =
TRUE;
21157 if (!weed_plant_has_leaf(event, WEED_LEAF_VALUE)) {
21158 ebuf = rec_error_add(ebuf,
"Param_change has no value", -1, tc);
21160 was_deleted =
TRUE;
21163 ebuf = rec_error_add(ebuf,
"Param_change has no init_event", -1, tc);
21165 was_deleted =
TRUE;
21170 event_id = (uint64_t)((weed_plant_t *)weed_get_voidptr_value(event,
WEED_LEAF_INIT_EVENT, NULL));
21173 g_print(
"pc looking for %"PRIu64" in ttable %d\n", event_id,
error);
21177 ebuf = rec_error_add(ebuf,
"Param_change has invalid init_event", -1, tc);
21179 was_deleted =
TRUE;
21181 filter_hash = weed_get_string_value((weed_plant_t *)init_event,
WEED_LEAF_FILTER, NULL);
21186 pnum >= (num_params = weed_leaf_num_elements((weed_plant_t *)init_event, WEED_LEAF_IN_PARAMETERS))) {
21187 ebuf = rec_error_add(ebuf,
"Param_change has invalid index", pnum, tc);
21189 was_deleted =
TRUE;
21191 ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
21192 if (!weed_plant_has_leaf(event, WEED_LEAF_VALUE)) {
21193 ebuf = rec_error_add(ebuf,
"Param_change has no value with index", pnum, tc);
21195 was_deleted =
TRUE;
21197 if (weed_leaf_seed_type(event, WEED_LEAF_VALUE) != weed_leaf_seed_type(ptmpls[pnum], WEED_LEAF_DEFAULT)) {
21198 ebuf = rec_error_add(ebuf,
"Param_change has invalid seed type with index", pnum, tc);
21200 was_deleted =
TRUE;
21203 host_tag_s = weed_get_string_value((weed_plant_t *)init_event,
WEED_LEAF_HOST_TAG, NULL);
21204 host_tag = atoi(host_tag_s);
21208 if (pchains[idx][pnum] == init_event) {
21209 if (weed_leaf_seed_type((weed_plant_t *)init_event, WEED_LEAF_IN_PARAMETERS) == WEED_SEED_INT64) {
21211 uint64_t *orig_pchanges = (uint64_t *)weed_get_int64_array((weed_plant_t *)init_event,
21212 WEED_LEAF_IN_PARAMETERS, NULL);
21214 uint64_t *pin_pchanges = (uint64_t *)
lives_malloc(num_params *
sizeof(uint64_t));
21216 for (i = 0; i < num_params; i++) {
21217 if (orig_pchanges[i] == 0 && i == pnum) pin_pchanges[i] = (uint64_t)event;
21218 else pin_pchanges[i] = (uint64_t)orig_pchanges[i];
21221 weed_leaf_delete((weed_plant_t *)init_event, WEED_LEAF_IN_PARAMETERS);
21222 weed_set_int64_array((weed_plant_t *)init_event, WEED_LEAF_IN_PARAMETERS, num_params,
21223 (int64_t *)pin_pchanges);
21228 void **orig_pchanges = weed_get_voidptr_array((weed_plant_t *)init_event,
21229 WEED_LEAF_IN_PARAMETERS, NULL);
21230 void **pin_pchanges = (
void **)
lives_malloc(num_params *
sizeof(
void *));
21232 for (i = 0; i < num_params; i++) {
21233 if (!orig_pchanges[i] && i == pnum) pin_pchanges[i] = (
void *)event;
21234 else pin_pchanges[i] = (
void *)orig_pchanges[i];
21236 weed_leaf_delete((weed_plant_t *)init_event, WEED_LEAF_IN_PARAMETERS);
21237 weed_set_voidptr_array((weed_plant_t *)init_event, WEED_LEAF_IN_PARAMETERS, num_params, pin_pchanges);
21254 pchains[idx][pnum] = event;
21264 case WEED_EVENT_TYPE_FRAME:
21265 if (tc == last_frame_tc) {
21266 ebuf = rec_error_add(ebuf,
"Duplicate frame event", -1, tc);
21268 was_deleted =
TRUE;
21273 ebuf = rec_error_add(ebuf,
"Frame event missing clips at", -1, tc);
21276 last_frame_tc = tc;
21278 clip_index = weed_get_int_array_counted(event,
WEED_LEAF_CLIPS, &num_tracks);
21282 new_frame_index = (int64_t *)
lives_malloc(num_tracks * 8);
21283 last_valid_frame = 0;
21285#ifdef DEBUG_MISSING_CLIPS
21286 g_print(
"pt zzz %d\n", num_tracks);
21288 for (i = 0; i < num_tracks; i++) {
21289 if (clip_index[i] > 0 && (clip_index[i] >
MAX_FILES || renumbered_clips[clip_index[i]] < 1 ||
21290 !
mainw->
files[renumbered_clips[clip_index[i]]])) {
21293 new_clip_index[i] = -1;
21294 new_frame_index[i] = 0;
21295 ebuf = rec_error_add(ebuf,
"Invalid clip number", clip_index[i], tc);
21297#ifdef DEBUG_MISSING_CLIPS
21298 g_print(
"found invalid clip number %d on track %d, renumbered_clips=%d\n", clip_index[i], i,
21299 renumbered_clips[clip_index[i]]);
21301 missing_clips =
TRUE;
21304 if (clip_index[i] > 0 && frame_index[i] > 0) {
21305 int rclip = renumbered_clips[clip_index[i]];
21306 if (lfps[rclip] != 0.) {
21309 }
else new_frame_index[i] = frame_index[i];
21312 ebuf = rec_error_add(ebuf,
"Invalid frame number", new_frame_index[i], tc);
21313 new_clip_index[i] = -1;
21314 new_frame_index[i] = 0;
21315 missing_frames =
TRUE;
21321 else new_clip_index[i] = clip_index[i];
21322 new_frame_index[i] = frame_index[i];
21323 last_valid_frame = i + 1;
21326 new_clip_index[i] = clip_index[i];
21327 new_frame_index[i] = frame_index[i];
21328 last_valid_frame = i + 1;
21333 if (last_valid_frame == 0) {
21338 *new_clip_index = -1;
21339 *new_frame_index = 0;
21341 weed_set_int_array(event,
WEED_LEAF_CLIPS, num_tracks, new_clip_index);
21342 weed_set_int64_array(event,
WEED_LEAF_FRAMES, num_tracks, new_frame_index);
21344 if (last_valid_frame < num_tracks) {
21348 frame_index = (int64_t *)
lives_malloc(last_valid_frame * 8);
21349 for (i = 0; i < last_valid_frame; i++) {
21350 clip_index[i] = new_clip_index[i];
21351 frame_index[i] = new_frame_index[i];
21353 num_tracks = last_valid_frame;
21357 weed_set_int_array(event,
WEED_LEAF_CLIPS, num_tracks, new_clip_index);
21358 weed_set_int64_array(event,
WEED_LEAF_FRAMES, num_tracks, new_frame_index);
21370 if ((num_atracks & 1) != 0) {
21371 ebuf = rec_error_add(ebuf,
"Invalid number of audio_clips", -1, tc);
21377 ebuf = rec_error_add(ebuf,
"Invalid number of audio_seeks", -1, tc);
21386 for (i = 0; i < num_atracks; i += 2) {
21387 if (aclip_index[i + 1] > 0) {
21388 if ((aclip_index[i + 1] >
MAX_FILES || renumbered_clips[aclip_index[i + 1]] < 1 ||
21389 !
mainw->
files[renumbered_clips[aclip_index[i + 1]]]) && aseek_index[i + 1] != 0.) {
21391 ebuf = rec_error_add(ebuf,
"Invalid audio clip number", aclip_index[i + 1], tc);
21392 missing_clips =
TRUE;
21394 new_aclip_index[j] = aclip_index[i];
21395 new_aclip_index[j + 1] = aclip_index[i + 1];
21396 new_aseek_index[j] = aseek_index[i];
21397 new_aseek_index[j + 1] = aseek_index[i + 1];
21398 if (aseek_index[j + 1] != 0.) add_atrack_to_list(aclip_index[i], aclip_index[i + 1]);
21399 else remove_atrack_from_list(aclip_index[i]);
21403 if (aclip_index[i] > -1) {
21404 if (mt && !mt->opts.pertrack_audio) {
21405 mt->opts.pertrack_audio =
TRUE;
21408 ebuf = rec_error_add(ebuf,
"Adding pertrack audio", -1, tc);
21409 }
else force_pertrack_audio =
TRUE;
21412 if (aclip_index[i] == -1) {
21413 if (mt && mt->opts.back_audio_tracks == 0) {
21414 mt->opts.back_audio_tracks = 1;
21415 ebuf = rec_error_add(ebuf,
"Adding backing audio", -1, tc);
21416 }
else force_backing_tracks = 1;
21436 case WEED_EVENT_TYPE_MARKER:
21439 ebuf = rec_error_add(ebuf,
"Unknown marker type", -1, tc);
21441 was_deleted =
TRUE;
21446 ebuf = rec_error_add(ebuf,
"Unknown marker type", marker_type, tc);
21448 was_deleted =
TRUE;
21451 ebuf = rec_error_add(ebuf,
"Block start marker has no tracks", -1, tc);
21453 was_deleted =
TRUE;
21458 ebuf = rec_error_add(ebuf,
"Invalid event_type", event_type, tc);
21460 was_deleted =
TRUE;
21462 if (!was_deleted && check_filter_map && last_filter_map
21465 ebuf = filter_map_check(trans_table, last_filter_map, last_deinit_tc, tc, ebuf);
21466 check_filter_map =
FALSE;
21468 event = event_next;
21470 if (!was_deleted && fps != 0.) {
21471 while (cur_tc < last_frame_tc) {
21475 shortcut = duplicate_frame_at(event_list, shortcut, cur_tc);
21476 ebuf = rec_error_add(ebuf,
"Duplicated frame at", -1, cur_tc);
21479 ebuf = rec_error_add(ebuf,
"Inserted missing blank frame", -1, cur_tc);
21495 ebuf = add_filter_deinits(event_list, trans_table, pchains, last_tc, ebuf);
21498 if (last_filter_map) ebuf = add_null_filter_map(event_list, last_filter_map, last_tc, ebuf);
21506 ebuf = rec_error_add(ebuf,
"Removed final blank frames", -1, last_tc);
21513 last_frame_tc = last_filter_map_tc = -1;
21514 last_frame_event = NULL;
21522 switch (event_type) {
21523 case WEED_EVENT_TYPE_FILTER_INIT:
21525 if (weed_plant_has_leaf(event, WEED_LEAF_IN_PARAMETERS)) {
21526 uint64_t *pin_params;
21528 num_params = weed_leaf_num_elements(event, WEED_LEAF_IN_PARAMETERS);
21530 if (weed_leaf_seed_type(event, WEED_LEAF_IN_PARAMETERS) == WEED_SEED_INT64) {
21531 pin_params = (uint64_t *)weed_get_int64_array(event, WEED_LEAF_IN_PARAMETERS, NULL);
21532 nin_params = (
void **)
lives_malloc(num_params *
sizeof(
void *));
21533 for (i = 0; i < num_params; i++) {
21534 nin_params[i] = (
void *)pin_params[i];
21537 weed_leaf_delete(event, WEED_LEAF_IN_PARAMETERS);
21538 weed_set_voidptr_array(event, WEED_LEAF_IN_PARAMETERS, num_params, nin_params);
21553 if (mt && event != mt->avol_init_event) {
21557 case WEED_EVENT_TYPE_PARAM_CHANGE:
21560 case WEED_EVENT_TYPE_FILTER_DEINIT:
21565 case WEED_EVENT_TYPE_FILTER_MAP:
21566 if (last_filter_map_tc == tc) {
21568 ebuf = rec_error_add(ebuf,
"Duplicate filter maps", -1, tc);
21571 last_filter_map_tc = tc;
21572 last_filter_map = event;
21574 case WEED_EVENT_TYPE_FRAME:
21575 last_frame_tc = tc;
21576 last_filter_map_tc = -1;
21577 last_frame_event = event;
21581 if (last_frame_event)
event = last_frame_event;
21583 }
else event = event_next;
21586 ebuf = add_missing_atrack_closers(event_list, fps, ebuf);
21588 if (missing_clips && missing_frames) {
21589 bit2 = (
_(
"clips and frames"));
21591 if (missing_clips) {
21592 bit2 = (
_(
"clips"));
21593 }
else if (missing_frames) {
21594 bit2 = (
_(
"frames"));
21601 if (mt && mt->auto_reloading) {
21604 bit1 = (
_(
"\nAuto reload layout.\n"));
21607 msg =
lives_strdup_printf(
_(
"%s\nSome %s are missing from the layout%s\nTherefore it could not be loaded properly.\n"),
21612 if (mt) mt->layout_prompt =
TRUE;
21625 LiVESWidget *ar_checkbutton;
21627 boolean needs_idlefunc =
FALSE;
21628 boolean did_backup = mt->did_backup;
21634 char *startdir = NULL;
21637 LIVES_ERROR(
"Loading event list for unknown set");
21650 startdir = lives_strdup(eload_dir);
21654 if (allow_auto_reload) {
21656 lives_signal_sync_connect(LIVES_GUI_OBJECT(ar_checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
21661 if (mt->idlefunc > 0) {
21664 needs_idlefunc =
TRUE;
21669 eload_file =
choose_file(startdir, NULL, filt, LIVES_FILE_CHOOSER_ACTION_OPEN, NULL, hbox);
21683 if (needs_idlefunc || (!did_backup && mt->auto_changed))
21697 weed_plant_t *event_list = NULL;
21702 boolean free_eload_file =
TRUE;
21704 boolean retval =
TRUE;
21705 boolean needs_idlefunc =
FALSE;
21707 int num_events = 0;
21713 old_avol_fx = mt->avol_fx;
21714 if (mt->idlefunc > 0) {
21717 needs_idlefunc =
TRUE;
21724 if (needs_idlefunc) mt->idlefunc =
mt_idle_add(mt);
21727 }
else free_eload_file =
FALSE;
21733 else eload_name = (
_(
"auto backup"));
21740 if (needs_idlefunc) mt->idlefunc =
mt_idle_add(mt);
21753 mt->event_list = NULL;
21758 d_print(
_(
"Loading layout from %s..."), eload_name);
21766 if ((event_list = load_event_list_inner(mt, fd, mt != NULL, &num_events, NULL, NULL)) == NULL) {
21769 if (
THREADVAR(read_failed) == fd + 1) {
21775 if (mt && retval != LIVES_RESPONSE_RETRY) {
21778 if (needs_idlefunc) mt->idlefunc =
mt_idle_add(mt);
21785 renumber_from_backup_layout_numbering(NULL);
21796 }
while (retval == LIVES_RESPONSE_RETRY);
21802 d_print(
_(
"Got %d events...processing..."), num_events);
21807 cfile->progress_start = 1;
21808 cfile->progress_end = num_events;
21818 rerenumber_clips(eload_file, NULL);
21820 renumber_from_backup_layout_numbering(mt);
21823 mt->avol_init_event = NULL;
21837 d_print(
_(
"%d errors detected.\n"), elist_errors);
21838 if (!mt->auto_reloading) {
21851 if (fd < 0 || !retval) {
21855 }
while (retval2 == LIVES_RESPONSE_RETRY);
21860 mt->layout_prompt =
FALSE;
21868 if (mt->avol_fx != old_avol_fx && mt->opts.aparam_view_list) {
21870 lives_list_free(mt->opts.aparam_view_list);
21871 mt->opts.aparam_view_list = NULL;
21876 lives_snprintf(mt->layout_name,
PATH_MAX,
"%s", eload_file);
21880 if (mt->layout_set_properties) msg = mt_set_vals_string();
21901 set_audio_filter_channel_values(mt);
21904 if (mt->opts.back_audio_tracks > 0) {
21908 if (free_eload_file)
lives_free(eload_file);
21914 return (event_list);
21920 weed_plant_t *event_next;
21931 event = event_next;
21939 if (mt->idlefunc > 0) {
21959 mt->event_list = NULL;
21972 lives_mt *mt = (lives_mt *)user_data;
21977 boolean rev_resp =
FALSE;
21979 if (mt->idlefunc > 0) {
21984 if (*mt->layout_name) {
22000 if (resp == 2 && rev_resp) {
22005 }
while (resp == 2 && rev_resp);
22010 if (resp == LIVES_RESPONSE_CANCEL) {
22015 if (resp == 2 && !rev_resp) {
22019 if (!
do_yesno_dialog(
"\nLayout will be deleted from the disk.\nAre you sure ?\n")) {
22032 _(
"The current layout has changes which have not been saved.\nAre you sure you wish to wipe it ?\n"),
22047 lives_mt *mt = (lives_mt *)user_data;
22048 weed_plant_t *new_event_list;
22053 if (mt->idlefunc > 0) {
22062 if (!new_event_list) {
22069 mt->event_list = NULL;
22071 mt->undo_buffer_used = 0;
22072 mt->undo_offset = 0;
22073 lives_list_free(mt->undos);
22078 for (i = 0; i < mt->num_video_tracks; i++) {
22081 lives_list_free(mt->video_draws);
22082 mt->video_draws = NULL;
22083 mt->num_video_tracks = 0;
22088 mt->audio_draws = NULL;
22090 if (mt->audio_vols) lives_list_free(mt->audio_vols);
22091 mt->audio_vols = NULL;
22093 mt->event_list = new_event_list;
22095 if (mt->selected_tracks) lives_list_free(mt->selected_tracks);
22096 mt->selected_tracks = NULL;
22100 if (!mt->ignore_load_vals) set_audio_mixer_vols(mt, mt->event_list);
22132 weed_plant_t *event_list;
22134 boolean retval =
TRUE;
22136 char *changefrom = NULL;
22139 if (old_set_name) {
22141 chlen = strlen(changefrom);
22145 if (old_set_name) {
22151 if ((event_list = load_event_list_inner(NULL, fd,
FALSE, NULL, NULL, NULL)) != NULL) {
22165 if (fd < 0 || !retval) {
22169 }
while (retval2 == LIVES_RESPONSE_RETRY);
22177 }
while (retval2 == LIVES_RESPONSE_RETRY);
22180 if (old_set_name && !
lives_strncmp((
char *)map->data, changefrom, chlen)) {
22183 if (lives_file_test(tmp, LIVES_FILE_TEST_EXISTS)) {
22187 prefs->
workdir, new_set_name, old_set_name, (
char *)map->data + chlen);
22188 lives_mv((
const char *)map->data, tmp);
22203 if ((old_set_name && !
lives_strncmp((
char *)map->data, changefrom, chlen)) ||
22204 (!old_set_name && (strstr((
char *)map->data, new_set_name) == NULL))) {
22206 char **array = lives_strsplit((
char *)map->data,
"|", -1);
22207 size_t origlen = strlen(array[0]);
22209 if (lives_file_test(tmp2, LIVES_FILE_TEST_EXISTS)) {
22211 prefs->
workdir, new_set_name, old_set_name, array[0] + chlen);
22215 lives_strfreev(array);
22228 if ((old_set_name && !
lives_strncmp((
char *)map->data, changefrom, chlen)) ||
22229 (!old_set_name && (strstr((
char *)map->data, new_set_name) == NULL))) {
22232 if (lives_file_test(tmp, LIVES_FILE_TEST_EXISTS)) {
22235 prefs->
workdir, new_set_name, old_set_name, (
char *)map->data + chlen);
22254 int resampled_frame;
22260 if (start <= resampled_frame && (end == 0 || end >= resampled_frame))
22265 array = lives_strsplit((
char *)lmap->data,
"|", -1);
22266 if (atoi(array[2]) != 0) {
22267 orig_fps = strtod(array[3], NULL);
22269 if (array[2] == 0) resampled_frame = 0;
22270 if (start <= resampled_frame && (end == 0 || end >= resampled_frame))
22273 lives_strfreev(array);
22295 (etime == 0. || etime <= mainw->files[clipno]->stored_layout_audio))
22301 array = lives_strsplit((
char *)lmap->data,
"|", -1);
22302 max_time = strtod(array[4], NULL);
22303 if (max_time > 0. && stime <= max_time && (etime == 0. || etime <= mainw->files[clipno]->stored_layout_audio)) {
22306 lives_strfreev(array);
22315 lives_mt *mt = (lives_mt *)user_data;
22331 LiVESWidget *dialog;
22332 lives_mt *mt = (lives_mt *)user_data;
22341 lives_mt *mt = (lives_mt *)user_data;
22342 mt->ignore_load_vals = !mt->ignore_load_vals;
22346static void mt_ac_audio_toggled(LiVESMenuItem * menuitem, livespointer user_data) {
22347 lives_mt *mt = (lives_mt *)user_data;
22348 mt->opts.autocross_audio = !mt->opts.autocross_audio;
22353 lives_mt *mt = (lives_mt *)user_data;
22380 xachans = xarate = xasamps = 0;
22384 if (response == LIVES_RESPONSE_CANCEL) {
22392 if (xachans == 0 && mt->audio_draws) {
22393 LiVESList *slist = mt->audio_draws;
22395 if (lives_widget_object_get_data(LIVES_WIDGET_OBJECT(slist->data),
"blocks")) {
22403 slist = slist->next;
22440 mt->user_arate = xarate;
22441 mt->user_achans = xachans;
22442 mt->user_asamps = xasamps;
22443 mt->user_signed_endian = xse;
22459 mt->audio_draws = NULL;
22463 if (mt->audio_vols) lives_list_free(mt->audio_vols);
22464 mt->audio_vols = NULL;
22471 if (mt->current_track >= 0) {
22475 mt->auto_changed =
TRUE;
22477 mt->changed =
TRUE;
22481static uint32_t event_list_get_byte_size(lives_mt * mt, weed_plant_t *event_list,
boolean nxprev,
int *num_events) {
22489 int tot_events = 0;
22500 leaves = weed_plant_list_leaves(event, NULL);
22502 for (i = 0; leaves[i]; i++) {
22507 tot += 4 * 3 + strlen(leaves[i]);
22508 ne = weed_leaf_num_elements(event, leaves[i]);
22509 st = weed_leaf_seed_type(event, leaves[i]);
22511 for (j = 0; j < ne; j++) tot += 4 + (st > 64 ? 8 : weed_leaf_element_size(event, leaves[i], j));
22518 event = event_list;
22519 leaves = weed_plant_list_leaves(event, NULL);
22521 for (i = 0; leaves[i]; i++) {
22522 tot += 4 * 3 + strlen(leaves[i]);
22523 ne = weed_leaf_num_elements(event, leaves[i]);
22524 st = weed_leaf_seed_type(event, leaves[i]);
22526 for (j = 0; j < ne; j++) tot += 4 + (st > 64 ? 8 : weed_leaf_element_size(event, leaves[i], j));
22531 if (num_events) *num_events = tot_events;
22537 lives_amixer_t *amixer = mt->amixer;
22546 for (
int i = 0; i < amixer->nchans; i++) {
22549 val = giw_vslider_get_value(GIW_VSLIDER(amixer->ch_sliders[i]));
22566 if (mt->audio_vols_back) lives_list_free(mt->audio_vols_back);
22571static void on_amixer_reset_clicked(LiVESButton * button, lives_mt * mt) {
22572 lives_amixer_t *amixer = mt->amixer;
22582 for (i = 0; i < amixer->nchans; i++) {
22583 float val = (float)LIVES_POINTER_TO_INT(lives_list_nth_data(mt->audio_vols_back, i)) /
LIVES_AVOL_SCALE;
22589 giw_vslider_set_value(GIW_VSLIDER(amixer->ch_sliders[i]), val);
22605static void after_amixer_gang_toggled(LiVESToggleButton * toggle, lives_amixer_t *amixer) {
22611 lives_amixer_t *amixer = mt->amixer;
22612 int layer = LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(adj),
"layer"));
22620 GiwVSlider *slider = GIW_VSLIDER(amixer->ch_sliders[layer]);
22621 val = giw_vslider_get_value(slider);
22625 LiVESRange *range = LIVES_RANGE(amixer->ch_sliders[layer]);
22634 for (i = mt->opts.back_audio_tracks; i < amixer->nchans; i++) {
22638 giw_vslider_set_value(GIW_VSLIDER(amixer->ch_sliders[i]), val);
22649 if (inv && mt->opts.back_audio_tracks > 0) {
22653 giw_vslider_set_value(GIW_VSLIDER(amixer->ch_sliders[0]), 1. - val < 0. ? 0. : 1. - val);
22666 for (i = 1; i < amixer->nchans; i++) {
22670 giw_vslider_set_value(GIW_VSLIDER(amixer->ch_sliders[i]), 1. - val < 0. ? 0. : 1. - val);
22672 amixer->ch_slider_fns[i]);
22678 amixer->ch_slider_fns[i]);
22686 if (!mt->is_rendering) {
22698 LiVESWidgetObject *adj;
22699 LiVESWidget *spinbutton;
22700 LiVESWidget *label;
22702 lives_amixer_t *amixer = mt->amixer;
22705 i += mt->opts.back_audio_tracks;
22711 amixer->ch_sliders[i] = giw_vslider_new(LIVES_ADJUSTMENT(adj));
22712 giw_vslider_set_legends_digits(GIW_VSLIDER(amixer->ch_sliders[i]), 1);
22713 giw_vslider_set_major_ticks_number(GIW_VSLIDER(amixer->ch_sliders[i]), 5);
22714 giw_vslider_set_minor_ticks_number(GIW_VSLIDER(amixer->ch_sliders[i]), 4);
22728 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(amixer->ch_sliders[i]),
"adj", adj);
22729 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(adj),
"layer", LIVES_INT_TO_POINTER(i));
22731 amixer->ch_slider_fns[i] = lives_signal_sync_connect_after(LIVES_GUI_OBJECT(adj), LIVES_WIDGET_VALUE_CHANGED_SIGNAL,
22742 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(amixer->ch_sliders[i]),
"label", label);
22749 gtk_spin_button_set_adjustment(LIVES_SPIN_BUTTON(spinbutton), LIVES_ADJUSTMENT(adj));
22758 lives_mt *mt = (lives_mt *)user_data;
22759 LiVESWidget *amixerw;
22760 LiVESWidget *top_vbox;
22762 LiVESWidget *vbox2;
22764 LiVESWidget *hbuttonbox;
22765 LiVESWidget *scrolledwindow;
22766 LiVESWidget *label;
22767 LiVESWidget *filler;
22768 LiVESWidget *eventbox;
22769 LiVESWidget *close_button;
22770 LiVESWidget *reset_button;
22773 lives_amixer_t *amixer;
22775 int nachans = lives_list_length(mt->audio_draws);
22782 if (nachans == 0)
return;
22789 mt->audio_vols_back = lives_list_copy(mt->audio_vols);
22791 amixer = mt->amixer = (lives_amixer_t *)
lives_malloc(
sizeof(lives_amixer_t));
22792 amixer->nchans = 0;
22794 amixer->ch_sliders = (LiVESWidget **)
lives_malloc(nachans *
sizeof(LiVESWidget *));
22829 LIVES_RESPONSE_RESET);
22834 LIVES_RESPONSE_OK);
22842 LIVES_KEY_m, LIVES_CONTROL_MASK,
22843 (LiVESAccelFlags)0);
22847 if (mt->opts.back_audio_tracks > 0) {
22863#if GTK_CHECK_VERSION(3, 0, 0)
22864 lives_signal_sync_connect(LIVES_GUI_OBJECT(amixer->inv_checkbutton), LIVES_WIDGET_EXPOSE_EVENT,
22871 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(amixer->inv_checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
22879 if (mt->opts.back_audio_tracks > 0 && mt->opts.pertrack_audio) {
22888 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
22890 amixer->inv_checkbutton);
22906#if GTK_CHECK_VERSION(3, 0, 0)
22907 lives_signal_sync_connect(LIVES_GUI_OBJECT(amixer->gang_checkbutton), LIVES_WIDGET_EXPOSE_EVENT,
22915 if (mt->opts.pertrack_audio) {
22923 lives_signal_sync_connect(LIVES_GUI_OBJECT(eventbox), LIVES_WIDGET_BUTTON_PRESS_EVENT,
22925 amixer->gang_checkbutton);
22942 for (
register int i = 0; i < nachans - mt->opts.back_audio_tracks; i++) {
22947 lives_signal_sync_connect(LIVES_GUI_OBJECT(close_button), LIVES_WIDGET_CLICKED_SIGNAL,
22951 lives_signal_sync_connect(LIVES_GUI_OBJECT(reset_button), LIVES_WIDGET_CLICKED_SIGNAL,
22952 LIVES_GUI_CALLBACK(on_amixer_reset_clicked),
22956 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
22958 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(amixer->gang_checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
22959 LIVES_GUI_CALLBACK(after_amixer_gang_toggled),
22960 (livespointer)amixer);
22961 lives_signal_sync_connect_after(LIVES_GUI_OBJECT(amixer->gang_checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
22966 after_amixer_gang_toggled(LIVES_TOGGLE_BUTTON(amixer->gang_checkbutton), amixer);
22970 on_amixer_reset_clicked(NULL, mt);
22982 LiVESWidget *eventbox = NULL;
22985 eventbox = (LiVESWidget *)lives_list_nth_data(mt->video_draws, ntrack);
22987 eventbox = (LiVESWidget *)lives_list_nth_data(mt->audio_draws, 1 - ntrack);
22994static track_rect *get_nth_block_for_track(lives_mt * mt,
int itrack,
int iblock) {
22998 if (!eventbox)
return NULL;
22999 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
23001 if (count == iblock)
return block;
23002 block = block->next;
23016 if (!mt || uid == 0l)
return NULL;
23018 list = mt->video_draws;
23021 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(list->data),
"blocks");
23023 if (block->uid == uid)
return block;
23024 block = block->next;
23028 list = mt->audio_draws;
23031 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(list->data),
"blocks");
23033 if (block->uid == uid)
return block;
23034 block = block->next;
23043 if (ntrack >= 0 && mt->video_draws && ntrack < lives_list_length(mt->video_draws))
return TRUE;
23049 if (ntrack <= 0 && mt->audio_draws && ntrack >= -(lives_list_length(mt->audio_draws)))
return TRUE;
23055 int track = mt->current_track;
23056 track_rect *lastblock;
23058 if (!eventbox)
return 0l;
23059 lastblock = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
23060 if (!lastblock)
return 0l;
23061 return lastblock->uid;
23067 track_rect *block, *lastblock;
23069 if (!eventbox)
return -1;
23070 lastblock = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"block_last");
23071 if (!lastblock)
return -1;
23072 block = (track_rect *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(eventbox),
"blocks");
23074 if (block == lastblock)
break;
23075 block = block->next;
23085 track_rect *block = get_nth_block_for_track(mt, ntrack, iblock);
23086 if (!block)
return -1;
23093 track_rect *block = get_nth_block_for_track(mt, ntrack, iblock);
23094 if (!block)
return -1;
23101 if (!mt)
return NULL;
23103 return get_block_from_time(ebox, time, mt);
23109 if (!block)
return -1;
23122 track_rect *oblock = NULL;
23123 weed_timecode_t sttc, endtc = 0;
23125 weed_plant_t **ptmpls;
23126 weed_plant_t **oparams;
23128 weed_plant_t *stevent, *enevent;
23129 weed_plant_t *filter;
23131 weed_plant_t *old_mt_init = mt->init_event;
23135 double region_start = mt->region_start;
23136 double region_end = mt->region_end;
23138 boolean did_backup =
FALSE;
23140 int nvids = lives_list_length(mt->video_draws);
23141 int current_fx = mt->current_fx;
23150 if (!block)
return;
23156 if (tparam == -1)
return;
23159 ptm = ptmpls[tparam];
23170 slist = lives_list_copy(mt->selected_tracks);
23172 if (mt->selected_tracks) {
23173 lives_list_free(mt->selected_tracks);
23174 mt->selected_tracks = NULL;
23177 for (i = 0; i < nvids; i++) {
23178 if (i == track)
continue;
23179 oblock = get_block_from_time((LiVESWidget *)lives_list_nth_data(mt->video_draws, i),
23186 }
else oblock = NULL;
23190 mt->is_atrans =
TRUE;
23193 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(track));
23194 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(i));
23202 oparams = (weed_plant_t **)weed_get_voidptr_array_counted(mt->init_event, WEED_LEAF_IN_PARAMETERS, &nparams);
23204 for (i = 0; i < nparams; i++) {
23205 if (weed_get_int_value(oparams[i],
WEED_LEAF_INDEX, NULL) == tparam)
break;
23208 stevent = oparams[i];
23210 enevent = weed_plant_new(WEED_PLANT_EVENT);
23211 weed_set_int_value(enevent, WEED_LEAF_EVENT_TYPE, WEED_EVENT_TYPE_PARAM_CHANGE);
23212 weed_set_int64_value(enevent, WEED_LEAF_TIMECODE, endtc);
23222 if (param_type == WEED_PARAM_INTEGER) {
23223 int min = weed_get_int_value(ptm, WEED_LEAF_MIN, NULL);
23224 int max = weed_get_int_value(ptm, WEED_LEAF_MAX, NULL);
23225 weed_set_int_value(stevent, WEED_LEAF_VALUE, i < track ? min : max);
23226 weed_set_int_value(enevent, WEED_LEAF_VALUE, i < track ? max : min);
23228 double min = weed_get_double_value(ptm, WEED_LEAF_MIN, NULL);
23229 double max = weed_get_double_value(ptm, WEED_LEAF_MAX, NULL);
23230 weed_set_double_value(stevent, WEED_LEAF_VALUE, i < track ? min : max);
23231 weed_set_double_value(enevent, WEED_LEAF_VALUE, i < track ? max : min);
23243 if (mt->selected_tracks) {
23244 lives_list_free(mt->selected_tracks);
23245 mt->selected_tracks = NULL;
23248 for (i = 0; i < nvids; i++) {
23249 if (i == track)
continue;
23250 oblock = get_block_from_time((LiVESWidget *)lives_list_nth_data(mt->video_draws, i),
23261 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(track));
23262 mt->selected_tracks = lives_list_append(mt->selected_tracks, LIVES_INT_TO_POINTER(i));
23270 oparams = (weed_plant_t **)weed_get_voidptr_array_counted(mt->init_event, WEED_LEAF_IN_PARAMETERS, &nparams);
23272 for (i = 0; i < nparams; i++) {
23273 if (weed_get_int_value(oparams[i],
WEED_LEAF_INDEX, NULL) == tparam)
break;
23276 stevent = oparams[i];
23278 enevent = weed_plant_new(WEED_PLANT_EVENT);
23279 weed_set_int_value(enevent, WEED_LEAF_EVENT_TYPE, WEED_EVENT_TYPE_PARAM_CHANGE);
23290 if (param_type == WEED_PARAM_INTEGER) {
23291 int min = weed_get_int_value(ptm, WEED_LEAF_MIN, NULL);
23292 int max = weed_get_int_value(ptm, WEED_LEAF_MAX, NULL);
23293 weed_set_int_value(stevent, WEED_LEAF_VALUE, i < track ? max : min);
23294 weed_set_int_value(enevent, WEED_LEAF_VALUE, i < track ? min : max);
23296 double min = weed_get_double_value(ptm, WEED_LEAF_MIN, NULL);
23297 double max = weed_get_double_value(ptm, WEED_LEAF_MAX, NULL);
23298 weed_set_double_value(stevent, WEED_LEAF_VALUE, i < track ? max : min);
23299 weed_set_double_value(enevent, WEED_LEAF_VALUE, i < track ? min : max);
23307 if (mt->init_event && mt->opts.autocross_audio)
23310 mt->is_atrans =
FALSE;
23311 mt->region_start = region_start;
23312 mt->region_end = region_end;
23313 lives_list_free(mt->selected_tracks);
23314 mt->selected_tracks = lives_list_copy(slist);
23315 if (slist) lives_list_free(slist);
23316 mt->current_fx = current_fx;
23317 mt->init_event = old_mt_init;
23321 mt->changed = mt->auto_changed =
TRUE;
23322 mt->did_backup = did_backup;
LIVES_GLOBAL_INLINE char * get_achannel_name(int totchans, int idx)
float get_float_audio_val_at_time(int fnum, int afd, double secs, int chnum, int chans)
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
lives_audio_track_state_t * get_audio_and_effects_state_at(weed_plant_t *event_list, weed_plant_t *st_event, weed_timecode_t fill_tc, int what_to_get, boolean exact)
get audio (and optionally video) state at timecode tc OR before event st_event
#define lives_vol_to_linear(vol)
#define is_realtime_aplayer(ptype)
#define lives_vol_from_linear(vol)
void on_boolean_toggled(LiVESWidgetObject *obj, livespointer user_data)
void email_author_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_rewind_activate(LiVESMenuItem *menuitem, livespointer user_data)
void suggest_feature_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_sepwin_activate(LiVESMenuItem *menuitem, livespointer user_data)
boolean config_event(LiVESWidget *widget, LiVESXEventConfigure *event, livespointer user_data)
void on_open_activate(LiVESMenuItem *menuitem, livespointer user_data)
void show_manual_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_show_file_info_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_open_vcd_activate(LiVESMenuItem *menuitem, livespointer device_type)
void help_translate_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_show_messages_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_mute_activate(LiVESMenuItem *menuitem, livespointer user_data)
void donate_activate(LiVESMenuItem *menuitem, livespointer user_data)
void popup_lmap_errors(LiVESMenuItem *menuitem, livespointer user_data)
boolean all_expose(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
void on_open_loc_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_open_utube_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_preview_clicked(LiVESButton *button, livespointer user_data)
boolean on_mouse_scroll(LiVESWidget *widget, LiVESXEventScroll *event, livespointer user_data)
void on_full_screen_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_loop_cont_activate(LiVESMenuItem *menuitem, livespointer user_data)
LIVES_GLOBAL_INLINE void lives_notify_int(int msgnumber, int msgint)
void on_quit_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_about_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_cleardisk_activate(LiVESWidget *widget, livespointer user_data)
boolean freeze_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
void on_close_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_playall_activate(LiVESMenuItem *menuitem, livespointer user_data)
void report_bug_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_capture_activate(LiVESMenuItem *menuitem, livespointer user_data)
char * on_load_set_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_open_sel_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_stop_activate(LiVESMenuItem *menuitem, livespointer user_data)
EXPOSE_FN_PROTOTYPE(expose_vid_event)
void on_resample_vid_ok(LiVESButton *, LiVESEntry *entry)
LIVES_GLOBAL_INLINE weed_layer_t * lives_layer_new_for_frame(int clip, frames_t frame)
LiVESPixbuf * layer_to_pixbuf(weed_layer_t *layer, boolean realpalette, boolean fordisplay)
boolean letterbox_layer(weed_layer_t *layer, int nwidth, int nheight, int width, int height, LiVESInterpType interp, int tpal, int tclamp)
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)
LIVES_GLOBAL_INLINE boolean gamma_convert_layer(int gamma_type, weed_layer_t *layer)
LIVES_GLOBAL_INLINE boolean lives_pixbuf_is_all_black(LiVESPixbuf *pixbuf)
LIVES_GLOBAL_INLINE boolean weed_palette_has_alpha(int pal)
boolean resize_layer(weed_layer_t *layer, int width, int height, LiVESInterpType interp, int opal_hint, int oclamp_hint)
resize a layer
double get_luma16(uint16_t r, uint16_t g, uint16_t b)
LIVES_GLOBAL_INLINE int weed_layer_get_width_pixels(weed_layer_t *layer)
LIVES_GLOBAL_INLINE int weed_layer_get_palette(weed_layer_t *layer)
boolean convert_layer_palette_full(weed_layer_t *layer, int outpl, int oclamping, int osampling, int osubspace, int tgamma)
convert the palette of a layer
#define WEED_GAMMA_MONITOR
frames_t virtual_to_images(int sfileno, frames_t sframe, frames_t eframe, boolean update_progress, LiVESPixbuf **pbr)
boolean is_virtual_frame(int sfileno, frames_t frame)
boolean do_yesno_dialog(const char *text)
boolean do_header_write_error(int clip)
LIVES_GLOBAL_INLINE void do_mt_undo_buf_error(void)
LiVESResponseType do_read_failed_error_s_with_retry(const char *fname, const char *errtext)
void do_threaded_dialog(const char *trans_text, boolean has_cancel)
LIVES_GLOBAL_INLINE void do_mt_no_jack_error(int warn_mask)
LIVES_GLOBAL_INLINE boolean do_mt_rect_prompt(void)
LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext)
LIVES_GLOBAL_INLINE void do_mt_audchan_error(int warn_mask)
LIVES_GLOBAL_INLINE void do_mt_no_audchan_error(void)
void end_threaded_dialog(void)
LIVES_GLOBAL_INLINE boolean do_event_list_warning(void)
LIVES_GLOBAL_INLINE void do_mt_backup_space_error(lives_mt *mt, int memreq_mb)
LIVES_GLOBAL_INLINE void do_after_crash_warning(void)
LiVESResponseType handle_backend_errors(boolean can_retry)
boolean do_mt_lb_warn(boolean lb)
LIVES_GLOBAL_INLINE void do_mt_undo_mem_error(void)
LIVES_GLOBAL_INLINE void do_bad_layout_error(void)
void do_read_failed_error_s(const char *s, const char *addinfo)
LIVES_GLOBAL_INLINE void do_layout_ascrap_file_error(void)
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
void threaded_dialog_spin(double fraction)
boolean check_storage_space(int clipno, boolean is_processing)
boolean do_yesno_dialog_with_check(const char *text, uint64_t warn_mask_number)
LIVES_GLOBAL_INLINE void do_layout_scrap_file_error(void)
char * make_weed_hashname(int filter_idx, boolean fullname, boolean use_extra_authors, char sep, boolean subs)
return value should be freed after use
int rte_get_numfilters(void)
int enabled_out_channels(weed_plant_t *plant, boolean count_repeats)
boolean has_video_chans_in(weed_plant_t *filter, boolean count_opt)
void weed_generator_end(weed_plant_t *inst)
boolean is_perchannel_multiw(weed_plant_t *param)
boolean has_perchannel_multiw(weed_plant_t *filter)
weed_plant_t * rte_keymode_get_instance(int key, int mode)
returns refcounted filter_instance bound to key/mode (or NULL)
weed_plant_t * weed_plant_deserialise(int fd, unsigned char **mem, weed_plant_t *plant)
char * weed_filter_idx_get_name(int idx, boolean add_subcats, boolean add_notes)
void deinit_render_effects(void)
switch off effects after render preview during rendering/render preview, we use the "keys" FX_KEYS_MA...
int weed_get_idx_for_hashname(const char *hashname, boolean fullname)
fullname includes author and version
void fill_param_vals_to(weed_plant_t *param, weed_plant_t *paramtmpl, int index)
for a multi valued parameter or pchange, we will fill WEED_LEAF_VALUE up to element index with WEED_L...
boolean interpolate_params(weed_plant_t *inst, void **pchains, weed_timecode_t tc)
interpolate all in_parameters for filter_instance inst, using void **pchain, which is an array of par...
size_t weed_plant_serialise(int fd, weed_plant_t *plant, unsigned char **mem)
int num_in_params(weed_plant_t *plant, boolean skip_hidden, boolean skip_internal)
boolean is_audio_channel_in(weed_plant_t *inst, int chnum)
void backup_weed_instances(void)
for multitrack
weed_plant_t ** weed_params_create(weed_plant_t *filter, boolean in)
int enabled_in_channels(weed_plant_t *plant, boolean count_repeats)
boolean has_non_alpha_palette(weed_plant_t *ctmpl, weed_plant_t *filter)
void restore_weed_instances(void)
char * weed_filter_idx_get_package_name(int idx)
boolean has_video_chans_out(weed_plant_t *filter, boolean count_opt)
LIVES_GLOBAL_INLINE int weed_instance_unref(weed_plant_t *inst)
weed_plant_t * get_weed_filter(int idx)
int get_transition_param(weed_plant_t *filter, boolean skip_internal)
weed_plant_t * weed_inst_in_param(weed_plant_t *inst, int param_num, boolean skip_hidden, boolean skip_internal)
LIVES_GLOBAL_INLINE int weed_get_sorted_filter(int i)
boolean is_pure_audio(weed_plant_t *plant, boolean count_opt)
TRUE if audio in or out and no vid in/out.
weed_plant_t * weed_instance_from_filter(weed_plant_t *filter)
lives_filter_error_t weed_reinit_effect(weed_plant_t *inst, boolean reinit_compound)
#define WEED_LEAF_HOST_TAG
#define WEED_LEAF_HOST_DEFAULT
#define WEED_LEAF_HOST_MENU_HIDE
char * lives_fx_cat_to_text(lives_fx_cat_t cat, boolean plural)
@ LIVES_FX_CAT_COMPOSITOR
@ LIVES_FX_CAT_VIDEO_EFFECT
@ LIVES_FX_CAT_TRANSITION
@ LIVES_FX_CAT_AUDIO_TRANSITION
@ LIVES_FX_CAT_AUDIO_EFFECT
@ LIVES_FX_CAT_VIDEO_TRANSITION
@ LIVES_FX_CAT_AV_TRANSITION
void remove_audio_for_track(weed_plant_t *event, int track)
int get_audio_frame_clip(weed_plant_t *event, int track)
returns clip number for track (track==-1 is backing audio)
double get_audio_frame_seek(weed_plant_t *event, int track)
returns velocity for track (track==-1 is backing audio)
boolean has_frame_event_at(weed_plant_t *event_list, weed_timecode_t tc, weed_plant_t **shortcut)
void insert_filter_init_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event)
void add_init_event_to_filter_map(weed_plant_t *fmap, weed_plant_t *event, void **hints)
void add_track_to_avol_init(weed_plant_t *filter, weed_plant_t *event, int nbtracks, boolean behind)
boolean init_event_is_process_last(weed_plant_t *event)
weed_plant_t * append_filter_map_event(weed_plant_t *event_list, weed_timecode_t tc, void **init_events)
void backup_host_tags(weed_plant_t *event_list, weed_timecode_t curr_tc)
void insert_filter_deinit_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event)
weed_plant_t * get_last_frame_event(weed_plant_t *event_list)
void delete_event(weed_plant_t *event_list, weed_plant_t *event)
void unlink_event(weed_plant_t *event_list, weed_plant_t *event)
weed_plant_t * get_prev_frame_event(weed_plant_t *event)
double event_list_get_end_secs(weed_plant_t *event_list)
void ** get_init_events_before(weed_plant_t *event, weed_plant_t *init_event, boolean add)
void insert_param_change_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event)
boolean move_event_right(weed_plant_t *event_list, weed_plant_t *event, boolean can_stay, double fps)
boolean render_to_clip(boolean new_clip, boolean transcode)
rendering
boolean filter_init_has_owner(weed_plant_t *init_event, int track)
LIVES_GLOBAL_INLINE weed_timecode_t weed_event_get_timecode(weed_event_t *event)
frames_t get_frame_event_frame(weed_plant_t *event, int layer)
int get_frame_event_clip(weed_plant_t *event, int layer)
LIVES_GLOBAL_INLINE boolean init_event_in_list(void **init_events, int num_inits, weed_plant_t *event)
render_details * create_render_details(int type)
LIVES_GLOBAL_INLINE weed_plant_t * get_prev_event(weed_plant_t *event)
weed_plant_t * process_events(weed_plant_t *next_event, boolean process_audio, weed_timecode_t curr_tc)
weed_plant_t * insert_frame_event_at(weed_plant_t *event_list, weed_timecode_t tc, int numframes, int *clips, int64_t *frames, weed_plant_t **shortcut)
void insert_audio_event_at(weed_plant_t *event, int track, int clipnum, double seek, double vel)
void move_filter_init_event(weed_plant_t *event_list, weed_timecode_t new_tc, weed_plant_t *init_event, double fps)
void event_list_replace_events(weed_plant_t *event_list, weed_plant_t *new_event_list)
replace events in event_list with events in new_event_list
LIVES_GLOBAL_INLINE weed_plant_t * get_first_event(weed_plant_t *event_list)
int count_events(weed_plant_t *event_list, boolean all_events, weed_timecode_t start_tc, weed_timecode_t end_tc)
LIVES_GLOBAL_INLINE weed_timecode_t get_event_timecode(weed_plant_t *plant)
void remove_filter_from_event_list(weed_plant_t *event_list, weed_plant_t *init_event)
void remove_frame_from_event(weed_plant_t *event_list, weed_plant_t *event, int track)
LIVES_GLOBAL_INLINE weed_plant_t * get_last_event(weed_plant_t *event_list)
weed_plant_t * append_filter_deinit_event(weed_plant_t *event_list, weed_timecode_t tc, void *init_event, void **pchain)
boolean is_blank_frame(weed_plant_t *event, boolean count_audio)
LIVES_GLOBAL_INLINE int get_event_type(weed_plant_t *plant)
boolean insert_filter_map_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event, boolean before_frames)
double get_audio_frame_vel(weed_plant_t *event, int track)
returns velocity for track (track==-1 is backing audio)
void event_list_free(weed_plant_t *event_list)
weed_plant_t * insert_marker_event_at(weed_plant_t *event_list, weed_plant_t *at_event, int marker_type, livespointer data)
weed_plant_t * get_filter_map_before(weed_plant_t *event, int ctrack, weed_plant_t *stop_event)
weed_plant_t * get_first_frame_event(weed_plant_t *event_list)
weed_plant_t * get_filter_map_after(weed_plant_t *event, int ctrack)
weed_plant_t * append_filter_init_event(weed_plant_t *event_list, weed_timecode_t tc, int filter_idx, int num_in_tracks, int key, weed_plant_t *inst)
weed_plant_t * get_audio_block_start(weed_plant_t *event_list, int track, weed_timecode_t tc, boolean seek_back)
void ** filter_init_add_pchanges(weed_plant_t *event_list, weed_plant_t *plant, weed_plant_t *init_event, int ntracks, int leave)
weed_plant_t * get_frame_event_at(weed_plant_t *event_list, weed_timecode_t tc, weed_plant_t *shortcut, boolean exact)
boolean filter_map_after_frame(weed_plant_t *fmap)
LIVES_GLOBAL_INLINE weed_plant_t * get_next_event(weed_plant_t *event)
weed_plant_t * get_next_frame_event(weed_plant_t *event)
boolean init_event_is_relevant(weed_plant_t *init_event, int ctrack)
LIVES_GLOBAL_INLINE weed_timecode_t weed_event_set_timecode(weed_event_t *event, weed_timecode_t tc)
void update_filter_maps(weed_plant_t *event, weed_plant_t *end_event, weed_plant_t *init_event)
void event_list_add_track(weed_plant_t *event_list, int layer)
LIVES_GLOBAL_INLINE weed_plant_t * insert_blank_frame_event_at(weed_plant_t *event_list, weed_timecode_t tc, weed_plant_t **shortcut)
weed_event_t * lives_event_list_new(weed_event_t *elist, const char *cdate)
lib-ish stuff
weed_timecode_t event_list_get_end_tc(weed_plant_t *event_list)
void restore_host_tags(weed_plant_t *event_list, weed_timecode_t curr_tc)
LIVES_GLOBAL_INLINE int weed_frame_event_get_audio_tracks(weed_event_t *event, int **clips, double **seeks)
weed_plant_t * get_frame_event_at_or_before(weed_plant_t *event_list, weed_timecode_t tc, weed_plant_t *shortcut)
void move_filter_deinit_event(weed_plant_t *event_list, weed_timecode_t new_tc, weed_plant_t *deinit_event, double fps, boolean rescale_pchanges)
LiVESWidget * create_event_list_dialog(weed_plant_t *event_list, weed_timecode_t start_tc, weed_timecode_t end_tc)
boolean move_event_left(weed_plant_t *event_list, weed_plant_t *event, boolean can_stay, double fps)
void remove_end_blank_frames(weed_plant_t *event_list, boolean remove_filter_inits)
#define WEED_LEAF_HOST_AUDIO_TRANSITION
#define WEED_LEAF_AUDIO_VOLUME_VALUES
#define WEED_LEAF_AUDIO_VOLUME_TRACKS
#define EVENT_MARKER_RECORD_START
#define WEED_EVENT_IS_FRAME(event)
#define WEED_LEAF_GAMMA_ENABLED
#define WEED_LEAF_IS_DEF_VALUE
#define WEED_LEAF_INIT_EVENTS
#define WEED_LEAF_PREV_CHANGE
#define WEED_LEAF_AUDIO_SEEKS
#define WEED_LEAF_DEINIT_EVENT
#define WEED_LEAF_NEEDS_SET
#define WEED_EVENT_IS_AUDIO_FRAME(event)
#define WEED_LEAF_NEXT_CHANGE
#define WEED_EVENT_IS_FILTER_DEINIT(event)
#define WEED_LEAF_AUDIO_CLIPS
#define WEED_EVENT_IS_MARKER(event)
#define EVENT_MARKER_RECORD_END
#define WEED_LEAF_INIT_EVENT
#define WEED_LEAF_WEED_EVENT_API_VERSION
parts of this may eventually become libweed-events
#define WEED_LEAF_PTRSIZE
deprecated
#define WEED_LEAF_AUDIO_SAMPLE_SIZE
#define WEED_LEAF_TRACK_LABEL_TRACKS
#define WEED_LEAF_PREVIOUS
#define WEED_LEAF_OUT_COUNT
#define WEED_EVENT_IS_FILTER_INIT(event)
#define WEED_LEAF_EVENT_ID
#define WEED_LEAF_IN_COUNT
#define WEED_LEAF_IN_TRACKS
#define WEED_LEAF_LIVES_TYPE
#define WEED_LEAF_AUDIO_SIGNED
#define WEED_PLANT_IS_EVENT_LIST(plant)
weed_plant_t weed_event_t
#define WEED_LEAF_TRACK_LABEL_VALUES
#define WEED_LEAF_HINT
for backwards compat.
#define WEED_LEAF_AUDIO_ENDIAN
#define WEED_EVENT_IS_PARAM_CHANGE(event)
#define EVENT_MARKER_BLOCK_START
#define WEED_LEAF_OUT_TRACKS
#define WEED_EVENT_IS_FILTER_MAP(event)
#define EVENT_MARKER_BLOCK_UNORDERED
boolean on_framedraw_enter(LiVESWidget *widget, LiVESXEventCrossing *event, lives_special_framedraw_rect_t *framedraw)
boolean on_framedraw_mouse_start(LiVESWidget *widget, LiVESXEventButton *event, lives_special_framedraw_rect_t *framedraw)
boolean on_framedraw_scroll(LiVESWidget *widget, LiVESXEventScroll *event, lives_special_framedraw_rect_t *framedraw)
boolean on_framedraw_mouse_update(LiVESWidget *widget, LiVESXEventMotion *event, lives_special_framedraw_rect_t *framedraw)
boolean on_framedraw_mouse_reset(LiVESWidget *widget, LiVESXEventButton *event, lives_special_framedraw_rect_t *framedraw)
boolean on_framedraw_leave(LiVESWidget *widget, LiVESXEventCrossing *event, lives_special_framedraw_rect_t *framedraw)
void set_interactive(boolean interactive)
void add_to_playframe(void)
void resize_play_window(void)
void make_play_window(void)
actually in gui.c
void add_to_clipmenu(void)
char * get_menu_name(lives_clip_t *sfile, boolean add_setname)
char * choose_file(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act, const char *title, LiVESWidget *extra_widget)
LiVESWidget * create_cdtrack_dialog(int type, livespointer user_data)
boolean redraw_tl_idle(void *data)
lives_clipinfo_t * create_clip_info_window(int audio_channels, boolean is_mt)
_entryw * create_rename_dialog(int type)
LIVES_GLOBAL_INLINE LiVESWidget * make_autoreload_check(LiVESHBox *hbox, boolean is_active)
boolean reshow_msg_area(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
boolean on_msg_area_scroll(LiVESWidget *widget, LiVESXEventScroll *event, livespointer user_data)
_entryw * create_cds_dialog(int type)
void do_mt_keys_window(void)
void msg_area_scroll(LiVESAdjustment *adj, livespointer userdata)
void run_diskspace_dialog_cb(LiVESWidget *w, livespointer data)
#define LIVES_PREVIEW_TYPE_VIDEO_ONLY
void on_open_fw_activate(LiVESMenuItem *menuitem, livespointer user_data)
error("LSD_RANDFUNC(ptr, size) must be defined")
LIVES_GLOBAL_INLINE int lives_getgid(void)
char * lives_datetime(uint64_t secs, boolean use_local)
LIVES_GLOBAL_INLINE uint64_t lives_random(void)
off_t sget_file_size(const char *name)
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
LIVES_GLOBAL_INLINE int lives_strappend(const char *string, int len, const char *xnew)
LIVES_GLOBAL_INLINE int lives_getuid(void)
boolean compress_files_in_dir(const char *dir, int method, void *data)
uint64_t gen_unique_id(void)
LIVES_GLOBAL_INLINE boolean lives_strncmp(const char *st1, const char *st2, size_t len)
returns FALSE if strings match
void * main_thread_execute(lives_funcptr_t func, int return_type, void *retval, const char *args_fmt,...)
void *(* lives_funcptr_t)(void *)
void defer_sigint(int signum)
LIVES_GLOBAL_INLINE void free_track_decoders(void)
void load_end_image(int frame)
void set_drawing_area_from_pixbuf(LiVESWidget *widget, LiVESPixbuf *pixbuf, lives_painter_surface_t *surface)
void load_start_image(int frame)
_palette * palette
interface colour settings
boolean resize_message_area(livespointer data)
LiVESPixbuf * pull_lives_pixbuf_at_size(int clip, int frame, const char *image_ext, weed_timecode_t tc, int width, int height, LiVESInterpType interp, boolean fordisp)
void catch_sigint(int signum)
void set_signal_handlers(SignalHandlerPointer sigfunc)
void resize(double scale)
void init_track_decoders(void)
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 ...
void break_me(const char *brkstr)
boolean check_layer_ready(weed_layer_t *layer)
block until layer pixel_data is ready.
void switch_to_file(int old_file, int new_file)
void close_current_file(int file_to_switch_to)
close current file, and try to switch to file_to_switch_to
ssize_t lives_read_buffered(int fd, void *buf, ssize_t count, boolean allow_less)
int lives_close_buffered(int fd)
void get_basename(char *filename)
ssize_t lives_popen(const char *com, boolean allow_error, char *buff, ssize_t buflen)
void(* SignalHandlerPointer)(int)
void lives_list_free_all(LiVESList **)
size_t get_token_count(const char *string, int delim)
#define MAX_FILES
max files is actually 1 more than this, since file 0 is the clipboard
void d_print_file_error_failed(void)
double calc_time_from_frame(int clip, int frame)
int lives_touch(const char *tfile)
#define LIVES_GLOBAL_INLINE
boolean check_for_ratio_fps(double fps)
void maybe_add_mt_idlefunc(void)
ssize_t lives_write_buffered(int fd, const char *buf, ssize_t count, boolean allow_fail)
#define DEF_FILE_PERMS
non-executable, is modified by the umask
#define IS_NORMAL_CLIP(clip)
void close_scrap_file(boolean remove)
void close_ascrap_file(boolean remove)
int lives_create_buffered(const char *pathname, int mode)
ssize_t lives_read_le_buffered(int fd, void *buf, ssize_t count, boolean allow_less)
#define CURRENT_CLIP_HAS_AUDIO
#define LIVES_LOCAL_INLINE
int lives_system(const char *com, boolean allow_error)
void set_undoable(const char *what, boolean sensitive)
char * repl_workdir(const char *entry, boolean fwd)
ssize_t lives_write_le_buffered(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
boolean get_new_handle(int index, const char *name)
int count_resampled_frames(int in_frames, double orig_fps, double resampled_fps)
const char * get_image_ext_for_type(lives_img_type_t imgtype)
LiVESInterpType get_interp_value(short quality, boolean low_for_mt)
void remove_layout_files(LiVESList *lmap)
#define FPS_MAX
maximum fps we will allow (double)
int lives_open_buffered_rdonly(const char *pathname)
int lives_mv(const char *from, const char *to)
boolean save_clip_values(int which_file)
void set_sel_label(LiVESWidget *label)
lives_direction_t
use REVERSE / FORWARD when a sign is used, BACKWARD / FORWARD when a parity is used
@ LIVES_DIRECTION_FORWARD
@ LIVES_DIRECTION_BACKWARD
int lives_rmdir(const char *dir, boolean force)
#define IS_VALID_CLIP(clip)
boolean int_array_contains_value(int *array, int num_elems, int value)
int lives_rm(const char *file)
void d_print_failed(void)
int lives_open2(const char *pathname, int flags)
void reset_clipmenu(void)
int lives_list_strcmp_index(LiVESList *list, livesconstpointer data, boolean case_sensitive)
void d_print(const char *fmt,...)
void add_to_recovery_file(const char *handle)
void lives_buffered_rdonly_slurp(int fd, off_t skip)
LiVESList * lives_list_append_unique(LiVESList *xlist, const char *add)
#define CURRENT_CLIP_IS_VALID
char * ensure_extension(const char *fname, const char *ext) WARN_UNUSED
void calc_maxspect(int rwidth, int rheight, int *cwidth, int *cheight)
boolean lives_freep(void **ptr)
boolean is_legal_set_name(const char *set_name, boolean allow_dupes, boolean leeway)
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
@ CLIP_TYPE_GENERATOR
frames from generator plugin
double lives_fix(double val, int decimals) GNU_CONST
char * get_dir(const char *filename)
boolean save_clip_value(int which, lives_clip_details_t, void *val)
#define CLIP_TOTAL_TIME(clip)
@ CANCEL_NO_PROPOGATE
cancel but keep opening
@ CANCEL_NO_MORE_PREVIEW
ran out of preview frames
@ CANCEL_VID_END
video playback completed
@ CANCEL_USER
user pressed stop
@ CANCEL_USER_PAUSED
cancelled and paused
int calc_frame_from_time(int filenum, double time)
nearest frame [1, frames]
#define MAINW_MSG_SIZE
mainw->msg bytesize
#define STYLE_3
style is lightish - allow themeing of widgets with dark text, otherwise use menu bg
#define DEF_BUTTON_HEIGHT
#define MAIN_SPIN_SPACER
pixel spacing for start/end spins for clip and multitrack editors
#define MIN_MSGBAR_HEIGHT
#define TICKS_PER_SECOND
ticks per second - GLOBAL TIMEBASE
#define LIVES_IS_INTERACTIVE
#define UNREC_LAYOUTS_DIR
#define LIVES_MAIN_WINDOW_WIDGET
#define STYLE_4
separator col. in mt
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
@ LIVES_STRING_CONSTANT_NONE
@ LIVES_STRING_CONSTANT_CL
"the current layout"
#define LIVES_SENSE_STATE_INTERACTIVE
#define LIVES_FILE_EXT_LAYOUT
#define FX_KEYS_MAX_VIRTUAL
must be >= FX_KEYS_PHYSICAL, and <=64 (number of bits in a 64bit int mask) (max number of keys accesi...
#define MAX_SET_NAME_LEN
sets
#define EFFORT_RANGE_MAX
if set to TRUE during playback then a new frame (or possibly the current one) will be displayed ASAP
#define STYLE_1
turn on theming if set
_fx_dialog * fx_dialog[2]
#define STYLE_2
colour the spinbuttons on the front page if set
#define LIVES_SENSE_STATE_INSENSITIZED
#define LAYOUT_MAP_FILENAME
#define LAYOUT_NUMBERING_FILENAME
#define LIVES_SENSE_STATE_SENSITIZED
#define COMBOWIDTHCHARS
char width of combo entries (default)
#define FX_KEYS_MAX
the rest of the keys are accessible through the multitrack renderer (must, be > FX_KEYS_MAX_VIRTUAL)
#define FN_KEYS
number of function keys
#define LIVES_FILENAME_NOREMOVE
#define GUI_SCREEN_HEIGHT
boolean mt_track_is_audio(lives_mt *mt, int ntrack)
return TRUE if ntrack is a valid backing audio track
void unpaint_line(lives_mt *mt, LiVESWidget *eventbox)
int mt_get_block_count(lives_mt *mt, int ntrack)
count blocks in track
void mt_load_vals_toggled(LiVESMenuItem *menuitem, livespointer user_data)
void mt_set_autotrans(int idx)
char * get_eload_filename(lives_mt *mt, boolean allow_auto_reload)
boolean mt_mark_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
void on_split_sel_activate(LiVESMenuItem *menuitem, livespointer user_data)
LIVES_LOCAL_INLINE void free_pkg_list(void)
void on_amixer_close_clicked(LiVESButton *button, lives_mt *mt)
weed_plant_t * add_blank_frames_up_to(weed_plant_t *event_list, weed_plant_t *start_event, weed_timecode_t end_tc, double fps)
void mt_tl_move(lives_mt *mt, double pos)
boolean on_track_between_release(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
void mt_clip_select(lives_mt *mt, boolean scroll)
void mt_clear_timeline(lives_mt *mt)
void mt_spin_start_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
void mt_backup(lives_mt *mt, int undo_type, weed_timecode_t tc)
boolean on_track_click(LiVESWidget *eventbox, LiVESXEventButton *event, livespointer user_data)
boolean mt_auto_backup(livespointer user_data)
track_rect * get_block_from_track_and_time(lives_mt *mt, int track, double time)
get timeline end time of block
void remove_gaps(LiVESMenuItem *menuitem, livespointer user_data)
void on_clear_event_list_activate(LiVESMenuItem *menuitem, livespointer user_data)
LiVESWidget * get_eventbox_for_track(lives_mt *mt, int ntrack)
LIVES_INLINE int poly_page_to_tab(uint32_t page)
void on_set_pvals_clicked(LiVESWidget *button, livespointer user_data)
LIVES_INLINE int poly_tab_to_page(uint32_t tab)
void on_next_node_clicked(LiVESWidget *button, livespointer user_data)
void clear_context(lives_mt *mt)
void multitrack_view_sel_events(LiVESMenuItem *menuitem, livespointer user_data)
LIVES_INLINE int mt_file_from_clip(lives_mt *mt, int clip)
boolean mt_track_is_video(lives_mt *mt, int ntrack)
return TRUE if ntrack is a valid video track
boolean resize_timeline(lives_mt *mt)
void multitrack_preview_clicked(LiVESWidget *button, livespointer user_data)
weed_plant_t * get_prev_fm(lives_mt *mt, int current_track, weed_plant_t *event)
boolean multitrack_insert(LiVESMenuItem *menuitem, livespointer user_data)
boolean all_present(weed_plant_t *event, LiVESList *sel)
void show_clipinfo_cb(LiVESMenuItem *menuitem, livespointer user_data)
void mt_fixup_events(lives_mt *mt, weed_plant_t *old_event, weed_plant_t *new_event)
uint32_t mt_idle_add(lives_mt *mt)
boolean show_in_out_images(livespointer user_data)
LIVES_LOCAL_INLINE int pkg_in_list(char *pkgstring)
boolean on_track_header_move(LiVESWidget *widget, LiVESXEventMotion *event, livespointer user_data)
track_rect * find_block_by_uid(lives_mt *mt, ulong uid)
void on_mt_showkeys_activate(LiVESMenuItem *menuitem, livespointer user_data)
void reset_renumbering(void)
void on_fx_insa_clicked(LiVESWidget *button, livespointer user_data)
void on_split_curr_activate(LiVESMenuItem *menuitem, livespointer user_data)
int add_video_track_behind(LiVESMenuItem *menuitem, livespointer user_data)
void multitrack_view_in_out(LiVESMenuItem *menuitem, livespointer user_data)
void on_jumpback_mark_activate(LiVESMenuItem *menuitem, livespointer user_data)
void mt_change_vals_activate(LiVESMenuItem *menuitem, livespointer user_data)
void mt_desensitise(lives_mt *mt)
boolean multitrack_audio_insert(LiVESMenuItem *menuitem, livespointer user_data)
void do_fx_list_context(lives_mt *mt, int fxcount)
void mt_init_tracks(lives_mt *mt, boolean set_min_max)
add basic tracks, or set tracks from mt->event_list
void set_timeline_end_secs(lives_mt *mt, double secs)
boolean mt_tlfor_frame(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
void mt_add_region_effect(LiVESMenuItem *menuitem, livespointer user_data)
void recover_layout_cancelled(boolean is_startup)
void on_next_fm_clicked(LiVESWidget *button, livespointer user_data)
void multitrack_playall(lives_mt *mt)
void remove_first_gaps(LiVESMenuItem *menuitem, livespointer user_data)
void selblock_cb(LiVESMenuItem *menuitem, livespointer user_data)
void unpaint_lines(lives_mt *mt)
void stored_event_list_free_undos(void)
boolean recover_layout(void)
void mt_delete_clips(lives_mt *mt, int file)
void activate_mt_preview(lives_mt *mt)
sensitize Show Preview and Apply buttons
#define POLY_WIDTH_MARGIN
boolean mt_trup(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
void insert_at_ctx_cb(LiVESMenuItem *menuitem, livespointer user_data)
void mt_add_block_effect(LiVESMenuItem *menuitem, livespointer user_data)
void list_fx_here_cb(LiVESMenuItem *menuitem, livespointer user_data)
void polymorph(lives_mt *mt, lives_mt_poly_state_t poly)
void on_prev_fm_clicked(LiVESWidget *button, livespointer user_data)
void save_layout_map(int *lmap, double *lmap_audio, const char *file, const char *dir)
boolean on_track_release(LiVESWidget *eventbox, LiVESXEventButton *event, livespointer user_data)
boolean on_render_activate(LiVESMenuItem *menuitem, livespointer user_data)
void track_select(lives_mt *mt)
must call after setting mt->current_track
void mt_do_autotransition(lives_mt *mt, track_rect *block)
call this on a block to apply autotransition on it
void wipe_layout(lives_mt *mt)
LIVES_INLINE boolean is_empty_track(LiVESWidgetObject *track)
void add_context_label(lives_mt *mt, const char *text)
void out_anchor_toggled(LiVESToggleButton *togglebutton, livespointer user_data)
void draw_region(lives_mt *mt)
void insert_audio(int filenum, weed_timecode_t offset_start, weed_timecode_t offset_end, weed_timecode_t tc, double avel, lives_direction_t direction, LiVESWidget *eventbox, lives_mt *mt, track_rect *in_block)
void mt_sensitise(lives_mt *mt)
void insert_here_cb(LiVESMenuItem *menuitem, livespointer user_data)
void in_out_end_changed(LiVESWidget *widget, livespointer user_data)
void mt_post_playback(lives_mt *mt)
LIVES_LOCAL_INLINE char * get_pkg_name(int pkgnum)
void mt_prepare_for_playback(lives_mt *mt)
void update_insert_mode(lives_mt *mt)
void set_mt_play_sizes_cfg(lives_mt *mt)
void do_fx_move_context(lives_mt *mt)
lives_mt * multitrack(weed_plant_t *event_list, int orig_file, double fps)
create and return lives_mt struct
void mt_change_max_disp_tracks(LiVESMenuItem *menuitem, livespointer user_data)
void show_frame_events_activate(LiVESMenuItem *menuitem, livespointer user_data)
track_rect * move_block(lives_mt *mt, track_rect *block, double timesecs, int old_track, int new_track)
void multitrack_play_sel(LiVESMenuItem *menuitem, livespointer user_data)
void set_mt_colours(lives_mt *mt)
void mt_spin_end_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
void set_poly_tab(lives_mt *mt, uint32_t tab)
EXPOSE_FN_END boolean on_timeline_update(LiVESWidget *widget, LiVESXEventMotion *event, livespointer user_data)
boolean on_track_move(LiVESWidget *widget, LiVESXEventMotion *event, livespointer user_data)
LIVES_GLOBAL_INLINE double mt_get_effect_time(lives_mt *mt)
void set_mixer_track_vol(lives_mt *mt, int trackno, double vol)
void mt_selection_lock(LiVESMenuItem *menuitem, livespointer user_data)
lock the time selection
boolean save_event_list_inner(lives_mt *mt, int fd, weed_plant_t *event_list, unsigned char **mem)
boolean on_timeline_press(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
void insert_frames(int filenum, weed_timecode_t offset_start, weed_timecode_t offset_end, weed_timecode_t tc, lives_direction_t direction, LiVESWidget *eventbox, lives_mt *mt, track_rect *in_block)
void on_amixer_slider_changed(LiVESAdjustment *adj, lives_mt *mt)
void on_jumpnext_mark_activate(LiVESMenuItem *menuitem, livespointer user_data)
boolean compare_filter_maps(weed_plant_t *fm1, weed_plant_t *fm2, int ctrack)
ctrack can be -1 to compare all events, else we cf for ctrack
void on_jumpnext_activate(LiVESMenuItem *menuitem, livespointer user_data)
LiVESWidget * amixer_add_channel_slider(lives_mt *mt, int i)
boolean on_track_header_release(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
boolean event_list_rectify(lives_mt *mt, weed_plant_t *event_list)
boolean used_in_current_layout(lives_mt *mt, int file)
void amixer_show(LiVESButton *button, livespointer user_data)
boolean multitrack_delete(lives_mt *mt, boolean save_layout)
void multitrack_undo(LiVESMenuItem *menuitem, livespointer user_data)
boolean mt_idle_show_current_frame(livespointer data)
LIVES_INLINE int mt_clip_from_file(lives_mt *mt, int file)
LiVESPixbuf * make_thumb(lives_mt *mt, int file, int width, int height, frames_t frame, LiVESInterpType interp, boolean noblanks)
void on_insgap_sel_activate(LiVESMenuItem *menuitem, livespointer user_data)
weed_plant_t * load_event_list(lives_mt *mt, char *eload_file)
void multitrack_redo(LiVESMenuItem *menuitem, livespointer user_data)
void multitrack_adj_start_end(LiVESMenuItem *menuitem, livespointer user_data)
void get_region_overlap(lives_mt *mt)
void on_mt_fx_edit_activate(LiVESMenuItem *menuitem, livespointer user_data)
LiVESList * layout_audio_is_affected(int clipno, double stime, double etime, LiVESList *xlays)
void delete_block_cb(LiVESMenuItem *menuitem, livespointer user_data)
void on_seltrack_activate(LiVESMenuItem *menuitem, livespointer user_data)
boolean mt_prevclip(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
int get_track_for_block(track_rect *block)
return track number for a given block
boolean on_track_header_click(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
boolean on_save_event_list_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_seltrack_toggled(LiVESWidget *checkbutton, livespointer user_data)
void migrate_layouts(const char *old_set_name, const char *new_set_name)
void mt_swap_play_pause(lives_mt *mt, boolean put_pause)
void move_init_in_filter_map(lives_mt *mt, weed_plant_t *event_list, weed_plant_t *event, weed_plant_t *ifrom, weed_plant_t *ito, int track, boolean after)
void on_jumpback_activate(LiVESMenuItem *menuitem, livespointer user_data)
void multitrack_view_details(LiVESMenuItem *menuitem, livespointer user_data)
void on_prev_node_clicked(LiVESWidget *button, livespointer user_data)
void delete_audio_track(lives_mt *mt, LiVESWidget *eventbox, boolean full)
LIVES_INLINE void set_params_unchanged(lives_mt *mt, lives_rfx_t *rfx)
void on_mt_delfx_activate(LiVESMenuItem *menuitem, livespointer user_data)
boolean on_load_event_list_activate(LiVESMenuItem *menuitem, livespointer user_data)
void delete_audio_tracks(lives_mt *mt, LiVESList *list, boolean full)
boolean on_track_between_click(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
void mt_change_disp_tracks_ok(LiVESButton *button, livespointer user_data)
void multitrack_end_cb(LiVESMenuItem *menuitem, livespointer user_data)
void set_track_label_string(lives_mt *mt, int track, const char *label)
void scroll_track_by_scrollbar(LiVESScrollbar *sbar, livespointer user_data)
boolean on_timeline_release(LiVESWidget *eventbox, LiVESXEventButton *event, livespointer user_data)
void avel_spin_changed(LiVESSpinButton *spinbutton, livespointer user_data)
void add_aparam_menuitems(lives_mt *mt)
void add_markers(lives_mt *mt, weed_plant_t *event_list, boolean add_block_ids)
boolean set_new_set_name(lives_mt *mt)
double get_mixer_track_vol(lives_mt *mt, int trackno)
void do_sel_context(lives_mt *mt)
void on_cback_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_del_node_clicked(LiVESWidget *button, livespointer user_data)
void on_insgap_cur_activate(LiVESMenuItem *menuitem, livespointer user_data)
LIVES_INLINE lives_mt_poly_state_t get_poly_state_from_page(lives_mt *mt)
char * set_values_from_defs(lives_mt *mt, boolean from_prefs)
LiVESList * load_layout_map(void)
double mt_get_block_entime(lives_mt *mt, int ntrack, int iblock)
return time in seconds of last frame event in block, + event duration
void remove_markers(weed_plant_t *event_list)
void insert_audio_at_ctx_cb(LiVESMenuItem *menuitem, livespointer user_data)
void edit_start_end_cb(LiVESMenuItem *menuitem, livespointer user_data)
LIVES_INLINE void print_layout_wiped(void)
void multitrack_view_events(LiVESMenuItem *menuitem, livespointer user_data)
void do_effect_context(lives_mt *mt, LiVESXEventButton *event)
void on_fx_insb_clicked(LiVESWidget *button, livespointer user_data)
void mt_zoom_in(LiVESMenuItem *menuitem, livespointer user_data)
void mt_quit_activate(LiVESMenuItem *menuitem, livespointer user_data)
boolean make_backup_space(lives_mt *mt, size_t space_needed)
void multitrack_view_clips(LiVESMenuItem *menuitem, livespointer user_data)
void insert_audio_here_cb(LiVESMenuItem *menuitem, livespointer user_data)
void on_resetp_clicked(LiVESWidget *button, livespointer user_data)
void do_block_context(lives_mt *mt, LiVESXEventButton *event, track_rect *block)
void stored_event_list_free_all(boolean wiped)
boolean check_for_layout_del(lives_mt *mt, boolean exiting)
void mt_zoom_out(LiVESMenuItem *menuitem, livespointer user_data)
void free_thumb_cache(int fnum, frames_t fromframe)
weed_plant_t * get_next_fm(lives_mt *mt, int current_track, weed_plant_t *event)
void do_track_context(lives_mt *mt, LiVESXEventButton *event, double timesecs, int track)
double mt_get_block_sttime(lives_mt *mt, int ntrack, int iblock)
return time in seconds of first frame event in block
char * get_track_name(lives_mt *mt, int track_num, boolean is_audio)
ulong mt_get_last_block_uid(lives_mt *mt)
get index of last inserted (wallclock time) block for track
LiVESPixbuf * make_thumb_fast_between(lives_mt *mt, int fileno, int width, int height, int tframe, int range)
LIVES_INLINE void mt_tl_move_relative(lives_mt *mt, double pos_rel)
LiVESWidget * add_audio_track(lives_mt *mt, int track, boolean behind)
void in_out_start_changed(LiVESWidget *widget, livespointer user_data)
void scroll_tracks(lives_mt *mt, int top_track, boolean set_value)
void on_prerender_aud_activate(LiVESMenuItem *menuitem, livespointer user_data)
void delete_video_track(lives_mt *mt, int layer, boolean full)
void ** mt_get_pchain(void)
boolean add_mt_param_box(lives_mt *mt)
void mt_aparam_view_toggled(LiVESMenuItem *menuitem, livespointer user_data)
LiVESList * layout_frame_is_affected(int clipno, int start, int end, LiVESList *xlays)
void unselect_all(lives_mt *mt)
unselect all blocks
void on_mt_list_fx_activate(LiVESMenuItem *menuitem, livespointer user_data)
LIVES_INLINE double get_time_from_x(lives_mt *mt, int x)
#define WEED_AUDIO_BIG_ENDIAN
void close_clip_cb(LiVESMenuItem *menuitem, livespointer user_data)
void mt_init_start_end_spins(lives_mt *mt)
LIVES_LOCAL_INLINE void reset_mt_play_sizes(lives_mt *mt)
boolean mt_tcoverlay_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
void in_anchor_toggled(LiVESToggleButton *togglebutton, livespointer user_data)
boolean track_arrow_pressed(LiVESWidget *ebox, LiVESXEventButton *event, livespointer user_data)
void animate_multitrack(lives_mt *mt)
void remove_current_from_affected_layouts(lives_mt *mt)
void mouse_mode_context(lives_mt *mt)
LIVES_LOCAL_INLINE int add_to_pkg_list(char *pkgstring)
void mt_center_on_cursor(LiVESMenuItem *menuitem, livespointer user_data)
boolean mt_tlback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
void on_split_activate(LiVESMenuItem *menuitem, livespointer user_data)
int add_video_track_front(LiVESMenuItem *menuitem, livespointer user_data)
void on_node_spin_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
boolean block_overlap(LiVESWidget *eventbox, double time_start, double time_end)
boolean on_multitrack_activate(LiVESMenuItem *menuitem, weed_plant_t *event_list)
menuitem callback
void update_filter_events(lives_mt *mt, weed_plant_t *first_event, weed_timecode_t start_tc, weed_timecode_t end_tc, int track, weed_timecode_t new_start_tc, int new_track)
void mt_show_current_frame(lives_mt *mt, boolean return_layer)
preview the current frame
void * find_init_event_in_ttable(ttable *trans_table, uint64_t in, boolean normal)
void update_grav_mode(lives_mt *mt)
boolean mt_trdown(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
boolean mt_load_recovery_layout(lives_mt *mt)
boolean mt_tlfor(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
#define WEED_AUDIO_LITTLE_ENDIAN
void event_list_free_undos(lives_mt *mt)
void mt_init_clips(lives_mt *mt, int orig_file, boolean add)
void on_rename_track_activate(LiVESMenuItem *menuitem, livespointer user_data)
boolean mt_tlback_frame(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
int get_clip_for_block(track_rect *block)
boolean write_backup_layout_numbering(lives_mt *mt)
void avel_reverse_toggled(LiVESToggleButton *togglebutton, livespointer user_data)
boolean mt_nextclip(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
#define MT_INOUT_TIME
min milliseconds to save autobackup when changing in / out spins
#define TRACK_I_HIDDEN_SCROLLED
#define QUANT_TIME(dbltime)
@ INSERT_MODE_NORMAL
the default (only insert if it fits)
@ INSERT_MODE_OVERWRITE
overwite existing blocks
#define AMIXER_WRATIO
audio mixer width ratio (fraction of screen width)
#define TIMELINE_TABLE_COLUMNS
#define QUANT_TICKS(ticks)
#define BLOCK_DRAW_SIMPLE
#define AMIXER_HRATIO
audio mixer height ratio (fraction of screen height)
@ MT_UNDO_INSERT_AUDIO_BLOCK
@ MT_UNDO_MOVE_AUDIO_BLOCK
@ MT_UNDO_FILTER_MAP_CHANGE
@ MT_UNDO_DELETE_AUDIO_BLOCK
@ MT_UNDO_NONE
no event_list
#define CLIP_LABEL_LENGTH
#define PEB_HRATIO
preview eventbox height ratio (fraction of screen height)
#define BLOCK_THUMB_WIDTH
#define CLIP_THUMB_HEIGHT
#define PEB_WRATIO
preview eventbox width ratio (fraction of screen width)
#define TIMECODE_LENGTH
length of timecode text entry, must be > 12
#define DEF_TIME
default seconds when there is no event_list
#define TRACK_I_HIDDEN_USER
#define LIVES_OSC_NOTIFY_MODE_CHANGED
mode changed to clip editor or to multitrack
LingoLayout * render_text_to_cr(LiVESWidget *widget, lives_painter_t *cr, const char *text, const char *fontname, double size, lives_text_mode_t mode, lives_colRGBA64_t *fg, lives_colRGBA64_t *bg, boolean center, boolean rising, double *top, int *offs_x, int dwidth, int *dheight)
@ LIVES_TEXT_MODE_FOREGROUND_ONLY
boolean check_filewrite_overwrites(void)
boolean special_cleanup(boolean is_ok)
LiVESPixbuf * mt_framedraw(lives_mt *mt, weed_layer_t *layer)
void on_paramwindow_button_clicked(LiVESButton *button, lives_rfx_t *rfx)
void update_visual_params(lives_rfx_t *rfx, boolean update_hidden)
apply internal value changes to interface widgets
void after_param_text_changed(LiVESWidget *textwidget, lives_rfx_t *rfx)
boolean make_param_box(LiVESVBox *top_vbox, lives_rfx_t *rfx)
make a dynamic parameter window
void rfx_free(lives_rfx_t *rfx)
boolean check_encoder_restrictions(boolean get_extension, boolean user_audio, boolean save_all)
lives_rfx_t * weed_to_rfx(weed_plant_t *plant, boolean show_reinits)
#define FX_CANDIDATE_AUDIO_VOL
#define LIVES_SEEK_FAST
good
#define RFX_FLAGS_NO_RESET
void on_preferences_activate(LiVESMenuItem *menuitem, livespointer user_data)
int set_boolean_pref(const char *key, boolean value)
int set_double_pref(const char *key, double value)
int set_string_pref(const char *key, const char *value)
void toggle_sets_pref(LiVESWidget *widget, livespointer prefidx)
callback to set to make a togglebutton or check_menu_item directly control a boolean pref widget is e...
boolean pref_factory_int(const char *prefidx, int newval, boolean permanent)
boolean pref_factory_bool(const char *prefidx, boolean newval, boolean permanent)
int set_int_pref(const char *key, int value)
#define WARN_MASK_LAYOUT_WIPE
#define JACK_OPTS_TIMEBASE_START
jack sets play start position
#define WARN_MASK_MT_NO_JACK
#define PREF_MAX_DISP_VTRACKS
#define WARN_MASK_MT_ACHANS
#define PREF_REC_EXT_AUDIO
#define JACK_OPTS_TRANSPORT_CLIENT
jack can start/stop
#define SEPWIN_TYPE_NON_STICKY
#define PREF_MT_BACKAUDIO
#define PREF_SHOW_DEVOPTS
#define PREF_MT_DEF_ASAMPS
#define PREF_MT_DEF_ARATE
#define PREF_MT_DEF_ACHANS
#define WARN_MASK_LAYOUT_LB
#define PREF_MT_DEF_HEIGHT
#define PREF_MT_DEF_WIDTH
#define SEPWIN_TYPE_STICKY
#define PREF_MT_DEF_SIGNED_ENDIAN
#define WARN_MASK_EXIT_MT
off by default on a fresh install
#define PREF_MT_PERTRACK_AUDIO
#define PREF_MT_ENTER_PROMPT
_future_prefs * future_prefs
#define PREF_ACTIVE_AUTOTRANS
weed_plant_t * quantise_events(weed_plant_t *in_list, double qfps, boolean allow_gap)
quantise from event_list_t *in_list to *out_list at the new rate of qfps
LIVES_GLOBAL_INLINE ticks_t q_gint64(ticks_t in, double fps)
LIVES_GLOBAL_INLINE ticks_t q_dbl(double in, double fps)
void check_string_choice_params(weed_plant_t *inst)
boolean on_rtew_delete_event(LiVESWidget *widget, LiVESXEventDelete *event, livespointer user_data)
void explain_missing_activate(LiVESMenuItem *menuitem, livespointer user_data)
void on_troubleshoot_activate(LiVESMenuItem *menuitem, livespointer user_data)
LiVESWidgetColor mt_timecode_bg
LiVESWidgetColor normal_fore
lives_colRGBA64_t mt_evbox
lives_colRGBA64_t mt_timeline_reg
LiVESWidgetColor menu_and_bars
LiVESWidgetColor normal_back
LiVESWidgetColor dark_red
LiVESWidgetColor light_green
lives_colRGBA64_t mt_mark
LiVESWidgetColor menu_and_bars_fore
LiVESWidgetColor mt_timecode_fg
int mt_auto_back
time diff to backup (-1 == never, 0 == after every change, > 0 == seconds)
boolean crash_recovery
TRUE==maintain mainw->recovery file.
boolean event_window_show_frame_events
boolean letterbox_mt
playback with letterbox (multitrack)
char workdir[PATH_MAX]
kept in locale encoding
boolean force64bit
< force system clock (rather than soundcard) for timing ( better for high framerates )
char ar_layout_name[PATH_MAX]
locale
boolean mt_pertrack_audio
char backend_sync[PATH_MAX *4]
LiVESWidget * aud_checkbutton
LiVESWidget * entry_asamps
LiVESWidget * rb_unsigned
LiVESWidget * entry_arate
LiVESWidget * entry_achans
lives_checkstatus_t has_mplayer2
lives_checkstatus_t has_mplayer
int seek_flag
plugin can change per frame
corresponds to one clip in the GUI
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
frames_t frames
number of video frames
frames_t tcache_dubious_from
height for thumbnail cache (width is fixed, but if this changes, invalidate)
void * ext_src
points to opaque source for non-disk types
lives_clip_type_t clip_type
int asampsize
audio sample size in bits (8 or 16)
lives_img_type_t img_type
frames_t stored_layout_frame
experimental for player
double stored_layout_audio
int vsize
frame height (vertical) in pixels
int achans
number of audio channels (0, 1 or 2)
boolean ratio_fps
framerate of the clip
LiVESList * tcache
set by clip alterations, frames from here onwards should be freed
uint32_t signed_endian
bitfield
double pb_fps
current playback rate, may vary from fps, can be 0. or negative
uint64_t unique_id
this and the handle can be used to uniquely id a file
char info_file[PATH_MAX]
used for asynch communication with externals
int hsize
frame width (horizontal) in pixels (NOT macropixels !)
char name[CLIP_NAME_MAXLEN]
the display name
int bpp
bits per pixel of the image frames, 24 or 32
int arate
current audio playback rate (varies if the clip rate is changed)
int stored_layout_idx
M highest value used.
lives_painter_surface_t * raudio_drawable
weed_plant_t * next_event
weed_plant_t * event_list
lives_painter_surface_t * laudio_drawable
LiVESWidget * textview_lrate
LiVESWidget * textview_fsize
LiVESWidget * textview_rrate
LiVESWidget * textview_type
LiVESWidget * textview_fps
LiVESWidget * textview_frames
LiVESWidget * textview_vtime
LiVESWidget * textview_size
int delegate
offset in list of current delegate
LiVESList * list
list of filter_idx from which user can delegate
LiVESXDevice * mouse_device
unused for gtk+ < 3.0.0
void * source
points to the source (e.g. a weed_plant_t)
frames_t frame
list of entries in clip thumbnail cache (for multitrack timeline)
LiVESList * xlays
immediately (to be) affected layout maps
LiVESWidget * m_sepwinbutton
LiVESWidget * m_rewindbutton
weed_plant_t * frame_layer
boolean stored_event_list_auto_changed
LiVESTextBuffer * layout_textbuffer
stores layout errors
size_t sl_undo_buffer_used
LiVESWidget * recent_submenu
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
int last_dprint_file
message output settings
char recent_file[PATH_MAX]
unsigned char * sl_undo_mem
LiVESWidget * vol_toolitem
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
boolean block_param_updates
block visual param changes from updating real values
LiVESWidget * recent[N_RECENT_FILES]
lives_mgeometry_t * mgeom
multi-head support
LiVESAccelGroup * accel_group
boolean reconfig
set to TRUE if a monitor / screen size change is detected
volatile boolean loop_cont
lives_painter_surface_t * raudio_drawable
char * string_constants[NUM_LIVES_STRING_CONSTANTS]
mt_opts multi_opts
some multitrack options that survive between mt calls
boolean no_interp
block interpolation (for single frame previews)
LiVESList * cliplist
hash table of clips in menu order
LiVESWidget * volume_scale
volatile lives_cancel_t cancelled
LiVESWidget * message_box
LiVESWidget * gens_submenu
LiVESWidget * play_window
int scrap_file
we throw odd sized frames here when recording in real time; used if a source is a generator or stream
LiVESList * affected_layout_marks
list of pairs of marks in affected_layouts_map, text between them should be deleted when stored_layou...
LiVESAdjustment * msg_adj
volatile boolean is_exiting
set during shutdown (inverse of only_close then)
weed_plant_t * filter_map
LiVESWidget * full_screen
ticks_t last_display_ticks
LiVESWidget * m_mutebutton
boolean recoverable_layout
int pre_src_file
video file we were playing before any ext input started
LiVESWidget * m_stopbutton
LiVESWidget * textwidget_focus
LiVESWidget * btoolbar
button toolbar - clip editor
lives_fx_candidate_t fx_candidates[MAX_FX_CANDIDATE_TYPES]
< effects which can have candidates from which a delegate is selected (current examples are: audio_vo...
LiVESWidget * m_loopbutton
LiVESWidget * show_layout_errors
weed_event_t * stored_event_list
stored mt -> clip editor
boolean unordered_blocks
are we recording unordered blocks ?
LiVESWidget * preview_box
LiVESWidget * spinbutton_start
LiVESList * current_layouts_map
map of all layouts for set
boolean recording_recovered
int ascrap_file
scrap file for recording audio scraps
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
LiVESList * stored_layout_undos
boolean stored_event_list_changed
lives_painter_surface_t * laudio_drawable
boolean internal_messaging
internal fx
boolean is_processing
states
lives_painter_surface_t * play_surface
int clipstore[FN_KEYS - 1][2]
stored clips (bookmarks) [0] = clip, [1] = frame
lives_painter_surface_t * msg_surface
LiVESWidget * m_playbutton
weed_plant_t * afilter_map
LiVESWidget * pl_eventbox
char stored_layout_name[PATH_MAX]
LiVESList * affected_layouts_map
map of layouts with errors
boolean mt_needs_idlefunc
set if we need to re-add the idlefunc for autobackup
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
LiVESWidget * msg_scrollbar
weed_event_t * event_list
current event_list, for recording
LiVESWidget * loop_continue
size_t data_len
including this mt_undo
LiVESWidget * pertrack_checkbutton
LiVESWidget * backaudio_checkbutton
LiVESWidget * always_checkbutton
boolean suggestion_followed
LiVESWidget * preview_button
#define lives_strdup_printf(fmt,...)
#define P_(String, StringPlural, n)
WEED_GLOBAL_INLINE int weed_filter_hints_unstable(weed_plant_t *filter)
WEED_GLOBAL_INLINE weed_plant_t * weed_param_get_template(weed_plant_t *param)
WEED_GLOBAL_INLINE int weed_chantmpl_is_optional(weed_plant_t *chantmpl)
WEED_GLOBAL_INLINE int weed_paramtmpl_get_type(weed_plant_t *paramtmpl)
WEED_GLOBAL_INLINE weed_plant_t ** weed_filter_get_out_chantmpls(weed_plant_t *filter, int *ntmpls)
WEED_GLOBAL_INLINE int weed_param_is_hidden(weed_plant_t *param, int temporary)
WEED_GLOBAL_INLINE char * weed_filter_get_package_name(weed_plant_t *filter)
WEED_GLOBAL_INLINE weed_plant_t ** weed_filter_get_in_paramtmpls(weed_plant_t *filter, int *ntmpls)
WEED_GLOBAL_INLINE weed_plant_t ** weed_instance_get_in_params(weed_plant_t *instance, int *nparams)