diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h index 5705b4d83ed..2419cc779dd 100644 --- a/source/blender/include/BIF_editaction.h +++ b/source/blender/include/BIF_editaction.h @@ -50,10 +50,20 @@ #define SLIDERWIDTH 125 #define ACTWIDTH (G.saction->actwidth) +/* Some types for easier type-testing */ +#define ACTTYPE_NONE 0 +#define ACTTYPE_ACHAN 1 +#define ACTTYPE_CONCHAN 2 + +/* Macros for easier/more consistant state testing */ #define VISIBLE_ACHAN(achan) ((achan->flag & ACHAN_HIDDEN)==0) -#define EDITABLE_ACHAN(achan) (((achan->flag & ACHAN_HIDDEN)==0) && ((achan->flag & ACHAN_PROTECTED)==0)) +#define EDITABLE_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && ((achan->flag & ACHAN_PROTECTED)==0)) +//#define EXPANDED_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && (achan->flag & ACHAN_EXPANDED)) +#define SEL_ACHAN(achan) ((achan->flag & ACHAN_SELECTED) || (achan->flag & ACHAN_HILIGHTED)) + #define EDITABLE_CONCHAN(conchan) ((conchan->flag & CONSTRAINT_CHANNEL_PROTECTED)==0) + #define CHANNEL_FILTER_LOC 0x00000001 /* Show location keys */ #define CHANNEL_FILTER_ROT 0x00000002 /* Show rotation keys */ #define CHANNEL_FILTER_SIZE 0x00000004 /* Show size keys */ @@ -81,8 +91,6 @@ void duplicate_meshchannel_keys(struct Key *key); void duplicate_actionchannel_keys(void); void transform_actionchannel_keys(int mode, int dummy); void transform_meshchannel_keys(char mode, struct Key *key); -struct Key *get_action_mesh_key(void); -int get_nearest_key_num(struct Key *key, short *mval, float *x); void snap_keys_to_frame(int snap_mode); void mirror_action_keys(short mirror_mode); void clean_shapekeys(struct Key *key); @@ -117,6 +125,11 @@ void deselect_meshchannel_keys (struct Key *key, int test, int sel); int select_channel(struct bAction *act, struct bActionChannel *chan, int selectmode); void select_actionchannel_by_name (struct bAction *act, char *name, int select); +/* */ +struct Key *get_action_mesh_key(void); +int get_nearest_key_num(struct Key *key, short *mval, float *x); +void *get_nearest_act_channel(short mval[], short *ret_type); + /* Action */ struct bActionChannel* get_hilighted_action_channel(struct bAction* action); struct bAction *add_empty_action(char *name); diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index b1017a9f5c0..06bc73bb957 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -1928,10 +1928,7 @@ static void delete_actionchannels (void) if (!chan && !conchan) return; - - if (!okee("Erase selected channels")) - return; - + for (chan=act->chanbase.first; chan; chan=next){ freechan = 0; next=chan->next; @@ -2709,19 +2706,83 @@ static void clever_keyblock_names(Key *key, short* mval){ } +static void clever_achannel_names(short *mval) +{ + void *act_channel; + bActionChannel *achan= NULL; + bConstraintChannel *conchan= NULL; + + int but=0; + char str[64]; + short protect, chantype; + + /* figure out what is under cursor */ + act_channel= get_nearest_act_channel(mval, &chantype); + + /* create items for clever-numbut */ + if (chantype == ACTTYPE_ACHAN) { + achan= (bActionChannel *)act_channel; + + strcpy(str, achan->name); + protect= (achan->flag & ACHAN_PROTECTED); + + add_numbut(but++, TEX, "ActChan: ", 0, 24, str, "Name of Action Channel"); + } + else if (chantype == ACTTYPE_CONCHAN) { + conchan= (bConstraintChannel *)act_channel; + + strcpy(str, conchan->name); + protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED); + + add_numbut(but++, TEX, "ConChan: ", 0, 24, str, "Name of Constraint Channel"); + } + else { + /* nothing under-cursor */ + return; + } + add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Group is expanded"); + + /* draw clever-numbut */ + if (do_clever_numbuts(str, but, REDRAW)) { + /* restore settings based on type */ + if (conchan) { + strcpy(conchan->name, str); + + if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED; + else conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED; + } + else if (achan) { + strcpy(achan->name, str); + + //if (expand) achan->flag |= ACHAN_EXPANDED; + //else achan->flag &= ~ACHAN_EXPANDED; + + if (protect) achan->flag |= ACHAN_PROTECTED; + else achan->flag &= ~ACHAN_PROTECTED; + } + + allqueue (REDRAWACTION, 0); + allqueue (REDRAWVIEW3D, 0); + } +} + +/* this gets called when nkey is pressed (no Transform Properties panel yet) */ static void numbuts_action(void) { /* now called from action window event loop, plus reacts on mouseclick */ /* removed Hos grunts for that reason! :) (ton) */ Key *key; short mval[2]; - - if ( (key = get_action_mesh_key()) ) { - getmouseco_areawin (mval); - if (mval[0]= NAMEWIDTH) + remove_marker(); allqueue(REDRAWTIME, 0); allqueue(REDRAWIPO, 0); @@ -3246,6 +3309,81 @@ int get_nearest_key_num(Key *key, short *mval, float *x) { return (num + 1); } +void *get_nearest_act_channel(short mval[], short *ret_type) +{ + /* Returns the 'channel' that is under the mouse cursor. + * This 'channel' can either be an action channel, or a constraint channel. + * + * #ret_type# is used to denote what type of channel was found. + * It should only be one of the ACTTYPE_* constant values. + */ + + bAction *act= G.saction->action; + bActionChannel *achan; + bConstraintChannel *conchan; + + float x,y; + int clickmin, clickmax; + int wsize; + + if (act == NULL) { + *ret_type= ACTTYPE_NONE; + return NULL; + } + + /* wsize is the greatest possible height (in pixels) that would be + * needed to draw all of the groups, action channels and constraint + * channels. + */ + wsize = count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP); + wsize += CHANNELHEIGHT/2; + + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + clickmin = (int) ((wsize - y) / (CHANNELHEIGHT+CHANNELSKIP)); + clickmax = clickmin; + + if (clickmax < 0) { + *ret_type= ACTTYPE_NONE; + return NULL; + } + + /* try in action channels */ + for (achan = act->chanbase.first; achan; achan=achan->next) { + if(VISIBLE_ACHAN(achan)) { + if (clickmax < 0) break; + + if (clickmin <= 0) { + /* found match - action channel */ + *ret_type= ACTTYPE_ACHAN; + return achan; + } + + --clickmin; + --clickmax; + } + else { + continue; + } + + /* try in constaint channels */ + for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) { + if (clickmax < 0) break; + + if (clickmin <= 0) { + /* found match - constraint channel */ + *ret_type= ACTTYPE_CONCHAN; + return conchan; + } + + --clickmin; + --clickmax; + } + } + + *ret_type= ACTTYPE_NONE; + return NULL; +} + /* ************************************* Action Editor Markers ************************************* */ void markers_selectkeys_between(void)