void widget_add_framedraw(LiVESVBox *box, int start, int end, boolean add_preview_button, int width, int height) { // adds the frame draw widget to box // the redraw button should be connected to an appropriate redraw function // after calling this function // an example of this is in 'trim frames' LiVESWidget *vseparator; LiVESWidget *vbox; LiVESWidget *hbox; LiVESWidget *label; LiVESAdjustment *spinbutton_adj; LiVESWidget *frame; lives_rfx_t *rfx; double fd_scale; b1_held=FALSE; mainw->framedraw_reset=NULL; vseparator = lives_vseparator_new(); lives_box_pack_start(LIVES_BOX(lives_widget_get_parent(LIVES_WIDGET(box))), vseparator, FALSE, FALSE, 0); lives_widget_show(vseparator); vbox = lives_vbox_new(FALSE, 0); lives_box_pack_start(LIVES_BOX(lives_widget_get_parent(LIVES_WIDGET(box))), vbox, FALSE, FALSE, 0); lives_container_set_border_width(LIVES_CONTAINER(vbox), widget_opts.border_width); fd_scale=calc_fd_scale(width,height); width/=fd_scale; height/=fd_scale; hbox = lives_hbox_new(FALSE, 0); lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, 0); fbord_eventbox=lives_event_box_new(); lives_container_set_border_width(LIVES_CONTAINER(fbord_eventbox),widget_opts.border_width); frame = lives_frame_new(NULL); lives_box_pack_start(LIVES_BOX(hbox), frame, FALSE, FALSE, 0); if (palette->style&STYLE_1) { lives_widget_set_bg_color(fbord_eventbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore); lives_widget_set_bg_color(frame, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back); lives_widget_set_fg_color(frame, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore); } mainw->fd_frame=frame; label = lives_standard_label_new(_("Preview")); lives_frame_set_label_widget(LIVES_FRAME(frame), label); lives_frame_set_shadow_type(LIVES_FRAME(frame), LIVES_SHADOW_NONE); mainw->framedraw=lives_event_box_new(); lives_widget_set_size_request(mainw->framedraw, width, height); lives_container_set_border_width(LIVES_CONTAINER(mainw->framedraw),1); lives_widget_set_events(mainw->framedraw, LIVES_BUTTON1_MOTION_MASK | LIVES_BUTTON_RELEASE_MASK | LIVES_BUTTON_PRESS_MASK| LIVES_ENTER_NOTIFY_MASK | LIVES_LEAVE_NOTIFY_MASK); mainw->framedraw_frame=start; lives_container_add(LIVES_CONTAINER(frame), fbord_eventbox); lives_container_add(LIVES_CONTAINER(fbord_eventbox), mainw->framedraw); if (palette->style&STYLE_1) { lives_widget_set_bg_color(mainw->framedraw, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back); lives_widget_set_fg_color(mainw->framedraw, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore); } lives_signal_connect_after(LIVES_GUI_OBJECT(mainw->framedraw), LIVES_WIDGET_EXPOSE_EVENT, LIVES_GUI_CALLBACK(expose_fd_event), NULL); hbox = lives_hbox_new(FALSE, 2); lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, 0); mainw->framedraw_spinbutton = lives_standard_spin_button_new(_("_Frame"), TRUE,start,start,end,1.,10.,0,LIVES_BOX(hbox),NULL); spinbutton_adj=lives_spin_button_get_adjustment(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton)); mainw->framedraw_scale=lives_hscale_new(LIVES_ADJUSTMENT(spinbutton_adj)); lives_box_pack_start(LIVES_BOX(hbox), mainw->framedraw_scale, TRUE, TRUE, 0); lives_scale_set_draw_value(LIVES_SCALE(mainw->framedraw_scale),FALSE); rfx=(lives_rfx_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(lives_widget_get_toplevel(LIVES_WIDGET(box))),"rfx"); mainw->framedraw_preview = lives_button_new_from_stock(LIVES_STOCK_REFRESH,_("_Preview")); lives_box_pack_start(LIVES_BOX(hbox), mainw->framedraw_preview, TRUE, FALSE, 0); lives_widget_set_sensitive(mainw->framedraw_spinbutton,FALSE); lives_widget_set_sensitive(mainw->framedraw_scale,FALSE); lives_signal_connect(mainw->framedraw_preview, LIVES_WIDGET_CLICKED_SIGNAL,LIVES_GUI_CALLBACK(start_preview),rfx); lives_widget_show_all(vbox); if (!add_preview_button) { lives_widget_hide(mainw->framedraw_preview); } }
void on_live_tvcard_activate(LiVESMenuItem *menuitem, livespointer user_data) { int cardno=0; int new_file=mainw->first_free_file; int response; char *com,*tmp; char *fifofile=lives_strdup_printf("%s/tvpic.%d",prefs->tmpdir,capable->mainpid); char *chanstr; char *devstr; char *fname; LiVESWidget *card_dialog; lives_tvcardw_t *tvcardw; mainw->open_deint=FALSE; card_dialog=create_cdtrack_dialog(4,NULL); tvcardw=(lives_tvcardw_t *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(card_dialog),"tvcard_data"); response=lives_dialog_run(LIVES_DIALOG(card_dialog)); if (response==LIVES_RESPONSE_CANCEL) { lives_widget_destroy(card_dialog); lives_free(fifofile); lives_free(tvcardw); return; } cardno=(int)mainw->fx1_val; chanstr=lives_strdup_printf("%d",(int)mainw->fx2_val); if (lives_list_find(mainw->videodevs,LIVES_INT_TO_POINTER(cardno))) { lives_widget_destroy(card_dialog); do_card_in_use_error(); lives_free(chanstr); lives_free(fifofile); lives_free(tvcardw); return; } fname=lives_strdup_printf(_("TV card %d"),cardno); if (!get_new_handle(new_file,fname)) { lives_widget_destroy(card_dialog); lives_free(chanstr); lives_free(fifofile); lives_free(fname); lives_free(tvcardw); return; } devstr=lives_strdup_printf("/dev/video%d",cardno); if (!check_dev_busy(devstr)) { lives_widget_destroy(card_dialog); do_dev_busy_error(fname); lives_free(devstr); lives_free(chanstr); lives_free(fifofile); lives_free(fname); lives_free(tvcardw); return; } mainw->videodevs=lives_list_append(mainw->videodevs,LIVES_INT_TO_POINTER(cardno)); mainw->current_file=new_file; cfile->deinterlace=mainw->open_deint; unlink(fifofile); mkfifo(fifofile,S_IRUSR|S_IWUSR); if (!tvcardw->use_advanced) { com=lives_strdup_printf("%s open_tv_card \"%s\" \"%s\" \"%s\" \"%s\"",prefs->backend,cfile->handle,chanstr, devstr,fifofile); } else { double fps=0.; char *driver=NULL,*outfmt=NULL; int width=0,height=0; int input=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(tvcardw->spinbuttoni)); if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(tvcardw->radiobuttond))) { width=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(tvcardw->spinbuttonw)); height=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(tvcardw->spinbuttonh)); fps=lives_spin_button_get_value(LIVES_SPIN_BUTTON(tvcardw->spinbuttonf)); } driver=lives_combo_get_active_text(LIVES_COMBO(tvcardw->combod)); outfmt=lives_combo_get_active_text(LIVES_COMBO(tvcardw->comboo)); com=lives_strdup_printf("%s open_tv_card \"%s\" \"%s\" \"%s\" \"%s\" %d %d %d %.3f \"%s\" \"%s\"", prefs->backend,cfile->handle,chanstr, devstr,fifofile,input,width,height,fps,driver,outfmt); lives_free(driver); lives_free(outfmt); } lives_widget_destroy(card_dialog); lives_free(tvcardw); mainw->com_failed=FALSE; lives_system(com,FALSE); lives_free(com); if (mainw->com_failed) { mainw->com_failed=FALSE; lives_free(fname); lives_free(chanstr); lives_free(fifofile); lives_free(devstr); return; } if (!open_yuv4m_inner(fifofile,fname,new_file,YUV4_TYPE_TV,cardno)) { lives_free(fname); lives_free(chanstr); lives_free(fifofile); lives_free(devstr); return; } lives_snprintf(cfile->type,40,"%s",fname); d_print((tmp=lives_strdup_printf(_("Opened TV card %d (%s)"),cardno,devstr))); lives_free(tmp); lives_free(fname); lives_free(chanstr); lives_free(devstr); lives_free(fifofile); }
static void start_preview(LiVESButton *button, lives_rfx_t *rfx) { int i; char *com; lives_widget_set_sensitive(mainw->framedraw_preview,FALSE); lives_widget_context_update(); if (mainw->did_rfx_preview) { #ifndef IS_MINGW com=lives_strdup_printf("%s stopsubsub \"%s\" 2>/dev/null",prefs->backend_sync,cfile->handle); lives_system(com,TRUE); // try to stop any in-progress preview #else // get pid from backend FILE *rfile; ssize_t rlen; char val[16]; int pid; com=lives_strdup_printf("%s get_pid_for_handle \"%s\"",prefs->backend_sync,cfile->handle); rfile=popen(com,"r"); rlen=fread(val,1,16,rfile); pclose(rfile); memset(val+rlen,0,1); pid=atoi(val); lives_win32_kill_subprocesses(pid,TRUE); #endif lives_free(com); if (cfile->start==0) { cfile->start=1; cfile->end=cfile->frames; } do_rfx_cleanup(rfx); } #ifndef IS_MINGW com=lives_strdup_printf("%s clear_pre_files \"%s\" 2>/dev/null",prefs->backend_sync,cfile->handle); #else com=lives_strdup_printf("%s clear_pre_files \"%s\" 2>NUL",prefs->backend_sync,cfile->handle); #endif lives_system(com,TRUE); // clear any .pre files from before for (i=0; i<rfx->num_params; i++) { rfx->params[i].changed=FALSE; } mainw->cancelled=CANCEL_NONE; mainw->error=FALSE; // within do_effect() we check and if do_effect(rfx,TRUE); // actually start effect processing in the background lives_widget_set_sensitive(mainw->framedraw_spinbutton,TRUE); lives_widget_set_sensitive(mainw->framedraw_scale,TRUE); if (mainw->framedraw_frame>cfile->start&&!(cfile->start==0&&mainw->framedraw_frame==1)) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton),cfile->start); else { load_rfx_preview(rfx); } mainw->did_rfx_preview=TRUE; }
void load_rfx_preview(lives_rfx_t *rfx) { // load a preview of an rfx (rendered effect) in clip editor LiVESPixbuf *pixbuf; FILE *infofile=NULL; int max_frame=0,tot_frames=0; int vend=cfile->start; int retval; int alarm_handle; int current_file=mainw->current_file; boolean retb; boolean timeout; weed_timecode_t tc; const char *img_ext; if (mainw->framedraw_frame==0) mainw->framedraw_frame=1; lives_set_cursor_style(LIVES_CURSOR_BUSY,NULL); clear_mainw_msg(); mainw->write_failed=FALSE; #define LIVES_RFX_TIMER 10*U_SEC if (cfile->clip_type==CLIP_TYPE_FILE&&vend<=cfile->end) { // pull some frames for 10 seconds alarm_handle=lives_alarm_set(LIVES_RFX_TIMER); do { lives_widget_context_update(); if (is_virtual_frame(mainw->current_file,vend)) { retb=virtual_to_images(mainw->current_file,vend,vend,FALSE,NULL); if (!retb) return; } vend++; timeout=lives_alarm_get(alarm_handle); } while (vend<=cfile->end&&!timeout&&!mainw->cancelled); lives_alarm_clear(alarm_handle); } if (mainw->cancelled) { lives_set_cursor_style(LIVES_CURSOR_NORMAL,NULL); return; } // get message from back end processor while (!(infofile=fopen(cfile->info_file,"r"))&&!mainw->cancelled) { // wait until we get at least 1 frame lives_widget_context_update(); if (cfile->clip_type==CLIP_TYPE_FILE&&vend<=cfile->end) { // if we have a virtual clip (frames inside a video file) // pull some more frames to images to get us started do { retb=FALSE; if (is_virtual_frame(mainw->current_file,vend)) { retb=virtual_to_images(mainw->current_file,vend,vend,FALSE,NULL); if (!retb) { fclose(infofile); return; } } vend++; } while (vend<=cfile->end&&!retb); } else { // otherwise wait lives_usleep(prefs->sleep_time); } } if (mainw->cancelled) { if (infofile) fclose(infofile); lives_set_cursor_style(LIVES_CURSOR_NORMAL,NULL); return; } do { retval=0; mainw->read_failed=FALSE; lives_fgets(mainw->msg,512,infofile); if (mainw->read_failed) retval=do_read_failed_error_s_with_retry(cfile->info_file,NULL,NULL); } while (retval==LIVES_RESPONSE_RETRY); fclose(infofile); if (strncmp(mainw->msg,"completed",9)) { if (rfx->num_in_channels>0) { max_frame=atoi(mainw->msg); } else { int numtok=get_token_count(mainw->msg,'|'); if (numtok>4) { char **array=lives_strsplit(mainw->msg,"|",numtok); max_frame=atoi(array[0]); cfile->hsize=atoi(array[1]); cfile->vsize=atoi(array[2]); cfile->fps=cfile->pb_fps=strtod(array[3],NULL); if (cfile->fps==0) cfile->fps=cfile->pb_fps=prefs->default_fps; tot_frames=atoi(array[4]); lives_strfreev(array); } } } else { max_frame=cfile->end; } lives_set_cursor_style(LIVES_CURSOR_NORMAL,NULL); if (max_frame>0) { if (rfx->num_in_channels==0) { int maxlen=calc_spin_button_width(1.,(double)tot_frames,0); lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton),1,tot_frames); lives_entry_set_width_chars(LIVES_ENTRY(mainw->framedraw_spinbutton),maxlen); lives_widget_queue_draw(mainw->framedraw_spinbutton); lives_widget_queue_draw(mainw->framedraw_scale); } if (mainw->framedraw_frame>max_frame) { lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->framedraw_spinbutton),max_frame); mainw->current_file=current_file; return; } } if (rfx->num_in_channels>0) { img_ext="pre"; } else { img_ext=get_image_ext_for_type(cfile->img_type); } tc=((mainw->framedraw_frame-1.))/cfile->fps*U_SECL; pixbuf=pull_lives_pixbuf_at_size(mainw->current_file,mainw->framedraw_frame,(char *)img_ext, tc,(double)cfile->hsize, (double)cfile->vsize,LIVES_INTERP_BEST); load_framedraw_image(pixbuf); redraw_framedraw_image(); mainw->current_file=current_file; }
void framedraw_redraw(lives_special_framedraw_rect_t *framedraw, boolean reload, LiVESPixbuf *pixbuf) { // this will draw the mask (framedraw_bitmap) and optionally reload the image // and then combine them int fd_height; int fd_width; int width,height; double xstartf,ystartf,xendf,yendf; lives_painter_t *cr; if (mainw->current_file<1||cfile==NULL) return; if (framedraw->rfx->source_type==LIVES_RFX_SOURCE_RFX) if (noupdate) return; fd_width=lives_widget_get_allocation_width(mainw->framedraw); fd_height=lives_widget_get_allocation_height(mainw->framedraw); width=cfile->hsize; height=cfile->vsize; calc_maxspect(fd_width,fd_height,&width,&height); // copy from orig, resize // copy orig layer to layer if (mainw->fd_layer!=NULL) { weed_layer_free(mainw->fd_layer); mainw->fd_layer=NULL; } if (reload||mainw->fd_layer_orig==NULL) load_framedraw_image(pixbuf); mainw->fd_layer=weed_layer_copy(NULL,mainw->fd_layer_orig); // resize to correct size resize_layer(mainw->fd_layer, width, height, LIVES_INTERP_BEST, WEED_PALETTE_END, 0); cr=layer_to_lives_painter(mainw->fd_layer); // draw on the lives_painter // her we dont offset because we are drawing in the pixbuf, not the widget switch (framedraw->type) { case LIVES_PARAM_SPECIAL_TYPE_RECT_MULTRECT: // deprecated // scale values if (framedraw->xstart_param->dp==0) { xstartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf/(double)cfile->hsize*(double)width; } else { xstartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf*(double)width; } if (framedraw->xend_param->dp==0) { xendf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf/(double)cfile->hsize*(double)width; } else { xendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf*(double)width; } if (framedraw->ystart_param->dp==0) { ystartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf/(double)cfile->vsize*(double)height; } else { ystartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf*(double)height; } if (framedraw->yend_param->dp==0) { yendf=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf/(double)cfile->vsize*(double)height; } else { yendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf*(double)height; } lives_painter_set_source_rgb(cr, 1., 0., 0.); lives_painter_rectangle(cr,xstartf-1.,ystartf-1.,xendf+2.,yendf+2.); lives_painter_stroke(cr); break; case LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT: case LIVES_PARAM_SPECIAL_TYPE_RECT_DEMASK: if (framedraw->xstart_param->dp==0) { xstartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf/(double)cfile->hsize*(double)width; } else { xstartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf*(double)width; } if (framedraw->xend_param->dp==0) { xendf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf/(double)cfile->hsize*(double)width; } else { xendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf*(double)width; } if (framedraw->ystart_param->dp==0) { ystartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf/(double)cfile->vsize*(double)height; } else { ystartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf*(double)height; } if (framedraw->yend_param->dp==0) { yendf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf/(double)cfile->vsize*(double)height; } else { yendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf*(double)height; } if (b1_held||framedraw->type==LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT) { lives_painter_set_source_rgb(cr, 1., 0., 0.); lives_painter_rectangle(cr,xstartf-1.,ystartf-1.,xendf-xstartf+2.,yendf-ystartf+2.); lives_painter_stroke(cr); } else { if (!b1_held) { // create a mask which is only opaque within the clipping area lives_painter_rectangle(cr,0,0,width,height); lives_painter_rectangle(cr,xstartf,ystartf,xendf-xstartf+1.,yendf-ystartf+1.); lives_painter_set_operator(cr, LIVES_PAINTER_OPERATOR_DEST_OUT); lives_painter_set_source_rgba(cr, .0, .0, .0, .5); lives_painter_set_fill_rule(cr, LIVES_PAINTER_FILL_RULE_EVEN_ODD); lives_painter_fill(cr); } } break; case LIVES_PARAM_SPECIAL_TYPE_SINGLEPOINT: if (framedraw->xstart_param->dp==0) { xstartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf/(double)cfile->hsize*(double)width; } else { xstartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf*(double)width; } if (framedraw->ystart_param->dp==0) { ystartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf/(double)cfile->vsize*(double)height; } else { ystartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf*(double)height; } lives_painter_set_source_rgb(cr, 1., 0., 0.); lives_painter_move_to(cr,xstartf,ystartf-3); lives_painter_line_to(cr,xstartf,ystartf+3); lives_painter_stroke(cr); lives_painter_move_to(cr,xstartf-3,ystartf); lives_painter_line_to(cr,xstartf+3,ystartf); lives_painter_stroke(cr); break; default: break; } lives_painter_to_layer(cr, mainw->fd_layer); lives_painter_destroy(cr); redraw_framedraw_image(); }