Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Want <cwant@ualberta.ca>2003-07-21 03:04:09 +0400
committerChris Want <cwant@ualberta.ca>2003-07-21 03:04:09 +0400
commitcf495e6655de7e7dce5115d487460a33fcb8b488 (patch)
tree88c14a4ba94f610ccf909bd68af4b0f786cee4e6 /source/blender/src/editaction.c
parent9a9cb5448b090ff88c6c46fec312c7f98941c248 (diff)
Support for using the action window as a tool for modifying
(mesh or lattice) RVK IpoCurves: support currently includes: - RVK sliders. Pressing the little triangle next to the word 'sliders' in the channel names opens them up. - NKEY in the area where the key block names are allows the user to change the name of the keyblock, and the max and min values of the RVK sliders. - ability to visualize the keyframes for the IpoCurves when the object is selected. - right mouse can be used to select the keys - border select in the main area can be used to border select keys. - AKEY selects/deselects all of the keys - GKEY and SKEY can be used to grab or scale the key selections. - XKEY deletes the selected keys. - DKEY duplicated the selected keys. - VKEY, HKEY and shift-HKEY change the bezier handles for the selected keys. Please, please, please test!
Diffstat (limited to 'source/blender/src/editaction.c')
-rw-r--r--source/blender/src/editaction.c872
1 files changed, 785 insertions, 87 deletions
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 01f0ff4ff2b..dbde1c22d84 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -57,6 +57,9 @@
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_lattice_types.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
@@ -67,6 +70,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_action.h"
+#include "BKE_key.h"
#include "BIF_gl.h"
#include "BIF_mywindow.h"
@@ -107,17 +111,24 @@ static void mouse_actionchannels(bAction *act, short *mval,
short *mvalo, int selectmode);
static void borderselect_action(void);
static void mouse_action(int selectmode);
+static void mouse_mesh_action(int selectmode, Key *key);
static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, bConstraintChannel **conchan);
+static void sethandles_actionchannel_keys(int code);
static void delete_actionchannels(void);
static void delete_actionchannel_keys(void);
static void duplicate_actionchannel_keys(void);
static void transform_actionchannel_keys(char mode);
+static void transform_meshchannel_keys(char mode, Key *key);
static void select_poseelement_by_name (char *name, int select);
static void hilight_channel (bAction *act, bActionChannel *chan, short hilight);
static void set_action_key_time (bAction *act, bPoseChannel *chan, int adrcode, short makecurve, float time);
+static void clever_numbuts_meshaction(Key *key, short* mval);
/* Implementation */
+short showsliders = 0;
+short ACTWIDTH = NAMEWIDTH;
+
static void select_poseelement_by_name (char *name, int select)
{
/* Synchs selection of channels with selection of object elements in posemode */
@@ -277,6 +288,40 @@ void remake_action_ipos(bAction *act)
}
}
+void remake_meshaction_ipos(Ipo *ipo)
+{
+ /* this puts the bezier triples in proper
+ * order and makes sure the bezier handles
+ * aren't too strange.
+ */
+ IpoCurve *icu;
+
+ for (icu = ipo->curve.first; icu; icu=icu->next){
+ sort_time_ipocurve(icu);
+ testhandles_ipocurve(icu);
+ }
+}
+
+static void meshkey_do_redraw(Key *key)
+{
+ remake_meshaction_ipos(key->ipo);
+ do_all_ipos();
+ do_spec_key(key);
+
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+
+}
+
+static void duplicate_meshchannel_keys(Key *key)
+{
+ duplicate_ipo_keys(key->ipo);
+ transform_meshchannel_keys ('g', key);
+}
+
+
static void duplicate_actionchannel_keys(void)
{
bAction *act;
@@ -396,6 +441,110 @@ static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel,
return firstchan;
}
+static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
+{
+ /* This function tries to find the RVK key that is
+ * closest to the user's mouse click
+ */
+ Key *key;
+ IpoCurve *icu;
+ IpoCurve *firsticu=NULL;
+ int foundsel=0;
+ float firstvert=-1, foundx=-1;
+ int i;
+ short mval[2];
+ float ymin, ymax, ybase;
+ rctf rectf;
+
+ *index=0;
+
+ key = get_action_mesh_key();
+
+ /* lets get the mouse position and process it so
+ * we can start testing selections
+ */
+ getmouseco_areawin (mval);
+ mval[0]-=7;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
+ mval[0]+=14;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
+
+ ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
+ *sel=0;
+
+ /* lets loop through the IpoCurves trying to find the closest
+ * bezier
+ */
+ for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+ /* lets not deal with the "speed" Ipo
+ */
+ if (!icu->adrcode) continue;
+
+ ymax = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
+ ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
+
+ /* Does this curve coorespond to the right
+ * strip?
+ */
+ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){
+
+ /* loop through the beziers in the curve
+ */
+ for (i=0; i<icu->totvert; i++){
+
+ /* Is this bezier in the right area?
+ */
+ if (icu->bezt[i].vec[1][0] > rectf.xmin &&
+ icu->bezt[i].vec[1][0] <= rectf.xmax ){
+
+ /* if no other curves have been picked ...
+ */
+ if (!firsticu){
+ /* mark this curve/bezier as the first
+ * selected
+ */
+ firsticu=icu;
+ firstvert=icu->bezt[i].vec[1][0];
+
+ /* sel = (is the bezier is already selected) ? 1 : 0;
+ */
+ *sel = icu->bezt[i].f2 & 1;
+ }
+
+ /* if the bezier is selected ...
+ */
+ if (icu->bezt[i].f2 & 1){
+ /* if we haven't found a selected one yet ...
+ */
+ if (!foundsel){
+ /* record the found x value
+ */
+ foundsel=1;
+ foundx = icu->bezt[i].vec[1][0];
+ }
+ }
+
+ /* if the bezier is unselected and not at the x
+ * position of a previous found selected bezier ...
+ */
+ else if (foundsel && icu->bezt[i].vec[1][0] != foundx){
+ /* lets return this found curve/bezier
+ */
+ *index=icu->bezt[i].vec[1][0];
+ *sel = 0;
+ return icu;
+ }
+ }
+ }
+ }
+ }
+
+ /* return what we've found
+ */
+ *index=firstvert;
+ return firsticu;
+}
+
static void mouse_action(int selectmode)
{
bAction *act;
@@ -439,6 +588,63 @@ static void mouse_action(int selectmode)
}
}
+static void mouse_mesh_action(int selectmode, Key *key)
+{
+ /* Handle a right mouse click selection in an
+ * action window displaying RVK data
+ */
+
+ IpoCurve *icu;
+ short sel;
+ float selx;
+ short mval[2];
+
+ /* going to assume that the only reason
+ * we got here is because it has been
+ * determined that we are a mesh with
+ * the right properties (i.e., have key
+ * data, etc)
+ */
+
+ /* get the click location, and the cooresponding
+ * ipo curve and selection time value
+ */
+ getmouseco_areawin (mval);
+ icu = get_nearest_meshchannel_key(&selx, &sel);
+
+ if (icu){
+ if (selectmode == SELECT_REPLACE) {
+ /* if we had planned to replace the
+ * selection, then we will first deselect
+ * all of the keys, and if the clicked on
+ * key had been unselected, we will select
+ * it, otherwise, we are done.
+ */
+ deselect_meshchannel_keys(key, 0);
+
+ if (sel == 0)
+ selectmode = SELECT_ADD;
+ else
+ /* the key is selected so we should
+ * deselect -- but everything is now deselected
+ * so we are done.
+ */
+ return;
+ }
+
+ /* select the key using the given mode
+ * and redraw as mush stuff as needed.
+ */
+ select_icu_key(icu, selx, selectmode);
+
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+
+ }
+}
+
static void borderselect_action(void)
{
rcti rect;
@@ -496,6 +702,61 @@ static void borderselect_action(void)
}
}
+static void borderselect_mesh(Key *key)
+{
+ rcti rect;
+ int val, adrcodemax, adrcodemin;
+ short mval[2];
+ float xmin, xmax;
+ int (*select_function)(BezTriple *);
+ IpoCurve *icu;
+
+ if ( (val = get_border(&rect, 3)) ){
+ /* set the selection function based on what
+ * mouse button had been used in the border
+ * select
+ */
+ if (val == LEFTMOUSE)
+ select_function = select_bezier_add;
+ else
+ select_function = select_bezier_subtract;
+
+ /* get the minimum and maximum adrcode numbers
+ * for the IpoCurves (this is the number that
+ * relates an IpoCurve to the keyblock it
+ * controls).
+ */
+ mval[0]= rect.xmin;
+ mval[1]= rect.ymin+2;
+ adrcodemax = get_nearest_key_num(key, mval, &xmin);
+ adrcodemax = (adrcodemax >= key->totkey) ? key->totkey : adrcodemax;
+
+ mval[0]= rect.xmax;
+ mval[1]= rect.ymax-2;
+ adrcodemin = get_nearest_key_num(key, mval, &xmax);
+ adrcodemin = (adrcodemin < 1) ? 1 : adrcodemin;
+
+ /* Lets loop throug the IpoCurves and do borderselect
+ * on the curves with adrcodes in our selected range.
+ */
+ for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+ /* lets not deal with the "speed" Ipo
+ */
+ if (!icu->adrcode) continue;
+ if ( (icu->adrcode >= adrcodemin) &&
+ (icu->adrcode <= adrcodemax) ) {
+ borderselect_icu_key(icu, xmin, xmax, select_function);
+ }
+ }
+
+ /* redraw stuff */
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ }
+}
+
+
bActionChannel* get_hilighted_action_channel(bAction* action)
{
bActionChannel *chan;
@@ -1017,6 +1278,192 @@ static void transform_actionchannel_keys(char mode)
MEM_freeN (tv);
}
+static void transform_meshchannel_keys(char mode, Key *key)
+{
+ /* this is the function that determines what happens
+ * to those little blocky rvk key things you have selected
+ * after you press a 'g' or an 's'. I'd love to say that
+ * I have an intimate knowledge of all of what this function
+ * is doing, but instead I'm just going to pretend.
+ */
+ TransVert *tv;
+ int /*sel=0,*/ i;
+ short mvals[2], mvalc[2], cent[2];
+ float sval[2], cval[2], lastcval[2];
+ short cancel=0;
+ float fac=0.0F;
+ int loop=1;
+ int tvtot=0;
+ float deltax, startx;
+ float cenf[2];
+ int invert=0, firsttime=1;
+ char str[256];
+
+ /* count all of the selected beziers, and
+ * set all 3 control handles to selected
+ */
+ tvtot=fullselect_ipo_keys(key->ipo);
+
+ /* If nothing is selected, bail out
+ */
+ if (!tvtot)
+ return;
+
+
+ /* Build the transvert structure
+ */
+ tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
+ tvtot=0;
+
+ tvtot = add_trans_ipo_keys(key->ipo, tv, tvtot);
+
+ /* Do the event loop
+ */
+ cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2;
+ cent[1] = curarea->winy + (G.saction->v2d.hor.ymax)/2;
+ areamouseco_to_ipoco(G.v2d, cent, &cenf[0], &cenf[1]);
+
+ getmouseco_areawin (mvals);
+ areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]);
+
+ startx=sval[0];
+ while (loop) {
+ /* Get the input
+ * If we're cancelling, reset transformations
+ * Else calc new transformation
+ * Perform the transformations
+ */
+ while (qtest()) {
+ short val;
+ unsigned short event= extern_qread(&val);
+
+ if (val) {
+ switch (event) {
+ case LEFTMOUSE:
+ case SPACEKEY:
+ case RETKEY:
+ loop=0;
+ break;
+ case XKEY:
+ break;
+ case ESCKEY:
+ case RIGHTMOUSE:
+ cancel=1;
+ loop=0;
+ break;
+ default:
+ arrows_move_cursor(event);
+ break;
+ };
+ }
+ }
+
+ if (cancel) {
+ for (i=0; i<tvtot; i++) {
+ tv[i].loc[0]=tv[i].oldloc[0];
+ tv[i].loc[1]=tv[i].oldloc[1];
+ }
+ }
+ else {
+ getmouseco_areawin (mvalc);
+ areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]);
+
+ if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
+ PIL_sleep_ms(1);
+ } else {
+ for (i=0; i<tvtot; i++){
+ tv[i].loc[0]=tv[i].oldloc[0];
+
+ switch (mode){
+ case 'g':
+ deltax = cval[0]-sval[0];
+ fac= deltax;
+
+ apply_keyb_grid(&fac, 0.0, 1.0, 0.1,
+ U.flag & AUTOGRABGRID);
+
+ tv[i].loc[0]+=fac;
+ break;
+ case 's':
+ startx=mvals[0]-(ACTWIDTH/2+(curarea->winrct.xmax
+ -curarea->winrct.xmin)/2);
+ deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax
+ -curarea->winrct.xmin)/2);
+ fac= fabs(deltax/startx);
+
+ apply_keyb_grid(&fac, 0.0, 0.2, 0.1,
+ U.flag & AUTOSIZEGRID);
+
+ if (invert){
+ if (i % 03 == 0){
+ memcpy (tv[i].loc, tv[i].oldloc,
+ sizeof(tv[i+2].oldloc));
+ }
+ if (i % 03 == 2){
+ memcpy (tv[i].loc, tv[i].oldloc,
+ sizeof(tv[i-2].oldloc));
+ }
+
+ fac*=-1;
+ }
+ startx= (G.scene->r.cfra);
+
+ tv[i].loc[0]-= startx;
+ tv[i].loc[0]*=fac;
+ tv[i].loc[0]+= startx;
+
+ break;
+ }
+ }
+ }
+ /* Display a message showing the magnitude of
+ * the grab/scale we are performing
+ */
+ if (mode=='s'){
+ sprintf(str, "sizeX: %.3f", fac);
+ headerprint(str);
+ }
+ else if (mode=='g'){
+ sprintf(str, "deltaX: %.3f", fac);
+ headerprint(str);
+ }
+
+ if (G.saction->lock){
+ /* doubt any of this code ever gets
+ * executed, but it might in the
+ * future
+ */
+
+ do_all_actions();
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+ force_draw_all();
+ }
+ else {
+ addqueue (curarea->win, REDRAWALL, 0);
+ force_draw ();
+ }
+ }
+
+ lastcval[0]= cval[0];
+ lastcval[1]= cval[1];
+ firsttime= 0;
+ }
+
+ /* fix up the Ipocurves and redraw stuff
+ */
+ meshkey_do_redraw(key);
+
+ MEM_freeN (tv);
+
+ /* did you understand all of that? I pretty much understand
+ * what it does, but the specifics seem a little weird and crufty.
+ */
+}
+
+
void deselect_actionchannel_keys (bAction *act, int test)
{
bActionChannel *chan;
@@ -1059,6 +1506,26 @@ void deselect_actionchannel_keys (bAction *act, int test)
}
}
+void deselect_meshchannel_keys (Key *key, int test)
+{
+ /* should deselect the rvk keys
+ */
+ int sel=1;
+
+ /* Determine if this is selection or deselection */
+ if (test){
+ if (is_ipo_key_selected(key->ipo)){
+ sel = 0;
+ }
+ }
+ else {
+ sel=0;
+ }
+
+ /* Set the flags */
+ set_ipo_key_selection(key->ipo, sel);
+}
+
void deselect_actionchannels (bAction *act, int test)
{
bActionChannel *chan;
@@ -1125,6 +1592,12 @@ static void hilight_channel (bAction *act, bActionChannel *chan, short select)
}
}
+/* select_mode = SELECT_REPLACE
+ * = SELECT_ADD
+ * = SELECT_SUBTRACT
+ * = SELECT_INVERT
+ */
+
static int select_channel(bAction *act, bActionChannel *chan,
int selectmode) {
/* Select the channel based on the selection mode
@@ -1277,6 +1750,15 @@ static void mouse_actionchannels(bAction *act, short *mval,
allqueue (REDRAWNLA, 0);
}
+static void delete_meshchannel_keys(Key *key)
+{
+ if (!okee("Erase selected keys"))
+ return;
+
+ delete_ipo_keys(key->ipo);
+
+ meshkey_do_redraw(key);
+}
static void delete_actionchannel_keys(void)
{
@@ -1369,6 +1851,13 @@ static void delete_actionchannels (void)
}
+static void sethandles_meshchannel_keys(int code, Key *key)
+{
+ sethandles_ipo_keys(key->ipo, code);
+
+ meshkey_do_redraw(key);
+}
+
static void sethandles_actionchannel_keys(int code)
{
bAction *act;
@@ -1660,7 +2149,8 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
short mval[2];
float dx,dy;
int cfra;
-
+ Key *key;
+
if(curarea->win==0) return;
saction= curarea->spacedata.first;
@@ -1674,6 +2164,8 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
getmouseco_areawin(mval);
+ key = get_action_mesh_key();
+
switch(event) {
case UI_BUT_EVENT:
do_blenderbuttons(val);
@@ -1690,92 +2182,172 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case DKEY:
- if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){
- duplicate_actionchannel_keys();
- remake_action_ipos(act);
+ if (key) {
+ if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH) {
+ duplicate_meshchannel_keys(key);
+ }
+ }
+ else {
+ if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){
+ duplicate_actionchannel_keys();
+ remake_action_ipos(act);
+ }
}
break;
+
case DELKEY:
+
case XKEY:
- if (mval[0]<ACTWIDTH)
- delete_actionchannels ();
- else
- delete_actionchannel_keys ();
+ if (key) {
+ delete_meshchannel_keys(key);
+ }
+ else {
+ if (mval[0]<NAMEWIDTH)
+ delete_actionchannels ();
+ else
+ delete_actionchannel_keys ();
+ }
break;
+
case GKEY:
- if (mval[0]>=ACTWIDTH)
- transform_actionchannel_keys ('g');
+ if (mval[0]>=ACTWIDTH) {
+ if (key) {
+ transform_meshchannel_keys('g', key);
+ }
+ else {
+ transform_actionchannel_keys ('g');
+ }
+ }
break;
+
case SKEY:
- if (mval[0]>=ACTWIDTH)
- transform_actionchannel_keys ('s');
+ if (mval[0]>=ACTWIDTH) {
+ if (key) {
+ transform_meshchannel_keys('s', key);
+ }
+ else {
+ transform_actionchannel_keys ('s');
+ }
+ }
break;
+
case AKEY:
- if (mval[0]<ACTWIDTH){
- deselect_actionchannels (act, 1);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
+ if (key) {
+ if (mval[0]<ACTWIDTH){
+ /* to do ??? */
+ }
+ else{
+ deselect_meshchannel_keys(key, 1);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ }
}
- else{
- deselect_actionchannel_keys (act, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
+ else {
+ if (mval[0]<NAMEWIDTH){
+ deselect_actionchannels (act, 1);
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ }
+ else if (mval[0]>ACTWIDTH){
+ deselect_actionchannel_keys (act, 1);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ }
}
break;
- /*** set the Ipo handles ***/
case VKEY:
- sethandles_actionchannel_keys(HD_VECT);
+ if (key) {
+ sethandles_meshchannel_keys(HD_VECT, key);
+ /* to do */
+ }
+ else {
+ sethandles_actionchannel_keys(HD_VECT);
+ }
break;
case HKEY:
- if(G.qual & LR_SHIFTKEY) sethandles_actionchannel_keys(HD_AUTO);
- else sethandles_actionchannel_keys(HD_ALIGN);
+ if (key) {
+ if(G.qual & LR_SHIFTKEY) {
+ sethandles_meshchannel_keys(HD_AUTO, key);
+ }
+ else {
+ sethandles_meshchannel_keys(HD_ALIGN, key);
+ }
+ }
+ else {
+ if(G.qual & LR_SHIFTKEY) {
+ sethandles_actionchannel_keys(HD_AUTO);
+ }
+ else {
+ sethandles_actionchannel_keys(HD_ALIGN);
+ }
+ }
break;
-
+
/*** set the Ipo type ***/
case TKEY:
- set_ipotype_actionchannels();
+ if (key) {
+ /* to do */
+ }
+ else {
+ set_ipotype_actionchannels();
+ }
break;
case BKEY:
- /* If the border select is initiated in the
- * part of the action window where the channel
- * names reside, then select the channels
- */
- if (mval[0]<ACTWIDTH){
- borderselect_function(mouse_actionchannels);
+ if (key) {
+ if (mval[0]<ACTWIDTH){
+ /* to do?? */
+ }
+ else {
+ borderselect_mesh(key);
+ }
}
+ else {
- /* If the border select is initiated in the
- * vertical scrollbar, then (de)select all keys
- * for the channels in the selection region
- */
- else if (IN_2D_VERT_SCROLL(mval)) {
- borderselect_function(select_all_keys_channels);
- }
+ /* If the border select is initiated in the
+ * part of the action window where the channel
+ * names reside, then select the channels
+ */
+ if (mval[0]<NAMEWIDTH){
+ borderselect_function(mouse_actionchannels);
+ }
+ else if (mval[0]>ACTWIDTH){
+
+ /* If the border select is initiated in the
+ * vertical scrollbar, then (de)select all keys
+ * for the channels in the selection region
+ */
+ if (IN_2D_VERT_SCROLL(mval)) {
+ borderselect_function(select_all_keys_channels);
+ }
- /* If the border select is initiated in the
- * horizontal scrollbar, then (de)select all keys
- * for the keyframes in the selection region
- */
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- borderselect_function(select_all_keys_frames);
- }
+ /* If the border select is initiated in the
+ * horizontal scrollbar, then (de)select all keys
+ * for the keyframes in the selection region
+ */
+ else if (IN_2D_HORIZ_SCROLL(mval)) {
+ borderselect_function(select_all_keys_frames);
+ }
- /* Other wise, select the action keys
- */
- else {
- borderselect_action();
+ /* Other wise, select the action keys
+ */
+ else {
+ borderselect_action();
+ }
+ }
}
break;
+
case RIGHTMOUSE:
/* Right clicking in the channel area selects the
* channel or constraint channel
*/
- if (mval[0]<ACTWIDTH) {
+ if (mval[0]<NAMEWIDTH) {
if(G.qual & LR_SHIFTKEY)
mouse_actionchannels(act, mval, NULL,
SELECT_INVERT);
@@ -1783,40 +2355,50 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
mouse_actionchannels(act, mval, NULL,
SELECT_REPLACE);
}
+ else if (mval[0]>ACTWIDTH) {
+
+ /* Right clicking in the vertical scrollbar selects
+ * all of the keys for that channel at that height
+ */
+ if (IN_2D_VERT_SCROLL(mval)) {
+ if(G.qual & LR_SHIFTKEY)
+ select_all_keys_channels(act, mval, NULL,
+ SELECT_INVERT);
+ else
+ select_all_keys_channels(act, mval, NULL,
+ SELECT_REPLACE);
+ }
- /* Right clicking in the vertical scrollbar selects
- * all of the keys for that channel at that height
- */
- else if (IN_2D_VERT_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_channels(act, mval, NULL,
- SELECT_INVERT);
- else
- select_all_keys_channels(act, mval, NULL,
- SELECT_REPLACE);
- }
-
- /* Right clicking in the horizontal scrollbar selects
- * all of the keys within 0.5 of the nearest integer
- * frame
- */
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_frames(act, mval, NULL,
- SELECT_INVERT);
- else
- select_all_keys_frames(act, mval, NULL,
- SELECT_REPLACE);
- }
-
- /* Clicking in the main area of the action window
- * selects keys
- */
- else {
- if(G.qual & LR_SHIFTKEY)
- mouse_action(SELECT_INVERT);
- else
- mouse_action(SELECT_REPLACE);
+ /* Right clicking in the horizontal scrollbar selects
+ * all of the keys within 0.5 of the nearest integer
+ * frame
+ */
+ else if (IN_2D_HORIZ_SCROLL(mval)) {
+ if(G.qual & LR_SHIFTKEY)
+ select_all_keys_frames(act, mval, NULL,
+ SELECT_INVERT);
+ else
+ select_all_keys_frames(act, mval, NULL,
+ SELECT_REPLACE);
+ }
+
+ /* Clicking in the main area of the action window
+ * selects keys
+ */
+ else {
+ if (key) {
+ if(G.qual & LR_SHIFTKEY)
+ mouse_mesh_action(SELECT_INVERT, key);
+ else
+ mouse_mesh_action(SELECT_REPLACE, key);
+ }
+ else {
+ if(G.qual & LR_SHIFTKEY)
+ mouse_action(SELECT_INVERT);
+ else
+ mouse_action(SELECT_REPLACE);
+ }
+ }
}
break;
@@ -1854,3 +2436,119 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
+Key *get_action_mesh_key(void) {
+ /* gets the key data from the currently selected
+ * mesh/lattice. If a mesh is not selected, or does not have
+ * key data, then we return NULL (currently only
+ * returns key data for RVK type meshes). If there
+ * is an action that is pinned, return null
+ */
+ Object *ob;
+ Key *key;
+
+ ob = OBACT;
+ if (!ob) return NULL;
+
+ if (G.saction->pin) return NULL;
+
+ if (ob->type==OB_MESH ) {
+ key = ((Mesh *)ob->data)->key;
+ }
+ else if (ob->type==OB_LATTICE ) {
+ key = ((Lattice *)ob->data)->key;
+ }
+ else return NULL;
+
+ if (key) {
+ if (key->type == KEY_RELATIVE)
+ return key;
+ }
+
+ return NULL;
+}
+
+int get_nearest_key_num(Key *key, short *mval, float *x) {
+ /* returns the key num that cooresponds to the
+ * y value of the mouse click. Does not check
+ * if this is a valid keynum. Also gives the Ipo
+ * x coordinate.
+ */
+ int num;
+ float ybase, y;
+
+ areamouseco_to_ipoco(G.v2d, mval, x, &y);
+
+ ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
+ num = (int) ((ybase - y) / (CHANNELHEIGHT+CHANNELSKIP));
+
+ return (num + 1);
+}
+
+static void clever_keyblock_names(Key *key, short* mval){
+ int but=0, i, keynum;
+ char str[64];
+ float x, min, max;
+ KeyBlock *kb;
+ /* get the keynum cooresponding to the y value
+ * of the mouse pointer, return if this is
+ * an invalid key number (and we don't deal
+ * with the speed ipo).
+ */
+
+ keynum = get_nearest_key_num(key, mval, &x);
+ if ( (keynum < 1) || (keynum >= key->totkey) )
+ return;
+
+ kb= key->block.first;
+ for (i=0; i<keynum; ++i) kb = kb->next;
+
+ if (kb->name[0] == '\0') {
+ sprintf(str, "Key %d", keynum);
+ }
+ else {
+ strcpy(str, kb->name);
+ }
+
+ if ( (kb->slidermin >= kb->slidermax) ) {
+ kb->slidermin = 0.0;
+ kb->slidermax = 1.0;
+ }
+
+ add_numbut(but++, TEX, "KB: ", 0, 24, str,
+ "Does this really need a tool tip?");
+ add_numbut(but++, NUM|FLO, "Slider min:",
+ -10000, kb->slidermax, &kb->slidermin, 0);
+ add_numbut(but++, NUM|FLO, "Slider max:",
+ kb->slidermin, 10000, &kb->slidermax, 0);
+
+ if (do_clever_numbuts(str, but, REDRAW)) {
+ strcpy(kb->name, str);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWIPO, 0);
+ }
+
+
+}
+
+void stupid_damn_numbuts_action(void){
+ /* I think this function might have been
+ * deemed clever if it could have been
+ * called from the event processing
+ * routine in this file -- rather than having
+ * to go from the NKEY event from blenderqread
+ * in toets.c (which returns 0 so nobody else
+ * can use the NKEY) then into the clever_numbuts
+ * routine in toolbox.c, the finally to this
+ * function. Grumble, grumble, grumble ...
+ */
+
+ Key *key;
+ short mval[2];
+
+ if ( (key = get_action_mesh_key()) ) {
+ getmouseco_areawin (mval);
+ if (mval[0]<NAMEWIDTH) {
+ clever_keyblock_names(key, mval);
+ }
+ }
+}