|
Blender
V2.59
|
00001 /* 00002 * $Id: nla_select.c 37246 2011-06-06 11:04:54Z nazgul $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Joshua Leung (major recode) 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <string.h> 00035 #include <stdio.h> 00036 00037 #include "DNA_anim_types.h" 00038 #include "DNA_scene_types.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_math.h" 00044 #include "BLI_rand.h" 00045 00046 #include "BKE_nla.h" 00047 #include "BKE_context.h" 00048 #include "BKE_screen.h" 00049 00050 #include "ED_anim_api.h" 00051 #include "ED_keyframes_edit.h" 00052 #include "ED_screen.h" 00053 00054 #include "RNA_access.h" 00055 #include "RNA_define.h" 00056 00057 #include "WM_api.h" 00058 #include "WM_types.h" 00059 00060 #include "UI_view2d.h" 00061 00062 #include "nla_intern.h" // own include 00063 00064 /* ******************** Utilities ***************************************** */ 00065 00066 /* Convert SELECT_* flags to ACHANNEL_SETFLAG_* flags */ 00067 static short selmodes_to_flagmodes (short sel) 00068 { 00069 /* convert selection modes to selection modes */ 00070 switch (sel) { 00071 case SELECT_SUBTRACT: 00072 return ACHANNEL_SETFLAG_CLEAR; 00073 break; 00074 00075 case SELECT_INVERT: 00076 return ACHANNEL_SETFLAG_INVERT; 00077 break; 00078 00079 case SELECT_ADD: 00080 default: 00081 return ACHANNEL_SETFLAG_ADD; 00082 break; 00083 } 00084 } 00085 00086 00087 /* ******************** Deselect All Operator ***************************** */ 00088 /* This operator works in one of three ways: 00089 * 1) (de)select all (AKEY) - test if select all or deselect all 00090 * 2) invert all (CTRL-IKEY) - invert selection of all keyframes 00091 * 3) (de)select all - no testing is done; only for use internal tools as normal function... 00092 */ 00093 00094 enum { 00095 DESELECT_STRIPS_NOTEST = 0, 00096 DESELECT_STRIPS_TEST, 00097 DESELECT_STRIPS_CLEARACTIVE, 00098 } /*eDeselectNlaStrips*/; 00099 00100 /* Deselects strips in the NLA Editor 00101 * - This is called by the deselect all operator, as well as other ones! 00102 * 00103 * - test: check if select or deselect all (1) or clear all active (2) 00104 * - sel: how to select keyframes 00105 * 0 = deselect 00106 * 1 = select 00107 * 2 = invert 00108 */ 00109 static void deselect_nla_strips (bAnimContext *ac, short test, short sel) 00110 { 00111 ListBase anim_data = {NULL, NULL}; 00112 bAnimListElem *ale; 00113 int filter; 00114 short smode; 00115 00116 /* determine type-based settings */ 00117 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS); 00118 00119 /* filter data */ 00120 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00121 00122 /* See if we should be selecting or deselecting */ 00123 if (test == DESELECT_STRIPS_TEST) { 00124 for (ale= anim_data.first; ale; ale= ale->next) { 00125 NlaTrack *nlt= (NlaTrack *)ale->data; 00126 NlaStrip *strip; 00127 00128 /* if any strip is selected, break out, since we should now be deselecting */ 00129 for (strip= nlt->strips.first; strip; strip= strip->next) { 00130 if (strip->flag & NLASTRIP_FLAG_SELECT) { 00131 sel= SELECT_SUBTRACT; 00132 break; 00133 } 00134 } 00135 00136 if (sel == SELECT_SUBTRACT) 00137 break; 00138 } 00139 } 00140 00141 /* convert selection modes to selection modes */ 00142 smode= selmodes_to_flagmodes(sel); 00143 00144 /* Now set the flags */ 00145 for (ale= anim_data.first; ale; ale= ale->next) { 00146 NlaTrack *nlt= (NlaTrack *)ale->data; 00147 NlaStrip *strip; 00148 00149 /* apply same selection to all strips */ 00150 for (strip= nlt->strips.first; strip; strip= strip->next) { 00151 /* set selection */ 00152 if (test != DESELECT_STRIPS_CLEARACTIVE) 00153 ACHANNEL_SET_FLAG(strip, smode, NLASTRIP_FLAG_SELECT); 00154 00155 /* clear active flag */ 00156 // TODO: for clear active, do we want to limit this to only doing this on a certain set of tracks though? 00157 strip->flag &= ~NLASTRIP_FLAG_ACTIVE; 00158 } 00159 } 00160 00161 /* Cleanup */ 00162 BLI_freelistN(&anim_data); 00163 } 00164 00165 /* ------------------- */ 00166 00167 static int nlaedit_deselectall_exec(bContext *C, wmOperator *op) 00168 { 00169 bAnimContext ac; 00170 00171 /* get editor data */ 00172 if (ANIM_animdata_get_context(C, &ac) == 0) 00173 return OPERATOR_CANCELLED; 00174 00175 /* 'standard' behaviour - check if selected, then apply relevant selection */ 00176 if (RNA_boolean_get(op->ptr, "invert")) 00177 deselect_nla_strips(&ac, DESELECT_STRIPS_NOTEST, SELECT_INVERT); 00178 else 00179 deselect_nla_strips(&ac, DESELECT_STRIPS_TEST, SELECT_ADD); 00180 00181 /* set notifier that things have changed */ 00182 WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_SELECTED, NULL); 00183 00184 return OPERATOR_FINISHED; 00185 } 00186 00187 void NLA_OT_select_all_toggle (wmOperatorType *ot) 00188 { 00189 /* identifiers */ 00190 ot->name= "Select or Deselect All"; 00191 ot->idname= "NLA_OT_select_all_toggle"; 00192 ot->description= "(De)Select all NLA-Strips"; 00193 00194 /* api callbacks */ 00195 ot->exec= nlaedit_deselectall_exec; 00196 ot->poll= nlaop_poll_tweakmode_off; 00197 00198 /* flags */ 00199 ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; 00200 00201 /* props */ 00202 RNA_def_boolean(ot->srna, "invert", 0, "Invert", ""); 00203 } 00204 00205 /* ******************** Border Select Operator **************************** */ 00206 /* This operator currently works in one of three ways: 00207 * -> BKEY - 1) all strips within region are selected (NLAEDIT_BORDERSEL_ALLSTRIPS) 00208 * -> ALT-BKEY - depending on which axis of the region was larger... 00209 * -> 2) x-axis, so select all frames within frame range (NLAEDIT_BORDERSEL_FRAMERANGE) 00210 * -> 3) y-axis, so select all frames within channels that region included (NLAEDIT_BORDERSEL_CHANNELS) 00211 */ 00212 00213 /* defines for borderselect mode */ 00214 enum { 00215 NLA_BORDERSEL_ALLSTRIPS = 0, 00216 NLA_BORDERSEL_FRAMERANGE, 00217 NLA_BORDERSEL_CHANNELS, 00218 } /* eNLAEDIT_BorderSelect_Mode */; 00219 00220 00221 static void borderselect_nla_strips (bAnimContext *ac, rcti rect, short mode, short selectmode) 00222 { 00223 ListBase anim_data = {NULL, NULL}; 00224 bAnimListElem *ale; 00225 int filter; 00226 00227 View2D *v2d= &ac->ar->v2d; 00228 rctf rectf; 00229 float ymin=(float)(-NLACHANNEL_HEIGHT), ymax=0; 00230 00231 /* convert border-region to view coordinates */ 00232 UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin+2, &rectf.xmin, &rectf.ymin); 00233 UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax-2, &rectf.xmax, &rectf.ymax); 00234 00235 /* filter data */ 00236 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS); 00237 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00238 00239 /* convert selection modes to selection modes */ 00240 selectmode= selmodes_to_flagmodes(selectmode); 00241 00242 /* loop over data, doing border select */ 00243 for (ale= anim_data.first; ale; ale= ale->next) { 00244 ymin= ymax - NLACHANNEL_STEP; 00245 00246 /* perform vertical suitability check (if applicable) */ 00247 if ( (mode == NLA_BORDERSEL_FRAMERANGE) || 00248 !((ymax < rectf.ymin) || (ymin > rectf.ymax)) ) 00249 { 00250 /* loop over data selecting (only if NLA-Track) */ 00251 if (ale->type == ANIMTYPE_NLATRACK) { 00252 NlaTrack *nlt= (NlaTrack *)ale->data; 00253 NlaStrip *strip; 00254 00255 /* only select strips if they fall within the required ranges (if applicable) */ 00256 for (strip= nlt->strips.first; strip; strip= strip->next) { 00257 if ( (mode == NLA_BORDERSEL_CHANNELS) || 00258 BKE_nlastrip_within_bounds(strip, rectf.xmin, rectf.xmax) ) 00259 { 00260 /* set selection */ 00261 ACHANNEL_SET_FLAG(strip, selectmode, NLASTRIP_FLAG_SELECT); 00262 00263 /* clear active flag */ 00264 strip->flag &= ~NLASTRIP_FLAG_ACTIVE; 00265 } 00266 } 00267 } 00268 } 00269 00270 /* set minimum extent to be the maximum of the next channel */ 00271 ymax= ymin; 00272 } 00273 00274 /* cleanup */ 00275 BLI_freelistN(&anim_data); 00276 } 00277 00278 /* ------------------- */ 00279 00280 static int nlaedit_borderselect_exec(bContext *C, wmOperator *op) 00281 { 00282 bAnimContext ac; 00283 rcti rect; 00284 short mode=0, selectmode=0; 00285 00286 /* get editor data */ 00287 if (ANIM_animdata_get_context(C, &ac) == 0) 00288 return OPERATOR_CANCELLED; 00289 00290 /* get settings from operator */ 00291 rect.xmin= RNA_int_get(op->ptr, "xmin"); 00292 rect.ymin= RNA_int_get(op->ptr, "ymin"); 00293 rect.xmax= RNA_int_get(op->ptr, "xmax"); 00294 rect.ymax= RNA_int_get(op->ptr, "ymax"); 00295 00296 if (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT) 00297 selectmode = SELECT_ADD; 00298 else 00299 selectmode = SELECT_SUBTRACT; 00300 00301 /* selection 'mode' depends on whether borderselect region only matters on one axis */ 00302 if (RNA_boolean_get(op->ptr, "axis_range")) { 00303 /* mode depends on which axis of the range is larger to determine which axis to use 00304 * - checking this in region-space is fine, as it's fundamentally still going to be a different rect size 00305 * - the frame-range select option is favoured over the channel one (x over y), as frame-range one is often 00306 * used for tweaking timing when "blocking", while channels is not that useful... 00307 */ 00308 if ((rect.xmax - rect.xmin) >= (rect.ymax - rect.ymin)) 00309 mode= NLA_BORDERSEL_FRAMERANGE; 00310 else 00311 mode= NLA_BORDERSEL_CHANNELS; 00312 } 00313 else 00314 mode= NLA_BORDERSEL_ALLSTRIPS; 00315 00316 /* apply borderselect action */ 00317 borderselect_nla_strips(&ac, rect, mode, selectmode); 00318 00319 /* set notifier that things have changed */ 00320 WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_SELECTED, NULL); 00321 00322 return OPERATOR_FINISHED; 00323 } 00324 00325 void NLA_OT_select_border(wmOperatorType *ot) 00326 { 00327 /* identifiers */ 00328 ot->name= "Border Select"; 00329 ot->idname= "NLA_OT_select_border"; 00330 ot->description= "Use box selection to grab NLA-Strips"; 00331 00332 /* api callbacks */ 00333 ot->invoke= WM_border_select_invoke; 00334 ot->exec= nlaedit_borderselect_exec; 00335 ot->modal= WM_border_select_modal; 00336 ot->cancel= WM_border_select_cancel; 00337 00338 ot->poll= nlaop_poll_tweakmode_off; 00339 00340 /* flags */ 00341 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00342 00343 /* rna */ 00344 WM_operator_properties_gesture_border(ot, 0); 00345 00346 RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", ""); 00347 } 00348 00349 /* ******************** Select Left/Right Operator ************************* */ 00350 /* Select keyframes left/right of the current frame indicator */ 00351 00352 /* defines for left-right select tool */ 00353 static EnumPropertyItem prop_nlaedit_leftright_select_types[] = { 00354 {NLAEDIT_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""}, 00355 {NLAEDIT_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""}, 00356 {NLAEDIT_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""}, 00357 {0, NULL, 0, NULL, NULL} 00358 }; 00359 00360 /* ------------------- */ 00361 00362 static void nlaedit_select_leftright (bContext *C, bAnimContext *ac, short leftright, short select_mode) 00363 { 00364 ListBase anim_data = {NULL, NULL}; 00365 bAnimListElem *ale; 00366 int filter; 00367 00368 Scene *scene= ac->scene; 00369 float xmin, xmax; 00370 00371 /* if currently in tweakmode, exit tweakmode first */ 00372 if (scene->flag & SCE_NLA_EDIT_ON) 00373 WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL); 00374 00375 /* if select mode is replace, deselect all keyframes (and channels) first */ 00376 if (select_mode==SELECT_REPLACE) { 00377 select_mode= SELECT_ADD; 00378 00379 /* deselect all other channels and keyframes */ 00380 ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); 00381 deselect_nla_strips(ac, 0, SELECT_SUBTRACT); 00382 } 00383 00384 /* get range, and get the right flag-setting mode */ 00385 if (leftright == NLAEDIT_LRSEL_LEFT) { 00386 xmin = MINAFRAMEF; 00387 xmax = (float)(CFRA + 0.1f); 00388 } 00389 else { 00390 xmin = (float)(CFRA - 0.1f); 00391 xmax = MAXFRAMEF; 00392 } 00393 00394 select_mode= selmodes_to_flagmodes(select_mode); 00395 00396 00397 /* filter data */ 00398 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS); 00399 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00400 00401 /* select strips on the side where most data occurs */ 00402 for (ale= anim_data.first; ale; ale= ale->next) { 00403 NlaTrack *nlt= (NlaTrack *)ale->data; 00404 NlaStrip *strip; 00405 00406 /* check each strip to see if it is appropriate */ 00407 for (strip= nlt->strips.first; strip; strip= strip->next) { 00408 if (BKE_nlastrip_within_bounds(strip, xmin, xmax)) { 00409 ACHANNEL_SET_FLAG(strip, select_mode, NLASTRIP_FLAG_SELECT); 00410 } 00411 } 00412 } 00413 00414 /* Cleanup */ 00415 BLI_freelistN(&anim_data); 00416 } 00417 00418 /* ------------------- */ 00419 00420 static int nlaedit_select_leftright_exec (bContext *C, wmOperator *op) 00421 { 00422 bAnimContext ac; 00423 short leftright = RNA_enum_get(op->ptr, "mode"); 00424 short selectmode; 00425 00426 /* get editor data */ 00427 if (ANIM_animdata_get_context(C, &ac) == 0) 00428 return OPERATOR_CANCELLED; 00429 00430 /* select mode is either replace (deselect all, then add) or add/extend */ 00431 if (RNA_boolean_get(op->ptr, "extend")) 00432 selectmode= SELECT_INVERT; 00433 else 00434 selectmode= SELECT_REPLACE; 00435 00436 /* if "test" mode is set, we don't have any info to set this with */ 00437 if (leftright == NLAEDIT_LRSEL_TEST) 00438 return OPERATOR_CANCELLED; 00439 00440 /* do the selecting now */ 00441 nlaedit_select_leftright(C, &ac, leftright, selectmode); 00442 00443 /* set notifier that keyframe selection (and channels too) have changed */ 00444 WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|ND_ANIMCHAN|NA_SELECTED, NULL); 00445 00446 return OPERATOR_FINISHED; 00447 } 00448 00449 static int nlaedit_select_leftright_invoke (bContext *C, wmOperator *op, wmEvent *event) 00450 { 00451 bAnimContext ac; 00452 short leftright = RNA_enum_get(op->ptr, "mode"); 00453 00454 /* get editor data */ 00455 if (ANIM_animdata_get_context(C, &ac) == 0) 00456 return OPERATOR_CANCELLED; 00457 00458 /* handle mode-based testing */ 00459 if (leftright == NLAEDIT_LRSEL_TEST) { 00460 Scene *scene= ac.scene; 00461 ARegion *ar= ac.ar; 00462 View2D *v2d= &ar->v2d; 00463 float x; 00464 00465 /* determine which side of the current frame mouse is on */ 00466 UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL); 00467 if (x < CFRA) 00468 RNA_int_set(op->ptr, "mode", NLAEDIT_LRSEL_LEFT); 00469 else 00470 RNA_int_set(op->ptr, "mode", NLAEDIT_LRSEL_RIGHT); 00471 } 00472 00473 /* perform selection */ 00474 return nlaedit_select_leftright_exec(C, op); 00475 } 00476 00477 void NLA_OT_select_leftright (wmOperatorType *ot) 00478 { 00479 /* identifiers */ 00480 ot->name= "Select Left/Right"; 00481 ot->idname= "NLA_OT_select_leftright"; 00482 ot->description= "Select strips to the left or the right of the current frame "; 00483 00484 /* api callbacks */ 00485 ot->invoke= nlaedit_select_leftright_invoke; 00486 ot->exec= nlaedit_select_leftright_exec; 00487 ot->poll= ED_operator_nla_active; 00488 00489 /* flags */ 00490 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00491 00492 /* id-props */ 00493 ot->prop= RNA_def_enum(ot->srna, "mode", prop_nlaedit_leftright_select_types, NLAEDIT_LRSEL_TEST, "Mode", ""); 00494 RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); 00495 } 00496 00497 00498 /* ******************** Mouse-Click Select Operator *********************** */ 00499 00500 /* select strip directly under mouse */ 00501 static void mouse_nla_strips (bContext *C, bAnimContext *ac, const int mval[2], short select_mode) 00502 { 00503 ListBase anim_data = {NULL, NULL}; 00504 bAnimListElem *ale = NULL; 00505 int filter; 00506 00507 View2D *v2d= &ac->ar->v2d; 00508 Scene *scene= ac->scene; 00509 NlaStrip *strip = NULL; 00510 int channel_index; 00511 float xmin, xmax, dummy; 00512 float x, y; 00513 00514 00515 /* use View2D to determine the index of the channel (i.e a row in the list) where keyframe was */ 00516 UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); 00517 UI_view2d_listview_view_to_cell(v2d, 0, NLACHANNEL_STEP, 0, (float)NLACHANNEL_HEIGHT_HALF, x, y, NULL, &channel_index); 00518 00519 /* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click 00520 * (that is the size of keyframe icons, so user should be expecting similar tolerances) 00521 */ 00522 UI_view2d_region_to_view(v2d, mval[0]-7, mval[1], &xmin, &dummy); 00523 UI_view2d_region_to_view(v2d, mval[0]+7, mval[1], &xmax, &dummy); 00524 00525 /* filter data */ 00526 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS); 00527 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00528 00529 /* try to get channel */ 00530 ale= BLI_findlink(&anim_data, channel_index); 00531 if (ale == NULL) { 00532 /* channel not found */ 00533 printf("Error: animation channel (index = %d) not found in mouse_nla_strips() \n", channel_index); 00534 BLI_freelistN(&anim_data); 00535 return; 00536 } 00537 else { 00538 /* found some channel - we only really should do somethign when its an Nla-Track */ 00539 if (ale->type == ANIMTYPE_NLATRACK) { 00540 NlaTrack *nlt= (NlaTrack *)ale->data; 00541 00542 /* loop over NLA-strips in this track, trying to find one which occurs in the necessary bounds */ 00543 for (strip= nlt->strips.first; strip; strip= strip->next) { 00544 if (BKE_nlastrip_within_bounds(strip, xmin, xmax)) 00545 break; 00546 } 00547 } 00548 00549 /* remove active channel from list of channels for separate treatment (since it's needed later on) */ 00550 BLI_remlink(&anim_data, ale); 00551 00552 /* free list of channels, since it's not used anymore */ 00553 BLI_freelistN(&anim_data); 00554 } 00555 00556 /* if currently in tweakmode, exit tweakmode before changing selection states 00557 * now that we've found our target... 00558 */ 00559 if (scene->flag & SCE_NLA_EDIT_ON) 00560 WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL); 00561 00562 /* for replacing selection, firstly need to clear existing selection */ 00563 if (select_mode == SELECT_REPLACE) { 00564 /* reset selection mode for next steps */ 00565 select_mode = SELECT_ADD; 00566 00567 /* deselect all strips */ 00568 deselect_nla_strips(ac, 0, SELECT_SUBTRACT); 00569 00570 /* deselect all other channels first */ 00571 ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); 00572 00573 /* Highlight NLA-Track */ 00574 if (ale->type == ANIMTYPE_NLATRACK) { 00575 NlaTrack *nlt= (NlaTrack *)ale->data; 00576 00577 nlt->flag |= NLATRACK_SELECTED; 00578 ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK); 00579 } 00580 } 00581 00582 /* only select strip if we clicked on a valid channel and hit something */ 00583 if (ale) { 00584 /* select the strip accordingly (if a matching one was found) */ 00585 if (strip) { 00586 select_mode= selmodes_to_flagmodes(select_mode); 00587 ACHANNEL_SET_FLAG(strip, select_mode, NLASTRIP_FLAG_SELECT); 00588 00589 /* if we selected it, we can make it active too 00590 * - we always need to clear the active strip flag though... 00591 */ 00592 deselect_nla_strips(ac, DESELECT_STRIPS_CLEARACTIVE, 0); 00593 if (strip->flag & NLASTRIP_FLAG_SELECT) 00594 strip->flag |= NLASTRIP_FLAG_ACTIVE; 00595 } 00596 00597 /* free this channel */ 00598 MEM_freeN(ale); 00599 } 00600 } 00601 00602 /* ------------------- */ 00603 00604 /* handle clicking */ 00605 static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event) 00606 { 00607 bAnimContext ac; 00608 Scene *scene; 00609 ARegion *ar; 00610 // View2D *v2d; /*UNUSED*/ 00611 short selectmode; 00612 00613 /* get editor data */ 00614 if (ANIM_animdata_get_context(C, &ac) == 0) 00615 return OPERATOR_CANCELLED; 00616 00617 /* get useful pointers from animation context data */ 00618 scene= ac.scene; 00619 ar= ac.ar; 00620 // v2d= &ar->v2d; 00621 00622 /* select mode is either replace (deselect all, then add) or add/extend */ 00623 if (RNA_boolean_get(op->ptr, "extend")) 00624 selectmode= SELECT_INVERT; 00625 else 00626 selectmode= SELECT_REPLACE; 00627 00628 /* select strips based upon mouse position */ 00629 mouse_nla_strips(C, &ac, event->mval, selectmode); 00630 00631 /* set notifier that things have changed */ 00632 WM_event_add_notifier(C, NC_ANIMATION|ND_NLA|NA_SELECTED, NULL); 00633 00634 /* for tweak grab to work */ 00635 return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH; 00636 } 00637 00638 void NLA_OT_click_select (wmOperatorType *ot) 00639 { 00640 /* identifiers */ 00641 ot->name= "Mouse Select"; 00642 ot->idname= "NLA_OT_click_select"; 00643 ot->description= "Handle clicks to select NLA Strips"; 00644 00645 /* api callbacks - absolutely no exec() this yet... */ 00646 ot->invoke= nlaedit_clickselect_invoke; 00647 ot->poll= ED_operator_nla_active; 00648 00649 /* flags */ 00650 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00651 00652 /* id-props */ 00653 RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY 00654 } 00655 00656 /* *********************************************** */