diff options
Diffstat (limited to 'source/blender/editors/space_clip/clip_ops.c')
-rw-r--r-- | source/blender/editors/space_clip/clip_ops.c | 1004 |
1 files changed, 1004 insertions, 0 deletions
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c new file mode 100644 index 00000000000..c52346fd4b6 --- /dev/null +++ b/source/blender/editors/space_clip/clip_ops.c @@ -0,0 +1,1004 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_ops.c + * \ingroup spclip + */ + +#include <errno.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_userdef_types.h" +#include "DNA_scene_types.h" /* min/max frames */ + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_report.h" +#include "BKE_main.h" +#include "BKE_library.h" +#include "BKE_movieclip.h" +#include "BKE_sound.h" +#include "BKE_tracking.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "UI_interface.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +/******************** view navigation utilities *********************/ + +static void sclip_zoom_set(SpaceClip *sc, ARegion *ar, float zoom) +{ + float oldzoom= sc->zoom; + int width, height; + + sc->zoom= zoom; + + if (sc->zoom > 0.1f && sc->zoom < 4.0f) + return; + + /* check zoom limits */ + ED_space_clip_size(sc, &width, &height); + + width*= sc->zoom; + height*= sc->zoom; + + if((width < 4) && (height < 4)) + sc->zoom= oldzoom; + else if((ar->winrct.xmax - ar->winrct.xmin) <= sc->zoom) + sc->zoom= oldzoom; + else if((ar->winrct.ymax - ar->winrct.ymin) <= sc->zoom) + sc->zoom= oldzoom; +} + +static void sclip_zoom_set_factor(SpaceClip *sc, ARegion *ar, float zoomfac) +{ + sclip_zoom_set(sc, ar, sc->zoom*zoomfac); +} + + +/******************** open clip operator ********************/ + +static void clip_filesel(bContext *C, wmOperator *op, const char *path) +{ + RNA_string_set(op->ptr, "filepath", path); + WM_event_add_fileselect(C, op); +} + +static void open_init(bContext *C, wmOperator *op) +{ + PropertyPointerRNA *pprop; + + op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); + uiIDContextProperty(C, &pprop->ptr, &pprop->prop); +} + +static int open_cancel(bContext *UNUSED(C), wmOperator *op) +{ + MEM_freeN(op->customdata); + op->customdata= NULL; + + return OPERATOR_CANCELLED; +} + +static int open_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + PropertyPointerRNA *pprop; + PointerRNA idptr; + MovieClip *clip= NULL; + char str[FILE_MAX]; + + RNA_string_get(op->ptr, "filepath", str); + /* default to frame 1 if there's no scene in context */ + + errno= 0; + + clip= BKE_add_movieclip_file(str); + + if(!clip) { + if(op->customdata) + MEM_freeN(op->customdata); + + BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, errno ? strerror(errno) : "Unsupported movie clip format"); + + return OPERATOR_CANCELLED; + } + + if(!op->customdata) + open_init(C, op); + + /* hook into UI */ + pprop= op->customdata; + + if(pprop->prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + clip->id.us--; + + RNA_id_pointer_create(&clip->id, &idptr); + RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr); + RNA_property_update(C, &pprop->ptr, pprop->prop); + } + else if(sc) { + ED_space_clip_set(C, sc, clip); + } + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_ADDED, clip); + + MEM_freeN(op->customdata); + + return OPERATOR_FINISHED; +} + +static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + char *path= U.textudir; + MovieClip *clip= NULL; + + if(sc) + clip= ED_space_clip(sc); + + if(clip) + path= clip->name; + + if(!RNA_property_is_set(op->ptr, "relative_path")) + RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS); + + if(RNA_property_is_set(op->ptr, "filepath")) + return open_exec(C, op); + + open_init(C, op); + + clip_filesel(C, op, path); + + return OPERATOR_RUNNING_MODAL; +} + +void CLIP_OT_open(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Open Clip"; + ot->description= "Open clip"; + ot->idname= "CLIP_OT_open"; + + /* api callbacks */ + ot->exec= open_exec; + ot->invoke= open_invoke; + ot->cancel= open_cancel; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); +} + +/******************* reload clip operator *********************/ + +static int reload_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= CTX_data_edit_movieclip(C); + + if(!clip) + return OPERATOR_CANCELLED; + + sc->scopes.ok= 0; + + BKE_movieclip_reload(clip); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_reload(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reload Clip"; + ot->description= "Reload clip"; + ot->idname= "CLIP_OT_reload"; + + /* api callbacks */ + ot->exec= reload_exec; +} + +/********************** view pan operator *********************/ + +typedef struct ViewPanData { + float x, y; + float xof, yof, xorig, yorig; + int event_type; + float *vec; +} ViewPanData; + +static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewPanData *vpd; + + op->customdata= vpd= MEM_callocN(sizeof(ViewPanData), "ClipViewPanData"); + WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR); + + vpd->x= event->x; + vpd->y= event->y; + + if(sc->flag&SC_LOCK_SELECTION) vpd->vec= &sc->xlockof; + else vpd->vec= &sc->xof; + + copy_v2_v2(&vpd->xof, vpd->vec); + copy_v2_v2(&vpd->xorig, &vpd->xof); + + vpd->event_type= event->type; + + WM_event_add_modal_handler(C, op); +} + +static void view_pan_exit(bContext *C, wmOperator *op, int cancel) +{ + ViewPanData *vpd= op->customdata; + + if(cancel) { + copy_v2_v2(vpd->vec, &vpd->xorig); + + ED_region_tag_redraw(CTX_wm_region(C)); + } + + WM_cursor_restore(CTX_wm_window(C)); + MEM_freeN(op->customdata); +} + +static int view_pan_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + float offset[2]; + + RNA_float_get_array(op->ptr, "offset", offset); + + if(sc->flag&SC_LOCK_SELECTION) { + sc->xlockof+= offset[0]; + sc->ylockof+= offset[1]; + } else { + sc->xof+= offset[0]; + sc->yof+= offset[1]; + } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (event->type==MOUSEPAN) { + SpaceClip *sc= CTX_wm_space_clip(C); + float offset[2]; + + offset[0]= (event->x - event->prevx)/sc->zoom; + offset[1]= (event->y - event->prevy)/sc->zoom; + + RNA_float_set_array(op->ptr, "offset", offset); + + view_pan_exec(C, op); + return OPERATOR_FINISHED; + } + else { + view_pan_init(C, op, event); + return OPERATOR_RUNNING_MODAL; + } +} + +static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewPanData *vpd= op->customdata; + float offset[2]; + + switch(event->type) { + case MOUSEMOVE: + copy_v2_v2(vpd->vec, &vpd->xorig); + offset[0]= (vpd->x - event->x)/sc->zoom; + offset[1]= (vpd->y - event->y)/sc->zoom; + RNA_float_set_array(op->ptr, "offset", offset); + view_pan_exec(C, op); + break; + case ESCKEY: + view_pan_exit(C, op, 1); + return OPERATOR_CANCELLED; + case SPACEKEY: + view_pan_exit(C, op, 0); + return OPERATOR_FINISHED; + default: + if(event->type==vpd->event_type && event->val==KM_RELEASE) { + view_pan_exit(C, op, 0); + return OPERATOR_FINISHED; + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int view_pan_cancel(bContext *C, wmOperator *op) +{ + view_pan_exit(C, op, 1); + + return OPERATOR_CANCELLED; +} + +void CLIP_OT_view_pan(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Pan"; + ot->idname= "CLIP_OT_view_pan"; + + /* api callbacks */ + ot->exec= view_pan_exec; + ot->invoke= view_pan_invoke; + ot->modal= view_pan_modal; + ot->cancel= view_pan_cancel; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_BLOCKING; + + /* properties */ + RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX, + "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); +} + +/********************** view zoom operator *********************/ + +typedef struct ViewZoomData { + float x, y; + float zoom; + int event_type; +} ViewZoomData; + +static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewZoomData *vpd; + + op->customdata= vpd= MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData"); + WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR); + + vpd->x= event->x; + vpd->y= event->y; + vpd->zoom= sc->zoom; + vpd->event_type= event->type; + + WM_event_add_modal_handler(C, op); +} + +static void view_zoom_exit(bContext *C, wmOperator *op, int cancel) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewZoomData *vpd= op->customdata; + + if(cancel) { + sc->zoom= vpd->zoom; + ED_region_tag_redraw(CTX_wm_region(C)); + } + + WM_cursor_restore(CTX_wm_window(C)); + MEM_freeN(op->customdata); +} + +static int view_zoom_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set_factor(sc, ar, RNA_float_get(op->ptr, "factor")); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (event->type==MOUSEZOOM) { + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + float factor; + + factor= 1.0f + (event->x-event->prevx+event->y-event->prevy)/300.0f; + RNA_float_set(op->ptr, "factor", factor); + sclip_zoom_set(sc, ar, sc->zoom*factor); + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; + } + else { + view_zoom_init(C, op, event); + return OPERATOR_RUNNING_MODAL; + } +} + +static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + ViewZoomData *vpd= op->customdata; + float factor; + + switch(event->type) { + case MOUSEMOVE: + factor= 1.0f + (vpd->x-event->x+vpd->y-event->y)/300.0f; + RNA_float_set(op->ptr, "factor", factor); + sclip_zoom_set(sc, ar, vpd->zoom*factor); + ED_region_tag_redraw(CTX_wm_region(C)); + break; + default: + if(event->type==vpd->event_type && event->val==KM_RELEASE) { + view_zoom_exit(C, op, 0); + return OPERATOR_FINISHED; + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int view_zoom_cancel(bContext *C, wmOperator *op) +{ + view_zoom_exit(C, op, 1); + return OPERATOR_CANCELLED; +} + +void CLIP_OT_view_zoom(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom"; + ot->idname= "CLIP_OT_view_zoom"; + + /* api callbacks */ + ot->exec= view_zoom_exec; + ot->invoke= view_zoom_invoke; + ot->modal= view_zoom_modal; + ot->cancel= view_zoom_cancel; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; + + /* properties */ + RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); +} + +/********************** view zoom in/out operator *********************/ + +static int view_zoom_in_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set_factor(sc, ar, 1.25f); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_zoom_out_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set_factor(sc, ar, 0.8f); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_zoom_inout_invoke(bContext *C, wmOperator *op, wmEvent *event, int out) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + float co[2], oldzoom= sc->zoom; + + ED_clip_mouse_pos(C, event, co); + + if(out) + view_zoom_out_exec(C, op); + else + view_zoom_in_exec(C, op); + + if(U.uiflag&USER_ZOOM_TO_MOUSEPOS) { + int width, height; + + ED_space_clip_size(sc, &width, &height); + + sc->xof+= ((co[0]-0.5)*width-sc->xof)*(sc->zoom-oldzoom)/sc->zoom; + sc->yof+= ((co[1]-0.5)*height-sc->yof)*(sc->zoom-oldzoom)/sc->zoom; + } + + return OPERATOR_FINISHED; +} + +static int view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return view_zoom_inout_invoke(C, op, event, 0); +} + +void CLIP_OT_view_zoom_in(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom In"; + ot->idname= "CLIP_OT_view_zoom_in"; + + /* api callbacks */ + ot->exec= view_zoom_in_exec; + ot->invoke= view_zoom_in_invoke; + ot->poll= ED_space_clip_poll; +} + +static int view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return view_zoom_inout_invoke(C, op, event, 1); +} + +void CLIP_OT_view_zoom_out(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom Out"; + ot->idname= "CLIP_OT_view_zoom_out"; + + /* api callbacks */ + ot->exec= view_zoom_out_exec; + ot->invoke= view_zoom_out_invoke; + ot->poll= ED_space_clip_poll; +} + +/********************** view zoom ratio operator *********************/ + +static int view_zoom_ratio_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set(sc, ar, RNA_float_get(op->ptr, "ratio")); + + /* ensure pixel exact locations for draw */ + sc->xof= (int)sc->xof; + sc->yof= (int)sc->yof; + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_view_zoom_ratio(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom Ratio"; + ot->idname= "CLIP_OT_view_zoom_ratio"; + + /* api callbacks */ + ot->exec= view_zoom_ratio_exec; + ot->poll= ED_space_clip_poll; + + /* properties */ + RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); +} + +/********************** view all operator *********************/ + +static int view_all_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc; + ARegion *ar; + int w, h, width, height; + float aspx, aspy; + + /* retrieve state */ + sc= CTX_wm_space_clip(C); + ar= CTX_wm_region(C); + + ED_space_clip_size(sc, &w, &h); + ED_space_clip_aspect(sc, &aspx, &aspy); + + w= w*aspx; + h= h*aspy; + + /* check if the image will fit in the image with zoom==1 */ + width= ar->winrct.xmax - ar->winrct.xmin + 1; + height= ar->winrct.ymax - ar->winrct.ymin + 1; + + if((w >= width || h >= height) && (width > 0 && height > 0)) { + float zoomx, zoomy; + + /* find the zoom value that will fit the image in the image space */ + zoomx= (float)width/w; + zoomy= (float)height/h; + sclip_zoom_set(sc, ar, 1.0f/power_of_2(1/MIN2(zoomx, zoomy))); + } + else + sclip_zoom_set(sc, ar, 1.0f); + + sc->xof= sc->yof= 0.0f; + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_view_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View All"; + ot->idname= "CLIP_OT_view_all"; + + /* api callbacks */ + ot->exec= view_all_exec; + ot->poll= ED_space_clip_poll; +} + +/********************** view selected operator *********************/ + +static int view_selected_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sc->xlockof= 0.0f; + sc->ylockof= 0.0f; + + ED_clip_view_selection(sc, ar, 1); + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_view_selected(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Selected"; + ot->idname= "CLIP_OT_view_selected"; + + /* api callbacks */ + ot->exec= view_selected_exec; + ot->poll= ED_space_clip_poll; +} + +/********************** change frame operator *********************/ + +static int change_frame_poll(bContext *C) +{ + /* prevent changes during render */ + if(G.rendering) + return 0; + + return ED_space_clip_poll(C); +} + +static void change_frame_apply(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + /* set the new frame number */ + CFRA= RNA_int_get(op->ptr, "frame"); + FRAMENUMBER_MIN_CLAMP(CFRA); + SUBFRA = 0.0f; + + /* do updates */ + sound_seek_scene(CTX_data_main(C), CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); +} + +static int change_frame_exec(bContext *C, wmOperator *op) +{ + change_frame_apply(C, op); + + return OPERATOR_FINISHED; +} + +static int frame_from_event(bContext *C, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); + int framenr= 0; + + if(ar->regiontype == RGN_TYPE_WINDOW) { + float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1); + + framenr= sfra+event->mval[0]/framelen; + } else { + float viewx, viewy; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy); + + framenr= (int)floor(viewx+0.5f); + } + + return framenr; +} + +static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + + if(ar->regiontype == RGN_TYPE_WINDOW) { + if(event->mval[1]>16) + return OPERATOR_PASS_THROUGH; + } + + RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); + + change_frame_apply(C, op); + + /* add temp handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + switch (event->type) { + case ESCKEY: + return OPERATOR_FINISHED; + + case MOUSEMOVE: + RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); + change_frame_apply(C, op); + break; + + case LEFTMOUSE: + case RIGHTMOUSE: + if (event->val==KM_RELEASE) + return OPERATOR_FINISHED; + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +void CLIP_OT_change_frame(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Change frame"; + ot->idname= "CLIP_OT_change_frame"; + ot->description= "Interactively change the current frame number"; + + /* api callbacks */ + ot->exec= change_frame_exec; + ot->invoke= change_frame_invoke; + ot->modal= change_frame_modal; + ot->poll= change_frame_poll; + + /* flags */ + ot->flag= OPTYPE_BLOCKING|OPTYPE_UNDO; + + /* rna */ + RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); +} + +/********************** rebuild proxies operator *********************/ + +typedef struct ProxyBuildJob { + Scene *scene; + struct Main *main; + MovieClip *clip; +} ProxyJob; + +static void proxy_freejob(void *pjv) +{ + ProxyJob *pj= pjv; + + MEM_freeN(pj); +} + +/* only this runs inside thread */ +static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress) +{ + ProxyJob *pj= pjv; + Scene *scene=pj->scene; + MovieClip *clip= pj->clip; + struct MovieDistortion *distortion= NULL; + int cfra, undistort; + short tc_flag, size_flag, quality, build_flag; + int sfra= SFRA, efra= EFRA; + int build_sizes[4], build_count= 0; + + tc_flag= clip->proxy.build_tc_flag; + size_flag= clip->proxy.build_size_flag; + quality= clip->proxy.quality; + build_flag= clip->proxy.build_flag; + undistort= build_flag&MCLIP_PROXY_RENDER_UNDISTORT; + + if(clip->source == MCLIP_SRC_MOVIE) { + if(clip->anim) + IMB_anim_index_rebuild(clip->anim, tc_flag, size_flag, quality, stop, do_update, progress); + + if(!undistort) { + return; + } + else { + sfra= 1; + efra= IMB_anim_get_duration(clip->anim, IMB_TC_NONE); + } + } + + if(size_flag&IMB_PROXY_25) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_25; + if(size_flag&IMB_PROXY_50) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_50; + if(size_flag&IMB_PROXY_75) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_75; + if(size_flag&IMB_PROXY_100) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_100; + + if(undistort) + distortion= BKE_tracking_distortion_create(); + + for(cfra= sfra; cfra<=efra; cfra++) { + if(clip->source != MCLIP_SRC_MOVIE) + BKE_movieclip_build_proxy_frame(clip, NULL, cfra, build_sizes, build_count, 0); + + if(undistort) + BKE_movieclip_build_proxy_frame(clip, distortion, cfra, build_sizes, build_count, 1); + + if(*stop || G.afbreek) + break; + + *do_update= 1; + *progress= ((float)cfra)/(efra-sfra); + } + + if(distortion) + BKE_tracking_distortion_destroy(distortion); +} + +static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) +{ + wmJob * steve; + ProxyJob *pj; + Scene *scene= CTX_data_scene(C); + ScrArea *sa= CTX_wm_area(C); + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + + if((clip->flag&MCLIP_USE_PROXY)==0) + return OPERATOR_CANCELLED; + + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies", WM_JOB_PROGRESS); + + pj= MEM_callocN(sizeof(ProxyJob), "proxy rebuild job"); + pj->scene= scene; + pj->main= CTX_data_main(C); + pj->clip= clip; + + WM_jobs_customdata(steve, pj, proxy_freejob); + WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|ND_DISPLAY, 0); + WM_jobs_callbacks(steve, proxy_startjob, NULL, NULL, NULL); + + G.afbreek= 0; + WM_jobs_start(CTX_wm_manager(C), steve); + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_rebuild_proxy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Rebuild Proxy and Timecode Indices"; + ot->idname= "CLIP_OT_rebuild_proxy"; + ot->description="Rebuild all selected proxies and timecode indeces using the job system"; + + /* api callbacks */ + ot->exec= sequencer_rebuild_proxy_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; +} + +/********************** mode set operator *********************/ + +static int mode_set_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + int mode= RNA_enum_get(op->ptr, "mode"); + int toggle= RNA_boolean_get(op->ptr, "toggle"); + + if(sc->mode==mode) { + if(toggle) + sc->mode= SC_MODE_TRACKING; + } else { + sc->mode= mode; + } + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CLIP, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_mode_set(wmOperatorType *ot) +{ + static EnumPropertyItem mode_items[] = { + {SC_MODE_TRACKING, "TRACKING", 0, "Tracking", "Show tracking and solving tools"}, + {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", 0, "Reconstruction", "Show tracking/reconstruction tools"}, + {SC_MODE_DISTORTION, "DISTORTION", 0, "Distortion", "Show distortion tools"}, + {0, NULL, 0, NULL, NULL}}; + + + /* identifiers */ + ot->name= "Set Clip Mode"; + ot->description = "Sets the clip interaction mode"; + ot->idname= "CLIP_OT_mode_set"; + + /* api callbacks */ + ot->exec= mode_set_exec; + + ot->poll= ED_space_clip_poll; + + /* properties */ + RNA_def_enum(ot->srna, "mode", mode_items, SC_MODE_TRACKING, "Mode", ""); + RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", ""); +} + +/********************** macroses *********************/ + +void ED_operatormacros_clip(void) +{ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot= WM_operatortype_append_macro("CLIP_OT_add_marker_move", "Add Marker and Move", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Add new marker and move it on movie"; + WM_operatortype_macro_define(ot, "CLIP_OT_add_marker"); + otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_struct_idprops_unset(otmacro->ptr, "release_confirm"); + + ot= WM_operatortype_append_macro("CLIP_OT_add_marker_slide", "Add Marker and Slide", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Add new marker and slide it with mouse until mouse button release"; + WM_operatortype_macro_define(ot, "CLIP_OT_add_marker"); + otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_boolean_set(otmacro->ptr, "release_confirm", 1); +} |