NLA SoC: Added BorderSelect operators (BKEY and Alt-BKEY)

These work in the same way as the ones in the Action Editor...
This commit is contained in:
Joshua Leung
2009-06-10 04:43:18 +00:00
parent 7dbc21ae3c
commit 2f8290434c
4 changed files with 154 additions and 2 deletions

View File

@@ -179,7 +179,7 @@ void NLA_OT_channels_select_border(wmOperatorType *ot)
ot->exec= nlachannels_borderselect_exec;
ot->modal= WM_border_select_modal;
ot->poll= ED_operator_areaactive;
ot->poll= nlaop_poll_tweakmode_off;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -449,7 +449,7 @@ void NLA_OT_channels_click (wmOperatorType *ot)
/* api callbacks */
ot->invoke= nlachannels_mouseclick_invoke;
ot->poll= ED_operator_areaactive;
ot->poll= nlaop_poll_tweakmode_off; // xxx?
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;

View File

@@ -81,6 +81,7 @@ enum {
/* --- */
void NLAEDIT_OT_select_all_toggle(wmOperatorType *ot);
void NLAEDIT_OT_select_border(wmOperatorType *ot);
void NLAEDIT_OT_click_select(wmOperatorType *ot);
/* **************************************** */

View File

@@ -126,6 +126,7 @@ void nla_operatortypes(void)
/* select */
WM_operatortype_append(NLAEDIT_OT_click_select);
WM_operatortype_append(NLAEDIT_OT_select_border);
WM_operatortype_append(NLAEDIT_OT_select_all_toggle);
/* edit */
@@ -186,6 +187,11 @@ static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "NLAEDIT_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "NLAEDIT_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
/* borderselect */
WM_keymap_add_item(keymap, "NLAEDIT_OT_select_border", BKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "NLAEDIT_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
/* editing */
/* tweakmode
* - enter and exit are separate operators with the same hotkey...

View File

@@ -208,6 +208,151 @@ void NLAEDIT_OT_select_all_toggle (wmOperatorType *ot)
RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
}
/* ******************** Border Select Operator **************************** */
/* This operator currently works in one of three ways:
* -> BKEY - 1) all strips within region are selected (ACTKEYS_BORDERSEL_ALLSTRIPS)
* -> ALT-BKEY - depending on which axis of the region was larger...
* -> 2) x-axis, so select all frames within frame range (ACTKEYS_BORDERSEL_FRAMERANGE)
* -> 3) y-axis, so select all frames within channels that region included (ACTKEYS_BORDERSEL_CHANNELS)
*/
/* defines for borderselect mode */
enum {
NLA_BORDERSEL_ALLSTRIPS = 0,
NLA_BORDERSEL_FRAMERANGE,
NLA_BORDERSEL_CHANNELS,
} eActKeys_BorderSelect_Mode;
static void borderselect_nla_strips (bAnimContext *ac, rcti rect, short mode, short selectmode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
View2D *v2d= &ac->ar->v2d;
rctf rectf;
float ymin=(float)(-NLACHANNEL_HEIGHT), ymax=0;
/* convert border-region to view coordinates */
UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin+2, &rectf.xmin, &rectf.ymin);
UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax-2, &rectf.xmax, &rectf.ymax);
/* filter data */
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* convert selection modes to selection modes */
selectmode= selmodes_to_flagmodes(selectmode);
/* loop over data, doing border select */
for (ale= anim_data.first; ale; ale= ale->next) {
ymax= ymin + NLACHANNEL_STEP;
/* perform vertical suitability check (if applicable) */
if ( (mode == NLA_BORDERSEL_FRAMERANGE) ||
!((ymax < rectf.ymin) || (ymin > rectf.ymax)) )
{
/* loop over data selecting (only if NLA-Track) */
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt= (NlaTrack *)ale->data;
NlaStrip *strip;
/* only select strips if they fall within the required ranges (if applicable) */
for (strip= nlt->strips.first; strip; strip= strip->next) {
if ( (mode == NLA_BORDERSEL_CHANNELS) ||
BKE_nlastrip_within_bounds(strip, rectf.xmin, rectf.xmax) )
{
/* set selection */
ACHANNEL_SET_FLAG(strip, selectmode, NLASTRIP_FLAG_SELECT);
/* clear active flag */
strip->flag &= ~NLASTRIP_FLAG_ACTIVE;
}
}
}
}
/* set maximum extent to be the minimum of the next channel */
ymin= ymax;
}
/* cleanup */
BLI_freelistN(&anim_data);
}
/* ------------------- */
static int nlaedit_borderselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
rcti rect;
short mode=0, selectmode=0;
int event;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
/* get settings from operator */
rect.xmin= RNA_int_get(op->ptr, "xmin");
rect.ymin= RNA_int_get(op->ptr, "ymin");
rect.xmax= RNA_int_get(op->ptr, "xmax");
rect.ymax= RNA_int_get(op->ptr, "ymax");
event= RNA_int_get(op->ptr, "event_type");
if (event == LEFTMOUSE) // FIXME... hardcoded
selectmode = SELECT_ADD;
else
selectmode = SELECT_SUBTRACT;
/* selection 'mode' depends on whether borderselect region only matters on one axis */
if (RNA_boolean_get(op->ptr, "axis_range")) {
/* mode depends on which axis of the range is larger to determine which axis to use
* - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
* - the frame-range select option is favoured over the channel one (x over y), as frame-range one is often
* used for tweaking timing when "blocking", while channels is not that useful...
*/
if ((rect.xmax - rect.xmin) >= (rect.ymax - rect.ymin))
mode= NLA_BORDERSEL_FRAMERANGE;
else
mode= NLA_BORDERSEL_CHANNELS;
}
else
mode= NLA_BORDERSEL_ALLSTRIPS;
/* apply borderselect action */
borderselect_nla_strips(&ac, rect, mode, selectmode);
return OPERATOR_FINISHED;
}
void NLAEDIT_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
ot->idname= "NLAEDIT_OT_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
ot->exec= nlaedit_borderselect_exec;
ot->modal= WM_border_select_modal;
ot->poll= nlaop_poll_tweakmode_off;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* rna */
RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
}
/* ******************** Mouse-Click Select Operator *********************** */
/* This operator works in one of 2 ways:
* 1) Select the strip directly under the mouse