Blender V2.61 - r43446

clip_ops.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2011 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  *
00022  * Contributor(s): Blender Foundation,
00023  *                 Sergey Sharybin
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00032 #include <errno.h>
00033 
00034 #include "MEM_guardedalloc.h"
00035 
00036 #include "DNA_userdef_types.h"
00037 #include "DNA_scene_types.h"    /* min/max frames */
00038 
00039 #include "BLI_utildefines.h"
00040 #include "BLI_math.h"
00041 
00042 #include "BKE_context.h"
00043 #include "BKE_global.h"
00044 #include "BKE_report.h"
00045 #include "BKE_main.h"
00046 #include "BKE_library.h"
00047 #include "BKE_movieclip.h"
00048 #include "BKE_sound.h"
00049 #include "BKE_tracking.h"
00050 
00051 #include "WM_api.h"
00052 #include "WM_types.h"
00053 
00054 #include "IMB_imbuf_types.h"
00055 #include "IMB_imbuf.h"
00056 
00057 #include "ED_screen.h"
00058 #include "ED_clip.h"
00059 
00060 #include "UI_interface.h"
00061 
00062 #include "RNA_access.h"
00063 #include "RNA_define.h"
00064 
00065 #include "UI_view2d.h"
00066 
00067 #include "clip_intern.h"    // own include
00068 
00069 /******************** view navigation utilities *********************/
00070 
00071 static void sclip_zoom_set(SpaceClip *sc, ARegion *ar, float zoom)
00072 {
00073     float oldzoom= sc->zoom;
00074     int width, height;
00075 
00076     sc->zoom= zoom;
00077 
00078     if (sc->zoom > 0.1f && sc->zoom < 4.0f)
00079         return;
00080 
00081     /* check zoom limits */
00082     ED_space_clip_size(sc, &width, &height);
00083 
00084     width*= sc->zoom;
00085     height*= sc->zoom;
00086 
00087     if((width < 4) && (height < 4))
00088         sc->zoom= oldzoom;
00089     else if((ar->winrct.xmax - ar->winrct.xmin) <= sc->zoom)
00090         sc->zoom= oldzoom;
00091     else if((ar->winrct.ymax - ar->winrct.ymin) <= sc->zoom)
00092         sc->zoom= oldzoom;
00093 }
00094 
00095 static void sclip_zoom_set_factor(SpaceClip *sc, ARegion *ar, float zoomfac)
00096 {
00097     sclip_zoom_set(sc, ar, sc->zoom*zoomfac);
00098 }
00099 
00100 
00101 /******************** open clip operator ********************/
00102 
00103 static void clip_filesel(bContext *C, wmOperator *op, const char *path)
00104 {
00105     RNA_string_set(op->ptr, "filepath", path);
00106     WM_event_add_fileselect(C, op);
00107 }
00108 
00109 static void open_init(bContext *C, wmOperator *op)
00110 {
00111     PropertyPointerRNA *pprop;
00112 
00113     op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
00114     uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
00115 }
00116 
00117 static int open_cancel(bContext *UNUSED(C), wmOperator *op)
00118 {
00119     MEM_freeN(op->customdata);
00120     op->customdata= NULL;
00121 
00122     return OPERATOR_CANCELLED;
00123 }
00124 
00125 static int open_exec(bContext *C, wmOperator *op)
00126 {
00127     SpaceClip *sc= CTX_wm_space_clip(C);
00128     PropertyPointerRNA *pprop;
00129     PointerRNA idptr;
00130     MovieClip *clip= NULL;
00131     char str[FILE_MAX];
00132 
00133     RNA_string_get(op->ptr, "filepath", str);
00134     /* default to frame 1 if there's no scene in context */
00135 
00136     errno= 0;
00137 
00138     clip= BKE_add_movieclip_file(str);
00139 
00140     if(!clip) {
00141         if(op->customdata)
00142             MEM_freeN(op->customdata);
00143 
00144         BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, errno ? strerror(errno) : "Unsupported movie clip format");
00145 
00146         return OPERATOR_CANCELLED;
00147     }
00148 
00149     if(!op->customdata)
00150         open_init(C, op);
00151 
00152     /* hook into UI */
00153     pprop= op->customdata;
00154 
00155     if(pprop->prop) {
00156         /* when creating new ID blocks, use is already 1, but RNA
00157          * pointer se also increases user, so this compensates it */
00158         clip->id.us--;
00159 
00160         RNA_id_pointer_create(&clip->id, &idptr);
00161         RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
00162         RNA_property_update(C, &pprop->ptr, pprop->prop);
00163     }
00164     else if(sc) {
00165         ED_space_clip_set(C, sc, clip);
00166     }
00167 
00168     WM_event_add_notifier(C, NC_MOVIECLIP|NA_ADDED, clip);
00169 
00170     MEM_freeN(op->customdata);
00171 
00172     return OPERATOR_FINISHED;
00173 }
00174 
00175 static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00176 {
00177     SpaceClip *sc= CTX_wm_space_clip(C);
00178     char *path= U.textudir;
00179     MovieClip *clip= NULL;
00180 
00181     if(sc)
00182         clip= ED_space_clip(sc);
00183 
00184     if(clip)
00185         path= clip->name;
00186 
00187     if(!RNA_struct_property_is_set(op->ptr, "relative_path"))
00188         RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
00189 
00190     if(RNA_struct_property_is_set(op->ptr, "filepath"))
00191         return open_exec(C, op);
00192 
00193     open_init(C, op);
00194 
00195     clip_filesel(C, op, path);
00196 
00197     return OPERATOR_RUNNING_MODAL;
00198 }
00199 
00200 void CLIP_OT_open(wmOperatorType *ot)
00201 {
00202     /* identifiers */
00203     ot->name= "Open Clip";
00204     ot->description= "Load a sequence of frames or a movie file";
00205     ot->idname= "CLIP_OT_open";
00206 
00207     /* api callbacks */
00208     ot->exec= open_exec;
00209     ot->invoke= open_invoke;
00210     ot->cancel= open_cancel;
00211 
00212     /* flags */
00213     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00214 
00215     /* properties */
00216     WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
00217 }
00218 
00219 /******************* reload clip operator *********************/
00220 
00221 static int reload_exec(bContext *C, wmOperator *UNUSED(op))
00222 {
00223     MovieClip *clip= CTX_data_edit_movieclip(C);
00224 
00225     if(!clip)
00226         return OPERATOR_CANCELLED;
00227 
00228     BKE_movieclip_reload(clip);
00229 
00230     WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
00231 
00232     return OPERATOR_FINISHED;
00233 }
00234 
00235 void CLIP_OT_reload(wmOperatorType *ot)
00236 {
00237     /* identifiers */
00238     ot->name= "Reload Clip";
00239     ot->description= "Reload clip";
00240     ot->idname= "CLIP_OT_reload";
00241 
00242     /* api callbacks */
00243     ot->exec= reload_exec;
00244 }
00245 
00246 /********************** view pan operator *********************/
00247 
00248 typedef struct ViewPanData {
00249     float x, y;
00250     float xof, yof, xorig, yorig;
00251     int event_type;
00252     float *vec;
00253 } ViewPanData;
00254 
00255 static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event)
00256 {
00257     SpaceClip *sc= CTX_wm_space_clip(C);
00258     ViewPanData *vpd;
00259 
00260     op->customdata= vpd= MEM_callocN(sizeof(ViewPanData), "ClipViewPanData");
00261     WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR);
00262 
00263     vpd->x= event->x;
00264     vpd->y= event->y;
00265 
00266     if(sc->flag&SC_LOCK_SELECTION) vpd->vec= &sc->xlockof;
00267     else vpd->vec= &sc->xof;
00268 
00269     copy_v2_v2(&vpd->xof, vpd->vec);
00270     copy_v2_v2(&vpd->xorig, &vpd->xof);
00271 
00272     vpd->event_type= event->type;
00273 
00274     WM_event_add_modal_handler(C, op);
00275 }
00276 
00277 static void view_pan_exit(bContext *C, wmOperator *op, int cancel)
00278 {
00279     ViewPanData *vpd= op->customdata;
00280 
00281     if(cancel) {
00282         copy_v2_v2(vpd->vec, &vpd->xorig);
00283 
00284         ED_region_tag_redraw(CTX_wm_region(C));
00285     }
00286 
00287     WM_cursor_restore(CTX_wm_window(C));
00288     MEM_freeN(op->customdata);
00289 }
00290 
00291 static int view_pan_exec(bContext *C, wmOperator *op)
00292 {
00293     SpaceClip *sc= CTX_wm_space_clip(C);
00294     float offset[2];
00295 
00296     RNA_float_get_array(op->ptr, "offset", offset);
00297 
00298     if(sc->flag&SC_LOCK_SELECTION) {
00299         sc->xlockof+= offset[0];
00300         sc->ylockof+= offset[1];
00301     } else {
00302         sc->xof+= offset[0];
00303         sc->yof+= offset[1];
00304     }
00305 
00306     ED_region_tag_redraw(CTX_wm_region(C));
00307 
00308     return OPERATOR_FINISHED;
00309 }
00310 
00311 static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
00312 {
00313     if (event->type==MOUSEPAN) {
00314         SpaceClip *sc= CTX_wm_space_clip(C);
00315         float offset[2];
00316 
00317         offset[0]= (event->x - event->prevx)/sc->zoom;
00318         offset[1]= (event->y - event->prevy)/sc->zoom;
00319 
00320         RNA_float_set_array(op->ptr, "offset", offset);
00321 
00322         view_pan_exec(C, op);
00323         return OPERATOR_FINISHED;
00324     }
00325     else {
00326         view_pan_init(C, op, event);
00327         return OPERATOR_RUNNING_MODAL;
00328     }
00329 }
00330 
00331 static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
00332 {
00333     SpaceClip *sc= CTX_wm_space_clip(C);
00334     ViewPanData *vpd= op->customdata;
00335     float offset[2];
00336 
00337     switch(event->type) {
00338         case MOUSEMOVE:
00339             copy_v2_v2(vpd->vec, &vpd->xorig);
00340             offset[0]= (vpd->x - event->x)/sc->zoom;
00341             offset[1]= (vpd->y - event->y)/sc->zoom;
00342             RNA_float_set_array(op->ptr, "offset", offset);
00343             view_pan_exec(C, op);
00344             break;
00345         case ESCKEY:
00346             view_pan_exit(C, op, 1);
00347             return OPERATOR_CANCELLED;
00348         case SPACEKEY:
00349             view_pan_exit(C, op, 0);
00350             return OPERATOR_FINISHED;
00351         default:
00352             if(event->type==vpd->event_type &&  event->val==KM_RELEASE) {
00353                 view_pan_exit(C, op, 0);
00354                 return OPERATOR_FINISHED;
00355             }
00356             break;
00357     }
00358 
00359     return OPERATOR_RUNNING_MODAL;
00360 }
00361 
00362 static int view_pan_cancel(bContext *C, wmOperator *op)
00363 {
00364     view_pan_exit(C, op, 1);
00365 
00366     return OPERATOR_CANCELLED;
00367 }
00368 
00369 void CLIP_OT_view_pan(wmOperatorType *ot)
00370 {
00371     /* identifiers */
00372     ot->name= "View Pan";
00373     ot->idname= "CLIP_OT_view_pan";
00374 
00375     /* api callbacks */
00376     ot->exec= view_pan_exec;
00377     ot->invoke= view_pan_invoke;
00378     ot->modal= view_pan_modal;
00379     ot->cancel= view_pan_cancel;
00380     ot->poll= ED_space_clip_poll;
00381 
00382     /* flags */
00383     ot->flag= OPTYPE_BLOCKING;
00384 
00385     /* properties */
00386     RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX,
00387         "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX);
00388 }
00389 
00390 /********************** view zoom operator *********************/
00391 
00392 typedef struct ViewZoomData {
00393     float x, y;
00394     float zoom;
00395     int event_type;
00396 } ViewZoomData;
00397 
00398 static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event)
00399 {
00400     SpaceClip *sc= CTX_wm_space_clip(C);
00401     ViewZoomData *vpd;
00402 
00403     op->customdata= vpd= MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData");
00404     WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR);
00405 
00406     vpd->x= event->x;
00407     vpd->y= event->y;
00408     vpd->zoom= sc->zoom;
00409     vpd->event_type= event->type;
00410 
00411     WM_event_add_modal_handler(C, op);
00412 }
00413 
00414 static void view_zoom_exit(bContext *C, wmOperator *op, int cancel)
00415 {
00416     SpaceClip *sc= CTX_wm_space_clip(C);
00417     ViewZoomData *vpd= op->customdata;
00418 
00419     if(cancel) {
00420         sc->zoom= vpd->zoom;
00421         ED_region_tag_redraw(CTX_wm_region(C));
00422     }
00423 
00424     WM_cursor_restore(CTX_wm_window(C));
00425     MEM_freeN(op->customdata);
00426 }
00427 
00428 static int view_zoom_exec(bContext *C, wmOperator *op)
00429 {
00430     SpaceClip *sc= CTX_wm_space_clip(C);
00431     ARegion *ar= CTX_wm_region(C);
00432 
00433     sclip_zoom_set_factor(sc, ar, RNA_float_get(op->ptr, "factor"));
00434 
00435     ED_region_tag_redraw(CTX_wm_region(C));
00436 
00437     return OPERATOR_FINISHED;
00438 }
00439 
00440 static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
00441 {
00442     if (event->type==MOUSEZOOM) {
00443         SpaceClip *sc= CTX_wm_space_clip(C);
00444         ARegion *ar= CTX_wm_region(C);
00445         float factor;
00446 
00447         factor= 1.0f + (event->x-event->prevx+event->y-event->prevy)/300.0f;
00448         RNA_float_set(op->ptr, "factor", factor);
00449         sclip_zoom_set(sc, ar, sc->zoom*factor);
00450         ED_region_tag_redraw(CTX_wm_region(C));
00451 
00452         return OPERATOR_FINISHED;
00453     }
00454     else {
00455         view_zoom_init(C, op, event);
00456         return OPERATOR_RUNNING_MODAL;
00457     }
00458 }
00459 
00460 static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
00461 {
00462     SpaceClip *sc= CTX_wm_space_clip(C);
00463     ARegion *ar= CTX_wm_region(C);
00464     ViewZoomData *vpd= op->customdata;
00465     float factor;
00466 
00467     switch(event->type) {
00468         case MOUSEMOVE:
00469             factor= 1.0f + (vpd->x-event->x+vpd->y-event->y)/300.0f;
00470             RNA_float_set(op->ptr, "factor", factor);
00471             sclip_zoom_set(sc, ar, vpd->zoom*factor);
00472             ED_region_tag_redraw(CTX_wm_region(C));
00473             break;
00474         default:
00475             if(event->type==vpd->event_type && event->val==KM_RELEASE) {
00476                 view_zoom_exit(C, op, 0);
00477                 return OPERATOR_FINISHED;
00478             }
00479             break;
00480     }
00481 
00482     return OPERATOR_RUNNING_MODAL;
00483 }
00484 
00485 static int view_zoom_cancel(bContext *C, wmOperator *op)
00486 {
00487     view_zoom_exit(C, op, 1);
00488     return OPERATOR_CANCELLED;
00489 }
00490 
00491 void CLIP_OT_view_zoom(wmOperatorType *ot)
00492 {
00493     /* identifiers */
00494     ot->name= "View Zoom";
00495     ot->idname= "CLIP_OT_view_zoom";
00496 
00497     /* api callbacks */
00498     ot->exec= view_zoom_exec;
00499     ot->invoke= view_zoom_invoke;
00500     ot->modal= view_zoom_modal;
00501     ot->cancel= view_zoom_cancel;
00502     ot->poll= ED_space_clip_poll;
00503 
00504     /* flags */
00505     ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
00506 
00507     /* properties */
00508     RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX,
00509         "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX);
00510 }
00511 
00512 /********************** view zoom in/out operator *********************/
00513 
00514 static int view_zoom_in_exec(bContext *C, wmOperator *UNUSED(op))
00515 {
00516     SpaceClip *sc= CTX_wm_space_clip(C);
00517     ARegion *ar= CTX_wm_region(C);
00518 
00519     sclip_zoom_set_factor(sc, ar, 1.25f);
00520 
00521     ED_region_tag_redraw(CTX_wm_region(C));
00522 
00523     return OPERATOR_FINISHED;
00524 }
00525 
00526 static int view_zoom_out_exec(bContext *C, wmOperator *UNUSED(op))
00527 {
00528     SpaceClip *sc= CTX_wm_space_clip(C);
00529     ARegion *ar= CTX_wm_region(C);
00530 
00531     sclip_zoom_set_factor(sc, ar, 0.8f);
00532 
00533     ED_region_tag_redraw(CTX_wm_region(C));
00534 
00535     return OPERATOR_FINISHED;
00536 }
00537 
00538 static int view_zoom_inout_invoke(bContext *C, wmOperator *op, wmEvent *event, int out)
00539 {
00540     SpaceClip *sc= CTX_wm_space_clip(C);
00541     float co[2], oldzoom= sc->zoom;
00542 
00543     ED_clip_mouse_pos(C, event, co);
00544 
00545     if(out)
00546         view_zoom_out_exec(C, op);
00547     else
00548         view_zoom_in_exec(C, op);
00549 
00550     if(U.uiflag&USER_ZOOM_TO_MOUSEPOS) {
00551         int width, height;
00552 
00553         ED_space_clip_size(sc, &width, &height);
00554 
00555         sc->xof+= ((co[0]-0.5f)*width-sc->xof)*(sc->zoom-oldzoom)/sc->zoom;
00556         sc->yof+= ((co[1]-0.5f)*height-sc->yof)*(sc->zoom-oldzoom)/sc->zoom;
00557     }
00558 
00559     return OPERATOR_FINISHED;
00560 }
00561 
00562 static int view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event)
00563 {
00564     return view_zoom_inout_invoke(C, op, event, 0);
00565 }
00566 
00567 void CLIP_OT_view_zoom_in(wmOperatorType *ot)
00568 {
00569     /* identifiers */
00570     ot->name= "View Zoom In";
00571     ot->idname= "CLIP_OT_view_zoom_in";
00572 
00573     /* api callbacks */
00574     ot->exec= view_zoom_in_exec;
00575     ot->invoke= view_zoom_in_invoke;
00576     ot->poll= ED_space_clip_poll;
00577 }
00578 
00579 static int view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event)
00580 {
00581     return view_zoom_inout_invoke(C, op, event, 1);
00582 }
00583 
00584 void CLIP_OT_view_zoom_out(wmOperatorType *ot)
00585 {
00586     /* identifiers */
00587     ot->name= "View Zoom Out";
00588     ot->idname= "CLIP_OT_view_zoom_out";
00589 
00590     /* api callbacks */
00591     ot->exec= view_zoom_out_exec;
00592     ot->invoke= view_zoom_out_invoke;
00593     ot->poll= ED_space_clip_poll;
00594 }
00595 
00596 /********************** view zoom ratio operator *********************/
00597 
00598 static int view_zoom_ratio_exec(bContext *C, wmOperator *op)
00599 {
00600     SpaceClip *sc= CTX_wm_space_clip(C);
00601     ARegion *ar= CTX_wm_region(C);
00602 
00603     sclip_zoom_set(sc, ar, RNA_float_get(op->ptr, "ratio"));
00604 
00605     /* ensure pixel exact locations for draw */
00606     sc->xof= (int)sc->xof;
00607     sc->yof= (int)sc->yof;
00608 
00609     ED_region_tag_redraw(CTX_wm_region(C));
00610 
00611     return OPERATOR_FINISHED;
00612 }
00613 
00614 void CLIP_OT_view_zoom_ratio(wmOperatorType *ot)
00615 {
00616     /* identifiers */
00617     ot->name= "View Zoom Ratio";
00618     ot->idname= "CLIP_OT_view_zoom_ratio";
00619 
00620     /* api callbacks */
00621     ot->exec= view_zoom_ratio_exec;
00622     ot->poll= ED_space_clip_poll;
00623 
00624     /* properties */
00625     RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX,
00626         "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
00627 }
00628 
00629 /********************** view all operator *********************/
00630 
00631 static int view_all_exec(bContext *C, wmOperator *UNUSED(op))
00632 {
00633     SpaceClip *sc;
00634     ARegion *ar;
00635     int w, h, width, height;
00636     float aspx, aspy;
00637 
00638     /* retrieve state */
00639     sc= CTX_wm_space_clip(C);
00640     ar= CTX_wm_region(C);
00641 
00642     ED_space_clip_size(sc, &w, &h);
00643     ED_space_clip_aspect(sc, &aspx, &aspy);
00644 
00645     w= w*aspx;
00646     h= h*aspy;
00647 
00648     /* check if the image will fit in the image with zoom==1 */
00649     width= ar->winrct.xmax - ar->winrct.xmin + 1;
00650     height= ar->winrct.ymax - ar->winrct.ymin + 1;
00651 
00652     if((w >= width || h >= height) && (width > 0 && height > 0)) {
00653         float zoomx, zoomy;
00654 
00655         /* find the zoom value that will fit the image in the image space */
00656         zoomx= (float)width/w;
00657         zoomy= (float)height/h;
00658         sclip_zoom_set(sc, ar, 1.0f/power_of_2(1/MIN2(zoomx, zoomy)));
00659     }
00660     else
00661         sclip_zoom_set(sc, ar, 1.0f);
00662 
00663     sc->xof= sc->yof= 0.0f;
00664 
00665     ED_region_tag_redraw(CTX_wm_region(C));
00666 
00667     return OPERATOR_FINISHED;
00668 }
00669 
00670 void CLIP_OT_view_all(wmOperatorType *ot)
00671 {
00672     /* identifiers */
00673     ot->name= "View All";
00674     ot->idname= "CLIP_OT_view_all";
00675 
00676     /* api callbacks */
00677     ot->exec= view_all_exec;
00678     ot->poll= ED_space_clip_poll;
00679 }
00680 
00681 /********************** view selected operator *********************/
00682 
00683 static int view_selected_exec(bContext *C, wmOperator *UNUSED(op))
00684 {
00685     SpaceClip *sc= CTX_wm_space_clip(C);
00686     ARegion *ar= CTX_wm_region(C);
00687 
00688     sc->xlockof= 0.0f;
00689     sc->ylockof= 0.0f;
00690 
00691     ED_clip_view_selection(sc, ar, 1);
00692     ED_region_tag_redraw(CTX_wm_region(C));
00693 
00694     return OPERATOR_FINISHED;
00695 }
00696 
00697 void CLIP_OT_view_selected(wmOperatorType *ot)
00698 {
00699     /* identifiers */
00700     ot->name= "View Selected";
00701     ot->idname= "CLIP_OT_view_selected";
00702 
00703     /* api callbacks */
00704     ot->exec= view_selected_exec;
00705     ot->poll= ED_space_clip_poll;
00706 }
00707 
00708 /********************** change frame operator *********************/
00709 
00710 static int change_frame_poll(bContext *C)
00711 {
00712     /* prevent changes during render */
00713     if(G.rendering)
00714         return 0;
00715 
00716     return ED_space_clip_poll(C);
00717 }
00718 
00719 static void change_frame_apply(bContext *C, wmOperator *op)
00720 {
00721     Scene *scene= CTX_data_scene(C);
00722 
00723     /* set the new frame number */
00724     CFRA= RNA_int_get(op->ptr, "frame");
00725     FRAMENUMBER_MIN_CLAMP(CFRA);
00726     SUBFRA = 0.0f;
00727 
00728     /* do updates */
00729     sound_seek_scene(CTX_data_main(C), CTX_data_scene(C));
00730     WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
00731 }
00732 
00733 static int change_frame_exec(bContext *C, wmOperator *op)
00734 {
00735     change_frame_apply(C, op);
00736 
00737     return OPERATOR_FINISHED;
00738 }
00739 
00740 static int frame_from_event(bContext *C, wmEvent *event)
00741 {
00742     ARegion *ar= CTX_wm_region(C);
00743     Scene *scene= CTX_data_scene(C);
00744     int framenr= 0;
00745 
00746     if(ar->regiontype == RGN_TYPE_WINDOW) {
00747         float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1);
00748 
00749         framenr= sfra+event->mval[0]/framelen;
00750     } else {
00751         float viewx, viewy;
00752 
00753         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
00754 
00755         framenr= (int)floor(viewx+0.5f);
00756     }
00757 
00758     return framenr;
00759 }
00760 
00761 static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
00762 {
00763     ARegion *ar= CTX_wm_region(C);
00764 
00765     if(ar->regiontype == RGN_TYPE_WINDOW) {
00766         if(event->mval[1]>16)
00767             return OPERATOR_PASS_THROUGH;
00768     }
00769 
00770     RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
00771 
00772     change_frame_apply(C, op);
00773 
00774     /* add temp handler */
00775     WM_event_add_modal_handler(C, op);
00776 
00777     return OPERATOR_RUNNING_MODAL;
00778 }
00779 
00780 static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
00781 {
00782     switch (event->type) {
00783         case ESCKEY:
00784             return OPERATOR_FINISHED;
00785 
00786         case MOUSEMOVE:
00787             RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
00788             change_frame_apply(C, op);
00789             break;
00790 
00791         case LEFTMOUSE:
00792         case RIGHTMOUSE:
00793             if (event->val==KM_RELEASE)
00794                 return OPERATOR_FINISHED;
00795             break;
00796     }
00797 
00798     return OPERATOR_RUNNING_MODAL;
00799 }
00800 
00801 void CLIP_OT_change_frame(wmOperatorType *ot)
00802 {
00803     /* identifiers */
00804     ot->name= "Change frame";
00805     ot->idname= "CLIP_OT_change_frame";
00806     ot->description= "Interactively change the current frame number";
00807 
00808     /* api callbacks */
00809     ot->exec= change_frame_exec;
00810     ot->invoke= change_frame_invoke;
00811     ot->modal= change_frame_modal;
00812     ot->poll= change_frame_poll;
00813 
00814     /* flags */
00815     ot->flag= OPTYPE_BLOCKING|OPTYPE_UNDO;
00816 
00817     /* rna */
00818     RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
00819 }
00820 
00821 /********************** rebuild proxies operator *********************/
00822 
00823 typedef struct ProxyBuildJob {
00824     Scene *scene;
00825     struct Main *main;
00826     MovieClip *clip;
00827     int clip_flag;
00828 } ProxyJob;
00829 
00830 static void proxy_freejob(void *pjv)
00831 {
00832     ProxyJob *pj= pjv;
00833 
00834     MEM_freeN(pj);
00835 }
00836 
00837 /* only this runs inside thread */
00838 static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
00839 {
00840     ProxyJob *pj= pjv;
00841     Scene *scene=pj->scene;
00842     MovieClip *clip= pj->clip;
00843     struct MovieDistortion *distortion= NULL;
00844     int cfra, undistort;
00845     short tc_flag, size_flag, quality, build_flag;
00846     int sfra= SFRA, efra= EFRA;
00847     int build_sizes[4], build_count= 0;
00848 
00849     tc_flag= clip->proxy.build_tc_flag;
00850     size_flag= clip->proxy.build_size_flag;
00851     quality= clip->proxy.quality;
00852     build_flag= clip->proxy.build_flag;
00853     undistort= build_flag&MCLIP_PROXY_RENDER_UNDISTORT;
00854 
00855     if(clip->source == MCLIP_SRC_MOVIE) {
00856         if(clip->anim)
00857             IMB_anim_index_rebuild(clip->anim, tc_flag, size_flag, quality, stop, do_update, progress);
00858 
00859         if(!undistort) {
00860             return;
00861         }
00862         else {
00863             sfra= 1;
00864             efra= IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
00865         }
00866     }
00867 
00868     if(size_flag&IMB_PROXY_25) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_25;
00869     if(size_flag&IMB_PROXY_50) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_50;
00870     if(size_flag&IMB_PROXY_75) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_75;
00871     if(size_flag&IMB_PROXY_100) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_100;
00872 
00873     if(undistort)
00874         distortion= BKE_tracking_distortion_create();
00875 
00876     for(cfra= sfra; cfra<=efra; cfra++) {
00877         if(clip->source != MCLIP_SRC_MOVIE)
00878             BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, NULL, cfra, build_sizes, build_count, 0);
00879 
00880         if(undistort)
00881             BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra, build_sizes, build_count, 1);
00882 
00883         if(*stop || G.afbreek)
00884             break;
00885 
00886         *do_update= 1;
00887         *progress= ((float)cfra)/(efra-sfra);
00888     }
00889 
00890     if(distortion)
00891         BKE_tracking_distortion_destroy(distortion);
00892 }
00893 
00894 static int clip_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
00895 {
00896     wmJob * steve;
00897     ProxyJob *pj;
00898     Scene *scene= CTX_data_scene(C);
00899     ScrArea *sa= CTX_wm_area(C);
00900     SpaceClip *sc= CTX_wm_space_clip(C);
00901     MovieClip *clip= ED_space_clip(sc);
00902 
00903     if((clip->flag&MCLIP_USE_PROXY)==0)
00904         return OPERATOR_CANCELLED;
00905 
00906     steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies", WM_JOB_PROGRESS);
00907 
00908     pj= MEM_callocN(sizeof(ProxyJob), "proxy rebuild job");
00909     pj->scene= scene;
00910     pj->main= CTX_data_main(C);
00911     pj->clip= clip;
00912     pj->clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS;
00913 
00914     WM_jobs_customdata(steve, pj, proxy_freejob);
00915     WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|ND_DISPLAY, 0);
00916     WM_jobs_callbacks(steve, proxy_startjob, NULL, NULL, NULL);
00917 
00918     G.afbreek= 0;
00919     WM_jobs_start(CTX_wm_manager(C), steve);
00920 
00921     ED_area_tag_redraw(CTX_wm_area(C));
00922 
00923     return OPERATOR_FINISHED;
00924 }
00925 
00926 void CLIP_OT_rebuild_proxy(wmOperatorType *ot)
00927 {
00928     /* identifiers */
00929     ot->name= "Rebuild Proxy and Timecode Indices";
00930     ot->idname= "CLIP_OT_rebuild_proxy";
00931     ot->description= "Rebuild all selected proxies and timecode indices in the background";
00932 
00933     /* api callbacks */
00934     ot->exec= clip_rebuild_proxy_exec;
00935     ot->poll= ED_space_clip_poll;
00936 
00937     /* flags */
00938     ot->flag= OPTYPE_REGISTER;
00939 }
00940 
00941 /********************** mode set operator *********************/
00942 
00943 static int mode_set_exec(bContext *C, wmOperator *op)
00944 {
00945     SpaceClip *sc= CTX_wm_space_clip(C);
00946     int mode= RNA_enum_get(op->ptr, "mode");
00947     int toggle= RNA_boolean_get(op->ptr, "toggle");
00948 
00949     if(sc->mode==mode) {
00950         if(toggle)
00951             sc->mode= SC_MODE_TRACKING;
00952     } else {
00953         sc->mode= mode;
00954     }
00955 
00956     WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CLIP, NULL);
00957 
00958     return OPERATOR_FINISHED;
00959 }
00960 
00961 void CLIP_OT_mode_set(wmOperatorType *ot)
00962 {
00963     static EnumPropertyItem mode_items[] = {
00964         {SC_MODE_TRACKING, "TRACKING", 0, "Tracking", "Show tracking and solving tools"},
00965         {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", 0, "Reconstruction", "Show tracking/reconstruction tools"},
00966         {SC_MODE_DISTORTION, "DISTORTION", 0, "Distortion", "Show distortion tools"},
00967         {0, NULL, 0, NULL, NULL}};
00968 
00969 
00970     /* identifiers */
00971     ot->name= "Set Clip Mode";
00972     ot->description = "Set the clip interaction mode";
00973     ot->idname= "CLIP_OT_mode_set";
00974 
00975     /* api callbacks */
00976     ot->exec= mode_set_exec;
00977 
00978     ot->poll= ED_space_clip_poll;
00979 
00980     /* properties */
00981     RNA_def_enum(ot->srna, "mode", mode_items, SC_MODE_TRACKING, "Mode", "");
00982     RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
00983 }
00984 
00985 /********************** macroses *********************/
00986 
00987 void ED_operatormacros_clip(void)
00988 {
00989     wmOperatorType *ot;
00990     wmOperatorTypeMacro *otmacro;
00991 
00992     ot= WM_operatortype_append_macro("CLIP_OT_add_marker_move", "Add Marker and Move", OPTYPE_UNDO|OPTYPE_REGISTER);
00993     ot->description = "Add new marker and move it on movie";
00994     WM_operatortype_macro_define(ot, "CLIP_OT_add_marker");
00995     otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
00996     RNA_struct_idprops_unset(otmacro->ptr, "release_confirm");
00997 
00998     ot= WM_operatortype_append_macro("CLIP_OT_add_marker_slide", "Add Marker and Slide", OPTYPE_UNDO|OPTYPE_REGISTER);
00999     ot->description = "Add new marker and slide it with mouse until mouse button release";
01000     WM_operatortype_macro_define(ot, "CLIP_OT_add_marker");
01001     otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
01002     RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
01003 }