New transform:
[blender.git] / source / blender / src / toolbox.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 #define PY_TOOLBOX 1
34
35 #include <math.h>
36 #include <ctype.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdarg.h>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #ifndef WIN32
46 #include <unistd.h>
47 #else
48 #include <io.h>
49 #include "BLI_winstuff.h"
50 #endif   
51
52 #include <fcntl.h>
53 #include "MEM_guardedalloc.h"
54
55 #include "BMF_Api.h"
56 #include "BIF_language.h"
57 #include "BIF_resources.h"
58
59 #include "DNA_image_types.h"
60 #include "DNA_object_types.h"
61 #include "DNA_mesh_types.h"
62 #include "DNA_lamp_types.h"
63 #include "DNA_screen_types.h"
64 #include "DNA_scene_types.h"
65 #include "DNA_userdef_types.h"
66 #include "DNA_view3d_types.h"
67
68 #include "BLI_blenlib.h"
69 #include "BLI_arithb.h"
70
71 #include "BKE_plugin_types.h"
72 #include "BKE_utildefines.h"
73 #include "BKE_mesh.h"
74 #include "BKE_displist.h"
75 #include "BKE_global.h"
76 #include "BKE_main.h"
77
78 #include "BIF_editnla.h"
79 #include "BIF_editarmature.h"
80 #include "BIF_editdeform.h"
81 #include "BIF_editfont.h"
82 #include "BIF_editmesh.h"
83 #include "BIF_editseq.h"
84 #include "BIF_editlattice.h"
85 #include "BIF_editsima.h"
86 #include "BIF_editoops.h"
87 #include "BIF_gl.h"
88 #include "BIF_graphics.h"
89 #include "BIF_imasel.h"
90 #include "BIF_mainqueue.h"
91 #include "BIF_interface.h"
92 #include "BIF_toolbox.h"
93 #include "BIF_mywindow.h"
94 #include "BIF_screen.h"
95 #include "BIF_space.h"
96 #include "BIF_tbcallback.h"
97 #include "BIF_transform.h"
98
99 #include "BDR_editobject.h"
100 #include "BDR_editcurve.h"
101 #include "BDR_editmball.h"
102
103 #include "BSE_editipo.h"
104 #include "BSE_buttons.h"
105 #include "BSE_filesel.h"
106 #include "BSE_edit.h"
107 #include "BSE_headerbuttons.h"
108
109 #include "IMB_imbuf.h"
110
111 #include "mydevice.h"
112 #include "blendef.h"
113 #include "render.h"             // R.flag
114
115 static int tbx1, tbx2, tby1, tby2, tbfontyofs, tbmain=0;
116 static int tbmemx=TBOXX/2, tbmemy=(TBOXEL-0.5)*TBOXH, tboldwin, addmode= 0;
117 static int oldcursor;
118
119         /* variables per item */
120 static char *tbstr, *tbstr1, *keystr;   
121 static void (*tbfunc)(int);
122 static int tbval;
123
124 /* *********** PC PATCH ************* */
125
126 void ColorFunc(int i)
127 {
128         if(i==TBOXBLACK) glColor3ub(0, 0, 0);
129         else if(i==TBOXWHITE) glColor3ub(240, 240, 240);
130         else if(i==TBOXGREY) glColor3ub(160, 160, 160);
131         else glColor3ub(0, 0, 0);
132 }
133
134 /* ********************* PYTHON TOOLBOX CALLBACK ************************* */
135
136 #ifdef PY_TOOLBOX 
137 /* see bpython/intern/py_toolbox.c */
138
139 /* moved to BIF_toolbox.h */
140 /* typedef char** (*tbox_callback)(int, int); */
141
142 TBcallback *callback_dummy(int level, int entry)
143 {
144         return NULL;
145 }       
146
147 /* callback func ptr for py_toolbox */
148 Tbox_callbackfunc g_toolbox_menucallback = &callback_dummy;
149
150 void tboxSetCallback(Tbox_callbackfunc f)
151 {
152         g_toolbox_menucallback = f;
153 }
154
155 #endif
156
157 /* ********************* TOOLBOX ITEMS ************************* */
158
159 void tbox_setinfo(int x, int y)
160 {
161         /* dependant of tbmain vars are set */
162         tbstr= 0;
163         tbstr1= 0;
164         tbfunc= 0;
165         tbval= 0;
166         keystr = NULL;
167
168 /* main menu entries: defined in BIF_toolbox.h */
169         
170         if(x==0) {
171                 switch(y) {
172                         case TBOX_MAIN_FILE:            tbstr= "FILE";          break;
173                         case TBOX_MAIN_EDIT:            tbstr= "EDIT";          break;
174                         case TBOX_MAIN_ADD:             
175                                 if (addmode==OB_MESH) tbstr= "  MESH";
176                                 else if(addmode==OB_CURVE) tbstr= "  CURVE";
177                                 else if(addmode==OB_SURF) tbstr= "  SURF";
178                                 else if(addmode==OB_MBALL) tbstr= "  META";
179                                 else tbstr= "ADD";
180                                 break;
181                         case TBOX_MAIN_OBJECT1:         tbstr= "OBJECT";        break;
182                         case TBOX_MAIN_OBJECT2:         tbstr= "OBJECT";        break;
183                         case TBOX_MAIN_MESH:            tbstr= "MESH";          break;
184                         case TBOX_MAIN_CURVE:           tbstr= "CURVE";         break;
185                         case TBOX_MAIN_KEY:                     tbstr= "KEY";           break;
186                         case TBOX_MAIN_RENDER:          tbstr= "RENDER";        break;
187                         case TBOX_MAIN_VIEW:            tbstr= "VIEW";          break;
188                         case TBOX_MAIN_SEQ:             tbstr= "SEQUENCE";      break;
189 #ifdef PY_TOOLBOX
190                         case TBOX_MAIN_PYTOOL:          
191                         {
192                                 if (g_toolbox_menucallback(0, 0)) // valid callback?
193                                         tbstr= "PYTOOL";        
194                                 break;
195                         }
196 #endif
197                 }
198         }
199         
200 /* TOPICS */
201         else {
202                 
203                 
204 /* FILE TOPICS */
205                 if(tbmain==TBOX_MAIN_FILE) {
206                         switch(y) {
207                                 case 0: tbstr= "New";                           tbstr1= "c|x";          keystr= "Ctrl X";       break;
208                                 case 1: tbstr= "Open";                          tbstr1= "F1";           keystr= "F1";           break;
209                                 case 2: tbstr= "Reopen Last";           tbstr1= "c|o";          keystr= "Ctrl O";       break;
210                                 case 3: tbstr= "Append";                        tbstr1= "shift+F1";     keystr= "Shift F1";     break;
211                                 case 4: tbstr= "";                                      tbstr1= "";                     keystr= "";                     break;
212                                 case 5: tbstr= "Save As";                       tbstr1= "F2";           keystr= "F2";           break;
213                                 case 6: tbstr= "Save";                          tbstr1= "c|w";          keystr= "Ctrl W";       break;
214                                 case 7: tbstr= "";                                      tbstr1= "";                     keystr= "";                     break;
215                                 case 8: tbstr= "Save Image";            tbstr1= "F3";           keystr= "F3";           break;
216                                 case 9: tbstr= "Save VRML";                     tbstr1= "c|F2";         keystr= "Ctrl F2";      break;
217                                 case 10: tbstr= "Save DXF";                     tbstr1= "shift+F2";     keystr= "Shift F2";     break;
218                                 case 11: tbstr= "Save VideoScape";      tbstr1= "a|w";          keystr= "Alt W";        break;
219                                 case 12: tbstr= "Save UserPrefs";       tbstr1= "c|u";          keystr= "Ctrl U";       break;
220                                 case 13: tbstr= "Quit";                         tbstr1= "q";            keystr= "Q";            break;
221                         }
222                 }
223
224 /* EDIT TOPICS */
225                 if(tbmain==TBOX_MAIN_EDIT) {
226                         switch(y) {
227                                 case 0: tbstr= "(De)Select All";        tbstr1= "a";    keystr= "A";            break;
228                                 case 1: tbstr= "Border Select";         tbstr1= "b";    keystr= "B";            break;
229                                 case 2: tbstr= "Select Linked";         tbstr1= "l";    keystr= "L";            break;
230                                 case 3: tbstr= "Hide Selected";         tbstr1= "h";    keystr= "H";            break;
231                                 case 4: tbstr= "Duplicate";                     tbstr1= "D";    keystr= "Shift D";      break;
232                                 case 5: tbstr= "Delete";                        tbstr1= "x";    keystr= "X";            break;
233                                 case 6: tbstr= "Edit Mode";                     tbstr1= "Tab";  keystr= "Tab";          break;
234                                 case 7: tbstr= "Grabber";                       tbstr1= "g";    keystr= "G";            break;
235                                 case 8: tbstr= "Rotate";                        tbstr1= "r";    keystr= "R";            break;
236                                 case 9: tbstr= "Scale";                         tbstr1= "s";    keystr= "S";            break;
237                                 case 10: tbstr= "Shrink/Fatten";        tbstr1= "a|s";  keystr= "Alt S";        break;
238                                 case 11: tbstr= "Shear";                        tbstr1= "c|s";  keystr= "Ctrl S";       break;
239                                 case 12: tbstr= "Warp/Bend";            tbstr1= "W";    keystr= "Shift W";      break;
240                                 case 13: tbstr= "Snap Menu";            tbstr1= "S";    keystr= "Shift S";      break;
241                         }
242                 }
243
244 /* ADD TOPICS */
245                 if(tbmain==TBOX_MAIN_ADD) {
246
247                         if(addmode==0) {
248                                 switch(y) {
249                                         case 0: tbstr= "Mesh";          tbstr1= ">>";   keystr= ">>";   tbval=OB_MESH;                                                                          break;
250                                         case 1: tbstr= "Curve";         tbstr1= ">>";   keystr= ">>";   tbval=OB_CURVE;                                                                         break;
251                                         case 2: tbstr= "Surface";       tbstr1= ">>";   keystr= ">>";   tbval=OB_SURF;                                                                          break;
252                                         case 3: tbstr= "Meta";          tbstr1= ">>";   keystr= ">>";   tbval=OB_MBALL;                                                                         break;
253                                         case 4: tbstr= "Text";          tbstr1= "";             keystr= "";             tbval=OB_FONT;  tbfunc= add_primitiveFont;                      break;
254                                         case 5: tbstr= "Empty";         tbstr1= "A";    keystr= "";             tbval=OB_EMPTY;                                                                         break;
255                                         case 6: tbstr= "";                      tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
256                                         case 7: tbstr= "Camera";        tbstr1= "A";    keystr= "";             tbval=OB_CAMERA;                                                                        break;
257                                         case 8: tbstr= "Lamp";          tbstr1= "A";    keystr= "";             tbval=OB_LAMP;                                                                          break;
258                                         case 9: tbstr= "Armature";      tbstr1= "";             keystr= "";             tbval=OB_ARMATURE;      tbfunc=add_primitiveArmature;   break;
259                                         case 10: tbstr= "";                     tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
260                                         case 11: tbstr= "Lattice";      tbstr1= "A";    keystr= "";             tbval=OB_LATTICE;                                                                       break;
261                                         case 12: tbstr= "";                     tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
262                                         case 13: tbstr= "";                     tbstr1= "";             keystr= "";             tbval=0;                                                                                        break;
263                                 }
264                                 if(tbstr1 && tbstr1[0]=='A') tbfunc= (void (*)(int))add_object_draw;
265                         }
266                         else if(addmode==OB_MESH) {             
267                                 switch(y) {
268                                         case 0: tbstr= ">Plane";        tbstr1= "A";    keystr= "";             tbval=0;        break;
269                                         case 1: tbstr= ">Cube";         tbstr1= "A";    keystr= "";             tbval=1;        break;
270                                         case 2: tbstr= ">Circle";       tbstr1= "A";    keystr= "";             tbval=4;        break;
271                                         case 3: tbstr= ">UVsphere";     tbstr1= "A";    keystr= "";             tbval=11;       break;
272                                         case 4: tbstr= ">Icosphere";tbstr1= "A";        keystr= "";             tbval=12;       break;
273                                         case 5: tbstr= ">Cylinder";     tbstr1= "A";    keystr= "";             tbval=5;        break;
274                                         case 6: tbstr= ">Tube";         tbstr1= "A";    keystr= "";             tbval=6;        break;
275                                         case 7: tbstr= ">Cone";         tbstr1= "A";    keystr= "";             tbval=7;        break;
276                                         case 8: tbstr= ">";                     tbstr1= "";             keystr= "";                                     break;
277                                         case 9: tbstr= ">Grid";         tbstr1= "A";    keystr= "";             tbval=10;       break;
278                                         case 13: tbstr= ">Monkey";      tbstr1= "A";    keystr= "";             tbval=13;       break;
279                                 }
280                                 if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveMesh;
281                         }
282                         else if(addmode==OB_SURF) {
283                                 switch(y) {
284                                         case 0: tbstr= ">Curve";        tbstr1= "A";    keystr= "";             tbval=0; break;
285                                         case 1: tbstr= ">Circle";       tbstr1= "A";    keystr= "";             tbval=1; break;
286                                         case 2: tbstr= ">Surface";      tbstr1= "A";    keystr= "";             tbval=2; break;
287                                         case 3: tbstr= ">Tube";         tbstr1= "A";    keystr= "";             tbval=3; break;
288                                         case 4: tbstr= ">Sphere";       tbstr1= "A";    keystr= "";             tbval=4; break;
289                                         case 5: tbstr= ">Donut";        tbstr1= "A";    keystr= "";             tbval=5; break;
290                                 }
291                                 if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveNurb;
292                         }
293 /*                      else if (addmode==OB_ARMATURE){
294                                 switch(y) {
295                                         case 0: tbstr= ">Bone";         tbstr1= "A";    keystr= "";             tbval=0; break;
296                                         case 1: tbstr= ">Hand";         tbstr1= "A";    keystr= "";             tbval=1; break;
297                                         case 2: tbstr= ">Biped";        tbstr1= "A";    keystr= "";             tbval=2; break;
298                                 }
299                                 if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveArmature;     
300                         }
301 */
302                         else if(addmode==OB_CURVE) {
303                                 switch(y) {
304                                         case 0: tbstr= ">Bezier Curve";         tbstr1= "A";    keystr= "";     tbval=10;       break;
305                                         case 1: tbstr= ">Bezier Circle";        tbstr1= "A";    keystr= "";     tbval=11;       break;
306                                         case 2: tbstr= ">";                                     tbstr1= "";             keystr= "";                             break;
307                                         case 3: tbstr= ">Nurbs Curve";          tbstr1= "A";    keystr= "";     tbval=40;       break;
308                                         case 4: tbstr= ">Nurbs Circle";         tbstr1= "A";    keystr= "";     tbval=41;       break;
309                                         case 5: tbstr= ">";                                     tbstr1= "";             keystr= "";                             break;
310                                         case 6: tbstr= ">Path";                         tbstr1= "A";    keystr= "";     tbval=46;       break;
311                                 }
312                                 if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveCurve;
313                         }
314                         else if(addmode==OB_MBALL) {
315                                 switch(y) {
316                                         case 0: tbstr= "Ball";                  tbstr1= "A";    tbval=1; break;
317                                         case 1: tbstr= "Tube";                  tbstr1= "A";    tbval=2; break;
318                                         case 2: tbstr= "Plane";                 tbstr1= "A";    tbval=3; break;
319                                         case 3: tbstr= "Elipsoid";              tbstr1= "A";    tbval=4; break;
320                                         case 4: tbstr= "Cube";                  tbstr1= "A";    tbval=5; break;
321                                         case 5: tbstr= "";                      tbstr1= "";             break;
322                                         case 6: tbstr= "";                      tbstr1= "";             break;
323                                         case 7: tbstr= "";                      tbstr1= "";             break;
324                                         case 8: tbstr= "";                      tbstr1= "";             break;
325                                         case 9: tbstr= "";                      tbstr1= "";             break;
326                                         case 10: tbstr= "";                     tbstr1= "";             break;
327                                         case 11: tbstr= "Duplicate";tbstr1= "D";        break;
328                                 }
329                                 if(tbstr1 && tbstr1[0]=='A') tbfunc= add_primitiveMball;
330                         }
331                 }
332                 
333 /* OB TOPICS 1 */
334                 else if(tbmain==TBOX_MAIN_OBJECT1) {
335                         switch(y) {
336                                 case 0: tbstr= "Clear Size";            tbstr1= "a|s";  keystr= "Alt S";        break;
337                                 case 1: tbstr= "Clear Rotation";        tbstr1= "a|r";  keystr= "Alt R";        break;
338                                 case 2: tbstr= "Clear Location";        tbstr1= "a|g";  keystr= "Alt G";        break;
339                                 case 3: tbstr= "Clear Origin";          tbstr1= "a|o";  keystr= "Alt O";        break;
340                                 case 4: tbstr= "Make Parent";           tbstr1= "c|p";  keystr= "Ctrl P";       break;
341                                 case 5: tbstr= "Clear Parent";          tbstr1= "a|p";  keystr= "Alt P";        break;
342 /*      Unkown what tbstr1 should be...
343                                 case 6: tbstr= "MkVert Parent";         tbstr1= "c|a|p";        keystr= "Ctrl Alt P";   break;
344 */
345                                 case 7: tbstr= "Make Track";            tbstr1= "c|t";  keystr= "Ctrl T";       break;
346                                 case 8: tbstr= "Clear Track";           tbstr1= "a|t";  keystr= "Alt T";        break;
347 /*                              case 9: tbstr= "";                                      tbstr1= "";             keystr= "";                     break; */
348                                 case 10: tbstr= "Image Displist";       tbstr1= "c|d";  keystr= "Ctrl D";       break;
349                                 case 11: tbstr= "Image Aspect";         tbstr1= "a|v";  keystr= "Alt V";        break;
350                                 case 12: tbstr= "Vect Paint";           tbstr1= "v";    keystr= "V";    break;
351                         }
352                 }
353                 
354 /* OB TOPICS 2 */
355                 else if(tbmain==TBOX_MAIN_OBJECT2) {
356                         switch(y) {
357                                 case 0: tbstr= "Edit Mode";                     tbstr1= "Tab";  keystr= "Tab";                  break;
358                                 case 1: tbstr= "Move To Layer";         tbstr1= "m";    keystr= "M";                    break;
359                                 case 2: tbstr= "Delete";                        tbstr1= "x";    keystr= "X";                    break;
360                                 case 3: tbstr= "Delete All";            tbstr1= "c|x";  keystr= "Ctrl X";               break;
361                                 case 4: tbstr= "Apply Size/Rot";        tbstr1= "c|a";  keystr= "Ctrl A";               break;
362                                 case 5: tbstr= "Apply Deform";          tbstr1= "c|A";  keystr= "Ctrl Shift A"; break;
363                                 case 6: tbstr= "Join";                          tbstr1= "c|j";  keystr= "Ctrl J";               break;
364                                 case 7: tbstr= "Make Local";            tbstr1= "l";    keystr= "L";                    break;
365                                 case 8: tbstr= "Select Linked";         tbstr1= "L";    keystr= "Shift L";              break;
366                                 case 9: tbstr= "Make Links";            tbstr1= "c|l";  keystr= "Ctrl L";               break;
367                                 case 10: tbstr= "Copy Menu";            tbstr1= "c|c";  keystr= "Ctrl C";               break;
368                                 case 11: tbstr= "Convert Menu";         tbstr1= "a|c";  keystr= "Alt C";                break;
369                                 case 12: tbstr= "Boolean Op";           tbstr1= "w";    keystr= "W";            break;
370                         }
371                 }
372
373 /* mesh TOPICS */
374                 else if(tbmain==TBOX_MAIN_MESH) {
375                         switch(y) {
376                                 case 0: tbstr= "Select Linked";         tbstr1= "l";    keystr= "L";            break;
377                                 case 1: tbstr= "Deselect Linked";       tbstr1= "L";    keystr= "Shift L";      break;
378                                 case 2: tbstr= "Extrude";                       tbstr1= "e";    keystr= "E";            break;
379                                 case 3: tbstr= "Delete Menu";           tbstr1= "x";    keystr= "X";            break;
380                                 case 4: tbstr= "Make edge/face";        tbstr1= "f";    keystr= "F";            break;
381                                 case 5: tbstr= "Fill";                          tbstr1= "F";    keystr= "Shift F";      break;
382                                 case 6: tbstr= "Split";                         tbstr1= "y";    keystr= "Y";            break;
383                                 case 7: tbstr= "Undo/reload";           tbstr1= "u";    keystr= "U";            break;
384                                 case 8: tbstr= "Calc Normals";          tbstr1= "c|n";  keystr= "Ctrl N";       break;
385                                 case 9: tbstr= "Separate";                      tbstr1= "p";    keystr= "P";            break;
386                                 case 10: tbstr= "Write Videosc";        tbstr1= "a|w";  keystr= "Alt W";        break;
387 /*                              case 11: tbstr= "";                                     tbstr1= "";             keystr= "";                     break; */
388                         }
389                 }
390         
391 /* CURVE TOPICS */
392                 else if(tbmain==TBOX_MAIN_CURVE) {
393                         switch(y) {
394                                 case 0: tbstr= "Select Linked";         tbstr1= "l";    keystr= "L";            break;
395                                 case 1: tbstr= "Deselect Linked";       tbstr1= "L";    keystr= "Shift L";      break;
396                                 case 2: tbstr= "Extrude";                       tbstr1= "e";    keystr= "E";            break;
397                                 case 3: tbstr= "Delete Menu";           tbstr1= "x";    keystr= "X";            break;
398                                 case 4: tbstr= "Make Segment";          tbstr1= "f";    keystr= "F";            break;
399                                 case 5: tbstr= "Cyclic";                        tbstr1= "c";    keystr= "C";            break;
400 /*                              case 6: tbstr= "";                                      tbstr1= "";             keystr= "";                     break; */
401                                 case 7: tbstr= "Select Row";            tbstr1= "R";    keystr= "Shift R";      break;
402                                 case 8: tbstr= "Calc Handle";           tbstr1= "h";    keystr= "H";            break;
403                                 case 9: tbstr= "Auto Handle";           tbstr1= "H";    keystr= "Shift H";      break;
404                                 case 10: tbstr= "Vect Handle";          tbstr1= "v";    keystr= "V";            break;
405                                 case 11: tbstr= "Specials";                     tbstr1= "w";    keystr= "W";            break;
406                         }
407                 }
408         
409 /* KEY TOPICS */
410                 else if(tbmain==TBOX_MAIN_KEY) {
411                         switch(y) {
412                                 case 0: tbstr= "Insert";        tbstr1= "i";            keystr= "I";            break;
413                                 case 1: tbstr= "Show";          tbstr1= "k";            keystr= "K";            break;
414                                 case 2: tbstr= "Next";          tbstr1= "PageUp";       keystr= "PgUp";         break;
415                                 case 3: tbstr= "Prev";          tbstr1= "PageDn";       keystr= "PgDn";         break;
416                                 case 4: tbstr= "Show+Sel";      tbstr1= "K";            keystr= "Shift K";      break;
417 /*                              case 5: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
418                                 case 6: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
419                                 case 7: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
420                                 case 8: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
421                                 case 9: tbstr= "";                      tbstr1= "";                     keystr= "";                     break;
422                                 case 10: tbstr= "";                     tbstr1= "";                     keystr= "";                     break;
423                                 case 11: tbstr= "";                     tbstr1= "";                     keystr= "";                     break; */
424                         }
425                 }
426 /* SEQUENCER TOPICS */
427                 else if(tbmain==TBOX_MAIN_SEQ) {
428                         switch(y) {
429                                 case 0: tbstr= "Add Strip";  tbstr1= "A"; keystr= "Shift A"; break;
430                                 case 1: tbstr= "Change Str"; tbstr1= "c"; keystr= "C";       break;
431                                 case 2: tbstr= "Delete Str"; tbstr1= "x"; keystr= "X";       break;
432                                 case 3: tbstr= "Make Meta";  tbstr1= "m"; keystr= "M";       break;
433                                 case 4: tbstr= "Str Params"; tbstr1= "n"; keystr= "N";       break;
434                         }
435                 }
436
437 /* RENDER TOPICS */
438                 else if(tbmain==TBOX_MAIN_RENDER) {
439                         switch(y) {
440                                 case 0: tbstr= "Render Window"; tbstr1= "F11";  keystr= "F11";          break;
441                                 case 1: tbstr= "Render";                tbstr1= "F12";  keystr= "F12";          break;
442                                 case 2: tbstr= "Set Border";    tbstr1= "B";    keystr= "Shift B";      break;
443                                 case 3: tbstr= "Image Zoom";    tbstr1= "z";    keystr= "Z";            break;
444 /*                              case 4: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
445                                 case 5: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
446                                 case 6: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
447                                 case 7: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
448                                 case 8: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
449                                 case 9: tbstr= "";                              tbstr1= "";             keystr= "";                     break;
450                                 case 10: tbstr= "";                             tbstr1= "";             keystr= "";                     break;
451                                 case 11: tbstr= "";                             tbstr1= "";             keystr= "";                     break; */
452                         }
453                 }
454         
455 /* VIEW TOPICS */
456                 else if(tbmain==TBOX_MAIN_VIEW) {
457                         switch(y) {
458 /*                              case 0: tbstr= "";              tbstr1= "";     break;
459                                 case 1: tbstr= "";              tbstr1= "";     break;
460                                 case 2: tbstr= "";              tbstr1= "";     break;
461                                 case 3: tbstr= "";              tbstr1= "";     break; */
462                                 case 4: tbstr= "Centre";                tbstr1= "c";    keystr= "C";            break;
463                                 case 5: tbstr= "Home";                  tbstr1= "C";    keystr= "Shift C";      break;
464 /*                              case 6: tbstr= "";              tbstr1= "";     break;
465                                 case 7: tbstr= "";              tbstr1= "";     break;
466                                 case 8: tbstr= "";              tbstr1= "";     break;*/
467                                 case 9: tbstr= "Z-Buffer";              tbstr1= "z";    keystr= "Z";            break;
468 /*                              case 10: tbstr= "";             tbstr1= "";     break;
469                                 case 11: tbstr= "";             tbstr1= "";     break;*/
470                         }
471                 }
472 #ifdef PY_TOOLBOX
473                 else if(tbmain==TBOX_MAIN_PYTOOL) {
474                         TBcallback *t= g_toolbox_menucallback(0, y); // call python menu constructor
475                         if (t) { 
476                                 tbstr = t->desc; 
477                                 keystr = t->key;
478                                 tbfunc = t->cb;
479                                 tbval = t->val;
480                         }
481                 }
482 #endif
483         }
484 }
485
486 /* ******************** INIT ************************** */
487
488 void bgnpupdraw(int startx, int starty, int endx, int endy)
489 {
490         #if defined(__sgi) || defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__)
491
492         /* this is a dirty patch: XgetImage gets sometimes the backbuffer */
493         my_get_frontbuffer_image(0, 0, 1, 1);
494         my_put_frontbuffer_image();
495         #endif
496
497         tboldwin= mywinget();
498
499         mywinset(G.curscreen->mainwin);
500         
501         /* tinsy bit larger, 1 pixel on the rand */
502         
503         glReadBuffer(GL_FRONT);
504         glDrawBuffer(GL_FRONT);
505
506         glFlush();
507
508         my_get_frontbuffer_image(startx-1, starty-4, endx-startx+5, endy-starty+6);
509
510         oldcursor= get_cursor();
511         set_cursor(CURSOR_STD);
512         
513         tbfontyofs= (TBOXH-11)/2 +1;    /* ypos text in toolbox */
514 }
515
516 void endpupdraw(void)
517 {
518         glFlush();
519         my_put_frontbuffer_image();
520         
521         if(tboldwin) {
522                 mywinset(tboldwin);
523                 set_cursor(oldcursor);
524         }
525
526         glReadBuffer(GL_BACK);
527         glDrawBuffer(GL_BACK);
528 }
529
530 /* ********************************************** */
531
532 void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
533 {
534         if( isalpha(ch)==0 ) return;
535         
536         if( isupper(ch) ) {
537                 *qual= LEFTSHIFTKEY;
538                 ch= tolower(ch);
539         }
540         
541         switch(ch) {
542         case 'a': *event= AKEY; break;
543         case 'b': *event= BKEY; break;
544         case 'c': *event= CKEY; break;
545         case 'd': *event= DKEY; break;
546         case 'e': *event= EKEY; break;
547         case 'f': *event= FKEY; break;
548         case 'g': *event= GKEY; break;
549         case 'h': *event= HKEY; break;
550         case 'i': *event= IKEY; break;
551         case 'j': *event= JKEY; break;
552         case 'k': *event= KKEY; break;
553         case 'l': *event= LKEY; break;
554         case 'm': *event= MKEY; break;
555         case 'n': *event= NKEY; break;
556         case 'o': *event= OKEY; break;
557         case 'p': *event= PKEY; break;
558         case 'q': *event= QKEY; break;
559         case 'r': *event= RKEY; break;
560         case 's': *event= SKEY; break;
561         case 't': *event= TKEY; break;
562         case 'u': *event= UKEY; break;
563         case 'v': *event= VKEY; break;
564         case 'w': *event= WKEY; break;
565         case 'x': *event= XKEY; break;
566         case 'y': *event= YKEY; break;
567         case 'z': *event= ZKEY; break;
568         }
569 }
570
571 void tbox_execute(void)
572 {
573         /* if tbfunc: call function */
574         /* if tbstr1 is a string: put value tbval in queue */
575         unsigned short event=0;
576         unsigned short qual1=0, qual2=0;
577
578         /* needed to check for valid selected objects */
579         Base *base=NULL;
580         Object *ob=NULL;
581
582         base= BASACT;
583         if (base) ob= base->object;
584
585         if(tbfunc) {
586                 tbfunc(tbval);
587         }
588         else if(tbstr1) {
589                 if(strcmp(tbstr1, "Tab")==0) {
590                         event= TABKEY;
591                 }
592                 else if(strcmp(tbstr1, "PageUp")==0) {
593                         event= PAGEUPKEY;
594                 }
595                 else if(strcmp(tbstr1, "PageDn")==0) {
596                         event= PAGEDOWNKEY;
597                 }
598                 else if(strcmp(tbstr1, "shift+F1")==0) {
599                         qual1= LEFTSHIFTKEY;
600                         event= F1KEY;
601                 }
602                 else if(strcmp(tbstr1, "shift+F2")==0) {
603                         qual1= LEFTSHIFTKEY;
604                         event= F2KEY;
605                 }
606                 /* ctrl-s (Shear): switch into editmode ### */
607                 else if(strcmp(tbstr1, "c|s")==0) {
608                         /* check that a valid object is selected to prevent crash */
609                         if(!ob) error("Only selected objects can be sheared");
610                         else if ((ob->type==OB_LAMP) || (ob->type==OB_EMPTY) || (ob->type==OB_FONT) || (ob->type==OB_CAMERA)) {
611                                 error("Only editable 3D objects can be sheared");
612                         }
613                         else if ((base->lay & G.vd->lay)==0) {
614                                 error("Only objects on visible layers can be sheared");
615                         }
616                         else {
617                                 if (!G.obedit) {
618                                         enter_editmode();
619                                         /* ### put these into a deselectall_gen() */
620                                         if(G.obedit->type==OB_MESH) deselectall_mesh();
621                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb();
622                                         else if(G.obedit->type==OB_MBALL) deselectall_mball();
623                                         else if(G.obedit->type==OB_LATTICE) deselectall_Latt();
624                                         /* ### */
625                                 }
626                                 qual1 = LEFTCTRLKEY;
627                                 event = SKEY;
628                         }
629                 }
630                 else if(strcmp(tbstr1, "W")==0) {
631                         if (!ob) error ("Only selected objects can be warped");
632                         /* check that a valid object is selected to prevent crash */
633                         else if ((ob->type==OB_LAMP) || (ob->type==OB_EMPTY) || (ob->type==OB_FONT) || (ob->type==OB_CAMERA)) {
634                                 error("Only editable 3D objects can be warped");
635                         }
636                         else if ((base->lay & G.vd->lay)==0) {
637                                 error("Only objects on visible layers can be warped");
638                         }
639                         else {
640                                 if (!G.obedit) {
641                                         enter_editmode();
642                                         /* ### put these into a deselectall_gen() */
643                                         if(G.obedit->type==OB_MESH) deselectall_mesh();
644                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) deselectall_nurb();
645                                         else if(G.obedit->type==OB_MBALL) deselectall_mball();
646                                         else if(G.obedit->type==OB_LATTICE) deselectall_Latt();
647                                         /* ### */
648                                 }
649                                 qual1 = LEFTSHIFTKEY;
650                                 event = WKEY;
651                         }
652                 }
653
654                 else if(strlen(tbstr1)<4 || (strlen(tbstr1)==4 && tbstr1[2]=='F')) {
655                                 
656                         if(tbstr1[1]=='|') {
657                                 if(tbstr1[0]=='c') qual1= LEFTCTRLKEY;
658                                 else if(tbstr1[0]=='a') qual1= LEFTALTKEY;
659                                 
660                                 if (tbstr1[2]=='F') {
661                                         switch(tbstr1[3]) {
662                                         case '1': event= F1KEY; break;
663                                         case '2': event= F2KEY; break;
664                                         case '3': event= F3KEY; break;
665                                         case '4': event= F4KEY; break;
666                                         case '5': event= F5KEY; break;
667                                         case '6': event= F6KEY; break;
668                                         case '7': event= F7KEY; break;
669                                         case '8': event= F8KEY; break;
670                                         case '9': event= F9KEY; break;
671                                         }
672                                 }
673                                 else asciitoraw(tbstr1[2], &event, &qual2);
674                         }
675                         else if(tbstr1[1]==0) {
676                                 asciitoraw(tbstr1[0], &event, &qual2);
677                         }
678                         else if(tbstr1[0]=='F') {
679                                 event= atoi(tbstr1+1);
680                                 switch(event) {
681                                         case 1: event= F1KEY; break;
682                                         case 2: event= F2KEY; break;
683                                         case 3: event= F3KEY; break;
684                                         case 4: event= F4KEY; break;
685                                         case 5: event= F5KEY; break;
686                                         case 6: event= F6KEY; break;
687                                         case 7: event= F7KEY; break;
688                                         case 8: event= F8KEY; break;
689                                         case 9: event= F9KEY; break;
690                                         case 10: event= F10KEY; break;
691                                         case 11: event= F11KEY; break;
692                                         case 12: event= F12KEY; break;
693                                 }
694                         }
695                 }
696                 
697                 if(event) {
698                         if(qual1) mainqenter(qual1, 1);
699                         if(qual2) mainqenter(qual2, 1);
700                         mainqenter(event, 1);
701                         mainqenter(event, 0);
702                         mainqenter(EXECUTE, 1);
703                         if(qual1) mainqenter(qual1, 0);
704                         if(qual2) mainqenter(qual2, 0);
705                 }
706         }
707         
708 }
709
710 void tbox_getmouse(mval)
711 short *mval;
712 {
713
714         getmouseco_sc(mval);
715
716 }
717
718 void tbox_setmain(int val)
719 {
720         tbmain= val;
721
722         if(tbmain==0 && G.obedit) {
723                 addmode= G.obedit->type;
724         }
725 }
726
727 void bgntoolbox(void)
728 {
729         short xmax, ymax, mval[2];
730         
731         xmax = G.curscreen->sizex;
732         ymax = G.curscreen->sizey;
733
734         tbox_getmouse(mval);
735         
736         if(mval[0]<95) mval[0]= 95;
737         if(mval[0]>xmax-95) mval[0]= xmax-95;
738
739         warp_pointer(mval[0], mval[1]);
740
741         tbx1= mval[0]-tbmemx;
742         tby1= mval[1]-tbmemy;
743         if(tbx1<10) tbx1= 10;
744         if(tby1<10) tby1= 10;
745         
746         tbx2= tbx1+TBOXX;
747         tby2= tby1+TBOXY;
748         if(tbx2>xmax) {
749                 tbx2= xmax-10;
750                 tbx1= tbx2-TBOXX;
751         }
752         if(tby2>ymax) {
753                 tby2= ymax-10;
754                 tby1= tby2-TBOXY;
755         }
756
757         bgnpupdraw(tbx1, tby1, tbx2, tby2);
758 }
759
760 void endtoolbox(void)
761 {
762         short mval[2];
763         
764         tbox_getmouse(mval);
765         if(mval[0]>tbx1 && mval[0]<tbx2)
766                 if(mval[1]>tby1 && mval[1]<tby2) {
767                         tbmemx= mval[0]-(tbx1);
768                         tbmemy= mval[1]-(tby1);
769         }
770         
771         endpupdraw();
772 }
773
774
775 void tbox_embossbox(short x1, short y1, short x2, short y2, short type) 
776 /* type: 0=menu, 1=menusel, 2=topic, 3=topicsel */
777 {
778         
779         if(type==0) {
780                 glColor3ub(160, 160, 160);
781                 glRects(x1+1, y1+1, x2-1, y2-1);
782         }
783         if(type==1) {
784                 glColor3ub(50, 50, 100);
785                 glRects(x1+1, y1+1, x2-1, y2-1);
786         }
787         if(type==2) {
788                 glColor3ub(190, 190, 190);
789                 glRects(x1+1, y1+1, x2-1, y2-1);
790         }
791         if(type==3) {
792                 cpack(0xc07070);
793                 glRects(x1+1, y1+1, x2-1, y2-1);
794         }
795         
796         if(type & 1) cpack(0xFFFFFF);
797         else cpack(0x0);
798 }
799
800
801 void tbox_drawelem_body( int x, int y, int type)
802 {
803         int x1 = 0, y1, x2 = 0, y2;
804         
805         if(x==0) {
806                 x1= tbx1; x2= tbx1+TBOXXL;
807         }
808         else if(x==1) {
809                 x1= tbx1+TBOXXL;
810                 x2= x1+ TBOXXR-1;
811         }
812         
813         y1= tby1+ (TBOXEL-y-1)*TBOXH;
814         y2= y1+TBOXH-1;
815         
816         tbox_embossbox(x1, y1, x2, y2, type);
817         
818 }
819
820 void tbox_drawelem_text( int x, int y, int type)
821 {
822         int x1 = 0, y1, x2 = 0, y2, len1, len2;
823         
824         if(x==0) {
825                 x1= tbx1; x2= tbx1+TBOXXL;
826         }
827         else if(x==1) {
828                 x1= tbx1+TBOXXL;
829                 x2= x1+ TBOXXR-1;
830         }
831         
832         y1= tby1+ (TBOXEL-y-1)*TBOXH;
833         y2= y1+TBOXH-1;
834         
835         if(type==0 || type==2) {
836                 ColorFunc(TBOXBLACK);
837         }
838         else {
839                 glColor3ub(240, 240, 240);
840         }
841         
842         /* text */
843         tbox_setinfo(x, y);
844         if(tbstr && tbstr[0]) {
845                 len1= 5+BMF_GetStringWidth(G.font, tbstr);
846                 if(keystr) len2= 5+BMF_GetStringWidth(G.font, keystr); else len2= 0;
847                 
848                 while(len1>0 && (len1+len2+5>x2-x1) ) {
849                         tbstr[strlen(tbstr)-1]= 0;
850                         len1= BMF_GetStringWidth(G.font, tbstr);
851                 }
852                 
853                 glRasterPos2i(x1+5, y1+tbfontyofs);
854                 BIF_DrawString(G.font, tbstr, (U.transopts & USER_TR_MENUS));
855                 
856                 if(keystr && keystr[0]) {
857                         if(type & 1) {
858                                 ColorFunc(TBOXBLACK);
859         
860                                 glRecti(x2-len2-2,  y1+2,  x2-3,  y2-2);
861                                 ColorFunc(TBOXWHITE);
862                                 glRasterPos2i(x2-len2,  y1+tbfontyofs);
863                                 BIF_DrawString(G.font, keystr, (U.transopts & USER_TR_MENUS));
864                         }
865                         else {
866                                 ColorFunc(TBOXBLACK);
867                                 glRasterPos2i(x2-len2,  y1+tbfontyofs);
868                                 BIF_DrawString(G.font, keystr, (U.transopts & USER_TR_MENUS));
869                         }
870                 }
871         }
872 }
873
874
875 void tbox_drawelem(x, y, type)
876 int x, y, type; 
877 {
878         /* type: 0=menu, 1=menusel, 2=topic, 3=topicsel */
879
880         tbox_drawelem_body(x, y, type);
881         tbox_drawelem_text(x, y, type);
882         
883 }
884
885 void tbox_getactive(x, y)
886 int *x, *y;
887 {
888         short mval[2];
889         
890         tbox_getmouse(mval);
891         
892         mval[0]-=tbx1;
893         if(mval[0]<TBOXXL) *x= 0;
894         else *x= 1;
895         
896         *y= mval[1]-tby1;
897         *y/= TBOXH;
898         *y= TBOXEL- *y-1;
899         if(*y<0) *y= 0;
900         if(*y>TBOXEL-1) *y= TBOXEL-1;
901         
902 }
903
904 void drawtoolbox(void)
905 {
906         int x, y, actx, acty, type;
907
908         tbox_getactive(&actx, &acty);
909
910         /* background */
911         for(x=0; x<2; x++) {
912                 
913                 for(y=0; y<TBOXEL; y++) {
914                         
915                         if(x==0) type= 0; 
916                         else type= 2;
917                         
918                         if(actx==x && acty==y) type++;
919                         if(type==0) {
920                                 if(tbmain==y) type= 1;
921                         }
922                         
923                         tbox_drawelem_body(x, y, type);
924                         
925                 }
926         }
927
928         /* text */
929         for(x=0; x<2; x++) {
930                 
931                 for(y=0; y<TBOXEL; y++) {
932                         
933                         if(x==0) type= 0; 
934                         else type= 2;
935                         
936                         if(actx==x && acty==y) type++;
937                         if(type==0) {
938                                 if(tbmain==y) type= 1;
939                         }
940                         
941                         tbox_drawelem_text(x, y, type);
942                         
943                 }
944         }
945         glFlush();              /* for geforce, to show it in the frontbuffer */
946
947 }
948
949
950 void toolbox(void)
951 {
952         int actx, acty, y;
953         unsigned short event;
954         short val, mval[2], xo= -1, yo=0;
955         
956         bgntoolbox();
957         glColor3ub(0xB0, 0xB0, 0xB0);
958         uiDrawMenuBox((float)tbx1, (float)tby1-1, (float)tbx2, (float)tby2, 0);
959         drawtoolbox();
960         
961         /* 
962          *      The active window will be put back in the queue.
963          */
964
965         while(1) {
966                 event= extern_qread(&val);
967                 if(event) {
968                         switch(event) {
969                                 case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: case RETKEY: case PADENTER:
970                                         if(val==1) {
971                                                 tbox_getactive(&actx, &acty);
972                                                 tbox_setinfo(actx, acty);
973                                                 
974                                                 if(event==RIGHTMOUSE) {
975                                                         if(addmode) {
976                                                                 addmode= 0;
977                                                                 drawtoolbox();
978                                                         }
979                                                 }
980                                                 else if(tbstr1 && tbstr1[0]=='>') {
981                                                         addmode= tbval;
982                                                         drawtoolbox();
983                                                 }
984                                                 else {
985                                                         endtoolbox();
986                                                         tbox_execute();
987                                                         return;
988                                                 }
989                                         }
990                                         break;
991                                 case ESCKEY:
992                                         /* alt keys: to prevent conflicts with over-draw and stow/push/pop at sgis */
993 #ifndef MAART
994 /* Temporary for making screen dumps (Alt+PrtSc) */
995                                 case LEFTALTKEY:
996                                 case RIGHTALTKEY:
997 #endif /* MAART */
998                                         if(val) endtoolbox();
999                                         return;
1000                         }
1001                 }
1002                 
1003                 tbox_getmouse(mval);
1004                 if(mval[0]<tbx1-10 || mval[0]>tbx2+10 || mval[1]<tby1-10 || mval[1]>tby2+10) break;
1005                 
1006                 tbox_getactive(&actx, &acty);
1007                 
1008                 /* mouse handling and redraw */
1009                 if(xo!=actx || yo!=acty) {
1010                         if(actx==0) {
1011                                 if (acty==0) addmode=0;
1012                                 
1013                                 tbox_drawelem(0, tbmain, 0);
1014                                 tbox_drawelem(0, acty, 1);
1015                                 
1016                                 tbmain= acty;
1017                                 addmode= 0;
1018                                 for(y=0; y<TBOXEL; y++) tbox_drawelem(1, y, 2);
1019                         }
1020                         else if(xo> -1) {
1021                                 if(xo==0) tbox_drawelem(xo, yo, 1);
1022                                 else tbox_drawelem(xo, yo, 2);
1023                                 tbox_drawelem(actx, acty, 3);
1024                         }
1025                         
1026                         glFlush();              /* for geforce, to show it in the frontbuffer */
1027                         
1028                         xo= actx;
1029                         yo= acty;
1030                 }
1031         }
1032
1033         endtoolbox();
1034 }
1035
1036 /* ************************************  */
1037
1038 /* this va_ stuff allows printf() style codes in these menus */
1039
1040 static int vconfirm(char *title, char *itemfmt, va_list ap)
1041 {
1042         char *s, buf[512];
1043
1044         s= buf;
1045         if (title) s+= sprintf(s, "%s%%t|", title);
1046         vsprintf(s, itemfmt, ap);
1047         
1048         return (pupmenu(buf)>=0);
1049 }
1050
1051 static int confirm(char *title, char *itemfmt, ...)
1052 {
1053         va_list ap;
1054         int ret;
1055         
1056         va_start(ap, itemfmt);
1057         ret= vconfirm(title, itemfmt, ap);
1058         va_end(ap);
1059         
1060         return ret;
1061 }
1062
1063 int okee(char *str, ...)
1064 {
1065         va_list ap;
1066         int ret;
1067         
1068         va_start(ap, str);
1069         ret= vconfirm("OK?", str, ap);
1070         va_end(ap);
1071         
1072         return ret;
1073 }
1074
1075 void notice(char *str, ...)
1076 {
1077         va_list ap;
1078         
1079         va_start(ap, str);
1080         vconfirm(NULL, str, ap);
1081         va_end(ap);
1082 }
1083
1084 void error(char *fmt, ...)
1085 {
1086         va_list ap;
1087         char nfmt[256];
1088
1089         sprintf(nfmt, "ERROR: %s", fmt);
1090
1091         va_start(ap, fmt);
1092         if (G.background || !G.curscreen || (R.flag & R_RENDERING)) {
1093                 vprintf(nfmt, ap);
1094                 printf("\n");
1095         } else {
1096                 vconfirm(NULL, nfmt, ap);
1097         }
1098         va_end(ap);
1099 }
1100
1101 int saveover(char *file)
1102 {
1103         return (!BLI_exists(file) || confirm("Save over", file));
1104 }
1105
1106 /* ****************** EXTRA STUFF **************** */
1107
1108 short button(short *var, short min, short max, char *str)
1109 {
1110         uiBlock *block;
1111         ListBase listb={0, 0};
1112         short x1,y1;
1113         short mval[2], ret=0;
1114
1115         if(min>max) min= max;
1116
1117         getmouseco_sc(mval);
1118         
1119         if(mval[0]<150) mval[0]=150;
1120         if(mval[1]<30) mval[1]=30;
1121         if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10;
1122         if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10;
1123
1124         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1125         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK);
1126
1127         x1=mval[0]-150; 
1128         y1=mval[1]-20; 
1129         
1130         uiDefButS(block, NUM, 0, str,   (short)(x1+5),(short)(y1+10),125,20, var,(float)min,(float)max, 0, 0, "");
1131         uiDefBut(block, BUT, 1, "OK",   (short)(x1+136),(short)(y1+10),25,20, NULL, 0, 0, 0, 0, "");
1132
1133         uiBoundsBlock(block, 5);
1134
1135         ret= uiDoBlocks(&listb, 0);
1136
1137         if(ret==UI_RETURN_OK) return 1;
1138         return 0;
1139 }
1140
1141 short sbutton(char *var, float min, float max, char *str)
1142 {
1143         uiBlock *block;
1144         ListBase listb={0, 0};
1145         short x1,y1;
1146         short mval[2], ret=0;
1147
1148         if(min>max) min= max;
1149
1150         getmouseco_sc(mval);
1151         
1152         if(mval[0]<150) mval[0]=150;
1153         if(mval[1]<30) mval[1]=30;
1154         if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10;
1155         if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10;
1156
1157         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1158         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
1159
1160         x1=mval[0]-150; 
1161         y1=mval[1]-20; 
1162         
1163         uiDefButC(block, TEX, 0, str,   x1+5,y1+10,125,20, var,(float)min,(float)max, 0, 0, "");
1164         uiDefBut(block, BUT, 1, "OK",   x1+136,y1+10,25,20, NULL, 0, 0, 0, 0, "");
1165
1166         uiBoundsBlock(block, 5);
1167
1168         ret= uiDoBlocks(&listb, 0);
1169
1170         if(ret==UI_RETURN_OK) return 1;
1171         return 0;
1172 }
1173
1174 short fbutton(float *var, float min, float max, float a1, float a2, 
1175 char *str)
1176 {
1177         uiBlock *block;
1178         ListBase listb={0, 0};
1179         short x1,y1;
1180         short mval[2], ret=0;
1181
1182         if(min>max) min= max;
1183
1184         getmouseco_sc(mval);
1185         
1186         if(mval[0]<150) mval[0]=150;
1187         if(mval[1]<30) mval[1]=30;
1188         if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10;
1189         if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10;
1190
1191         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1192         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
1193
1194         x1=mval[0]-150; 
1195         y1=mval[1]-20; 
1196         
1197         uiDefButF(block, NUM, 0, str,(short)(x1+5),(short)(y1+10),125,20, var, min, max, a1, a2, "");
1198         uiDefBut(block, BUT, 1, "OK",(short)(x1+136),(short)(y1+10), 35, 20, NULL, 0, 0, 0, 0, "");
1199
1200         uiBoundsBlock(block, 2);
1201
1202         ret= uiDoBlocks(&listb, 0);
1203
1204         if(ret==UI_RETURN_OK) return 1;
1205         return 0;
1206 }
1207
1208 int movetolayer_buts(unsigned int *lay)
1209 {
1210         uiBlock *block;
1211         ListBase listb={0, 0};
1212         int dx, dy, a, x1, y1, sizex=160, sizey=30;
1213         short pivot[2], mval[2], ret=0;
1214         
1215         if(G.vd->localview) {
1216                 error("Not in localview ");
1217                 return ret;
1218         }
1219
1220         getmouseco_sc(mval);
1221
1222         pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30);
1223         pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10);
1224         
1225         if (pivot[0]!=mval[0] || pivot[1]!=mval[1])
1226                 warp_pointer(pivot[0], pivot[1]);
1227
1228         mywinset(G.curscreen->mainwin);
1229         
1230         x1= pivot[0]-sizex+10; 
1231         y1= pivot[1]-sizey/2; 
1232
1233         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1234         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_ENTER_OK);
1235         
1236         dx= (sizex-5)/12;
1237         dy= sizey/2;
1238         
1239         /* buttons have 0 as return event, to prevent menu to close on hotkeys */
1240         
1241         uiBlockBeginAlign(block);
1242         for(a=0; a<5; a++) 
1243                 uiDefButI(block, TOGR|BIT|a, 0, "",(short)(x1+a*dx),(short)(y1+dy),(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
1244         for(a=0; a<5; a++) 
1245                 uiDefButI(block, TOGR|BIT|(a+10), 0, "",(short)(x1+a*dx),(short)y1,(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
1246         x1+= 5;
1247         
1248         uiBlockBeginAlign(block);
1249         for(a=5; a<10; a++) 
1250                 uiDefButI(block, TOGR|BIT|a, 0, "",(short)(x1+a*dx),(short)(y1+dy),(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
1251         for(a=5; a<10; a++) 
1252                 uiDefButI(block, TOGR|BIT|(a+10), 0, "",(short)(x1+a*dx),(short)y1,(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
1253         uiBlockEndAlign(block);
1254
1255         x1-= 5;
1256         uiDefBut(block, BUT, 1, "OK", (short)(x1+10*dx+10), (short)y1, (short)(3*dx), (short)(2*dy), NULL, 0, 0, 0, 0, "");
1257
1258         uiBoundsBlock(block, 2);
1259
1260         ret= uiDoBlocks(&listb, 0);
1261
1262         if(ret==UI_RETURN_OK) return 1;
1263         return 0;
1264 }
1265
1266 /* ********************** CLEVER_NUMBUTS ******************** */
1267
1268 #define MAXNUMBUTS      24
1269
1270 VarStruct numbuts[MAXNUMBUTS];
1271 void *numbpoin[MAXNUMBUTS];
1272 int numbdata[MAXNUMBUTS];
1273
1274 void draw_numbuts_tip(char *str, int x1, int y1, int x2, int y2)
1275 {
1276         static char *last=0;    /* avoid ugly updates! */
1277         int temp;
1278         
1279         if(str==last) return;
1280         last= str;
1281         if(str==0) return;
1282
1283         glColor3ub(160, 160, 160); /* MGREY */
1284         glRecti(x1+4,  y2-36,  x2-4,  y2-16);
1285
1286         cpack(0x0);
1287
1288         temp= 0;
1289         while( BIF_GetStringWidth(G.fonts, str+temp, (U.transopts & USER_TR_BUTTONS))>(x2 - x1-24)) temp++;
1290         glRasterPos2i(x1+16, y2-30);
1291         BIF_DrawString(G.fonts, str+temp, (U.transopts & USER_TR_BUTTONS));
1292 }
1293
1294 int do_clever_numbuts(char *name, int tot, int winevent)
1295 {
1296         ListBase listb= {NULL, NULL};
1297         uiBlock *block;
1298         VarStruct *varstr;
1299         int a, sizex, sizey, x1, y2;
1300         short mval[2], event;
1301         
1302         if(tot<=0 || tot>MAXNUMBUTS) return 0;
1303
1304         getmouseco_sc(mval);
1305
1306         /* size */
1307         sizex= 235;
1308         sizey= 30+20*(tot+1);
1309         
1310         /* center */
1311         if(mval[0]<sizex/2) mval[0]=sizex/2;
1312         if(mval[1]<sizey/2) mval[1]=sizey/2;
1313         if(mval[0]>G.curscreen->sizex -sizex/2) mval[0]= G.curscreen->sizex -sizex/2;
1314         if(mval[1]>G.curscreen->sizey -sizey/2) mval[1]= G.curscreen->sizey -sizey/2;
1315
1316         mywinset(G.curscreen->mainwin);
1317         
1318         x1= mval[0]-sizex/2; 
1319         y2= mval[1]+sizey/2;
1320         
1321         block= uiNewBlock(&listb, "numbuts", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1322         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK);
1323         
1324         /* WATCH IT: TEX BUTTON EXCEPTION */
1325         /* WARNING: ONLY A SINGLE BIT-BUTTON POSSIBLE: WE WORK AT COPIED DATA! 
1326 */
1327
1328         uiDefBut(block, LABEL, 0, name, (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 1.0, 0.0, 0, 0, ""); 
1329
1330         if(name[0]=='A' && name[7]=='O') {
1331                 y2 -= 20;
1332                 uiDefBut(block, LABEL, 0, "Rotations in degrees!",      (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 0.0, 0.0, 0, 0, "");
1333         }
1334         
1335         varstr= &numbuts[0];
1336         for(a=0; a<tot; a++, varstr++) {
1337                 if(varstr->type==TEX) {
1338                         uiDefBut(block, TEX, 0, varstr->name,(short)(x1+15),(short)(y2-55-20*a),(short)(sizex-60), 19, numbpoin[a], varstr->min, varstr->max, 0, 0, varstr->tip);
1339                 }
1340                 else  {
1341                         uiDefBut(block, varstr->type, 0, varstr->name,(short)(x1+15),(short)(y2-55-20*a), (short)(sizex-60), 19, &(numbdata[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
1342                 }
1343         }
1344
1345         uiDefBut(block, BUT, 4000, "OK", (short)(x1+sizex-40),(short)(y2-35-20*a), 25, (short)(sizey-50), 0, 0, 0, 0, 0, "OK: Assign Values");
1346
1347         uiBoundsBlock(block, 5);
1348
1349         event= uiDoBlocks(&listb, 0);
1350
1351         areawinset(curarea->win);
1352         
1353         if(event & UI_RETURN_OK) {
1354                 
1355                 varstr= &numbuts[0];
1356                 for(a=0; a<tot; a++, varstr++) {
1357                         if(varstr->type==TEX);
1358                         else if ELEM( (varstr->type & BUTPOIN), FLO, INT ) memcpy(numbpoin[a], numbdata+a, 4);
1359                         else if((varstr->type & BUTPOIN)==SHO ) *((short *)(numbpoin[a]))= *( (short *)(numbdata+a));
1360                         
1361                         if( strncmp(varstr->name, "Rot", 3)==0 ) {
1362                                 float *fp;
1363                                 
1364                                 fp= numbpoin[a];
1365                                 fp[0]= M_PI*fp[0]/180.0;
1366                         }
1367                 }
1368                 
1369                 if(winevent) {
1370                         ScrArea *sa;
1371                 
1372                         sa= G.curscreen->areabase.first;
1373                         while(sa) {
1374                                 if(sa->spacetype==curarea->spacetype) addqueue(sa->win, winevent, 1);
1375                                 sa= sa->next;
1376                         }
1377                 }
1378                 
1379                 return 1;
1380         }
1381         return 0;
1382 }
1383
1384 void add_numbut(int nr, int type, char *str, float min, float max, void *poin, char *tip)
1385 {
1386         if(nr>=MAXNUMBUTS) return;
1387
1388         numbuts[nr].type= type;
1389         strcpy(numbuts[nr].name, str);
1390         numbuts[nr].min= min;
1391         numbuts[nr].max= max;
1392         if(tip) 
1393                 strcpy(numbuts[nr].tip, tip);
1394         else
1395                 strcpy(numbuts[nr].tip, "");
1396         
1397         
1398         /*WATCH: TEX BUTTON EXCEPTION */
1399         
1400         numbpoin[nr]= poin;
1401         
1402         if ELEM( (type & BUTPOIN), FLO, INT ) memcpy(numbdata+nr, poin, 4);
1403         if((type & BUTPOIN)==SHO ) *((short *)(numbdata+nr))= *( (short *)poin);
1404         
1405         if( strncmp(numbuts[nr].name, "Rot", 3)==0 ) {
1406                 float *fp;
1407                 
1408                 fp= (float *)(numbdata+nr);
1409                 fp[0]= 180.0*fp[0]/M_PI;
1410         }
1411
1412 }
1413
1414 void clever_numbuts(void)
1415 {
1416         
1417         if(curarea->spacetype==SPACE_VIEW3D) {
1418                 // panel now
1419         }
1420         else if(curarea->spacetype==SPACE_NLA){
1421                 // panel now
1422         }
1423         else if(curarea->spacetype==SPACE_IPO) {
1424                 // panel now
1425         }
1426         else if(curarea->spacetype==SPACE_SEQ) {
1427                 // panel now
1428         }
1429         else if(curarea->spacetype==SPACE_IMAGE) {
1430                 // panel now
1431         }
1432         else if(curarea->spacetype==SPACE_IMASEL) {
1433                 clever_numbuts_imasel();
1434         }
1435         else if(curarea->spacetype==SPACE_BUTS){
1436                 clever_numbuts_buts();
1437         }
1438         else if(curarea->spacetype==SPACE_OOPS) {
1439                 clever_numbuts_oops();
1440         }
1441         else if(curarea->spacetype==SPACE_ACTION){
1442                 // in its own queue
1443         }
1444         else if(curarea->spacetype==SPACE_FILE) {
1445                 clever_numbuts_filesel();
1446         }
1447 }
1448
1449
1450 void replace_names_but(void)
1451 {
1452         Image *ima= G.main->image.first;
1453         short len, tot=0;
1454         char old[64], new[64], temp[80];
1455         
1456         strcpy(old, "/");
1457         strcpy(new, "/");
1458         
1459         add_numbut(0, TEX, "Old:", 0, 63, old, 0);
1460         add_numbut(1, TEX, "New:", 0, 63, new, 0);
1461
1462         if (do_clever_numbuts("Replace image name", 2, REDRAW) ) {
1463                 
1464                 len= strlen(old);
1465                 
1466                 while(ima) {
1467                         
1468                         if(strncmp(old, ima->name, len)==0) {
1469                                 
1470                                 strcpy(temp, new);
1471                                 strcat(temp, ima->name+len);
1472                                 BLI_strncpy(ima->name, temp, sizeof(ima->name));
1473                                 
1474                                 if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
1475                                 ima->ibuf= 0;
1476                                 ima->ok= 1;
1477                                 
1478                                 tot++;
1479                         }
1480                         
1481                         ima= ima->id.next;
1482                 }
1483
1484                 notice("Replaced %d names", tot);
1485         }
1486         
1487 }
1488
1489
1490 /* ********************** NEW TOOLBOX ********************** */
1491
1492 ListBase tb_listb= {NULL, NULL};
1493
1494 #define TB_TAB  256
1495 #define TB_ALT  512
1496 #define TB_CTRL 1024
1497 #define TB_PAD  2048
1498 #define TB_SHIFT 4096
1499
1500 typedef struct TBitem {
1501         int icon;
1502         char *name;
1503         int retval;
1504         void *poin;
1505 } TBitem;
1506
1507 static void tb_do_hotkey(void *arg, int event)
1508 {
1509         unsigned short i, key=0;
1510         unsigned short qual[] = { 0,0,0,0 };
1511         
1512         if(event & TB_CTRL) {
1513                 qual[0] = LEFTCTRLKEY;
1514                 event &= ~TB_CTRL;
1515         }
1516         if(event & TB_ALT) {
1517                 qual[1] = LEFTALTKEY;
1518                 event &= ~TB_ALT;
1519         }
1520         if(event & TB_SHIFT) {
1521                 qual[2] = LEFTSHIFTKEY;
1522                 event &= ~TB_SHIFT;
1523         }
1524         
1525         if(event & TB_TAB) key= TABKEY;
1526         else if(event & TB_PAD) {
1527                 event &= ~TB_PAD;
1528                 switch(event) {
1529                 case '0': key= PAD0; break;
1530                 case '5': key= PAD5; break;
1531                 case '/': key= PADSLASHKEY; break;
1532                 case '.': key= PADPERIOD; break;
1533                 case '*': key= PADASTERKEY; break;
1534                 case 'h': key= HOMEKEY; break;
1535                 case 'u': key= PAGEUPKEY; break;
1536                 case 'd': key= PAGEDOWNKEY; break;
1537                 }
1538         }
1539         else asciitoraw(event, &key, &qual[3]);
1540
1541         for (i=0;i<4;i++)
1542         {
1543                 if(qual[i]) mainqenter(qual[i], 1);
1544         }
1545         mainqenter(key, 1);
1546         mainqenter(key, 0);
1547         mainqenter(EXECUTE, 1);
1548
1549         for (i=0;i<4;i++)
1550         {
1551                 if(qual[i]) mainqenter(qual[i], 0);
1552         }
1553 }
1554
1555 /* *************Select ********** */
1556
1557 static TBitem tb_object_select_layer1_5[]= {
1558 {       0, "1",         1, NULL},
1559 {       0, "2",         2, NULL},
1560 {       0, "3",         3, NULL},
1561 {       0, "4",         4, NULL},
1562 {       0, "5",         5, NULL},
1563 {  -1, "",              0, do_view3d_select_object_layermenu}};
1564
1565 static TBitem tb_object_select_layer6_10[]= {
1566 {       0, "6",         6, NULL},
1567 {       0, "7",         7, NULL},
1568 {       0, "8",         8, NULL},
1569 {       0, "9",         9, NULL},
1570 {       0, "10",        10, NULL},
1571 {  -1, "",              0, do_view3d_select_object_layermenu}};
1572
1573 static TBitem tb_object_select_layer11_15[]= {
1574 {       0, "11",        11, NULL},
1575 {       0, "12",        12, NULL},
1576 {       0, "13",        13, NULL},
1577 {       0, "14",        14, NULL},
1578 {       0, "15",        15, NULL},
1579 {  -1, "",              0, do_view3d_select_object_layermenu}};
1580
1581 static TBitem tb_object_select_layer16_20[]= {
1582 {       0, "16",        16, NULL},
1583 {       0, "17",        17, NULL},
1584 {       0, "18",        18, NULL},
1585 {       0, "19",        19, NULL},
1586 {       0, "20",        20, NULL},
1587 {  -1, "",              0, do_view3d_select_object_layermenu}};
1588
1589 static TBitem tb_object_select_layer[]= {
1590 {       0, "Layers 1-5",        0,              tb_object_select_layer1_5},
1591 {       0, "Layers 6-10",       0,              tb_object_select_layer6_10},
1592 {       0, "Layers 11-15",      0,              tb_object_select_layer11_15},
1593 {       0, "Layers 16-20",      0,              tb_object_select_layer16_20},
1594 {  -1, "",                      0, tb_do_hotkey}};
1595
1596 static TBitem tb_object_select_type[]= {
1597 {       0, "Mesh",              1, NULL},
1598 {       0, "Curve",     2, NULL},
1599 {       0, "Surface",   3, NULL},
1600 {       0, "Meta",              4, NULL},
1601 {       0, "SEPR",              0, NULL},
1602 {       0, "Armature",  5, NULL},
1603 {       0, "Lattice",   6, NULL},
1604 {       0, "Text",              7, NULL},
1605 {       0, "Empty",     8, NULL},
1606 {       0, "SEPR",              0, NULL},
1607 {       0, "Camera",    9, NULL},
1608 {       0, "Lamp",              10, NULL},
1609 {  -1, "",                      0, do_view3d_select_object_typemenu}};
1610
1611 static TBitem tb_object_select_linked[]= {
1612 {       0, "Object Ipo|Shift L, 1",     1, NULL},
1613 {       0, "ObData|Shift L, 2",         2, NULL},
1614 {       0, "Material|Shift L, 3",       3, NULL},
1615 {       0, "Texture|Shift L, 4",        4, NULL},
1616 {  -1, "",                      0, do_view3d_select_object_linkedmenu}};
1617
1618 static TBitem tb_object_select_grouped[]= {
1619 {       0, "Children|Shift G, 1",       1, NULL},
1620 {       0, "Immediate Children|Shift G, 2",     2, NULL},
1621 {       0, "Parent|Shift G, 3",         3, NULL},
1622 {       0, "Objects on Shared Layers|Shift G, 4",       4, NULL},
1623 {  -1, "",                      0, do_view3d_select_object_groupedmenu}};
1624
1625 static TBitem tb_object_select[]= {
1626 {       0, "Border Select|B",   'b', NULL},
1627 {       0, "SEPR",                              0, NULL},
1628 {       0, "Select/Deselect All|A",     'a', NULL},
1629 {       0, "Select All by Layer",       0,              tb_object_select_layer},
1630 {       0, "Select All by Type",        0,              tb_object_select_type},
1631 {       0, "SEPR",                              0, NULL},
1632 {       0, "Linked",    0,      tb_object_select_linked},
1633 {       0, "Grouped",   0,      tb_object_select_grouped},
1634 {  -1, "",                      0, tb_do_hotkey}};
1635
1636 static TBitem tb_mesh_select[]= {
1637 {       0, "Border Select|B",               0, NULL},
1638 {       0, "SEPR",                          0, NULL},
1639 {       0, "(De)select All|A",              2, NULL},
1640 {       0, "Inverse",                       3, NULL},
1641 {       0, "SEPR",                          0, NULL},
1642 {       0, "Random...",                             5, NULL},
1643 {       0, "Non-Manifold|Shift Ctrl Alt M", 9, NULL},
1644 {       0, "SEPR",                          0, NULL},
1645 {       0, "More|Ctrl NumPad +",            7, NULL},
1646 {       0, "Less|Ctrl NumPad -",            8, NULL},
1647 {       0, "SEPR",                          0, NULL},
1648 {       0, "Vertex Loop...|Alt B",          10, NULL},
1649 {       0, "Face Loop...|Shift R",          6, NULL},
1650 {       0, "Linked Vertices|Ctrl L",        4, NULL},
1651 {  -1, "",                      0, do_view3d_select_meshmenu}};
1652
1653
1654 static TBitem tb_curve_select[]= {
1655 {       0, "Border Select|B",   0, NULL},
1656 {       0, "SEPR",                              0, NULL},
1657 {       0, "(De)select All|A",  2, NULL},
1658 {       0, "Inverse",                   3, NULL},
1659 {       0, "Row|Shift R",                       5, NULL},
1660 {  -1, "",                              0, do_view3d_select_curvemenu}};
1661
1662 static TBitem tb__select[]= {
1663 {       0, "Border Select|B",   'b', NULL},
1664 {       0, "(De)select All|A",  'a', NULL},
1665 {  -1, "",                      0, tb_do_hotkey}};
1666
1667
1668 /* *************Edit ********** */
1669
1670 static TBitem tb_edit[]= {
1671 {       0, "Exit Editmode|Tab",         TB_TAB, NULL},
1672 {  -1, "",                      0, tb_do_hotkey}};
1673
1674 static TBitem tb_curve_edit_seg[]= {
1675 {       0, "Subdivide|W, 1",            0, NULL},
1676 {       0, "Switch Direction|W, 2",     1, NULL},
1677 {  -1, "",                      0, do_view3d_edit_curve_segmentsmenu}};
1678
1679 static TBitem tb_curve_edit_cv[]= {
1680 {       0, "Tilt|T",    't', NULL},
1681 {       0, "Clear Tilt|Alt T",                  TB_ALT|'t', NULL},
1682 {       0, "Separate|P",        'p', NULL},
1683 {       0, "SEPR",                                                              0, NULL},
1684 {       0, "Automatic|Shift H",                 'H', NULL},
1685 {       0, "Toggle Free/Aligned|H",     'h', NULL},
1686 {       0, "Vector|V",                                  TB_ALT|'t', NULL},
1687 {       0, "SEPR",                                                              0, NULL},
1688 {       0, "Make Vertex Parent|Ctrl P", TB_CTRL|'p', NULL},
1689 {       0, "Add Hook|Ctrl H",                   TB_CTRL|'h', NULL},
1690 {  -1, "",                      0, tb_do_hotkey}};
1691
1692
1693 static TBitem tb_curve_edit[]= {
1694 {       0, "Exit Editmode|Tab",         TB_TAB, NULL},
1695 {       0, "SEPR",                                                              0, NULL},
1696 {       0, "Extrude|E",                 'e',            NULL},
1697 {       0, "Duplicate|Shift D", 'D',            NULL},
1698 {       0, "Make Segment|F",    'f',            NULL},
1699 {       0, "Toggle Cyclic|C",   'c',            NULL},
1700 {       0, "Delete...|X",               'x',            NULL},
1701 {       0, "SEPR",                                                              0, NULL},
1702 {       0, "Control Points",    0,              tb_curve_edit_cv},
1703 {       0, "Segments",  0,              tb_curve_edit_seg},
1704 {  -1, "",                      0, tb_do_hotkey}};
1705
1706
1707 static TBitem tb_mesh_edit_vertex[]= {
1708 {       0, "Merge...|Alt M",            5, NULL},
1709 {       0, "Split|Y",                           4,              NULL},
1710 {       0, "Separate|P",                        3,              NULL},
1711 {       0, "SEPR",                                      0, NULL},
1712 {       0, "Smooth|W, 0",                       2, NULL},
1713 {       0, "Remove Doubles|W, 5",                       1, NULL},
1714 {       0, "SEPR",                                      0, NULL},
1715 {       0, "Make Vertex Parent|Ctrl P",         0, NULL},
1716 {       0, "Add Hook|Ctrl H",           6, NULL},
1717 {  -1, "",                      0, do_view3d_edit_mesh_verticesmenu}};
1718
1719 static TBitem tb_mesh_edit_edge[]= {
1720 {       0, "Make Edge/Face|F",                  5,              NULL},
1721 {       0, "SEPR",                                              0, NULL},
1722 {       0, "Bevel|W, Alt 1",                                    6,              NULL},
1723 {       0, "Loop Subdivide|Ctrl R",             4,              NULL},
1724 {       0, "Knife Subdivide...|Shift K",        3,              NULL},
1725 {       0, "SEPR",                                                              0, NULL},
1726 {       0, "Subdivide|W, 1",                    2,              NULL},
1727 {       0, "Subdivide Fractal|W, 2",    1,              NULL},
1728 {       0, "Subdivide Smooth|W, 3",             0,              NULL},
1729 {       0, "SEPR",                                                              0, NULL},
1730 {       0, "Mark Seam|Ctrl E",                  7,              NULL},
1731 {       0, "Clear Seam|Ctrl E",                 8,              NULL},
1732 {       0, "SEPR",                                                              0, NULL},
1733 {       0, "Crease SubSurf|Shift E",    9,              NULL},
1734 {       0, "SEPR",                                                              0, NULL},
1735 {       0, "Rotate Edge|Ctrl E",        10,             NULL},
1736 {  -1, "",                      0, do_view3d_edit_mesh_edgesmenu}};
1737
1738 static TBitem tb_mesh_edit_face[]= {
1739 {       0, "Make Edge/Face|F",                  'f',            NULL},
1740 {       0, "Fill|Shift F",                              'F',            NULL},
1741 {       0, "Beautify Fill|Alt F",                       TB_ALT|'f',             NULL},
1742 {       0, "SEPR",                                      0, NULL},
1743 {       0, "Convert to Triangles|Ctrl T",       TB_CTRL|'t',            NULL},
1744 {       0, "Convert to Quads|Alt J",            TB_ALT|'j',             NULL},
1745 {       0, "Flip Triangle Edges|Ctrl F",        TB_CTRL|'f',            NULL},
1746 {  -1, "",                      0, tb_do_hotkey}};
1747
1748
1749 static TBitem tb_mesh_edit_normal[]= {
1750 {       0, "Recalculate Outside|Ctrl N",        2,              NULL},
1751 {       0, "Recalculate Inside|Ctrl Shift N",   1,              NULL},
1752 {       0, "SEPR",                                      0, NULL},
1753 {       0, "Flip|W, 9",                                 0,              NULL},
1754 {  -1, "",                      0, do_view3d_edit_mesh_normalsmenu}};
1755
1756 static TBitem tb_mesh_edit[]= {
1757 {       0, "Exit Editmode|Tab",         TB_TAB, NULL},
1758 {       0, "Undo|U",                    'u',            NULL},
1759 {       0, "Redo|Shift U",              'U',            NULL},
1760 {       0, "SEPR",                              0,                      NULL},
1761 {       0, "Extrude|E",                 'e',            NULL},
1762 {       0, "Duplicate|Shift D", 'D',            NULL},
1763 {       0, "Delete...|X",               'x',            NULL},
1764 {       0, "SEPR",                              0,                      NULL},
1765 {       0, "Vertices",          0,              tb_mesh_edit_vertex},
1766 {       0, "Edges",             0,              tb_mesh_edit_edge},
1767 {       0, "Faces",             0,              tb_mesh_edit_face},
1768 {       0, "Normals",           0,              tb_mesh_edit_normal},
1769 {  -1, "",                      0, tb_do_hotkey}};
1770
1771
1772 static TBitem tb_object_ipo[]= {
1773 {       0, "Show/Hide",         'k', NULL},
1774 {       0, "Select Next",       TB_PAD|'u', NULL},
1775 {       0, "Select Prev",       TB_PAD|'d', NULL},
1776 {  -1, "",                      0, tb_do_hotkey}};
1777
1778
1779 static TBitem tb_object_edit[]= {
1780 {       0, "Enter Editmode|Tab",        TB_TAB, NULL},
1781 {       0, "SEPR",                                                              0, NULL},
1782 {       0, "Duplicate|Shift D",                 'D',            NULL},
1783 {       0, "Duplicate Linked|Alt D",    TB_ALT|'d', NULL},
1784 {       0, "Delete|X",                                  'x',            NULL},
1785 {       0, "SEPR",                                                              0, NULL},
1786 {       0, "Object Keys",       0, tb_object_ipo},
1787 {  -1, "",                      0, tb_do_hotkey}};
1788
1789
1790 /* ************* Type  ********** */
1791
1792 static TBitem tb_obdata_hide[]= {
1793 {       0, "Show Hidden|Alt H",                 TB_ALT|'h',             NULL},
1794 {       0, "Hide Selected|H",                   'h',            NULL},
1795 {       0, "Hide Deselected|Shift H",   'H',            NULL},
1796 {  -1, "",                      0, tb_do_hotkey}};
1797
1798 static void tb_do_mesh(void *arg, int event){
1799         Mesh *me= get_mesh(OBACT);
1800         switch(event) {
1801         case 1: common_insertkey(); break;
1802         case 2: G.f ^= G_DRAWEDGES; break;
1803         case 3: G.f ^= G_DRAWFACES; break;
1804         case 4: G.f ^= G_DRAWNORMALS; break;
1805         case 5: me->flag ^= ME_SUBSURF; makeDispList(OBACT); break;
1806         case 6: me->flag ^= ME_OPT_EDGES; makeDispList(OBACT); break;
1807         }
1808         addqueue(curarea->win, REDRAW, 1);
1809 }
1810
1811 static TBitem tb_mesh[]= {
1812 {       0, "Insert Keyframe|I",                 1,              NULL},
1813 {       0, "SEPR",                                              0, NULL},
1814 {       0, "Show/Hide Edges",                   2,              NULL},
1815 {       0, "Show/Hide Faces",                   3,              NULL},
1816 {       0, "Show/Hide Normals",                 4,              NULL},
1817 {       0, "SEPR",                                              0,      NULL},
1818 {       0, "Subdivision Surface",               5,              NULL},
1819 {       0, "SubSurf Optimal",                   6,              NULL},
1820 {       0, "SEPR",                                              0, NULL},
1821 {       0, "Show/Hide Vertices",        0,              tb_obdata_hide},
1822 {  -1, "",                      0, tb_do_mesh}};
1823
1824 static TBitem tb_curve_hide[]= {
1825 {       0, "Show Hidden|Alt H",                 10,             NULL},
1826 {       0, "Hide Selected|H",                   11,             NULL},
1827 {  -1, "",                      0, do_view3d_edit_curve_showhidemenu}};
1828
1829
1830 static TBitem tb_curve[]= {
1831 {       0, "Insert Keyframe|I",                 'i',            NULL},
1832 {       0, "SEPR",                                              0, NULL},
1833 {       0, "Show/Hide Control Points",  0,              tb_curve_hide},
1834 {  -1, "",                      0, tb_do_hotkey}};
1835
1836 static TBitem tb_obdata[]= {
1837 {       0, "Duplicate|Shift D",                 'D',            NULL},
1838 {       0, "Delete|X",                                  'x',            NULL},
1839 {  -1, "",                      0, tb_do_hotkey}};
1840
1841 static TBitem tb_object_parent[]= {
1842 {       0, "Make Parent...|Ctrl P",             TB_CTRL|'p', NULL},
1843 {       0, "Clear Parent...|Alt P",             TB_ALT|'p', NULL},
1844 {  -1, "",                      0, tb_do_hotkey}};
1845
1846 static TBitem tb_object_track[]= {
1847 {       0, "Make Track|Ctrl T",                 TB_CTRL|'t', NULL},
1848 {       0, "Clear Track|Alt T",                 TB_ALT|'t', NULL},
1849 {  -1, "",                      0, tb_do_hotkey}};
1850
1851 static TBitem tb_object[]= {
1852 {       0, "Insert Keyframe|I",                 'i',            NULL},
1853 {       0, "SEPR",                                                              0, NULL},
1854 {       0, "Make Links...|Ctrl L",              TB_CTRL|'l', NULL},
1855 {       0, "Make Single User...|U",     'u',            NULL},
1856 {       0, "Copy Attributes...|Ctrl C", TB_CTRL|'c', NULL},
1857 {       0, "SEPR",                                                              0, NULL},
1858 {       0, "Parent",    0,              tb_object_parent},
1859 {       0, "Track",     0,              tb_object_track},
1860 {       0, "SEPR",                                                              0, NULL},
1861 {       0, "Boolean Operation|W",       'w', NULL},
1862 {       0, "Join Objects...|Ctrl J",    TB_CTRL|'j', NULL},
1863 {       0, "Convert Object Type...|Alt C",      TB_ALT|'c', NULL},
1864 {       0, "SEPR",                                                              0, NULL},
1865 {       0, "Move to Layer...|M",                'm', NULL},
1866 {  -1, "",                      0, tb_do_hotkey}};
1867
1868
1869 /* *************VIEW ********** */
1870
1871 static void tb_do_view_dt(void *arg, int event){
1872         G.vd->drawtype= event;
1873         addqueue(curarea->win, REDRAW, 1);
1874 }
1875
1876 static TBitem tb_view_dt[]= {
1877 {       ICON_BBOX, "Bounding Box",      1, NULL},
1878 {       ICON_WIRE, "Wireframe|Z",       2, NULL},
1879 {       ICON_SOLID, "Solid|Z",          3, NULL},
1880 {       ICON_SMOOTH, "Shaded|Ctrl Z",           4, NULL},
1881 {       ICON_POTATO, "Textured|Alt Z",  5, NULL},
1882 {  -1, "",                      0, tb_do_view_dt}};
1883
1884 static TBitem tb_view_alignview[]= {
1885 {       0, "Centre View to Cursor|C",           'c', NULL},
1886 {       0, "Align Active Camera to View|Ctrl Alt NumPad 0",
1887 TB_CTRL|TB_ALT|TB_PAD|'0', NULL}, 
1888 {       0, "Align View to Selected|NumPad *",           TB_PAD|'*', NULL},
1889 {  -1, "",                      0, tb_do_hotkey}};
1890
1891 static TBitem tb_view[]= {
1892 {       0, "Viewport Shading",                  0, tb_view_dt},
1893 {       0, "SEPR",                                              0, NULL},
1894 {       0, "Ortho/Perspective|NumPad 5",        TB_PAD|'5', NULL},
1895 {       0, "Local/Global View|NumPad /",        TB_PAD|'/', NULL},
1896 {       0, "SEPR",                                              0, NULL},
1897 {       0, "Align View",                        0, tb_view_alignview},
1898 {       0, "SEPR",              0, NULL},
1899 {       0, "View Selected|NumPad .",    TB_PAD|'.', NULL},
1900 {       0, "View All|Home",             TB_PAD|'h', NULL},
1901 {       0, "SEPR",              0, NULL},
1902 {       0, "Play Back Animation|Alt A", TB_ALT|'a', NULL},
1903 {       0, "Camera Fly Mode|Shift F", TB_SHIFT|'f', NULL},
1904 {  -1, "",                      0, tb_do_hotkey}};
1905
1906
1907 /* *************TRANSFORM ********** */
1908
1909 static TBitem tb_transform_moveaxis[]= {
1910 {       0, "X Global|G, X",     0, NULL},
1911 {       0, "Y Global|G, Y",     1, NULL},
1912 {       0, "Z Global|G, Z",     2, NULL},
1913 {       0, "SEPR",                                      0, NULL},
1914 {       0, "X Local|G, X, X",   3, NULL},
1915 {       0, "Y Local|G, Y, Y",   4, NULL},
1916 {       0, "Z Local|G, Z, Z",   5, NULL},
1917 {  -1, "",                      0, do_view3d_transform_moveaxismenu}};
1918
1919 static TBitem tb_transform_rotateaxis[]= {
1920 {       0, "X Global|R, X",     0, NULL},
1921 {       0, "Y Global|R, Y",     1, NULL},
1922 {       0, "Z Global|R, Z",     2, NULL},
1923 {       0, "SEPR",                                      0, NULL},
1924 {       0, "X Local|R, X, X",   3, NULL},
1925 {       0, "Y Local|R, Y, Y",   4, NULL},
1926 {       0, "Z Local|R, Z, Z",   5, NULL},
1927 {  -1, "",                      0, do_view3d_transform_rotateaxismenu}};
1928
1929 static TBitem tb_transform_scaleaxis[]= {
1930 {       0, "X Global|S, X",     0, NULL},
1931 {       0, "Y Global|S, Y",     1, NULL},
1932 {       0, "Z Global|S, Z",     2, NULL},
1933 {       0, "SEPR",                                      0, NULL},
1934 {       0, "X Local|S, X, X",   3, NULL},
1935 {       0, "Y Local|S, Y, Y",   4, NULL},
1936 {       0, "Z Local|S, Z, Z",   5, NULL},
1937 {  -1, "",                      0, do_view3d_transform_scaleaxismenu}};
1938
1939 static void tb_do_transform_clearapply(void *arg, int event)
1940 {
1941         Object *ob;
1942         ob= OBACT;
1943         
1944         switch(event)
1945         {
1946             case 0: /* clear location */
1947                         clear_object('g');
1948                         break;
1949                 case 1: /* clear rotation */
1950                         clear_object('r');
1951                         break;
1952                 case 2: /* clear size */
1953                         clear_object('s');
1954                         break;
1955                 case 3: /* apply size/rotation */
1956                         apply_object();
1957                         break;
1958                 case 4: /* apply deformation */
1959                         object_apply_deform(ob);
1960                         break;
1961                 case 5: /* make duplicates real */
1962                         if (ob->transflag & OB_DUPLI) make_duplilist_real();
1963                         else error("The active object does not have dupliverts");
1964                         break;
1965         }
1966 }
1967
1968 static TBitem tb_transform_clearapply[]= {
1969 {       0, "Clear Location|Alt G",              0, NULL},
1970 {       0, "Clear Rotation|Alt R",              1, NULL},
1971 {       0, "Clear Size|Alt S",                  2, NULL},
1972 {       0, "SEPR",                                      0, NULL},
1973 {       0, "Apply Size/Rotation|Ctrl A", 3, NULL},
1974 {       0, "Apply Deformation|Shift Ctrl A", 4, NULL},
1975 {       0, "Make Duplicates Real|Shift Ctrl A", 5, NULL},
1976 {  -1, "",                      0, tb_do_transform_clearapply}};
1977
1978 static TBitem tb_transform_snap[]= {
1979 {       0, "Selection -> Grid|Shift S, 1",              1, NULL},
1980 {       0, "Selection -> Cursor|Shift S, 2",    2, NULL},
1981 {       0, "Cursor -> Grid|Shift S, 3",                 3, NULL},
1982 {       0, "Cursor -> Selection|Shift S, 4", 4, NULL},
1983 {       0, "Selection -> Center|Shift S, 5", 5, NULL},
1984 {  -1, "",                      0, do_view3d_edit_snapmenu}};
1985
1986 static void tb_do_transform(void *arg, int event)
1987 {
1988         switch(event)
1989         {
1990                 case 0: /* Grab/move */
1991                         Transform(TFM_TRANSLATION);
1992                         break;
1993                 case 1: /* Rotate */
1994                         Transform(TFM_ROTATION);
1995                         break;
1996                 case 2: /* Scale */
1997                         Transform(TFM_RESIZE);
1998                         break;
1999                 case 3: /* transform properties */
2000                         add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
2001                         break;
2002                 case 4: /* snap */
2003                         snapmenu();
2004                         break;
2005                 case 5: /* Shrink/Fatten Along Normals */
2006                         transform('N');
2007                         break;
2008                 case 6: /* Shear */
2009                         Transform(TFM_SHEAR);
2010                         break;
2011                 case 7: /* Warp */
2012                         transform('w');
2013                         break;
2014                 case 8: /* proportional edit (toggle) */
2015                         if(G.f & G_PROPORTIONAL) G.f &= ~G_PROPORTIONAL;
2016                         else G.f |= G_PROPORTIONAL;
2017                         break;
2018         }
2019         allqueue(REDRAWVIEW3D, 0);
2020 }
2021
2022 static TBitem tb_transform_object_mirror[]= {
2023 {       0, "X Local|Ctrl M, 1",         1, NULL},
2024 {       0, "Y Local|Ctrl M, 2",         2, NULL},
2025 {       0, "Z Local|Ctrl M, 3",         3, NULL},
2026 {  -1, "",                      0, do_view3d_object_mirrormenu}};
2027
2028 static TBitem tb_transform[]= {
2029 {       0, "Grab/Move|G",       0, NULL},
2030 {       0, "Grab/Move on Axis| ",       0, tb_transform_moveaxis},
2031 {       0, "Rotate|R",          1, NULL},
2032 {       0, "Rotate on Axis",    0, tb_transform_rotateaxis},
2033 {       0, "Scale|S",           2, NULL},
2034 {       0, "Scale on Axis",     0, tb_transform_scaleaxis},
2035 {       0, "SEPR",                                      0, NULL},
2036 {       0, "Mirror",    0, tb_transform_object_mirror},
2037 {       0, "SEPR",                                      0, NULL},
2038 {       ICON_MENU_PANEL, "Properties|N", 3, NULL},
2039 {       0, "Snap",              0, tb_transform_snap},
2040 {       0, "SEPR",                                      0, NULL},
2041 {       0, "Clear/Apply",       0, tb_transform_clearapply},
2042 {  -1, "",                      0, tb_do_transform}};
2043
2044 static TBitem tb_transform_edit_mirror[]= {
2045 {       0, "X Global|Ctrl M, 1",        1, NULL},
2046 {       0, "Y Global|Ctrl M, 2",        2, NULL},
2047 {       0, "Z Global|Ctrl M, 3",        3, NULL},
2048 {       0, "SEPR",                                      0, NULL},
2049 {       0, "X Local|Ctrl M, 4",         4, NULL},
2050 {       0, "Y Local|Ctrl M, 5",         5, NULL},
2051 {       0, "Z Local|Ctrl M, 6",         6, NULL},
2052 {       0, "SEPR",                                      0, NULL},
2053 {       0, "X View|Ctrl M, 7",  7, NULL},
2054 {       0, "Y View|Ctrl M, 8",  8, NULL},
2055 {       0, "Z View|Ctrl M, 9",  9, NULL},
2056 {  -1, "",                      0, do_view3d_edit_mirrormenu}};
2057
2058 static TBitem tb_transform_editmode1[]= {
2059 {       0, "Grab/Move|G",       0, NULL},
2060 {       0, "Grab/Move on Axis| ",       0, tb_transform_moveaxis},
2061 {       0, "Rotate|R",          1, NULL},
2062 {       0, "Rotate on Axis",    0, tb_transform_rotateaxis},
2063 {       0, "Scale|S",           2, NULL},
2064 {       0, "Scale on Axis",     0, tb_transform_scaleaxis},
2065 {       0, "SEPR",                                      0, NULL},
2066 {       0, "Mirror",    0, tb_transform_edit_mirror},
2067 {       0, "Shrink/Fatten|Alt S", 5, NULL},
2068 {       0, "Shear|Ctrl S", 6, NULL},
2069 {       0, "Warp|Shift W",      7, NULL},
2070 {       0, "SEPR",                                      0, NULL},
2071 {       ICON_MENU_PANEL, "Properties|N", 3, NULL},
2072 {       0, "Snap",              0, tb_transform_snap},
2073 {       0, "SEPR",                                      0, NULL},
2074 {       0, "Proportional Edit|O",       8,              NULL},
2075 {  -1, "",                      0, tb_do_transform}};
2076
2077
2078 static TBitem tb_transform_editmode2[]= {
2079 {       0, "Grab/Move|G",       0, NULL},
2080 {       0, "Grab/Move on Axis| ",       0, tb_transform_moveaxis},
2081 {       0, "Rotate|R",          1, NULL},
2082 {       0, "Rotate on Axis",    0, tb_transform_rotateaxis},
2083 {       0, "Scale|S",           2, NULL},
2084 {       0, "Scale on Axis",     0, tb_transform_scaleaxis},
2085 {       0, "SEPR",                                      0, NULL},
2086 {       ICON_MENU_PANEL, "Properties|N", 3, NULL},
2087 {       0, "Snap",              0, tb_transform_snap},
2088 {  -1, "",                      0, tb_do_transform}};
2089
2090
2091 /* *************ADD ********** */
2092
2093 static TBitem addmenu_mesh[]= {
2094 {       0, "Plane",     0, NULL},
2095 {       0, "Cube",              1, NULL},
2096 {       0, "Circle",    2, NULL},
2097 {       0, "UVsphere",  3, NULL},
2098 {       0, "Icosphere", 4, NULL},
2099 {       0, "Cylinder",  5, NULL},
2100 {       0, "Tube",              6, NULL},
2101 {       0, "Cone",              7, NULL},
2102 {       0, "SEPR",              0, NULL},
2103 {       0, "Grid",              8, NULL},
2104 {       0, "Monkey",    9, NULL},
2105 {  -1, "",                      0, do_info_add_meshmenu}};
2106
2107 static TBitem addmenu_curve[]= {
2108 {       0, "Bezier Curve",      0, NULL},
2109 {       0, "Bezier Circle", 1, NULL},
2110 {       0, "NURBS Curve",       2, NULL},
2111 {       0, "NURBS Circle",      3, NULL},
2112 {       0, "Path",                      4, NULL},
2113 {  -1, "",                      0, do_info_add_curvemenu}};
2114
2115 static TBitem addmenu_surf[]= {
2116 {       0, "NURBS Curve",       0, NULL},
2117 {       0, "NURBS Circle",      1, NULL},
2118 {       0, "NURBS Surface", 2, NULL},
2119 {       0, "NURBS Tube",        3, NULL},
2120 {       0, "NURBS Sphere",      4, NULL},
2121 {       0, "NURBS Donut",       5, NULL},
2122 {  -1, "",                      0, do_info_add_surfacemenu}};
2123
2124 static TBitem addmenu_meta[]= {
2125 {       0, "Meta Ball",         0, NULL},
2126 {       0, "Meta Tube",         1, NULL},
2127 {       0, "Meta Plane",        2, NULL},
2128 {       0, "Meta Ellipsoid", 3, NULL},
2129 {       0, "Meta Cube",         4, NULL},
2130 {  -1, "",                      0, do_info_add_metamenu}};
2131
2132 static TBitem addmenu_lamp[]= {
2133 {       0, "Lamp",      0, NULL},
2134 {       0, "Sun",       1, NULL},
2135 {       0, "Spot",      2, NULL},
2136 {       0, "Hemi", 3, NULL},
2137 {       0, "Area",      4, NULL},
2138 {  -1, "",                      0, do_info_add_lampmenu}};
2139
2140 static TBitem addmenu_YF_lamp[]= {
2141 {       0, "Lamp",      0, NULL},
2142 {       0, "Sun",       1, NULL},
2143 {       0, "Spot",      2, NULL},
2144 {       0, "Hemi", 3, NULL},
2145 {       0, "Area",      4, NULL},
2146 {       0, "Photon",    5, NULL},
2147 {  -1, "",                      0, do_info_add_lampmenu}};
2148
2149
2150 static TBitem addmenu_armature[]= {
2151 {       0, "Bones",     8, NULL},
2152 {  -1, "",                      0, do_info_addmenu}};
2153
2154 static TBitem tb_add[]= {
2155 {       0, "Mesh",              0, addmenu_mesh},
2156 {       0, "Curve",     1, addmenu_curve},
2157 {       0, "Surface",   2, addmenu_surf},
2158 {       0, "Meta",      3, addmenu_meta},
2159 {       0, "Text",              4, NULL},
2160 {       0, "Empty",     5, NULL},
2161 {       0, "SEPR",              0, NULL},
2162 {       0, "Camera",    6, NULL},
2163 {       0, "Lamp",              7, addmenu_lamp},
2164 {       0, "SEPR",              0, NULL},
2165 {       0, "Armature",  8, NULL},
2166 {       0, "Lattice",   9, NULL},
2167 {  -1, "",                      0, do_info_addmenu}};
2168
2169 static TBitem tb_add_YF[]= {
2170 {       0, "Mesh",              0, addmenu_mesh},
2171 {       0, "Curve",     1, addmenu_curve},
2172 {       0, "Surface",   2, addmenu_surf},
2173 {       0, "Meta",      3, addmenu_meta},
2174 {       0, "Text",              4, NULL},
2175 {       0, "Empty",     5, NULL},
2176 {       0, "SEPR",              0, NULL},
2177 {       0, "Camera",    6, NULL},
2178 {       0, "Lamp",              7, addmenu_YF_lamp},
2179 {       0, "SEPR",              0, NULL},
2180 {       0, "Armature",  8, NULL},
2181 {       0, "Lattice",   9, NULL},
2182 {  -1, "",                      0, do_info_addmenu}};
2183
2184 static TBitem tb_empty[]= {
2185 {       0, "Nothing...",        0, NULL},
2186 {  -1, "",              0, NULL}};
2187
2188
2189
2190 static uiBlock *tb_makemenu(void *arg)
2191 {
2192         static int counter=0;
2193         TBitem *item= arg, *itemt;
2194         uiBlock *block;
2195         int yco= 0;
2196         char str[10];
2197         
2198         if(arg==NULL) return NULL;
2199         
2200         sprintf(str, "tb %d", counter++);
2201         block= uiNewBlock(&tb_listb, str, UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
2202         uiBlockSetCol(block, TH_MENU_ITEM);
2203
2204         // last item has do_menu func, has to be stored in each button
2205         itemt= item;
2206         while(itemt->icon != -1) itemt++;
2207         uiBlockSetButmFunc(block, itemt->poin, NULL);
2208
2209         // now make the buttons
2210         while(item->icon != -1) {
2211
2212                 if(strcmp(item->name, "SEPR")==0) {
2213                         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 50, 6, NULL, 0.0, 0.0, 0, 0, "");
2214                 }
2215                 else if(item->icon) {
2216                         uiDefIconTextBut(block, BUTM, 1, item->icon, item->name, 0, yco-=20, 80, 19, NULL, 0.0, 0.0, 0, item->retval, "");
2217                 }
2218                 else if(item->poin) {
2219                         uiDefIconTextBlockBut(block, tb_makemenu, item->poin, ICON_RIGHTARROW_THIN, item->name, 0, yco-=20, 80, 19, "");
2220                 }
2221                 else {
2222                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, item->name, 0, yco-=20, 80, 19, NULL, 0.0, 0.0, 0, item->retval, "");
2223                 }
2224                 item++;
2225         }
2226         uiTextBoundsBlock(block, 60);
2227         
2228         /* direction is also set in the function that calls this */
2229         uiBlockSetDirection(block, UI_RIGHT|UI_CENTRE);
2230
2231         return block;
2232 }
2233
2234 static int tb_mainx= 0, tb_mainy= -5;
2235 static void store_main(void *arg1, void *arg2)
2236 {
2237         tb_mainx= (int)arg1;
2238         tb_mainy= (int)arg2;
2239 }
2240
2241 void toolbox_n(void)
2242 {
2243         uiBlock *block;
2244         uiBut *but;
2245         TBitem *menu1=NULL, *menu2=NULL, *menu3=NULL; 
2246         TBitem *menu4=NULL, *menu5=NULL, *menu6=NULL;
2247         int dx;
2248         short event, mval[2], tot=0;
2249         char *str1=NULL, *str2=NULL, *str3=NULL, *str4=NULL, *str5=NULL, *str6=NULL;
2250         
2251         mywinset(G.curscreen->mainwin); // we go to screenspace
2252         
2253         block= uiNewBlock(&tb_listb, "toolbox", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
2254         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
2255         uiBlockSetCol(block, TH_MENU_ITEM);
2256         
2257         dx= 64;
2258         
2259         /* select context for main items */
2260         if(curarea->spacetype==SPACE_VIEW3D) {
2261                 /* standard menu */
2262                 menu1= tb_object; str1= "Object";
2263                 if (G.scene->r.renderer==R_YAFRAY) {
2264                         menu2= tb_add_YF; str2= "Add";
2265                 } else {
2266                         menu2= tb_add; str2= "Add";
2267                 }
2268                 menu3= tb_object_select; str3= "Select";
2269                 menu4= tb_object_edit; str4= "Edit";
2270                 menu5= tb_transform; str5= "Transform";
2271                 menu6= tb_view; str6= "View";
2272                 
2273                 if(G.obedit) {
2274                         if(G.obedit->type==OB_MESH) {
2275                                 menu1= tb_mesh; str1= "Mesh";
2276                                 menu2= addmenu_mesh; 
2277                                 menu3= tb_mesh_select;
2278                                 menu4= tb_mesh_edit; 
2279                                 menu5= tb_transform_editmode1;
2280                         }
2281                         else if(G.obedit->type==OB_CURVE) {
2282                                 menu1= tb_curve; str1= "Curve";
2283                                 menu2= addmenu_curve;
2284                                 menu3= tb_curve_select;
2285                                 menu4= tb_curve_edit;
2286                                 menu5= tb_transform_editmode1;
2287                         }
2288                         else if(G.obedit->type==OB_SURF) {
2289                                 menu1= tb_curve; str1= "Surface";
2290                                 menu2= addmenu_surf; 
2291                                 menu3= tb_curve_select;
2292                                 menu4= tb_curve_edit;
2293                                 menu5= tb_transform_editmode1;
2294                         }
2295                         else if(G.obedit->type==OB_MBALL) {
2296                                 menu1= tb_obdata; str1= "Meta";
2297                                 menu2= addmenu_meta;
2298                                 menu3= tb__select;
2299                                 menu4= tb_edit;
2300                                 menu5= tb_transform_editmode2;
2301                         }
2302                         else if(G.obedit->type==OB_ARMATURE) {
2303                                 menu1= tb_obdata;str1= "Armature";
2304                                 menu2= addmenu_armature;
2305                                 menu3= tb__select;
2306                                 menu4= tb_edit;
2307                                 menu5= tb_transform_editmode2;
2308                         }
2309                         else if(G.obedit->type==OB_LATTICE) {
2310                                 menu1= tb_empty;str1= "Lattice";
2311                                 menu2= tb_empty;
2312                                 menu3= tb__select;
2313                                 menu4= tb_edit;
2314                                 menu5= tb_transform_editmode1;
2315                         }
2316                         
2317                 }
2318                 else {
2319                 }
2320                 tot= 6;
2321         }
2322         
2323         getmouseco_sc(mval);
2324         
2325         /* create the main buttons menu */
2326         if(tot==6) {
2327         
2328                 /* check if it fits */
2329                 if(mval[0]-1.5*dx+tb_mainx < 6) mval[0]= 6 + 1.5*dx -tb_mainx;
2330                 else if(mval[0]+1.5*dx+tb_mainx > G.curscreen->sizex-6) 
2331                         mval[0]= G.curscreen->sizex-6-1.5*dx-tb_mainx;
2332
2333                 if(mval[1]-20+tb_mainy < 6) mval[1]= 6+20 -tb_mainy;
2334                 else if(mval[1]+20+tb_mainy > G.curscreen->sizey-6) 
2335                         mval[1]= G.curscreen->sizey-6-20-tb_mainy;
2336         
2337                 but=uiDefBlockBut(block, tb_makemenu, menu1, str1,      mval[0]-(1.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
2338                 uiButSetFlag(but, UI_MAKE_TOP|UI_MAKE_RIGHT);
2339                 uiButSetFunc(but, store_main, (void *)dx, (void *)-5);
2340
2341                 but=uiDefBlockBut(block, tb_makemenu, menu2, str2,      mval[0]-(0.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
2342                 uiButSetFlag(but, UI_MAKE_TOP);
2343                 uiButSetFunc(but, store_main, (void *)0, (void *)-5);
2344
2345                 but=uiDefBlockBut(block, tb_makemenu, menu3, str3,      mval[0]+(0.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
2346                 uiButSetFlag(but, UI_MAKE_TOP|UI_MAKE_LEFT);
2347                 uiButSetFunc(but, store_main, (void *)-dx, (void *)-5);
2348
2349                 but=uiDefBlockBut(block, tb_makemenu, menu4, str4,      mval[0]-(1.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
2350                 uiButSetFlag(but, UI_MAKE_DOWN|UI_MAKE_RIGHT);
2351                 uiButSetFunc(but, store_main, (void *)dx, (void *)5);
2352
2353                 but=uiDefBlockBut(block, tb_makemenu, menu5, str5,      mval[0]-(0.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
2354                 uiButSetFlag(but, UI_MAKE_DOWN);
2355                 uiButSetFunc(but, store_main, (void *)0, (void *)5);
2356
2357                 but=uiDefBlockBut(block, tb_makemenu, menu6, str6,      mval[0]+(0.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
2358                 uiButSetFlag(but, UI_MAKE_DOWN|UI_MAKE_LEFT);
2359                 uiButSetFunc(but, store_main, (void *)-dx, (void *)5);
2360         }
2361         
2362         uiBoundsBlock(block, 2);
2363         event= uiDoBlocks(&tb_listb, 0);
2364         
2365         mywinset(curarea->win);
2366 }
2367
2368 void toolbox_n_add(void)
2369 {
2370         tb_mainx= 0;
2371         tb_mainy= -5;
2372         toolbox_n();
2373 }