|
Blender
V2.59
|
00001 /* 00002 * 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * Contributor(s): Blender Foundation, 2003-2009, Campbell Barton 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <stdlib.h> 00033 #include <math.h> 00034 #include <string.h> 00035 00036 #ifndef WIN32 00037 #include <unistd.h> 00038 #else 00039 #include <io.h> 00040 #endif 00041 #include <sys/types.h> 00042 00043 #include "BLI_blenlib.h" 00044 #include "BLI_math.h" 00045 #include "BLI_utildefines.h" 00046 00047 #include "DNA_scene_types.h" 00048 00049 #include "BKE_context.h" 00050 #include "BKE_sequencer.h" 00051 00052 #include "WM_api.h" 00053 #include "WM_types.h" 00054 00055 #include "RNA_define.h" 00056 00057 /* for menu/popup icons etc etc*/ 00058 00059 #include "ED_types.h" 00060 #include "ED_screen.h" 00061 00062 #include "UI_view2d.h" 00063 00064 /* own include */ 00065 #include "sequencer_intern.h" 00066 static void *find_nearest_marker(int UNUSED(d1), int UNUSED(d2)) {return NULL;} 00067 00068 static void select_surrounding_handles(Scene *scene, Sequence *test) /* XXX BRING BACK */ 00069 { 00070 Sequence *neighbor; 00071 00072 neighbor=find_neighboring_sequence(scene, test, SEQ_SIDE_LEFT, -1); 00073 if (neighbor) { 00074 neighbor->flag |= SELECT; 00075 recurs_sel_seq(neighbor); 00076 neighbor->flag |= SEQ_RIGHTSEL; 00077 } 00078 neighbor=find_neighboring_sequence(scene, test, SEQ_SIDE_RIGHT, -1); 00079 if (neighbor) { 00080 neighbor->flag |= SELECT; 00081 recurs_sel_seq(neighbor); 00082 neighbor->flag |= SEQ_LEFTSEL; 00083 } 00084 test->flag |= SELECT; 00085 } 00086 00087 /* used for mouse selection and for SEQUENCER_OT_select_active_side() */ 00088 static void select_active_side(ListBase *seqbase, int sel_side, int channel, int frame) 00089 { 00090 Sequence *seq; 00091 00092 for(seq= seqbase->first; seq; seq=seq->next) { 00093 if(channel==seq->machine) { 00094 switch(sel_side) { 00095 case SEQ_SIDE_LEFT: 00096 if (frame > (seq->startdisp)) { 00097 seq->flag &= ~(SEQ_RIGHTSEL|SEQ_LEFTSEL); 00098 seq->flag |= SELECT; 00099 } 00100 break; 00101 case SEQ_SIDE_RIGHT: 00102 if (frame < (seq->startdisp)) { 00103 seq->flag &= ~(SEQ_RIGHTSEL|SEQ_LEFTSEL); 00104 seq->flag |= SELECT; 00105 } 00106 break; 00107 case SEQ_SIDE_BOTH: 00108 seq->flag &= ~(SEQ_RIGHTSEL|SEQ_LEFTSEL); 00109 break; 00110 } 00111 } 00112 } 00113 } 00114 00115 /* used for mouse selection and for SEQUENCER_OT_select_active_side() */ 00116 static void select_linked_time(ListBase *seqbase, Sequence *seq_link) 00117 { 00118 Sequence *seq; 00119 00120 for(seq= seqbase->first; seq; seq=seq->next) { 00121 if(seq_link->machine != seq->machine) { 00122 int left_match = (seq->startdisp == seq_link->startdisp) ? 1:0; 00123 int right_match = (seq->enddisp == seq_link->enddisp) ? 1:0; 00124 00125 if(left_match && right_match) { 00126 /* a direct match, copy the selection settinhs */ 00127 seq->flag &= ~(SELECT|SEQ_LEFTSEL|SEQ_RIGHTSEL); 00128 seq->flag |= seq_link->flag & (SELECT|SEQ_LEFTSEL|SEQ_RIGHTSEL); 00129 00130 recurs_sel_seq(seq); 00131 } 00132 else if(seq_link->flag & SELECT && (left_match || right_match)) { 00133 00134 /* clear for reselection */ 00135 seq->flag &= ~(SEQ_LEFTSEL|SEQ_RIGHTSEL); 00136 00137 if(left_match && seq_link->flag & SEQ_LEFTSEL) 00138 seq->flag |= SELECT|SEQ_LEFTSEL; 00139 00140 if(right_match && seq_link->flag & SEQ_RIGHTSEL) 00141 seq->flag |= SELECT|SEQ_RIGHTSEL; 00142 00143 recurs_sel_seq(seq); 00144 } 00145 } 00146 } 00147 } 00148 00149 #if 0 // BRING BACK 00150 void select_surround_from_last(Scene *scene) 00151 { 00152 Sequence *seq=get_last_seq(scene); 00153 00154 if (seq==NULL) 00155 return; 00156 00157 select_surrounding_handles(scene, seq); 00158 } 00159 #endif 00160 00161 00162 static void select_single_seq(Scene *scene, Sequence *seq, int deselect_all) /* BRING BACK */ 00163 { 00164 Editing *ed= seq_give_editing(scene, FALSE); 00165 00166 if(deselect_all) 00167 deselect_all_seq(scene); 00168 seq_active_set(scene, seq); 00169 00170 if((seq->type==SEQ_IMAGE) || (seq->type==SEQ_MOVIE)) { 00171 if(seq->strip) 00172 strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR-1); 00173 } 00174 else if(seq->type==SEQ_SOUND) { 00175 if(seq->strip) 00176 strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR-1); 00177 } 00178 seq->flag|= SELECT; 00179 recurs_sel_seq(seq); 00180 } 00181 00182 // remove this function, replace with invert operator 00183 //void swap_select_seq(Scene *scene) 00184 #if 0 00185 static void select_neighbor_from_last(Scene *scene, int lr) 00186 { 00187 Sequence *seq= seq_active_get(scene); 00188 Sequence *neighbor; 00189 int change = 0; 00190 if (seq) { 00191 neighbor=find_neighboring_sequence(scene, seq, lr, -1); 00192 if (neighbor) { 00193 switch (lr) { 00194 case SEQ_SIDE_LEFT: 00195 neighbor->flag |= SELECT; 00196 recurs_sel_seq(neighbor); 00197 neighbor->flag |= SEQ_RIGHTSEL; 00198 seq->flag |= SEQ_LEFTSEL; 00199 break; 00200 case SEQ_SIDE_RIGHT: 00201 neighbor->flag |= SELECT; 00202 recurs_sel_seq(neighbor); 00203 neighbor->flag |= SEQ_LEFTSEL; 00204 seq->flag |= SEQ_RIGHTSEL; 00205 break; 00206 } 00207 seq->flag |= SELECT; 00208 change = 1; 00209 } 00210 } 00211 if (change) { 00212 } 00213 } 00214 #endif 00215 00216 /* (de)select operator */ 00217 static int sequencer_deselect_exec(bContext *C, wmOperator *UNUSED(op)) 00218 { 00219 Scene *scene= CTX_data_scene(C); 00220 Editing *ed= seq_give_editing(scene, FALSE); 00221 Sequence *seq; 00222 int desel = 0; 00223 00224 for(seq= ed->seqbasep->first; seq; seq=seq->next) { 00225 if(seq->flag & SEQ_ALLSEL) { 00226 desel= 1; 00227 break; 00228 } 00229 } 00230 00231 for(seq= ed->seqbasep->first; seq; seq=seq->next) { 00232 if (desel) { 00233 seq->flag &= ~SEQ_ALLSEL; 00234 } 00235 else { 00236 seq->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); 00237 seq->flag |= SELECT; 00238 } 00239 } 00240 00241 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00242 00243 return OPERATOR_FINISHED; 00244 } 00245 00246 void SEQUENCER_OT_select_all_toggle(struct wmOperatorType *ot) 00247 { 00248 /* identifiers */ 00249 ot->name= "Select or Deselect All"; 00250 ot->idname= "SEQUENCER_OT_select_all_toggle"; 00251 ot->description="Select or deselect all strips"; 00252 00253 /* api callbacks */ 00254 ot->exec= sequencer_deselect_exec; 00255 ot->poll= sequencer_edit_poll; 00256 00257 /* flags */ 00258 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00259 } 00260 00261 00262 /* (de)select operator */ 00263 static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) 00264 { 00265 Scene *scene= CTX_data_scene(C); 00266 Editing *ed= seq_give_editing(scene, FALSE); 00267 Sequence *seq; 00268 00269 for(seq= ed->seqbasep->first; seq; seq=seq->next) { 00270 if (seq->flag & SELECT) { 00271 seq->flag &= ~SEQ_ALLSEL; 00272 } 00273 else { 00274 seq->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); 00275 seq->flag |= SELECT; 00276 } 00277 } 00278 00279 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00280 00281 return OPERATOR_FINISHED; 00282 } 00283 00284 void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot) 00285 { 00286 /* identifiers */ 00287 ot->name= "Select Inverse"; 00288 ot->idname= "SEQUENCER_OT_select_inverse"; 00289 ot->description="Select unselected strips"; 00290 00291 /* api callbacks */ 00292 ot->exec= sequencer_select_inverse_exec; 00293 ot->poll= sequencer_edit_poll; 00294 00295 /* flags */ 00296 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00297 } 00298 00299 static int sequencer_select_invoke(bContext *C, wmOperator *op, wmEvent *event) 00300 { 00301 View2D *v2d= UI_view2d_fromcontext(C); 00302 Scene *scene= CTX_data_scene(C); 00303 Editing *ed= seq_give_editing(scene, FALSE); 00304 short extend= RNA_boolean_get(op->ptr, "extend"); 00305 short linked_handle= RNA_boolean_get(op->ptr, "linked_handle"); 00306 short left_right= RNA_boolean_get(op->ptr, "left_right"); 00307 short linked_time= RNA_boolean_get(op->ptr, "linked_time"); 00308 00309 Sequence *seq,*neighbor, *act_orig; 00310 int hand,sel_side; 00311 TimeMarker *marker; 00312 00313 if(ed==NULL) 00314 return OPERATOR_CANCELLED; 00315 00316 marker=find_nearest_marker(SCE_MARKERS, 1); //XXX - dummy function for now 00317 00318 seq= find_nearest_seq(scene, v2d, &hand, event->mval); 00319 00320 // XXX - not nice, Ctrl+RMB needs to do left_right only when not over a strip 00321 if(seq && linked_time && left_right) 00322 left_right= FALSE; 00323 00324 00325 if (marker) { 00326 int oldflag; 00327 /* select timeline marker */ 00328 if (extend) { 00329 oldflag= marker->flag; 00330 if (oldflag & SELECT) 00331 marker->flag &= ~SELECT; 00332 else 00333 marker->flag |= SELECT; 00334 } 00335 else { 00336 /* deselect_markers(0, 0); */ /* XXX, in 2.4x, seq selection used to deselect all, need to re-thnik this for 2.5 */ 00337 marker->flag |= SELECT; 00338 } 00339 00340 } else if (left_right) { 00341 /* use different logic for this */ 00342 float x; 00343 deselect_all_seq(scene); 00344 UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL); 00345 00346 SEQP_BEGIN(ed, seq) { 00347 if (x < CFRA) { 00348 if(seq->enddisp < CFRA) { 00349 seq->flag |= SELECT; 00350 recurs_sel_seq(seq); 00351 } 00352 } 00353 else { 00354 if(seq->startdisp > CFRA) { 00355 seq->flag |= SELECT; 00356 recurs_sel_seq(seq); 00357 } 00358 } 00359 } 00360 SEQ_END 00361 00362 { 00363 SpaceSeq *sseq= CTX_wm_space_seq(C); 00364 if (sseq && sseq->flag & SEQ_MARKER_TRANS) { 00365 TimeMarker *tmarker; 00366 00367 for (tmarker= scene->markers.first; tmarker; tmarker= tmarker->next) { 00368 if( ((x < CFRA) && tmarker->frame < CFRA) || 00369 ((x >= CFRA) && tmarker->frame >= CFRA) 00370 ) { 00371 tmarker->flag |= SELECT; 00372 } 00373 else { 00374 tmarker->flag &= ~SELECT; 00375 } 00376 } 00377 } 00378 } 00379 } else { 00380 // seq= find_nearest_seq(scene, v2d, &hand, mval); 00381 00382 act_orig= ed->act_seq; 00383 00384 if(extend == 0 && linked_handle==0) 00385 deselect_all_seq(scene); 00386 00387 if(seq) { 00388 seq_active_set(scene, seq); 00389 00390 if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) { 00391 if(seq->strip) { 00392 strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR-1); 00393 } 00394 } else 00395 if (seq->type == SEQ_SOUND) { 00396 if(seq->strip) { 00397 strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR-1); 00398 } 00399 } 00400 00401 if(extend && (seq->flag & SELECT) && ed->act_seq == act_orig ) { 00402 switch(hand) { 00403 case SEQ_SIDE_NONE: 00404 if (linked_handle==0) 00405 seq->flag &= ~SEQ_ALLSEL; 00406 break; 00407 case SEQ_SIDE_LEFT: 00408 seq->flag ^= SEQ_LEFTSEL; 00409 break; 00410 case SEQ_SIDE_RIGHT: 00411 seq->flag ^= SEQ_RIGHTSEL; 00412 break; 00413 } 00414 } 00415 else { 00416 seq->flag |= SELECT; 00417 if(hand==SEQ_SIDE_LEFT) seq->flag |= SEQ_LEFTSEL; 00418 if(hand==SEQ_SIDE_RIGHT) seq->flag |= SEQ_RIGHTSEL; 00419 } 00420 00421 /* On Alt selection, select the strip and bordering handles */ 00422 if (linked_handle && !ELEM(hand, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) { 00423 if(extend==0) deselect_all_seq(scene); 00424 seq->flag |= SELECT; 00425 select_surrounding_handles(scene, seq); 00426 } 00427 else if (linked_handle && ELEM(hand, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT) && (seq->flag & SELECT)) { 00428 /* 00429 * First click selects adjacent handles on that side. 00430 * Second click selects all strips in that direction. 00431 * If there are no adjacent strips, it just selects all in that direction. 00432 */ 00433 sel_side= hand; 00434 neighbor=find_neighboring_sequence(scene, seq, sel_side, -1); 00435 if (neighbor) { 00436 switch (sel_side) { 00437 case SEQ_SIDE_LEFT: 00438 if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) { 00439 if(extend==0) deselect_all_seq(scene); 00440 seq->flag |= SELECT; 00441 00442 select_active_side(ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, seq->startdisp); 00443 } else { 00444 if(extend==0) deselect_all_seq(scene); 00445 seq->flag |= SELECT; 00446 00447 neighbor->flag |= SELECT; 00448 recurs_sel_seq(neighbor); 00449 neighbor->flag |= SEQ_RIGHTSEL; 00450 seq->flag |= SEQ_LEFTSEL; 00451 } 00452 break; 00453 case SEQ_SIDE_RIGHT: 00454 if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) { 00455 if(extend==0) deselect_all_seq(scene); 00456 seq->flag |= SELECT; 00457 00458 select_active_side(ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, seq->startdisp); 00459 } else { 00460 if(extend==0) deselect_all_seq(scene); 00461 seq->flag |= SELECT; 00462 00463 neighbor->flag |= SELECT; 00464 recurs_sel_seq(neighbor); 00465 neighbor->flag |= SEQ_LEFTSEL; 00466 seq->flag |= SEQ_RIGHTSEL; 00467 } 00468 break; 00469 } 00470 } else { 00471 if(extend==0) deselect_all_seq(scene); 00472 select_active_side(ed->seqbasep, sel_side, seq->machine, seq->startdisp); 00473 } 00474 } 00475 recurs_sel_seq(seq); 00476 00477 if(linked_time) { 00478 select_linked_time(ed->seqbasep, seq); 00479 } 00480 } 00481 } 00482 00483 /* marker transform */ 00484 #if 0 // XXX probably need to redo this differently for 2.5 00485 if (marker) { 00486 int mval[2], xo, yo; 00487 // getmouseco_areawin(mval); 00488 xo= mval[0]; 00489 yo= mval[1]; 00490 00491 while(get_mbut()) { 00492 // getmouseco_areawin(mval); 00493 if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) { 00494 transform_markers('g', 0); 00495 return; 00496 } 00497 } 00498 } 00499 #endif 00500 00501 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00502 00503 /* allowing tweaks */ 00504 return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH; 00505 } 00506 00507 void SEQUENCER_OT_select(wmOperatorType *ot) 00508 { 00509 /* identifiers */ 00510 ot->name= "Activate/Select"; 00511 ot->idname= "SEQUENCER_OT_select"; 00512 ot->description="Select a strip (last selected becomes the \"active strip\")"; 00513 00514 /* api callbacks */ 00515 ot->invoke= sequencer_select_invoke; 00516 ot->poll= ED_operator_sequencer_active; 00517 00518 /* flags */ 00519 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00520 00521 /* properties */ 00522 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection."); 00523 RNA_def_boolean(ot->srna, "linked_handle", 0, "Linked Handle", "Select handles next to the active strip."); 00524 /* for animation this is an enum but atm having an enum isnt useful for us */ 00525 RNA_def_boolean(ot->srna, "left_right", 0, "Left/Right", "select based on the frame side the cursor is on."); 00526 RNA_def_boolean(ot->srna, "linked_time", 0, "Linked Time", "Select other strips at the same time."); 00527 } 00528 00529 00530 00531 00532 /* run recursivly to select linked */ 00533 static int select_more_less_seq__internal(Scene *scene, int sel, int linked) { 00534 Editing *ed= seq_give_editing(scene, FALSE); 00535 Sequence *seq, *neighbor; 00536 int change=0; 00537 int isel; 00538 00539 if(ed==NULL) return 0; 00540 00541 if (sel) { 00542 sel = SELECT; 00543 isel = 0; 00544 } else { 00545 sel = 0; 00546 isel = SELECT; 00547 } 00548 00549 if (!linked) { 00550 /* if not linked we only want to touch each seq once, newseq */ 00551 for(seq= ed->seqbasep->first; seq; seq= seq->next) { 00552 seq->tmp = NULL; 00553 } 00554 } 00555 00556 for(seq= ed->seqbasep->first; seq; seq= seq->next) { 00557 if((int)(seq->flag & SELECT) == sel) { 00558 if ((linked==0 && seq->tmp)==0) { 00559 /* only get unselected nabours */ 00560 neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, isel); 00561 if (neighbor) { 00562 if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor);} 00563 else neighbor->flag &= ~SELECT; 00564 if (linked==0) neighbor->tmp = (Sequence *)1; 00565 change = 1; 00566 } 00567 neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, isel); 00568 if (neighbor) { 00569 if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor);} 00570 else neighbor->flag &= ~SELECT; 00571 if (linked==0) neighbor->tmp = (void *)1; 00572 change = 1; 00573 } 00574 } 00575 } 00576 } 00577 00578 return change; 00579 } 00580 00581 00582 00583 /* select more operator */ 00584 static int sequencer_select_more_exec(bContext *C, wmOperator *UNUSED(op)) 00585 { 00586 Scene *scene= CTX_data_scene(C); 00587 00588 if(!select_more_less_seq__internal(scene, 0, 0)) 00589 return OPERATOR_CANCELLED; 00590 00591 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00592 00593 return OPERATOR_FINISHED; 00594 } 00595 00596 void SEQUENCER_OT_select_more(wmOperatorType *ot) 00597 { 00598 /* identifiers */ 00599 ot->name= "Select More"; 00600 ot->idname= "SEQUENCER_OT_select_more"; 00601 ot->description="Select more strips adjacent to the current selection"; 00602 00603 /* api callbacks */ 00604 ot->exec= sequencer_select_more_exec; 00605 ot->poll= sequencer_edit_poll; 00606 00607 /* flags */ 00608 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00609 00610 /* properties */ 00611 } 00612 00613 00614 /* select less operator */ 00615 static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op)) 00616 { 00617 Scene *scene= CTX_data_scene(C); 00618 00619 if(!select_more_less_seq__internal(scene, 1, 0)) 00620 return OPERATOR_CANCELLED; 00621 00622 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00623 00624 return OPERATOR_FINISHED; 00625 } 00626 00627 void SEQUENCER_OT_select_less(wmOperatorType *ot) 00628 { 00629 /* identifiers */ 00630 ot->name= "Select less"; 00631 ot->idname= "SEQUENCER_OT_select_less"; 00632 ot->description="Shrink the current selection of adjacent selected strips"; 00633 00634 /* api callbacks */ 00635 ot->exec= sequencer_select_less_exec; 00636 ot->poll= sequencer_edit_poll; 00637 00638 /* flags */ 00639 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00640 00641 /* properties */ 00642 } 00643 00644 00645 /* select pick linked operator (uses the mouse) */ 00646 static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event) 00647 { 00648 Scene *scene= CTX_data_scene(C); 00649 View2D *v2d= UI_view2d_fromcontext(C); 00650 00651 short extend= RNA_boolean_get(op->ptr, "extend"); 00652 00653 Sequence *mouse_seq; 00654 int selected, hand; 00655 00656 /* this works like UV, not mesh */ 00657 mouse_seq= find_nearest_seq(scene, v2d, &hand, event->mval); 00658 if (!mouse_seq) 00659 return OPERATOR_FINISHED; /* user error as with mesh?? */ 00660 00661 if (extend==0) 00662 deselect_all_seq(scene); 00663 00664 mouse_seq->flag |= SELECT; 00665 recurs_sel_seq(mouse_seq); 00666 00667 selected = 1; 00668 while (selected) { 00669 selected = select_more_less_seq__internal(scene, 1, 1); 00670 } 00671 00672 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00673 00674 return OPERATOR_FINISHED; 00675 } 00676 00677 void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot) 00678 { 00679 /* identifiers */ 00680 ot->name= "Select pick linked"; 00681 ot->idname= "SEQUENCER_OT_select_linked_pick"; 00682 ot->description="Select a chain of linked strips nearest to the mouse pointer"; 00683 00684 /* api callbacks */ 00685 ot->invoke= sequencer_select_linked_pick_invoke; 00686 ot->poll= ED_operator_sequencer_active; 00687 00688 /* flags */ 00689 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00690 00691 /* properties */ 00692 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "extend the selection"); 00693 } 00694 00695 00696 /* select linked operator */ 00697 static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) 00698 { 00699 Scene *scene= CTX_data_scene(C); 00700 int selected; 00701 00702 selected = 1; 00703 while (selected) { 00704 selected = select_more_less_seq__internal(scene, 1, 1); 00705 } 00706 00707 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00708 00709 return OPERATOR_FINISHED; 00710 } 00711 00712 void SEQUENCER_OT_select_linked(wmOperatorType *ot) 00713 { 00714 /* identifiers */ 00715 ot->name= "Select linked"; 00716 ot->idname= "SEQUENCER_OT_select_linked"; 00717 ot->description="Select all strips adjacent to the current selection"; 00718 00719 /* api callbacks */ 00720 ot->exec= sequencer_select_linked_exec; 00721 ot->poll= sequencer_edit_poll; 00722 00723 /* flags */ 00724 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00725 00726 /* properties */ 00727 } 00728 00729 00730 /* select handles operator */ 00731 static int sequencer_select_handles_exec(bContext *C, wmOperator *op) 00732 { 00733 Scene *scene= CTX_data_scene(C); 00734 Editing *ed= seq_give_editing(scene, 0); 00735 Sequence *seq; 00736 int sel_side= RNA_enum_get(op->ptr, "side"); 00737 00738 00739 for(seq= ed->seqbasep->first; seq; seq=seq->next) { 00740 if (seq->flag & SELECT) { 00741 switch(sel_side) { 00742 case SEQ_SIDE_LEFT: 00743 seq->flag &= ~SEQ_RIGHTSEL; 00744 seq->flag |= SEQ_LEFTSEL; 00745 break; 00746 case SEQ_SIDE_RIGHT: 00747 seq->flag &= ~SEQ_LEFTSEL; 00748 seq->flag |= SEQ_RIGHTSEL; 00749 break; 00750 case SEQ_SIDE_BOTH: 00751 seq->flag |= SEQ_LEFTSEL+SEQ_RIGHTSEL; 00752 break; 00753 } 00754 } 00755 } 00756 00757 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00758 00759 return OPERATOR_FINISHED; 00760 } 00761 00762 void SEQUENCER_OT_select_handles(wmOperatorType *ot) 00763 { 00764 /* identifiers */ 00765 ot->name= "Select Handles"; 00766 ot->idname= "SEQUENCER_OT_select_handles"; 00767 ot->description="Select manipulator handles on the sides of the selected strip"; 00768 00769 /* api callbacks */ 00770 ot->exec= sequencer_select_handles_exec; 00771 ot->poll= sequencer_edit_poll; 00772 00773 /* flags */ 00774 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00775 00776 /* properties */ 00777 RNA_def_enum(ot->srna, "side", prop_side_types, SEQ_SIDE_BOTH, "Side", "The side of the handle that is selected"); 00778 } 00779 00780 /* select side operator */ 00781 static int sequencer_select_active_side_exec(bContext *C, wmOperator *op) 00782 { 00783 Scene *scene= CTX_data_scene(C); 00784 Editing *ed= seq_give_editing(scene, 0); 00785 Sequence *seq_act= seq_active_get(scene); 00786 00787 if (ed==NULL || seq_act==NULL) 00788 return OPERATOR_CANCELLED; 00789 00790 seq_act->flag |= SELECT; 00791 00792 select_active_side(ed->seqbasep, RNA_enum_get(op->ptr, "side"), seq_act->machine, seq_act->startdisp); 00793 00794 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00795 00796 return OPERATOR_FINISHED; 00797 } 00798 00799 void SEQUENCER_OT_select_active_side(wmOperatorType *ot) 00800 { 00801 /* identifiers */ 00802 ot->name= "Select Active Side"; 00803 ot->idname= "SEQUENCER_OT_select_active_side"; 00804 ot->description="Select strips on the nominated side of the active strip"; 00805 00806 /* api callbacks */ 00807 ot->exec= sequencer_select_active_side_exec; 00808 ot->poll= sequencer_edit_poll; 00809 00810 /* flags */ 00811 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00812 00813 /* properties */ 00814 RNA_def_enum(ot->srna, "side", prop_side_types, SEQ_SIDE_BOTH, "Side", "The side of the handle that is selected"); 00815 } 00816 00817 00818 /* borderselect operator */ 00819 static int sequencer_borderselect_exec(bContext *C, wmOperator *op) 00820 { 00821 Scene *scene= CTX_data_scene(C); 00822 Editing *ed= seq_give_editing(scene, FALSE); 00823 View2D *v2d= UI_view2d_fromcontext(C); 00824 00825 Sequence *seq; 00826 rcti rect; 00827 rctf rectf, rq; 00828 short selecting = (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT); 00829 int mval[2]; 00830 00831 if(ed==NULL) 00832 return OPERATOR_CANCELLED; 00833 00834 rect.xmin= RNA_int_get(op->ptr, "xmin"); 00835 rect.ymin= RNA_int_get(op->ptr, "ymin"); 00836 rect.xmax= RNA_int_get(op->ptr, "xmax"); 00837 rect.ymax= RNA_int_get(op->ptr, "ymax"); 00838 00839 mval[0]= rect.xmin; 00840 mval[1]= rect.ymin; 00841 UI_view2d_region_to_view(v2d, mval[0], mval[1], &rectf.xmin, &rectf.ymin); 00842 mval[0]= rect.xmax; 00843 mval[1]= rect.ymax; 00844 UI_view2d_region_to_view(v2d, mval[0], mval[1], &rectf.xmax, &rectf.ymax); 00845 00846 for(seq= ed->seqbasep->first; seq; seq= seq->next) { 00847 seq_rectf(seq, &rq); 00848 00849 if(BLI_isect_rctf(&rq, &rectf, 0)) { 00850 if(selecting) seq->flag |= SELECT; 00851 else seq->flag &= ~SEQ_ALLSEL; 00852 recurs_sel_seq(seq); 00853 } 00854 } 00855 00856 WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER|NA_SELECTED, scene); 00857 00858 return OPERATOR_FINISHED; 00859 } 00860 00861 00862 /* ****** Border Select ****** */ 00863 void SEQUENCER_OT_select_border(wmOperatorType *ot) 00864 { 00865 /* identifiers */ 00866 ot->name= "Border Select"; 00867 ot->idname= "SEQUENCER_OT_select_border"; 00868 ot->description="Enable border select mode"; 00869 00870 /* api callbacks */ 00871 ot->invoke= WM_border_select_invoke; 00872 ot->exec= sequencer_borderselect_exec; 00873 ot->modal= WM_border_select_modal; 00874 ot->cancel= WM_border_select_cancel; 00875 00876 ot->poll= ED_operator_sequencer_active; 00877 00878 /* flags */ 00879 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00880 00881 /* rna */ 00882 WM_operator_properties_gesture_border(ot, FALSE); 00883 }