Blender V2.61 - r43446
|
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) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation, 2003-2009, Campbell Barton 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <stdlib.h> 00032 #include <math.h> 00033 #include <string.h> 00034 00035 #ifndef WIN32 00036 #include <unistd.h> 00037 #else 00038 #include <io.h> 00039 #endif 00040 #include <sys/types.h> 00041 00042 #include "MEM_guardedalloc.h" 00043 00044 #include "BLI_blenlib.h" 00045 #include "BLI_math.h" 00046 #include "BLI_utildefines.h" 00047 00048 #include "DNA_scene_types.h" 00049 #include "DNA_userdef_types.h" 00050 00051 #include "BKE_context.h" 00052 #include "BKE_global.h" 00053 #include "BKE_main.h" 00054 #include "BKE_sequencer.h" 00055 #include "BKE_report.h" 00056 00057 00058 #include "WM_api.h" 00059 #include "WM_types.h" 00060 00061 #include "RNA_define.h" 00062 #include "RNA_enum_types.h" 00063 00064 /* for menu/popup icons etc etc*/ 00065 00066 #include "ED_screen.h" 00067 00068 #include "UI_view2d.h" 00069 00070 #include "BKE_sound.h" 00071 00072 #ifdef WITH_AUDASPACE 00073 # include "AUD_C-API.h" 00074 #endif 00075 00076 /* own include */ 00077 #include "sequencer_intern.h" 00078 00079 /* Generic functions, reused by add strip operators */ 00080 00081 /* avoid passing multiple args and be more verbose */ 00082 #define SEQPROP_STARTFRAME (1<<0) 00083 #define SEQPROP_ENDFRAME (1<<1) 00084 #define SEQPROP_NOPATHS (1<<2) 00085 #define SEQPROP_NOCHAN (1<<3) 00086 00087 #define SELECT 1 00088 00089 static void sequencer_generic_props__internal(wmOperatorType *ot, int flag) 00090 { 00091 if(flag & SEQPROP_STARTFRAME) 00092 RNA_def_int(ot->srna, "frame_start", 0, INT_MIN, INT_MAX, "Start Frame", "Start frame of the sequence strip", INT_MIN, INT_MAX); 00093 00094 if(flag & SEQPROP_ENDFRAME) 00095 RNA_def_int(ot->srna, "frame_end", 0, INT_MIN, INT_MAX, "End Frame", "End frame for the color strip", INT_MIN, INT_MAX); /* not useual since most strips have a fixed length */ 00096 00097 RNA_def_int(ot->srna, "channel", 1, 1, MAXSEQ, "Channel", "Channel to place this strip into", 1, MAXSEQ); 00098 00099 RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "replace the current selection"); 00100 00101 RNA_def_boolean(ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips"); 00102 } 00103 00104 static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op, const char *identifier) 00105 { 00106 if(RNA_struct_find_property(op->ptr, identifier)) { 00107 Scene *scene= CTX_data_scene(C); 00108 Sequence *last_seq= seq_active_get(scene); 00109 if(last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) { 00110 char path[sizeof(last_seq->strip->dir)]; 00111 BLI_strncpy(path, last_seq->strip->dir, sizeof(path)); 00112 BLI_path_abs(path, G.main->name); 00113 RNA_string_set(op->ptr, identifier, path); 00114 } 00115 } 00116 } 00117 00118 static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, wmEvent *event, int flag) 00119 { 00120 View2D *v2d= UI_view2d_fromcontext(C); 00121 00122 float mval_v2d[2]; 00123 00124 UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mval_v2d[0], &mval_v2d[1]); 00125 00126 /* effect strips dont need a channel initialized from the mouse */ 00127 if(!(flag & SEQPROP_NOCHAN)) { 00128 RNA_int_set(op->ptr, "channel", (int)mval_v2d[1]+0.5f); 00129 } 00130 00131 RNA_int_set(op->ptr, "frame_start", (int)mval_v2d[0]); 00132 00133 if ((flag & SEQPROP_ENDFRAME) && RNA_struct_property_is_set(op->ptr, "frame_end")==0) 00134 RNA_int_set(op->ptr, "frame_end", (int)mval_v2d[0] + 25); // XXX arbitary but ok for now. 00135 00136 if (!(flag & SEQPROP_NOPATHS)) { 00137 sequencer_generic_invoke_path__internal(C, op, "filepath"); 00138 sequencer_generic_invoke_path__internal(C, op, "directory"); 00139 } 00140 } 00141 00142 static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op) 00143 { 00144 int relative= RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path"); 00145 int is_file= -1; 00146 memset(seq_load, 0, sizeof(SeqLoadInfo)); 00147 00148 seq_load->start_frame= RNA_int_get(op->ptr, "frame_start"); 00149 seq_load->end_frame= seq_load->start_frame; /* un-set */ 00150 00151 seq_load->channel= RNA_int_get(op->ptr, "channel"); 00152 seq_load->len= 1; // images only, if endframe isnt set! 00153 00154 if(RNA_struct_find_property(op->ptr, "filepath")) { 00155 RNA_string_get(op->ptr, "filepath", seq_load->path); /* full path, file is set by the caller */ 00156 is_file= 1; 00157 } else if (RNA_struct_find_property(op->ptr, "directory")) { 00158 RNA_string_get(op->ptr, "directory", seq_load->path); /* full path, file is set by the caller */ 00159 is_file= 0; 00160 } 00161 00162 if((is_file != -1) && relative) 00163 BLI_path_rel(seq_load->path, G.main->name); 00164 00165 00166 if (RNA_struct_find_property(op->ptr, "frame_end")) { 00167 seq_load->end_frame = RNA_int_get(op->ptr, "frame_end"); 00168 } 00169 00170 if (RNA_struct_find_property(op->ptr, "replace_sel") && RNA_boolean_get(op->ptr, "replace_sel")) 00171 seq_load->flag |= SEQ_LOAD_REPLACE_SEL; 00172 00173 if (RNA_struct_find_property(op->ptr, "cache") && RNA_boolean_get(op->ptr, "cache")) 00174 seq_load->flag |= SEQ_LOAD_SOUND_CACHE; 00175 00176 if (RNA_struct_find_property(op->ptr, "sound") && RNA_boolean_get(op->ptr, "sound")) 00177 seq_load->flag |= SEQ_LOAD_MOVIE_SOUND; 00178 00179 /* always use this for ops */ 00180 seq_load->flag |= SEQ_LOAD_FRAME_ADVANCE; 00181 00182 00183 if(is_file==1) { 00184 BLI_strncpy(seq_load->name, BLI_path_basename(seq_load->path), sizeof(seq_load->name)); 00185 } 00186 else if(RNA_struct_find_property(op->ptr, "files")) { 00187 /* used for image strip */ 00188 /* best guess, first images name */ 00189 RNA_BEGIN(op->ptr, itemptr, "files") { 00190 char *name= RNA_string_get_alloc(&itemptr, "name", NULL, 0); 00191 BLI_strncpy(seq_load->name, name, sizeof(seq_load->name)); 00192 MEM_freeN(name); 00193 break; 00194 } 00195 RNA_END; 00196 } 00197 } 00198 00199 /* add scene operator */ 00200 static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) 00201 { 00202 Scene *scene= CTX_data_scene(C); 00203 Editing *ed= seq_give_editing(scene, TRUE); 00204 00205 Scene *sce_seq; 00206 00207 Sequence *seq; /* generic strip vars */ 00208 Strip *strip; 00209 00210 int start_frame, channel; /* operator props */ 00211 00212 start_frame= RNA_int_get(op->ptr, "frame_start"); 00213 channel= RNA_int_get(op->ptr, "channel"); 00214 00215 sce_seq= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene")); 00216 00217 if (sce_seq==NULL) { 00218 BKE_report(op->reports, RPT_ERROR, "Scene not found"); 00219 return OPERATOR_CANCELLED; 00220 } 00221 00222 seq = alloc_sequence(ed->seqbasep, start_frame, channel); 00223 seq->type= SEQ_SCENE; 00224 seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */ 00225 00226 seq->scene= sce_seq; 00227 seq->sfra= sce_seq->r.sfra; 00228 00229 /* basic defaults */ 00230 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); 00231 strip->len = seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1; 00232 strip->us= 1; 00233 00234 strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); 00235 00236 BLI_strncpy(seq->name+2, sce_seq->id.name+2, sizeof(seq->name)-2); 00237 seqbase_unique_name_recursive(&ed->seqbase, seq); 00238 00239 seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + strip->len, 0); 00240 00241 calc_sequence_disp(scene, seq); 00242 sort_seq(scene); 00243 00244 if (RNA_boolean_get(op->ptr, "replace_sel")) { 00245 deselect_all_seq(scene); 00246 seq_active_set(scene, seq); 00247 seq->flag |= SELECT; 00248 } 00249 00250 if(RNA_boolean_get(op->ptr, "overlap") == FALSE) { 00251 if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); 00252 } 00253 00254 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); 00255 00256 return OPERATOR_FINISHED; 00257 } 00258 00259 00260 static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) 00261 { 00262 if(!ED_operator_sequencer_active(C)) { 00263 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active"); 00264 return OPERATOR_CANCELLED; 00265 } 00266 00267 if(!RNA_struct_property_is_set(op->ptr, "scene")) 00268 return WM_enum_search_invoke(C, op, event); 00269 00270 sequencer_generic_invoke_xy__internal(C, op, event, 0); 00271 return sequencer_add_scene_strip_exec(C, op); 00272 // needs a menu 00273 // return WM_menu_invoke(C, op, event); 00274 } 00275 00276 00277 void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot) 00278 { 00279 PropertyRNA *prop; 00280 00281 /* identifiers */ 00282 ot->name= "Add Scene Strip"; 00283 ot->idname= "SEQUENCER_OT_scene_strip_add"; 00284 ot->description= "Add a strip to the sequencer using a blender scene as a source"; 00285 00286 /* api callbacks */ 00287 ot->invoke= sequencer_add_scene_strip_invoke; 00288 ot->exec= sequencer_add_scene_strip_exec; 00289 00290 ot->poll= ED_operator_scene_editable; 00291 00292 /* flags */ 00293 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00294 00295 sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); 00296 prop= RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", ""); 00297 RNA_def_enum_funcs(prop, RNA_scene_itemf); 00298 ot->prop= prop; 00299 } 00300 00301 static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoadFunc seq_load_func) 00302 { 00303 Scene *scene= CTX_data_scene(C); /* only for sound */ 00304 Editing *ed= seq_give_editing(scene, TRUE); 00305 SeqLoadInfo seq_load; 00306 Sequence *seq; 00307 int tot_files; 00308 const short overlap= RNA_boolean_get(op->ptr, "overlap"); 00309 00310 seq_load_operator_info(&seq_load, op); 00311 00312 if (seq_load.flag & SEQ_LOAD_REPLACE_SEL) 00313 deselect_all_seq(scene); 00314 00315 tot_files= RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); 00316 00317 if(tot_files) { 00318 /* multiple files */ 00319 char dir_only[FILE_MAX]; 00320 char file_only[FILE_MAX]; 00321 00322 BLI_split_dir_part(seq_load.path, dir_only, sizeof(dir_only)); 00323 00324 RNA_BEGIN(op->ptr, itemptr, "files") { 00325 RNA_string_get(&itemptr, "name", file_only); 00326 BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only); 00327 00328 seq= seq_load_func(C, ed->seqbasep, &seq_load); 00329 00330 if(overlap == FALSE) { 00331 if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); 00332 } 00333 } 00334 RNA_END; 00335 } 00336 else { 00337 /* single file */ 00338 seq= seq_load_func(C, ed->seqbasep, &seq_load); 00339 00340 if(overlap == FALSE) { 00341 if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); 00342 } 00343 } 00344 00345 if (seq_load.tot_success==0) { 00346 BKE_reportf(op->reports, RPT_ERROR, "File \"%s\" could not be loaded", seq_load.path); 00347 return OPERATOR_CANCELLED; 00348 } 00349 00350 sort_seq(scene); 00351 seq_update_muting(ed); 00352 00353 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); 00354 00355 return OPERATOR_FINISHED; 00356 } 00357 00358 /* add movie operator */ 00359 static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op) 00360 { 00361 return sequencer_add_generic_strip_exec(C, op, sequencer_add_movie_strip); 00362 } 00363 00364 00365 static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) 00366 { 00367 00368 if(!ED_operator_sequencer_active(C)) { 00369 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active"); 00370 return OPERATOR_CANCELLED; 00371 } 00372 00373 /* This is for drag and drop */ 00374 if(RNA_collection_length(op->ptr, "files") || RNA_struct_property_is_set(op->ptr, "filepath")) { 00375 sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS); 00376 return sequencer_add_movie_strip_exec(C, op); 00377 } 00378 00379 sequencer_generic_invoke_xy__internal(C, op, event, 0); 00380 00381 WM_event_add_fileselect(C, op); 00382 return OPERATOR_RUNNING_MODAL; 00383 00384 //return sequencer_add_movie_strip_exec(C, op); 00385 } 00386 00387 00388 void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) 00389 { 00390 00391 /* identifiers */ 00392 ot->name= "Add Movie Strip"; 00393 ot->idname= "SEQUENCER_OT_movie_strip_add"; 00394 ot->description= "Add a movie strip to the sequencer"; 00395 00396 /* api callbacks */ 00397 ot->invoke= sequencer_add_movie_strip_invoke; 00398 ot->exec= sequencer_add_movie_strip_exec; 00399 00400 ot->poll= ED_operator_scene_editable; 00401 00402 /* flags */ 00403 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00404 00405 WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES); 00406 sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); 00407 RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie"); 00408 } 00409 00410 /* add sound operator */ 00411 00412 static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op) 00413 { 00414 return sequencer_add_generic_strip_exec(C, op, sequencer_add_sound_strip); 00415 } 00416 00417 static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) 00418 { 00419 00420 if(!ED_operator_sequencer_active(C)) { 00421 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active"); 00422 return OPERATOR_CANCELLED; 00423 } 00424 00425 /* This is for drag and drop */ 00426 if(RNA_collection_length(op->ptr, "files") || RNA_struct_property_is_set(op->ptr, "filepath")) { 00427 sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS); 00428 return sequencer_add_sound_strip_exec(C, op); 00429 } 00430 00431 sequencer_generic_invoke_xy__internal(C, op, event, 0); 00432 00433 WM_event_add_fileselect(C, op); 00434 return OPERATOR_RUNNING_MODAL; 00435 00436 //return sequencer_add_sound_strip_exec(C, op); 00437 } 00438 00439 00440 void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot) 00441 { 00442 00443 /* identifiers */ 00444 ot->name= "Add Sound Strip"; 00445 ot->idname= "SEQUENCER_OT_sound_strip_add"; 00446 ot->description= "Add a sound strip to the sequencer"; 00447 00448 /* api callbacks */ 00449 ot->invoke= sequencer_add_sound_strip_invoke; 00450 ot->exec= sequencer_add_sound_strip_exec; 00451 00452 ot->poll= ED_operator_scene_editable; 00453 00454 /* flags */ 00455 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00456 00457 WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES); 00458 sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); 00459 RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory"); 00460 } 00461 00462 /* add image operator */ 00463 static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) 00464 { 00465 /* cant use the generic function for this */ 00466 00467 Scene *scene= CTX_data_scene(C); /* only for sound */ 00468 Editing *ed= seq_give_editing(scene, TRUE); 00469 SeqLoadInfo seq_load; 00470 Sequence *seq; 00471 00472 Strip *strip; 00473 StripElem *se; 00474 00475 seq_load_operator_info(&seq_load, op); 00476 00477 /* images are unique in how they handle this - 1 per strip elem */ 00478 seq_load.len= RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); 00479 00480 if(seq_load.len==0) 00481 return OPERATOR_CANCELLED; 00482 00483 if(seq_load.flag & SEQ_LOAD_REPLACE_SEL) 00484 deselect_all_seq(scene); 00485 00486 00487 /* main adding function */ 00488 seq= sequencer_add_image_strip(C, ed->seqbasep, &seq_load); 00489 strip= seq->strip; 00490 se= strip->stripdata; 00491 00492 RNA_BEGIN(op->ptr, itemptr, "files") { 00493 char *filename= RNA_string_get_alloc(&itemptr, "name", NULL, 0); 00494 BLI_strncpy(se->name, filename, sizeof(se->name)); 00495 MEM_freeN(filename); 00496 se++; 00497 } 00498 RNA_END; 00499 00500 if(seq_load.len == 1) { 00501 if(seq_load.start_frame < seq_load.end_frame) { 00502 seq->endstill= seq_load.end_frame - seq_load.start_frame; 00503 } 00504 } 00505 00506 calc_sequence_disp(scene, seq); 00507 00508 sort_seq(scene); 00509 00510 /* last active name */ 00511 strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR-1); 00512 00513 if(RNA_boolean_get(op->ptr, "overlap") == FALSE) { 00514 if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); 00515 } 00516 00517 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); 00518 00519 return OPERATOR_FINISHED; 00520 } 00521 00522 static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) 00523 { 00524 00525 if(!ED_operator_sequencer_active(C)) { 00526 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active"); 00527 return OPERATOR_CANCELLED; 00528 } 00529 00530 00531 /* drag drop has set the names */ 00532 if(RNA_collection_length(op->ptr, "files")) { 00533 sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME|SEQPROP_NOPATHS); 00534 return sequencer_add_image_strip_exec(C, op); 00535 } 00536 00537 sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME); 00538 00539 WM_event_add_fileselect(C, op); 00540 return OPERATOR_RUNNING_MODAL; 00541 } 00542 00543 00544 void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) 00545 { 00546 00547 /* identifiers */ 00548 ot->name= "Add Image Strip"; 00549 ot->idname= "SEQUENCER_OT_image_strip_add"; 00550 ot->description= "Add an image or image sequence to the sequencer"; 00551 00552 /* api callbacks */ 00553 ot->invoke= sequencer_add_image_strip_invoke; 00554 ot->exec= sequencer_add_image_strip_exec; 00555 00556 ot->poll= ED_operator_scene_editable; 00557 00558 /* flags */ 00559 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00560 00561 WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILES); 00562 sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME); 00563 } 00564 00565 00566 /* add_effect_strip operator */ 00567 static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) 00568 { 00569 Scene *scene= CTX_data_scene(C); 00570 Editing *ed= seq_give_editing(scene, TRUE); 00571 00572 Sequence *seq; /* generic strip vars */ 00573 Strip *strip; 00574 struct SeqEffectHandle sh; 00575 00576 int start_frame, end_frame, channel, type; /* operator props */ 00577 00578 Sequence *seq1, *seq2, *seq3; 00579 const char *error_msg; 00580 00581 start_frame= RNA_int_get(op->ptr, "frame_start"); 00582 end_frame= RNA_int_get(op->ptr, "frame_end"); 00583 channel= RNA_int_get(op->ptr, "channel"); 00584 00585 type= RNA_enum_get(op->ptr, "type"); 00586 00587 // XXX move to invoke 00588 if(!seq_effect_find_selected(scene, NULL, type, &seq1, &seq2, &seq3, &error_msg)) { 00589 BKE_report(op->reports, RPT_ERROR, error_msg); 00590 return OPERATOR_CANCELLED; 00591 } 00592 00593 /* If seq1 is NULL and no error was rasied it means the seq is standalone 00594 * (like color strips) and we need to check its start and end frames are valid */ 00595 if (seq1==NULL && end_frame <= start_frame) { 00596 BKE_report(op->reports, RPT_ERROR, "Start and end frame are not set"); 00597 return OPERATOR_CANCELLED; 00598 } 00599 00600 seq = alloc_sequence(ed->seqbasep, start_frame, channel); 00601 seq->type= type; 00602 00603 BLI_strncpy(seq->name+2, give_seqname(seq), sizeof(seq->name)-2); 00604 seqbase_unique_name_recursive(&ed->seqbase, seq); 00605 00606 sh = get_sequence_effect(seq); 00607 00608 seq->seq1= seq1; 00609 seq->seq2= seq2; 00610 seq->seq3= seq3; 00611 00612 sh.init(seq); 00613 00614 if (!seq1) { /* effect has no deps */ 00615 seq->len= 1; 00616 seq_tx_set_final_right(seq, end_frame); 00617 } 00618 00619 seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; 00620 00621 calc_sequence(scene, seq); 00622 00623 /* basic defaults */ 00624 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); 00625 strip->len = seq->len; 00626 strip->us= 1; 00627 if(seq->len>0) 00628 strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); 00629 00630 if (seq->type==SEQ_PLUGIN) { 00631 char path[FILE_MAX]; 00632 RNA_string_get(op->ptr, "filepath", path); 00633 00634 sh.init_plugin(seq, path); 00635 00636 if(seq->plugin==NULL) { 00637 BLI_remlink(ed->seqbasep, seq); 00638 seq_free_sequence(scene, seq); 00639 BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load", path); 00640 return OPERATOR_CANCELLED; 00641 } 00642 } else if (seq->type == SEQ_COLOR) { 00643 SolidColorVars *colvars= (SolidColorVars *)seq->effectdata; 00644 RNA_float_get_array(op->ptr, "color", colvars->col); 00645 seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */ 00646 00647 } else if (seq->type == SEQ_ADJUSTMENT) { 00648 seq->blend_mode= SEQ_CROSS; 00649 } 00650 00651 /* an unset channel is a special case where we automatically go above 00652 * the other strips. */ 00653 if(!RNA_struct_property_is_set(op->ptr, "channel")) { 00654 if(seq->seq1) { 00655 int chan= MAX3( seq->seq1 ? seq->seq1->machine : 0, 00656 seq->seq2 ? seq->seq2->machine : 0, 00657 seq->seq3 ? seq->seq3->machine : 0); 00658 if(chan < MAXSEQ) 00659 seq->machine= chan; 00660 } 00661 } 00662 00663 if(RNA_boolean_get(op->ptr, "overlap") == FALSE) { 00664 if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); 00665 } 00666 00667 update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */ 00668 00669 00670 /* not sure if this is needed with update_changed_seq_and_deps. 00671 * it was NOT called in blender 2.4x, but wont hurt */ 00672 sort_seq(scene); 00673 00674 if (RNA_boolean_get(op->ptr, "replace_sel")) { 00675 deselect_all_seq(scene); 00676 seq_active_set(scene, seq); 00677 seq->flag |= SELECT; 00678 } 00679 00680 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); 00681 00682 return OPERATOR_FINISHED; 00683 } 00684 00685 00686 /* add color */ 00687 static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) 00688 { 00689 short is_type_set= RNA_struct_property_is_set(op->ptr, "type"); 00690 int type= -1; 00691 int prop_flag= SEQPROP_ENDFRAME; 00692 00693 if(!ED_operator_sequencer_active(C)) { 00694 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active"); 00695 return OPERATOR_CANCELLED; 00696 } 00697 00698 if(is_type_set) { 00699 type= RNA_enum_get(op->ptr, "type"); 00700 00701 /* when invoking an effect strip which uses inputs, 00702 * skip initialzing the channel from the mouse. 00703 * Instead leave the property unset so exec() initializes it to be 00704 * above the strips its applied to. */ 00705 if(get_sequence_effect_num_inputs(type) != 0) { 00706 prop_flag |= SEQPROP_NOCHAN; 00707 } 00708 } 00709 00710 sequencer_generic_invoke_xy__internal(C, op, event, prop_flag); 00711 00712 if (is_type_set && type==SEQ_PLUGIN) { 00713 /* only plugins need the file selector */ 00714 return WM_operator_filesel(C, op, event); 00715 } 00716 else { 00717 return sequencer_add_effect_strip_exec(C, op); 00718 } 00719 } 00720 00721 void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) 00722 { 00723 /* identifiers */ 00724 ot->name= "Add Effect Strip"; 00725 ot->idname= "SEQUENCER_OT_effect_strip_add"; 00726 ot->description= "Add an effect to the sequencer, most are applied on top of existing strips"; 00727 00728 /* api callbacks */ 00729 ot->invoke= sequencer_add_effect_strip_invoke; 00730 ot->exec= sequencer_add_effect_strip_exec; 00731 00732 ot->poll= ED_operator_scene_editable; 00733 00734 /* flags */ 00735 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00736 00737 WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); 00738 sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME); 00739 RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); 00740 RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); 00741 }