Blender V2.61 - r43446

numinput.c

Go to the documentation of this file.
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) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): Jonathan Smith
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <math.h>           /* fabs */
00034 #include <stdio.h>          /* for size_t */
00035 
00036 #include "BLI_utildefines.h"
00037 #include "BLI_string.h"
00038 
00039 #include "WM_types.h"
00040 
00041 #include "ED_numinput.h"
00042 
00043 /* ************************** Functions *************************** */
00044 
00045 /* ************************** NUMINPUT **************************** */
00046 
00047 void initNumInput(NumInput *n)
00048 {
00049     n->flag     =
00050     n->idx      =
00051     n->idx_max  =
00052     n->inv[0]   =
00053     n->inv[1]   =
00054     n->inv[2]   =
00055     n->ctrl[0]  = 
00056     n->ctrl[1]  = 
00057     n->ctrl[2]  = 0;
00058 
00059     n->val[0]       = 
00060     n->val[1]   = 
00061     n->val[2]   = 0.0f;
00062 }
00063 
00064 void outputNumInput(NumInput *n, char *str)
00065 {
00066     char cur;
00067     char inv[] = "1/";
00068     short i, j;
00069 
00070     for (j=0; j<=n->idx_max; j++) {
00071         /* if AFFECTALL and no number typed and cursor not on number, use first number */
00072         if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
00073             i = 0;
00074         else
00075             i = j;
00076 
00077         if (n->idx != i)
00078             cur = ' ';
00079         else
00080             cur = '|';
00081 
00082         if (n->inv[i])
00083             inv[0] = '1';
00084         else
00085             inv[0] = 0;
00086 
00087         if( n->val[i] > 1e10f || n->val[i] < -1e10f )
00088             BLI_snprintf(&str[j*20], 20, "%s%.4e%c", inv, n->val[i], cur);
00089         else
00090             switch (n->ctrl[i]) {
00091             case 0:
00092                 BLI_snprintf(&str[j*20], 20, "%sNONE%c", inv, cur);
00093                 break;
00094             case 1:
00095             case -1:
00096                 BLI_snprintf(&str[j*20], 20, "%s%.0f%c", inv, n->val[i], cur);
00097                 break;
00098             case 10:
00099             case -10:
00100                 BLI_snprintf(&str[j*20], 20, "%s%.f.%c", inv, n->val[i], cur);
00101                 break;
00102             case 100:
00103             case -100:
00104                 BLI_snprintf(&str[j*20], 20, "%s%.1f%c", inv, n->val[i], cur);
00105                 break;
00106             case 1000:
00107             case -1000:
00108                 BLI_snprintf(&str[j*20], 20, "%s%.2f%c", inv, n->val[i], cur);
00109                 break;
00110             case 10000:
00111             case -10000:
00112                 BLI_snprintf(&str[j*20], 20, "%s%.3f%c", inv, n->val[i], cur);
00113                 break;
00114             default:
00115                 BLI_snprintf(&str[j*20], 20, "%s%.4e%c", inv, n->val[i], cur);
00116             }
00117     }
00118 }
00119 
00120 short hasNumInput(NumInput *n)
00121 {
00122     short i;
00123 
00124     for (i=0; i<=n->idx_max; i++) {
00125         if (n->ctrl[i])
00126             return 1;
00127     }
00128 
00129     return 0;
00130 }
00131 
00132 void applyNumInput(NumInput *n, float *vec)
00133 {
00134     short i, j;
00135 
00136     if (hasNumInput(n)) {
00137         for (j=0; j<=n->idx_max; j++) {
00138             /* if AFFECTALL and no number typed and cursor not on number, use first number */
00139             if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
00140                 i = 0;
00141             else
00142                 i = j;
00143 
00144             if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) {
00145                 vec[j] = 1.0f;
00146             }
00147             else if (n->val[i] == 0.0f && n->flag & NUM_NO_ZERO) {
00148                 vec[j] = 0.0001f;
00149             }
00150             else {
00151                 if (n->inv[i])
00152                 {
00153                     vec[j] = 1.0f / n->val[i];
00154                 }
00155                 else
00156                 {
00157                     vec[j] = n->val[i];
00158                 }
00159             }
00160         }
00161     }
00162 }
00163 
00164 char handleNumInput(NumInput *n, wmEvent *event)
00165 {
00166     float Val = 0;
00167     short idx = n->idx, idx_max = n->idx_max;
00168 
00169     if (event->type == EVT_MODAL_MAP) {
00170         switch (event->val) {
00171         case NUM_MODAL_INCREMENT_UP:
00172             if (!n->ctrl[idx])
00173                 n->ctrl[idx] = 1;
00174 
00175             n->val[idx] += n->increment;
00176             break;
00177         case NUM_MODAL_INCREMENT_DOWN:
00178             if (!n->ctrl[idx])
00179                 n->ctrl[idx] = 1;
00180 
00181             n->val[idx] -= n->increment;
00182             break;
00183         default:
00184             return 0;
00185         }
00186     } else {
00187         switch (event->type) {
00188         case BACKSPACEKEY:
00189             if (n->ctrl[idx] == 0) {
00190                 n->val[0]       =
00191                     n->val[1]   =
00192                     n->val[2]   = 0.0f;
00193                 n->ctrl[0]      =
00194                     n->ctrl[1]  =
00195                     n->ctrl[2]  = 0;
00196                 n->inv[0]       =
00197                     n->inv[1]   =
00198                     n->inv[2]   = 0;
00199             }
00200             else {
00201                 n->val[idx] = 0.0f;
00202                 n->ctrl[idx] = 0;
00203                 n->inv[idx] = 0;
00204             }
00205             break;
00206         case PERIODKEY:
00207         case PADPERIOD:
00208             if (n->flag & NUM_NO_FRACTION)
00209                 return 0;
00210 
00211             switch (n->ctrl[idx])
00212             {
00213             case 0:
00214             case 1:
00215                 n->ctrl[idx] = 10;
00216                 break;
00217             case -1:
00218                 n->ctrl[idx] = -10;
00219             }
00220             break;
00221         case PADMINUS:
00222             if(event->alt)
00223                 break;
00224         case MINUSKEY:
00225             if (n->flag & NUM_NO_NEGATIVE)
00226                 break;
00227 
00228             if (n->ctrl[idx]) {
00229                 n->ctrl[idx] *= -1;
00230                 n->val[idx] *= -1;
00231             }
00232             else
00233                 n->ctrl[idx] = -1;
00234             break;
00235         case PADSLASHKEY:
00236         case SLASHKEY:
00237             if (n->flag & NUM_NO_FRACTION)
00238                 return 0;
00239 
00240             n->inv[idx] = !n->inv[idx];
00241             break;
00242         case TABKEY:
00243             if (idx_max == 0)
00244                 return 0;
00245 
00246             idx++;
00247             if (idx > idx_max)
00248                 idx = 0;
00249             n->idx = idx;
00250             break;
00251         case PAD9:
00252         case NINEKEY:
00253             Val += 1.0f;
00254         case PAD8:
00255         case EIGHTKEY:
00256             Val += 1.0f;
00257         case PAD7:
00258         case SEVENKEY:
00259             Val += 1.0f;
00260         case PAD6:
00261         case SIXKEY:
00262             Val += 1.0f;
00263         case PAD5:
00264         case FIVEKEY:
00265             Val += 1.0f;
00266         case PAD4:
00267         case FOURKEY:
00268             Val += 1.0f;
00269         case PAD3:
00270         case THREEKEY:
00271             Val += 1.0f;
00272         case PAD2:
00273         case TWOKEY:
00274             Val += 1.0f;
00275         case PAD1:
00276         case ONEKEY:
00277             Val += 1.0f;
00278         case PAD0:
00279         case ZEROKEY:
00280             if (!n->ctrl[idx])
00281                 n->ctrl[idx] = 1;
00282 
00283             if (fabsf(n->val[idx]) > 9999999.0f);
00284             else if (n->ctrl[idx] == 1) {
00285                 n->val[idx] *= 10;
00286                 n->val[idx] += Val;
00287             }
00288             else if (n->ctrl[idx] == -1) {
00289                 n->val[idx] *= 10;
00290                 n->val[idx] -= Val;
00291             }
00292             else {
00293                 /* float resolution breaks when over six digits after comma */
00294                 if( ABS(n->ctrl[idx]) < 10000000) {
00295                     n->val[idx] += Val / (float)n->ctrl[idx];
00296                     n->ctrl[idx] *= 10;
00297                 }
00298             }
00299             break;
00300         default:
00301             return 0;
00302         }
00303     }
00304     
00305     // printf("%f\n", n->val[idx]);
00306 
00307     /* REDRAW SINCE NUMBERS HAVE CHANGED */
00308     return 1;
00309 }