Transform fixes
[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 <stdlib.h>
34 #include <string.h>
35 #include <math.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #ifndef WIN32
42 #include <unistd.h>
43 #else
44 #include <io.h>
45 #endif
46
47 #include "MEM_guardedalloc.h"
48
49 #include "blendef.h"
50
51 #include "mydevice.h"
52
53 #include "BLI_arithb.h"
54
55 #include "transform_numinput.h"
56 #include "transform.h"
57
58 /* ************************** Functions *************************** */
59
60 /* ************************** NUMINPUT **************************** */
61
62 void outputNumInput(NumInput *n, char *str)
63 {
64         char cur;
65         short i, j;
66
67         for (j=0; j<=n->idx_max; j++) {
68                 /* if AFFECTALL and no number typed and cursor not on number, use first number */
69                 if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
70                         i = 0;
71                 else
72                         i = j;
73
74                 if (n->idx != i)
75                         cur = ' ';
76                 else
77                         cur = '|';
78
79                 switch (n->ctrl[i]) {
80                 case 0:
81                         sprintf(&str[j*20], "NONE%c", cur);
82                         break;
83                 case 1:
84                 case -1:
85                         sprintf(&str[j*20], "%.0f%c", n->val[i], cur);
86                         break;
87                 case 10:
88                 case -10:
89                         sprintf(&str[j*20], "%.f.%c", n->val[i], cur);
90                         break;
91                 case 100:
92                 case -100:
93                         sprintf(&str[j*20], "%.1f%c", n->val[i], cur);
94                         break;
95                 case 1000:
96                 case -1000:
97                         sprintf(&str[j*20], "%.2f%c", n->val[i], cur);
98                 case 10000:
99                 case -10000:
100                         sprintf(&str[j*20], "%.3f%c", n->val[i], cur);
101                         break;
102                 default:
103                         sprintf(&str[j*20], "%.4f%c", n->val[i], cur);
104                 }
105         }
106 }
107
108 short hasNumInput(NumInput *n)
109 {
110         short i;
111
112         for (i=0; i<=n->idx_max; i++) {
113                 if (n->ctrl[i])
114                         return 1;
115         }
116
117         return 0;
118 }
119
120 void applyNumInput(NumInput *n, float *vec)
121 {
122         short i, j;
123
124         if (hasNumInput(n)) {
125                 for (j=0; j<=n->idx_max; j++) {
126                         /* if AFFECTALL and no number typed and cursor not on number, use first number */
127                         if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0)
128                                 i = 0;
129                         else
130                                 i = j;
131
132                         if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) {
133                                 vec[j] = 1.0f;
134                         }
135                         else if (n->val[i] == 0.0f && n->flag & NUM_NO_ZERO) {
136                                 vec[j] = 0.0001f;
137                         }
138                         else {
139                                 vec[j] = n->val[i];
140                         }
141                 }
142         }
143 }
144
145 char handleNumInput(NumInput *n, unsigned short event)
146 {
147         float Val = 0;
148         short idx = n->idx, idx_max = n->idx_max;
149
150         switch (event) {
151         case BACKSPACEKEY:
152                 if (n->ctrl[idx] == 0) {
153                         n->val[0]               = 
154                                 n->val[1]       = 
155                                 n->val[2]       = 0.0f;
156                         n->ctrl[0]              = 
157                                 n->ctrl[1]      = 
158                                 n->ctrl[2]      = 0;
159                 }
160                 else {
161                         n->val[idx] = 0.0f;
162                         n->ctrl[idx] = 0;
163                 }
164                 break;
165         case PERIODKEY:
166         case PADPERIOD:
167                 if (n->flag & NUM_NO_FRACTION)
168                         break;
169
170                 switch (n->ctrl[idx])
171                 {
172                 case 0:
173                 case 1:
174                         n->ctrl[idx] = 10;
175                         break;
176                 case -1:
177                         n->ctrl[idx] = -10;
178                 }
179                 break;
180         case MINUSKEY:
181                 if (n->flag & NUM_NO_NEGATIVE)
182                         break;
183
184                 if (n->ctrl[idx]) {
185                         n->ctrl[idx] *= -1;
186                         n->val[idx] *= -1;
187                 }
188                 else
189                         n->ctrl[idx] = -1;
190                 break;
191         case TABKEY:
192                 idx++;
193                 if (idx > idx_max)
194                         idx = 0;
195                 n->idx = idx;
196                 break;
197         case PAD9:
198         case NINEKEY:
199                 Val += 1.0f;
200         case PAD8:
201         case EIGHTKEY:
202                 Val += 1.0f;
203         case PAD7:
204         case SEVENKEY:
205                 Val += 1.0f;
206         case PAD6:
207         case SIXKEY:
208                 Val += 1.0f;
209         case PAD5:
210         case FIVEKEY:
211                 Val += 1.0f;
212         case PAD4:
213         case FOURKEY:
214                 Val += 1.0f;
215         case PAD3:
216         case THREEKEY:
217                 Val += 1.0f;
218         case PAD2:
219         case TWOKEY:
220                 Val += 1.0f;
221         case PAD1:
222         case ONEKEY:
223                 Val += 1.0f;
224         case PAD0:
225         case ZEROKEY:
226                 if (!n->ctrl[idx])
227                         n->ctrl[idx] = 1;
228
229                 if (n->ctrl[idx] == 1) {
230                         n->val[idx] *= 10;
231                         n->val[idx] += Val;
232                 }
233                 else if (n->ctrl[idx] == -1) {
234                         n->val[idx] *= 10;
235                         n->val[idx] -= Val;
236                 }
237                 else {
238                         n->val[idx] += Val / (float)n->ctrl[idx];
239                         n->ctrl[idx] *= 10;
240                 }
241                 break;
242         default:
243                 return 0;
244         }
245         /* REDRAW SINCE NUMBERS HAVE CHANGED */
246         return 1;
247 }