6c2546970118a2a9061a49162ab01b7ca77ac89b
[blender.git] / source / blender / src / transform_numinput.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>              /* for sprintf          */
34
35 #include "BKE_global.h" /* for G                        */
36
37 #include "mydevice.h"   /* for KEY defines      */
38
39 #include "transform.h"
40
41 /* ************************** Functions *************************** */
42
43 /* ************************** NUMINPUT **************************** */
44
45 void outputNumInput(NumInput *n, char *str)
46 {
47         char cur;
48         short i, j;
49
50         for (j=0; j<=n->idx_max; j++) {
51                 /* if AFFECTALL and no number typed and cursor not on number, use first number */
52                 if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
53                         i = 0;
54                 else
55                         i = j;
56
57                 if (n->idx != i)
58                         cur = ' ';
59                 else
60                         cur = '|';
61
62                 switch (n->ctrl[i]) {
63                 case 0:
64                         sprintf(&str[j*20], "NONE%c", cur);
65                         break;
66                 case 1:
67                 case -1:
68                         sprintf(&str[j*20], "%.0f%c", n->val[i], cur);
69                         break;
70                 case 10:
71                 case -10:
72                         sprintf(&str[j*20], "%.f.%c", n->val[i], cur);
73                         break;
74                 case 100:
75                 case -100:
76                         sprintf(&str[j*20], "%.1f%c", n->val[i], cur);
77                         break;
78                 case 1000:
79                 case -1000:
80                         sprintf(&str[j*20], "%.2f%c", n->val[i], cur);
81                 case 10000:
82                 case -10000:
83                         sprintf(&str[j*20], "%.3f%c", n->val[i], cur);
84                         break;
85                 default:
86                         sprintf(&str[j*20], "%.4f%c", n->val[i], cur);
87                 }
88         }
89 }
90
91 short hasNumInput(NumInput *n)
92 {
93         short i;
94
95         for (i=0; i<=n->idx_max; i++) {
96                 if (n->ctrl[i])
97                         return 1;
98         }
99
100         return 0;
101 }
102
103 void applyNumInput(NumInput *n, float *vec)
104 {
105         short i, j;
106
107         if (hasNumInput(n)) {
108                 for (j=0; j<=n->idx_max; j++) {
109                         /* if AFFECTALL and no number typed and cursor not on number, use first number */
110                         if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
111                                 i = 0;
112                         else
113                                 i = j;
114
115                         if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) {
116                                 vec[j] = 1.0f;
117                         }
118                         else if (n->val[i] == 0.0f && n->flag & NUM_NO_ZERO) {
119                                 vec[j] = 0.0001f;
120                         }
121                         else {
122                                 vec[j] = n->val[i];
123                         }
124                 }
125         }
126 }
127
128 char handleNumInput(NumInput *n, unsigned short event)
129 {
130         float Val = 0;
131         short idx = n->idx, idx_max = n->idx_max;
132
133         switch (event) {
134         case BACKSPACEKEY:
135                 if (n->ctrl[idx] == 0) {
136                         n->val[0]               = 
137                                 n->val[1]       = 
138                                 n->val[2]       = 0.0f;
139                         n->ctrl[0]              = 
140                                 n->ctrl[1]      = 
141                                 n->ctrl[2]      = 0;
142                 }
143                 else {
144                         n->val[idx] = 0.0f;
145                         n->ctrl[idx] = 0;
146                 }
147                 break;
148         case PERIODKEY:
149         case PADPERIOD:
150                 if (n->flag & NUM_NO_FRACTION)
151                         break;
152
153                 switch (n->ctrl[idx])
154                 {
155                 case 0:
156                 case 1:
157                         n->ctrl[idx] = 10;
158                         break;
159                 case -1:
160                         n->ctrl[idx] = -10;
161                 }
162                 break;
163         case PADMINUS:
164                 if(G.qual & LR_ALTKEY)
165                         break;
166         case MINUSKEY:
167                 if (n->flag & NUM_NO_NEGATIVE)
168                         break;
169
170                 if (n->ctrl[idx]) {
171                         n->ctrl[idx] *= -1;
172                         n->val[idx] *= -1;
173                 }
174                 else
175                         n->ctrl[idx] = -1;
176                 break;
177         case TABKEY:
178                 idx++;
179                 if (idx > idx_max)
180                         idx = 0;
181                 n->idx = idx;
182                 break;
183         case PAD9:
184         case NINEKEY:
185                 Val += 1.0f;
186         case PAD8:
187         case EIGHTKEY:
188                 Val += 1.0f;
189         case PAD7:
190         case SEVENKEY:
191                 Val += 1.0f;
192         case PAD6:
193         case SIXKEY:
194                 Val += 1.0f;
195         case PAD5:
196         case FIVEKEY:
197                 Val += 1.0f;
198         case PAD4:
199         case FOURKEY:
200                 Val += 1.0f;
201         case PAD3:
202         case THREEKEY:
203                 Val += 1.0f;
204         case PAD2:
205         case TWOKEY:
206                 Val += 1.0f;
207         case PAD1:
208         case ONEKEY:
209                 Val += 1.0f;
210         case PAD0:
211         case ZEROKEY:
212                 if (!n->ctrl[idx])
213                         n->ctrl[idx] = 1;
214
215                 if (n->ctrl[idx] == 1) {
216                         n->val[idx] *= 10;
217                         n->val[idx] += Val;
218                 }
219                 else if (n->ctrl[idx] == -1) {
220                         n->val[idx] *= 10;
221                         n->val[idx] -= Val;
222                 }
223                 else {
224                         n->val[idx] += Val / (float)n->ctrl[idx];
225                         n->ctrl[idx] *= 10;
226                 }
227                 break;
228         default:
229                 return 0;
230         }
231         /* REDRAW SINCE NUMBERS HAVE CHANGED */
232         return 1;
233 }