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