A couple of render improvements;
[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 #endif   
50
51 #include <fcntl.h>
52 #include "MEM_guardedalloc.h"
53
54 #include "BMF_Api.h"
55 #include "BIF_language.h"
56 #include "BIF_resources.h"
57
58 #include "DNA_group_types.h"
59 #include "DNA_image_types.h"
60 #include "DNA_lamp_types.h"
61 #include "DNA_mesh_types.h"
62 #include "DNA_node_types.h"
63 #include "DNA_object_types.h"
64 #include "DNA_screen_types.h"
65 #include "DNA_space_types.h"
66 #include "DNA_scene_types.h"
67 #include "DNA_userdef_types.h"
68 #include "DNA_view3d_types.h"
69
70 #include "BLI_blenlib.h"
71 #include "BLI_arithb.h"
72
73 #include "BKE_displist.h"
74 #include "BKE_depsgraph.h"
75 #include "BKE_global.h"
76 #include "BKE_library.h"
77 #include "BKE_mesh.h"
78 #include "BKE_node.h"
79 #include "BKE_main.h"
80 #include "BKE_plugin_types.h"
81 #include "BKE_utildefines.h"
82
83 #include "BIF_editnla.h"
84 #include "BIF_editarmature.h"
85 #include "BIF_editdeform.h"
86 #include "BIF_editfont.h"
87 #include "BIF_editmesh.h"
88 #include "BIF_editseq.h"
89 #include "BIF_editlattice.h"
90 #include "BIF_editsima.h"
91 #include "BIF_editoops.h"
92 #include "BIF_editview.h"
93 #include "BIF_gl.h"
94 #include "BIF_graphics.h"
95 #include "BIF_imasel.h"
96 #include "BIF_interface.h"
97 #include "BIF_mainqueue.h"
98 #include "BIF_mywindow.h"
99 #include "BIF_renderwin.h"
100 #include "BIF_screen.h"
101 #include "BIF_space.h"
102 #include "BIF_toolbox.h"
103 #include "BIF_tbcallback.h"
104 #include "BIF_transform.h"
105
106 #include "BDR_editobject.h"
107 #include "BDR_editcurve.h"
108 #include "BDR_editmball.h"
109
110 #include "BSE_drawipo.h"
111 #include "BSE_edit.h"
112 #include "BSE_editipo.h"
113 #include "BSE_filesel.h"
114 #include "BSE_headerbuttons.h"
115 #include "BSE_node.h"
116
117 #include "IMB_imbuf.h"
118
119 #include "blendef.h"
120 #include "butspace.h"
121 #include "mydevice.h"
122
123 void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
124 {
125         if( isalpha(ch)==0 ) return;
126         
127         if( isupper(ch) ) {
128                 *qual= LEFTSHIFTKEY;
129                 ch= tolower(ch);
130         }
131         
132         switch(ch) {
133         case 'a': *event= AKEY; break;
134         case 'b': *event= BKEY; break;
135         case 'c': *event= CKEY; break;
136         case 'd': *event= DKEY; break;
137         case 'e': *event= EKEY; break;
138         case 'f': *event= FKEY; break;
139         case 'g': *event= GKEY; break;
140         case 'h': *event= HKEY; break;
141         case 'i': *event= IKEY; break;
142         case 'j': *event= JKEY; break;
143         case 'k': *event= KKEY; break;
144         case 'l': *event= LKEY; break;
145         case 'm': *event= MKEY; break;
146         case 'n': *event= NKEY; break;
147         case 'o': *event= OKEY; break;
148         case 'p': *event= PKEY; break;
149         case 'q': *event= QKEY; break;
150         case 'r': *event= RKEY; break;
151         case 's': *event= SKEY; break;
152         case 't': *event= TKEY; break;
153         case 'u': *event= UKEY; break;
154         case 'v': *event= VKEY; break;
155         case 'w': *event= WKEY; break;
156         case 'x': *event= XKEY; break;
157         case 'y': *event= YKEY; break;
158         case 'z': *event= ZKEY; break;
159         }
160 }
161
162 /* ************************************  */
163
164 /* this va_ stuff allows printf() style codes in these menus */
165
166 static int vconfirm(char *title, char *itemfmt, va_list ap)
167 {
168         char *s, buf[512];
169
170         s= buf;
171         if (title) s+= sprintf(s, "%s%%t|", title);
172         vsprintf(s, itemfmt, ap);
173         
174         return (pupmenu(buf)>=0);
175 }
176
177 static int confirm(char *title, char *itemfmt, ...)
178 {
179         va_list ap;
180         int ret;
181         
182         va_start(ap, itemfmt);
183         ret= vconfirm(title, itemfmt, ap);
184         va_end(ap);
185         
186         return ret;
187 }
188
189 int okee(char *str, ...)
190 {
191         va_list ap;
192         int ret;
193         char titlestr[256];
194         
195         sprintf(titlestr, "OK? %%i%d", ICON_HELP);
196         
197         va_start(ap, str);
198         ret= vconfirm(titlestr, str, ap);
199         va_end(ap);
200         
201         return ret;
202 }
203
204 void notice(char *str, ...)
205 {
206         va_list ap;
207         
208         va_start(ap, str);
209         vconfirm(NULL, str, ap);
210         va_end(ap);
211 }
212
213 void error(char *fmt, ...)
214 {
215         va_list ap;
216         char nfmt[256];
217         char titlestr[256];
218         
219         sprintf(titlestr, "Error %%i%d", ICON_ERROR);
220         
221         sprintf(nfmt, "%s", fmt);
222         
223         va_start(ap, fmt);
224         if (G.background || !G.curscreen) {
225                 vprintf(nfmt, ap);
226                 printf("\n");
227         } else {
228                 vconfirm(titlestr, nfmt, ap);
229         }
230         va_end(ap);
231 }
232
233 int saveover(char *file)
234 {
235         return (!BLI_exists(file) || confirm("Save over", file));
236 }
237
238 /* ****************** EXTRA STUFF **************** */
239
240 short button(short *var, short min, short max, char *str)
241 {
242         uiBlock *block;
243         ListBase listb={0, 0};
244         short x1,y1;
245         short mval[2], ret=0;
246
247         if(min>max) min= max;
248
249         getmouseco_sc(mval);
250         
251         if(mval[0]<150) mval[0]=150;
252         if(mval[1]<30) mval[1]=30;
253         if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10;
254         if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10;
255
256         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
257         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK);
258
259         x1=mval[0]-150; 
260         y1=mval[1]-20; 
261         
262         uiDefButS(block, NUM, 0, str,   (short)(x1+5),(short)(y1+10),125,20, var,(float)min,(float)max, 0, 0, "");
263         uiDefBut(block, BUT, 1, "OK",   (short)(x1+136),(short)(y1+10),25,20, NULL, 0, 0, 0, 0, "");
264
265         uiBoundsBlock(block, 5);
266
267         ret= uiDoBlocks(&listb, 0);
268
269         if(ret==UI_RETURN_OK) return 1;
270         return 0;
271 }
272
273 short sbutton(char *var, float min, float max, char *str)
274 {
275         uiBlock *block;
276         ListBase listb={0, 0};
277         short x1,y1;
278         short mval[2], ret=0;
279
280         if(min>max) min= max;
281
282         getmouseco_sc(mval);
283         
284         if(mval[0]<150) mval[0]=150;
285         if(mval[1]<30) mval[1]=30;
286         if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10;
287         if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10;
288
289         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
290         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK);
291
292         x1=mval[0]-150; 
293         y1=mval[1]-20; 
294         
295         uiDefButC(block, TEX, 0, str,   x1+5,y1+10,125,20, var,(float)min,(float)max, 0, 0, "");
296         uiDefBut(block, BUT, 1, "OK",   x1+136,y1+10,25,20, NULL, 0, 0, 0, 0, "");
297
298         uiBoundsBlock(block, 5);
299
300         ret= uiDoBlocks(&listb, 0);
301
302         if(ret==UI_RETURN_OK) return 1;
303         return 0;
304 }
305
306 short fbutton(float *var, float min, float max, float a1, float a2, char *str)
307 {
308         uiBlock *block;
309         ListBase listb={0, 0};
310         short x1,y1;
311         short mval[2], ret=0;
312
313         if(min>max) min= max;
314
315         getmouseco_sc(mval);
316         
317         if(mval[0]<150) mval[0]=150;
318         if(mval[1]<30) mval[1]=30;
319         if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10;
320         if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10;
321
322         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
323         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
324
325         x1=mval[0]-150; 
326         y1=mval[1]-20; 
327         
328         uiDefButF(block, NUM, 0, str,(short)(x1+5),(short)(y1+10),125,20, var, min, max, a1, a2, "");
329         uiDefBut(block, BUT, 1, "OK",(short)(x1+136),(short)(y1+10), 35, 20, NULL, 0, 0, 0, 0, "");
330
331         uiBoundsBlock(block, 2);
332
333         ret= uiDoBlocks(&listb, 0);
334
335         if(ret==UI_RETURN_OK) return 1;
336         return 0;
337 }
338
339 int movetolayer_buts(unsigned int *lay)
340 {
341         uiBlock *block;
342         ListBase listb={0, 0};
343         int dx, dy, a, x1, y1, sizex=160, sizey=30;
344         short pivot[2], mval[2], ret=0;
345         
346         if(G.vd->localview) {
347                 error("Not in localview ");
348                 return ret;
349         }
350
351         getmouseco_sc(mval);
352
353         pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30);
354         pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10);
355         
356         if (pivot[0]!=mval[0] || pivot[1]!=mval[1])
357                 warp_pointer(pivot[0], pivot[1]);
358
359         mywinset(G.curscreen->mainwin);
360         
361         x1= pivot[0]-sizex+10; 
362         y1= pivot[1]-sizey/2; 
363
364         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
365         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_ENTER_OK);
366         
367         dx= (sizex-5)/12;
368         dy= sizey/2;
369         
370         /* buttons have 0 as return event, to prevent menu to close on hotkeys */
371         
372         uiBlockBeginAlign(block);
373         for(a=0; a<5; a++) 
374                 uiDefButBitI(block, TOGR, 1<<a, 0, "",(short)(x1+a*dx),(short)(y1+dy),(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
375         for(a=0; a<5; a++) 
376                 uiDefButBitI(block, TOGR, 1<<(a+10), 0, "",(short)(x1+a*dx),(short)y1,(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
377         x1+= 5;
378         
379         uiBlockBeginAlign(block);
380         for(a=5; a<10; a++) 
381                 uiDefButBitI(block, TOGR, 1<<a, 0, "",(short)(x1+a*dx),(short)(y1+dy),(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
382         for(a=5; a<10; a++) 
383                 uiDefButBitI(block, TOGR, 1<<(a+10), 0, "",(short)(x1+a*dx),(short)y1,(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
384         uiBlockEndAlign(block);
385
386         x1-= 5;
387         uiDefBut(block, BUT, 1, "OK", (short)(x1+10*dx+10), (short)y1, (short)(3*dx), (short)(2*dy), NULL, 0, 0, 0, 0, "");
388
389         uiBoundsBlock(block, 2);
390
391         ret= uiDoBlocks(&listb, 0);
392
393         if(ret==UI_RETURN_OK) return 1;
394         return 0;
395 }
396
397 int movetolayer_short_buts(short *lay)
398 {
399         uiBlock *block;
400         ListBase listb={0, 0};
401         int dx, dy, a, x1, y1, sizex=120, sizey=30;
402         short pivot[2], mval[2], ret=0;
403         
404         getmouseco_sc(mval);
405         
406         pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30);
407         pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10);
408         
409         if (pivot[0]!=mval[0] || pivot[1]!=mval[1])
410                 warp_pointer(pivot[0], pivot[1]);
411         
412         mywinset(G.curscreen->mainwin);
413         
414         x1= pivot[0]-sizex+10; 
415         y1= pivot[1]-sizey/2; 
416         
417         block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
418         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_ENTER_OK);
419         
420         dx= (sizex-5)/10;
421         dy= sizey/2;
422         
423         /* buttons have 0 as return event, to prevent menu to close on hotkeys */
424         
425         uiBlockBeginAlign(block);
426         for(a=0; a<8; a++) 
427                 uiDefButBitS(block, TOGR, 1<<a, 0, "",(short)(x1+a*dx),(short)(y1+dy),(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
428         for(a=0; a<8; a++) 
429                 uiDefButBitS(block, TOGR, 1<<(a+8), 0, "",(short)(x1+a*dx),(short)y1,(short)dx,(short)dy, lay, 0, 0, 0, 0, "");
430         
431         uiBlockEndAlign(block);
432         
433         x1-= 5;
434         uiDefBut(block, BUT, 1, "OK", (short)(x1+8*dx+10), (short)y1, (short)(3*dx), (short)(2*dy), NULL, 0, 0, 0, 0, "");
435         
436         uiBoundsBlock(block, 2);
437         
438         ret= uiDoBlocks(&listb, 0);
439         
440         if(ret==UI_RETURN_OK) return 1;
441         return 0;
442 }
443
444
445 /* ********************** CLEVER_NUMBUTS ******************** */
446
447 #define MAXNUMBUTS      24
448
449 VarStruct numbuts[MAXNUMBUTS];
450 void *numbpoin[MAXNUMBUTS];
451 int numbdata[MAXNUMBUTS];
452
453 void draw_numbuts_tip(char *str, int x1, int y1, int x2, int y2)
454 {
455         static char *last=0;    /* avoid ugly updates! */
456         int temp;
457         
458         if(str==last) return;
459         last= str;
460         if(str==0) return;
461
462         glColor3ub(160, 160, 160); /* MGREY */
463         glRecti(x1+4,  y2-36,  x2-4,  y2-16);
464
465         cpack(0x0);
466
467         temp= 0;
468         while( BIF_GetStringWidth(G.fonts, str+temp, (U.transopts & USER_TR_BUTTONS))>(x2 - x1-24)) temp++;
469         glRasterPos2i(x1+16, y2-30);
470         BIF_DrawString(G.fonts, str+temp, (U.transopts & USER_TR_BUTTONS));
471 }
472
473 int do_clever_numbuts(char *name, int tot, int winevent)
474 {
475         ListBase listb= {NULL, NULL};
476         uiBlock *block;
477         VarStruct *varstr;
478         int a, sizex, sizey, x1, y2;
479         short mval[2], event;
480         
481         /* Clear all events so tooltips work, this is not ideal and
482         only needed because calls from the menu still have some events
483         left over when do_clever_numbuts is called.
484         Calls from keyshortcuts do not have this problem.*/
485         ScrArea *sa;
486         BWinEvent temp_bevt;
487         for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
488                 if(sa->win) {
489                         while( bwin_qread( sa->win, &temp_bevt ) ) {}
490                 }
491                 if(sa->headwin) {
492                         while( bwin_qread( sa->headwin, &temp_bevt ) ) {}
493                 }
494         }
495         /* Done clearing events */
496         
497         
498         if(tot<=0 || tot>MAXNUMBUTS) return 0;
499
500         getmouseco_sc(mval);
501
502         /* size */
503         sizex= 235;
504         sizey= 30+20*(tot+1);
505         
506         /* center */
507         if(mval[0]<sizex/2) mval[0]=sizex/2;
508         if(mval[1]<sizey/2) mval[1]=sizey/2;
509         if(mval[0]>G.curscreen->sizex -sizex/2) mval[0]= G.curscreen->sizex -sizex/2;
510         if(mval[1]>G.curscreen->sizey -sizey/2) mval[1]= G.curscreen->sizey -sizey/2;
511
512         mywinset(G.curscreen->mainwin);
513         
514         x1= mval[0]-sizex/2; 
515         y2= mval[1]+sizey/2;
516         
517         block= uiNewBlock(&listb, "numbuts", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
518         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK);
519         
520         /* WATCH IT: TEX BUTTON EXCEPTION */
521         /* WARNING: ONLY A SINGLE BIT-BUTTON POSSIBLE: WE WORK AT COPIED DATA! */
522         
523         BIF_ThemeColor(TH_MENU_TEXT); /* makes text readable on dark theme */
524         
525         uiDefBut(block, LABEL, 0, name, (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 1.0, 0.0, 0, 0, ""); 
526         
527         /*
528         if(name[0]=='A' && name[7]=='O') {
529                 y2 -= 20;
530                 uiDefBut(block, LABEL, 0, "Rotations in degrees!",      (short)(x1+15), (short)(y2-35), (short)(sizex-60), 19, 0, 0.0, 0.0, 0, 0, "");
531         }*/
532         
533         uiBlockBeginAlign(block);
534         varstr= &numbuts[0];
535         for(a=0; a<tot; a++, varstr++) {
536                 
537                 if(varstr->type==TEX) {
538                         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);
539                 }
540                 else  {
541                         
542                         if(varstr->type==LABEL) /* dont include the label when rounding the buttons */
543                                 uiBlockEndAlign(block);
544                         
545                         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);
546                         
547                         if(varstr->type==LABEL)
548                                 uiBlockBeginAlign(block);
549                 }
550
551                 
552         }
553         uiBlockEndAlign(block);
554
555         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");
556         
557         uiBoundsBlock(block, 5);
558
559         event= uiDoBlocks(&listb, 0);
560
561         areawinset(curarea->win);
562         
563         if(event & UI_RETURN_OK) {
564                 
565                 varstr= &numbuts[0];
566                 for(a=0; a<tot; a++, varstr++) {
567                         if(varstr->type==TEX);
568                         else if ELEM( (varstr->type & BUTPOIN), FLO, INT ) memcpy(numbpoin[a], numbdata+a, 4);
569                         else if((varstr->type & BUTPOIN)==SHO ) *((short *)(numbpoin[a]))= *( (short *)(numbdata+a));
570                         
571                         /*
572                         if( strncmp(varstr->name, "Rot", 3)==0 ) {
573                                 float *fp;
574                                 
575                                 fp= numbpoin[a];
576                                 fp[0]= M_PI*fp[0]/180.0;
577                         }*/
578                 }
579                 
580                 if(winevent) {
581                         ScrArea *sa;
582                 
583                         sa= G.curscreen->areabase.first;
584                         while(sa) {
585                                 if(sa->spacetype==curarea->spacetype) addqueue(sa->win, winevent, 1);
586                                 sa= sa->next;
587                         }
588                 }
589                 
590                 return 1;
591         }
592         return 0;
593 }
594
595 void add_numbut(int nr, int type, char *str, float min, float max, void *poin, char *tip)
596 {
597         if(nr>=MAXNUMBUTS) return;
598
599         numbuts[nr].type= type;
600         strcpy(numbuts[nr].name, str);
601         numbuts[nr].min= min;
602         numbuts[nr].max= max;
603         if(tip) 
604                 strcpy(numbuts[nr].tip, tip);
605         else
606                 strcpy(numbuts[nr].tip, "");
607         
608         
609         /*WATCH: TEX BUTTON EXCEPTION */
610         
611         numbpoin[nr]= poin;
612         
613         if ELEM( (type & BUTPOIN), FLO, INT ) memcpy(numbdata+nr, poin, 4);
614         if((type & BUTPOIN)==SHO ) *((short *)(numbdata+nr))= *( (short *)poin);
615         
616         /* if( strncmp(numbuts[nr].name, "Rot", 3)==0 ) {
617                 float *fp;
618                 
619                 fp= (float *)(numbdata+nr);
620                 fp[0]= 180.0*fp[0]/M_PI;
621         } */
622
623 }
624
625 void clever_numbuts(void)
626 {
627         
628         if(curarea->spacetype==SPACE_VIEW3D) {
629                 // panel now
630         }
631         else if(curarea->spacetype==SPACE_NLA){
632                 // panel now
633         }
634         else if(curarea->spacetype==SPACE_IPO) {
635                 // panel now
636         }
637         else if(curarea->spacetype==SPACE_SEQ) {
638                 // panel now
639         }
640         else if(curarea->spacetype==SPACE_IMAGE) {
641                 // panel now
642         }
643         else if(curarea->spacetype==SPACE_IMASEL) {
644                 clever_numbuts_imasel();
645         }
646         else if(curarea->spacetype==SPACE_OOPS) {
647                 clever_numbuts_oops();
648         }
649         else if(curarea->spacetype==SPACE_ACTION){
650                 // in its own queue
651         }
652         else if(curarea->spacetype==SPACE_FILE) {
653                 clever_numbuts_filesel();
654         }
655 }
656
657
658 void replace_names_but(void)
659 {
660         Image *ima= G.main->image.first;
661         short len, tot=0;
662         char old[64], new[64], temp[80];
663         
664         strcpy(old, "/");
665         strcpy(new, "/");
666         
667         add_numbut(0, TEX, "Old:", 0, 63, old, 0);
668         add_numbut(1, TEX, "New:", 0, 63, new, 0);
669
670         if (do_clever_numbuts("Replace image name", 2, REDRAW) ) {
671                 
672                 len= strlen(old);
673                 
674                 while(ima) {
675                         
676                         if(strncmp(old, ima->name, len)==0) {
677                                 
678                                 strcpy(temp, new);
679                                 strcat(temp, ima->name+len);
680                                 BLI_strncpy(ima->name, temp, sizeof(ima->name));
681                                 
682                                 if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
683                                 ima->ibuf= 0;
684                                 ima->ok= 1;
685                                 
686                                 tot++;
687                         }
688                         
689                         ima= ima->id.next;
690                 }
691
692                 notice("Replaced %d names", tot);
693         }
694         
695 }
696
697
698 /* ********************** NEW TOOLBOX ********************** */
699
700 ListBase tb_listb= {NULL, NULL};
701
702 #define TB_TAB  256
703 #define TB_ALT  512
704 #define TB_CTRL 1024
705 #define TB_PAD  2048
706 #define TB_SHIFT 4096
707
708 typedef struct TBitem {
709         int icon;
710         char *name;
711         int retval;
712         void *poin;
713 } TBitem;
714
715 static void tb_do_hotkey(void *arg, int event)
716 {
717         unsigned short i, key=0;
718         unsigned short qual[] = { 0,0,0,0 };
719         
720         if(event & TB_CTRL) {
721                 qual[0] = LEFTCTRLKEY;
722                 event &= ~TB_CTRL;
723         }
724         if(event & TB_ALT) {
725                 qual[1] = LEFTALTKEY;
726                 event &= ~TB_ALT;
727         }
728         if(event & TB_SHIFT) {
729                 qual[2] = LEFTSHIFTKEY;
730                 event &= ~TB_SHIFT;
731         }
732         
733         if(event & TB_TAB) key= TABKEY;
734         else if(event & TB_PAD) {
735                 event &= ~TB_PAD;
736                 switch(event) {
737                 case '-': key= PADMINUS; break;
738                 case '+': key= PADPLUSKEY; break;
739                 case '0': key= PAD0; break;
740                 case '5': key= PAD5; break;
741                 case '/': key= PADSLASHKEY; break;
742                 case '.': key= PADPERIOD; break;
743                 case '*': key= PADASTERKEY; break;
744                 case 'h': key= HOMEKEY; break;
745                 case 'u': key= PAGEUPKEY; break;
746                 case 'd': key= PAGEDOWNKEY; break;
747                 }
748         }
749         else asciitoraw(event, &key, &qual[3]);
750
751         for (i=0;i<4;i++)
752         {
753                 if(qual[i]) mainqenter(qual[i], 1);
754         }
755         mainqenter(key, 1);
756         mainqenter(key, 0);
757         mainqenter(EXECUTE, 1);
758
759         for (i=0;i<4;i++)
760         {
761                 if(qual[i]) mainqenter(qual[i], 0);
762         }
763 }
764
765 /* *************Select ********** */
766
767 static TBitem tb_object_select_layer1_5[]= {
768 {       0, "1",         1, NULL},
769 {       0, "2",         2, NULL},
770 {       0, "3",         3, NULL},
771 {       0, "4",         4, NULL},
772 {       0, "5",         5, NULL},
773 {  -1, "",              0, do_view3d_select_object_layermenu}};
774
775 static TBitem tb_object_select_layer6_10[]= {
776 {       0, "6",         6, NULL},
777 {       0, "7",         7, NULL},
778 {       0, "8",         8, NULL},
779 {       0, "9",         9, NULL},
780 {       0, "10",        10, NULL},
781 {  -1, "",              0, do_view3d_select_object_layermenu}};
782
783 static TBitem tb_object_select_layer11_15[]= {
784 {       0, "11",        11, NULL},
785 {       0, "12",        12, NULL},
786 {       0, "13",        13, NULL},
787 {       0, "14",        14, NULL},
788 {       0, "15",        15, NULL},
789 {  -1, "",              0, do_view3d_select_object_layermenu}};
790
791 static TBitem tb_object_select_layer16_20[]= {
792 {       0, "16",        16, NULL},
793 {       0, "17",        17, NULL},
794 {       0, "18",        18, NULL},
795 {       0, "19",        19, NULL},
796 {       0, "20",        20, NULL},
797 {  -1, "",              0, do_view3d_select_object_layermenu}};
798
799 static TBitem tb_object_select_layer[]= {
800 {       0, "Layers 1-5",        0,              tb_object_select_layer1_5},
801 {       0, "Layers 6-10",       0,              tb_object_select_layer6_10},
802 {       0, "Layers 11-15",      0,              tb_object_select_layer11_15},
803 {       0, "Layers 16-20",      0,              tb_object_select_layer16_20},
804 {  -1, "",                      0, tb_do_hotkey}};
805
806 static TBitem tb_object_select_type[]= {
807 {       0, "Mesh",              1, NULL},
808 {       0, "Curve",     2, NULL},
809 {       0, "Surface",   3, NULL},
810 {       0, "Meta",              4, NULL},
811 {       0, "SEPR",              0, NULL},
812 {       0, "Armature",  5, NULL},
813 {       0, "Lattice",   6, NULL},
814 {       0, "Text",              7, NULL},
815 {       0, "Empty",     8, NULL},
816 {       0, "SEPR",              0, NULL},
817 {       0, "Camera",    9, NULL},
818 {       0, "Lamp",              10, NULL},
819 {  -1, "",                      0, do_view3d_select_object_typemenu}};
820
821 static TBitem tb_object_select_linked[]= {
822 {       0, "Object Ipo|Shift L, 1",     1, NULL},
823 {       0, "ObData|Shift L, 2",         2, NULL},
824 {       0, "Material|Shift L, 3",       3, NULL},
825 {       0, "Texture|Shift L, 4",        4, NULL},
826 {  -1, "",                      0, do_view3d_select_object_linkedmenu}};
827
828 static TBitem tb_object_select_grouped[]= {
829 {       0, "Children|Shift G, 1",       1, NULL},
830 {       0, "Immediate Children|Shift G, 2",     2, NULL},
831 {       0, "Parent|Shift G, 3",         3, NULL},
832 {       0, "Objects on Shared Layers|Shift G, 4",       4, NULL},
833 {  -1, "",                      0, do_view3d_select_object_groupedmenu}};
834
835 static TBitem tb_object_select[]= {
836 {       0, "Border Select|B",   0, NULL},
837 {       0, "SEPR",                              0, NULL},
838 {       0, "Select/Deselect All|A",     1, NULL},
839 {       0, "Inverse",                   2, NULL},
840 {       0, "Select All by Layer",       0,              tb_object_select_layer},
841 {       0, "Select All by Type",        0,              tb_object_select_type},
842 {       0, "SEPR",                              0, NULL},
843 {       0, "Linked",    0,      tb_object_select_linked},
844 {       0, "Grouped",   0,      tb_object_select_grouped},
845 {  -1, "",                      0, do_view3d_select_objectmenu}};
846
847 static TBitem tb_mesh_select[]= {
848 {       0, "Border Select|B",               0, NULL},
849 {       0, "SEPR",                          0, NULL},
850 {       0, "(De)select All|A",              2, NULL},
851 {       0, "Inverse",                       3, NULL},
852 {       0, "SEPR",                          0, NULL},
853 {       0, "Random...",                             5, NULL},
854 {       0, "Non-Manifold|Shift Ctrl Alt M", 9, NULL},
855 {       0, "Sharp Edges|Shift Ctrl Alt S", 14, NULL},
856 {       0, "Linked Flat Faces|Shift Ctrl Alt F", 15, NULL},
857 {       0, "Triangles|Shift Ctrl Alt 3",    11, NULL},
858 {       0, "Quads|Shift Ctrl Alt 4",        12, NULL},
859 {       0, "Non-Triangles/Quads|Shift Ctrl Alt 5", 13, NULL},
860 {       0, "SEPR",                          0, NULL},
861 {       0, "More|Ctrl NumPad +",            7, NULL},
862 {       0, "Less|Ctrl NumPad -",            8, NULL},
863 {       0, "SEPR",                          0, NULL},
864 {       0, "Linked Vertices|Ctrl L",        4, NULL},
865 {  -1, "",                      0, do_view3d_select_meshmenu}};
866
867
868 static TBitem tb_curve_select[]= {
869 {       0, "Border Select|B",   0, NULL},
870 {       0, "SEPR",                              0, NULL},
871 {       0, "(De)select All|A",  2, NULL},
872 {       0, "Inverse",                   3, NULL},
873 {       0, "Row|Shift R",                       5, NULL},
874 {  -1, "",                              0, do_view3d_select_curvemenu}};
875
876 static TBitem tb__select[]= {
877 {       0, "Border Select|B",   'b', NULL},
878 {       0, "(De)select All|A",  'a', NULL},
879 {  -1, "",                      0, tb_do_hotkey}};
880
881
882 /* *************Edit ********** */
883
884 static TBitem tb_edit[]= {
885 {       0, "Exit Editmode|Tab",         TB_TAB, NULL},
886 {  -1, "",                      0, tb_do_hotkey}};
887
888 static TBitem tb_curve_edit_seg[]= {
889 {       0, "Subdivide|W, 1",            0, NULL},
890 {       0, "Switch Direction|W, 2",     1, NULL},
891 {  -1, "",                      0, do_view3d_edit_curve_segmentsmenu}};
892
893 static TBitem tb_curve_edit_cv[]= {
894 {       0, "Tilt|T",    't', NULL},
895 {       0, "Clear Tilt|Alt T",                  TB_ALT|'t', NULL},
896 {       0, "Separate|P",        'p', NULL},
897 {       0, "SEPR",                                                              0, NULL},
898 {       0, "Automatic|Shift H",                 'H', NULL},
899 {       0, "Toggle Free/Aligned|H",     'h', NULL},
900 {       0, "Vector|V",                                  'v', NULL},
901 {       0, "SEPR",                                                              0, NULL},
902 {       0, "Make Vertex Parent|Ctrl P", TB_CTRL|'p', NULL},
903 {       0, "Add Hook|Ctrl H",                   TB_CTRL|'h', NULL},
904 {  -1, "",                      0, tb_do_hotkey}};
905
906
907 static TBitem tb_curve_edit[]= {
908 {       0, "Exit Editmode|Tab",         TB_TAB, NULL},
909 {       0, "SEPR",                                                              0, NULL},
910 {       0, "Extrude|E",                 'e',            NULL},
911 {       0, "Duplicate|Shift D", 'D',            NULL},
912 {       0, "Make Segment|F",    'f',            NULL},
913 {       0, "Toggle Cyclic|C",   'c',            NULL},
914 {       0, "Delete...|X",               'x',            NULL},
915 {       0, "SEPR",                                                              0, NULL},
916 {       0, "Control Points",    0,              tb_curve_edit_cv},
917 {       0, "Segments",  0,              tb_curve_edit_seg},
918 {  -1, "",                      0, tb_do_hotkey}};
919
920
921 static TBitem tb_mesh_edit_vertex[]= {
922 {       0, "Merge...|Alt M",            5, NULL},
923 {       0, "Rip|V",                                     7, NULL},
924 {       0, "Split|Y",                           4,              NULL},
925 {       0, "Separate|P",                        3,              NULL},
926 {       0, "SEPR",                                      0, NULL},
927 {       0, "Smooth|W, Alt 1",                   2, NULL},
928 {       0, "Remove Doubles|W, 5",                       1, NULL},
929 {       0, "SEPR",                                      0, NULL},
930 {       0, "Make Vertex Parent|Ctrl P",         0, NULL},
931 {       0, "Add Hook|Ctrl H",           6, NULL},
932 {  -1, "",                      0, do_view3d_edit_mesh_verticesmenu}};
933
934 static TBitem tb_mesh_edit_edge[]= {
935 {       0, "Make Edge/Face|F",                  5,              NULL},
936 {       0, "SEPR",                                              0, NULL},
937 {       0, "Bevel|W, Alt 2",                                    6,              NULL},
938 {       0, "Loop Subdivide|Ctrl R",             4,              NULL},
939 {       0, "Knife Subdivide...|Shift K",        3,              NULL},
940 {       0, "SEPR",                                                              0, NULL},
941 {       0, "Subdivide|W, 1",                    2,              NULL},
942 {       0, "Subdivide Fractal|W, 2",    1,              NULL},
943 {       0, "Subdivide Smooth|W, 3",             0,              NULL},
944 {       0, "SEPR",                                                              0, NULL},
945 {       0, "Mark Seam|Ctrl E",                  7,              NULL},
946 {       0, "Clear Seam|Ctrl E",                 8,              NULL},
947 {       0, "SEPR",                                                              0, NULL},
948 {       0, "Crease SubSurf|Shift E",    9,              NULL},
949 {       0, "SEPR",                                                              0, NULL},
950 {       0, "Rotate Edge CW|Ctrl E",     10,             NULL},
951 {       0, "Rotate Edge CCW|Ctrl E",    11,             NULL},
952 {       0, "SEPR",                                                              0, NULL},
953 {       0, "Slide Edge|Ctrl E", 12,             NULL},
954 {       0, "Delete Edge Loop|X",        13,             NULL},
955 {  -1, "",                      0, do_view3d_edit_mesh_edgesmenu}};
956
957 static TBitem tb_mesh_edit_face[]= {
958 {       0, "Make Edge/Face|F",                  5,              NULL},
959 {       0, "Fill|Shift F",                              0,              NULL},
960 {       0, "Beautify Fill|Alt F",                       1,              NULL},
961 {       0, "SEPR",                                      0, NULL},
962 {       0, "Convert to Triangles|Ctrl T",       2,              NULL},
963 {       0, "Convert to Quads|Alt J",            3,              NULL},
964 {       0, "Flip Triangle Edges|Ctrl F",        4,              NULL},
965 {       0, "Set Smooth|W, Alt 3",       6,              NULL},
966 {       0, "Set Solid|W, Alt 4",        7,              NULL},
967 {  -1, "",                      0, do_view3d_edit_mesh_facesmenu}};
968
969
970 static TBitem tb_mesh_edit_normal[]= {
971 {       0, "Recalculate Outside|Ctrl N",        2,              NULL},
972 {       0, "Recalculate Inside|Ctrl Shift N",   1,              NULL},
973 {       0, "SEPR",                                      0, NULL},
974 {       0, "Flip|W, 9",                                 0,              NULL},
975 {  -1, "",                      0, do_view3d_edit_mesh_normalsmenu}};
976
977 static TBitem tb_mesh_edit[]= {
978 {       0, "Exit Editmode|Tab",         TB_TAB, NULL},
979 {       0, "Undo|U",                    'u',            NULL},
980 {       0, "Redo|Shift U",              'U',            NULL},
981 {       0, "SEPR",                              0,                      NULL},
982 {       0, "Extrude|E",                 'e',            NULL},
983 {       0, "Duplicate|Shift D", 'D',            NULL},
984 {       0, "Delete...|X",               'x',            NULL},
985 {       0, "SEPR",                              0,                      NULL},
986 {       0, "Vertices",          0,              tb_mesh_edit_vertex},
987 {       0, "Edges",             0,              tb_mesh_edit_edge},
988 {       0, "Faces",             0,              tb_mesh_edit_face},
989 {       0, "Normals",           0,              tb_mesh_edit_normal},
990 {  -1, "",                      0, tb_do_hotkey}};
991
992
993 static TBitem tb_object_ipo[]= {
994 {       0, "Show/Hide",         'k', NULL},
995 {       0, "Select Next",       TB_PAD|'u', NULL},
996 {       0, "Select Prev",       TB_PAD|'d', NULL},
997 {  -1, "",                      0, tb_do_hotkey}};
998
999
1000 static TBitem tb_object_edit[]= {
1001 {       0, "Enter Editmode|Tab",        TB_TAB, NULL},
1002 {       0, "SEPR",                                                              0, NULL},
1003 {       0, "Duplicate|Shift D",                 'D',            NULL},
1004 {       0, "Duplicate Linked|Alt D",    TB_ALT|'d', NULL},
1005 {       0, "Delete|X",                                  'x',            NULL},
1006 {       0, "SEPR",                                                              0, NULL},
1007 {       0, "Object Keys",       0, tb_object_ipo},
1008 {  -1, "",                      0, tb_do_hotkey}};
1009
1010
1011 /* ************* Type  ********** */
1012
1013 static TBitem tb_obdata_hide[]= {
1014 {       0, "Show Hidden|Alt H",                 TB_ALT|'h',             NULL},
1015 {       0, "Hide Selected|H",                   'h',            NULL},
1016 {       0, "Hide Deselected|Shift H",   'H',            NULL},
1017 {  -1, "",                      0, tb_do_hotkey}};
1018
1019 static void tb_do_mesh(void *arg, int event){
1020         switch(event) {
1021         case 1: common_insertkey(); break;
1022         case 2: G.f ^= G_DRAWEDGES; break;
1023         case 3: G.f ^= G_DRAWFACES; break;
1024         case 4: G.f ^= G_DRAWNORMALS; break;
1025         case 5: flip_subdivison(OBACT, -1); break;
1026         }
1027         addqueue(curarea->win, REDRAW, 1);
1028 }
1029
1030 static TBitem tb_mesh[]= {
1031 {       0, "Insert Keyframe|I",                 1,              NULL},
1032 {       0, "SEPR",                                              0, NULL},
1033 {       0, "Show/Hide Edges",                   2,              NULL},
1034 {       0, "Show/Hide Faces",                   3,              NULL},
1035 {       0, "Show/Hide Normals",                 4,              NULL},
1036 {       0, "SEPR",                                              0,      NULL},
1037 {       0, "Subdivision Surface",               5,              NULL},
1038 {       0, "SEPR",                                              0, NULL},
1039 {       0, "Show/Hide Vertices",        0,              tb_obdata_hide},
1040 {  -1, "",                      0, tb_do_mesh}};
1041
1042 static TBitem tb_curve_hide[]= {
1043 {       0, "Show Hidden|Alt H",                 10,             NULL},
1044 {       0, "Hide Selected|H",                   11,             NULL},
1045 {  -1, "",                      0, do_view3d_edit_curve_showhidemenu}};
1046
1047
1048 static TBitem tb_curve[]= {
1049 {       0, "Insert Keyframe|I",                 'i',            NULL},
1050 {       0, "SEPR",                                              0, NULL},
1051 {       0, "Show/Hide Points",  0,              tb_curve_hide},
1052 {  -1, "",                      0, tb_do_hotkey}};
1053
1054 static TBitem tb_obdata[]= {
1055 {       0, "Duplicate|Shift D",                 'D',            NULL},
1056 {       0, "Delete|X",                                  'x',            NULL},
1057 {  -1, "",                      0, tb_do_hotkey}};
1058
1059 static TBitem tb_object_parent[]= {
1060 {       0, "Make Parent...|Ctrl P",             TB_CTRL|'p', NULL},
1061 {       0, "Clear Parent...|Alt P",             TB_ALT|'p', NULL},
1062 {  -1, "",                      0, tb_do_hotkey}};
1063
1064 static TBitem tb_object_track[]= {
1065 {       0, "Make Track|Ctrl T",                 TB_CTRL|'t', NULL},
1066 {       0, "Clear Track|Alt T",                 TB_ALT|'t', NULL},
1067 {  -1, "",                      0, tb_do_hotkey}};
1068
1069 static TBitem tb_object[]= {
1070 {       0, "Insert Keyframe|I",                 'i',            NULL},
1071 {       0, "SEPR",                                                              0, NULL},
1072 {       0, "Make Links...|Ctrl L",              TB_CTRL|'l', NULL},
1073 {       0, "Make Single User...|U",     'u',            NULL},
1074 {       0, "Copy Attributes...|Ctrl C", TB_CTRL|'c', NULL},
1075 {       0, "SEPR",                                                              0, NULL},
1076 {       0, "Parent",    0,              tb_object_parent},
1077 {       0, "Track",     0,              tb_object_track},
1078 {       0, "SEPR",                                                              0, NULL},
1079 {       0, "Boolean Operation|W",       'w', NULL},
1080 {       0, "Join Objects...|Ctrl J",    TB_CTRL|'j', NULL},
1081 {       0, "Convert Object Type...|Alt C",      TB_ALT|'c', NULL},
1082 {       0, "SEPR",                                                              0, NULL},
1083 {       0, "Move to Layer...|M",                'm', NULL},
1084 {  -1, "",                      0, tb_do_hotkey}};
1085
1086
1087 /* *************VIEW ********** */
1088
1089 static void tb_do_view_dt(void *arg, int event){
1090         G.vd->drawtype= event;
1091         addqueue(curarea->win, REDRAW, 1);
1092 }
1093
1094 static TBitem tb_view_dt[]= {
1095 {       ICON_BBOX, "Bounding Box",      1, NULL},
1096 {       ICON_WIRE, "Wireframe|Z",       2, NULL},
1097 {       ICON_SOLID, "Solid|Z",          3, NULL},
1098 {       ICON_SMOOTH, "Shaded|Shift Z",          4, NULL},
1099 {       ICON_POTATO, "Textured|Alt Z",  5, NULL},
1100 {  -1, "",                      0, tb_do_view_dt}};
1101
1102 static TBitem tb_view_alignview[]= {
1103 {       0, "Centre View to Cursor|C",           'c', NULL},
1104 {       0, "Align Active Camera to View|Ctrl Alt NumPad 0",
1105 TB_CTRL|TB_ALT|TB_PAD|'0', NULL}, 
1106 {       0, "Align View to Selected|NumPad *",           TB_PAD|'*', NULL},
1107 {  -1, "",                      0, tb_do_hotkey}};
1108
1109 static TBitem tb_view[]= {
1110 {       0, "Viewport Shading",                  0, tb_view_dt},
1111 {       0, "SEPR",                                              0, NULL},
1112 {       0, "Ortho/Perspective|NumPad 5",        TB_PAD|'5', NULL},
1113 {       0, "Local/Global View|NumPad /",        TB_PAD|'/', NULL},
1114 {       0, "SEPR",                                              0, NULL},
1115 {       0, "Align View",                        0, tb_view_alignview},
1116 {       0, "SEPR",              0, NULL},
1117 {       0, "View Selected|NumPad .",    TB_PAD|'.', NULL},
1118 {       0, "View All|Home",             TB_PAD|'h', NULL},
1119 {       0, "SEPR",              0, NULL},
1120 {       0, "Play Back Animation|Alt A", TB_ALT|'a', NULL},
1121 {       0, "Camera Fly Mode|Shift F", TB_SHIFT|'f', NULL},
1122 {  -1, "",                      0, tb_do_hotkey}};
1123
1124
1125 /* *************TRANSFORM ********** */
1126
1127 static TBitem tb_transform_moveaxis[]= {
1128 {       0, "X Global|G, X",     0, NULL},
1129 {       0, "Y Global|G, Y",     1, NULL},
1130 {       0, "Z Global|G, Z",     2, NULL},
1131 {       0, "SEPR",                                      0, NULL},
1132 {       0, "X Local|G, X, X",   3, NULL},
1133 {       0, "Y Local|G, Y, Y",   4, NULL},
1134 {       0, "Z Local|G, Z, Z",   5, NULL},
1135 {  -1, "",                      0, do_view3d_transform_moveaxismenu}};
1136
1137 static TBitem tb_transform_rotateaxis[]= {
1138 {       0, "X Global|R, X",     0, NULL},
1139 {       0, "Y Global|R, Y",     1, NULL},
1140 {       0, "Z Global|R, Z",     2, NULL},
1141 {       0, "SEPR",                                      0, NULL},
1142 {       0, "X Local|R, X, X",   3, NULL},
1143 {       0, "Y Local|R, Y, Y",   4, NULL},
1144 {       0, "Z Local|R, Z, Z",   5, NULL},
1145 {  -1, "",                      0, do_view3d_transform_rotateaxismenu}};
1146
1147 static TBitem tb_transform_scaleaxis[]= {
1148 {       0, "X Global|S, X",     0, NULL},
1149 {       0, "Y Global|S, Y",     1, NULL},
1150 {       0, "Z Global|S, Z",     2, NULL},
1151 {       0, "SEPR",                                      0, NULL},
1152 {       0, "X Local|S, X, X",   3, NULL},
1153 {       0, "Y Local|S, Y, Y",   4, NULL},
1154 {       0, "Z Local|S, Z, Z",   5, NULL},
1155 {  -1, "",                      0, do_view3d_transform_scaleaxismenu}};
1156
1157 static void tb_do_transform_clearapply(void *arg, int event)
1158 {
1159         Object *ob;
1160         ob= OBACT;
1161         
1162         switch(event)
1163         {
1164             case 0: /* clear location */
1165                         clear_object('g');
1166                         break;
1167                 case 1: /* clear rotation */
1168                         clear_object('r');
1169                         break;
1170                 case 2: /* clear size */
1171                         clear_object('s');
1172                         break;
1173                 case 3: /* apply size/rotation */
1174                         apply_object();
1175                         break;
1176                 case 4: /* apply deformation */
1177                         object_apply_deform(ob);
1178                         break;
1179                 case 5: /* make duplicates real */
1180                         if (ob->transflag & OB_DUPLI) make_duplilist_real();
1181                         else error("The active object does not have dupliverts");
1182                         break;
1183         }
1184 }
1185
1186 static TBitem tb_transform_clearapply[]= {
1187 {       0, "Clear Location|Alt G",              0, NULL},
1188 {       0, "Clear Rotation|Alt R",              1, NULL},
1189 {       0, "Clear Size|Alt S",                  2, NULL},
1190 {       0, "SEPR",                                      0, NULL},
1191 {       0, "Apply Size/Rotation|Ctrl A", 3, NULL},
1192 {       0, "Apply Deformation|Shift Ctrl A", 4, NULL},
1193 {       0, "Make Duplicates Real|Shift Ctrl A", 5, NULL},
1194 {  -1, "",                      0, tb_do_transform_clearapply}};
1195
1196 static TBitem tb_transform_snap[]= {
1197 {       0, "Selection -> Grid|Shift S, 1",              1, NULL},
1198 {       0, "Selection -> Cursor|Shift S, 2",    2, NULL},
1199 {       0, "Cursor -> Grid|Shift S, 3",                 3, NULL},
1200 {       0, "Cursor -> Selection|Shift S, 4", 4, NULL},
1201 {       0, "Selection -> Center|Shift S, 5", 5, NULL},
1202 {  -1, "",                      0, do_view3d_edit_snapmenu}};
1203
1204 static void tb_do_transform(void *arg, int event)
1205 {
1206         switch(event)
1207         {
1208                 case 0: /* Grab/move */
1209                         initTransform(TFM_TRANSLATION, CTX_NONE);
1210                         Transform();
1211                         break;
1212                 case 1: /* Rotate */
1213                         initTransform(TFM_ROTATION, CTX_NONE);
1214                         Transform();
1215                         break;
1216                 case 2: /* Scale */
1217                         initTransform(TFM_RESIZE,CTX_NONE);
1218                         Transform();
1219                         break;
1220                 case 3: /* transform properties */
1221                         add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
1222                         break;
1223                 case 4: /* snap */
1224                         snapmenu();
1225                         break;
1226                 case 5: /* Shrink/Fatten Along Normals */
1227                         initTransform(TFM_SHRINKFATTEN, CTX_NONE);
1228                         Transform();
1229                         break;
1230                 case 6: /* Shear */
1231                         initTransform(TFM_SHEAR, CTX_NONE);
1232                         Transform();
1233                         break;
1234                 case 7: /* Warp */
1235                         initTransform(TFM_WARP, CTX_NONE);
1236                         Transform();
1237                         break;
1238                 case 8: /* proportional edit (toggle) */
1239                         if(G.scene->proportional) G.scene->proportional= 0;
1240                         else G.scene->proportional= 1;
1241                         break;
1242                 case 10:
1243                         docentre(0);
1244                         break;
1245                 case 11:
1246                         docentre_new();
1247                         break;
1248                 case 12:
1249                         docentre_cursor();
1250                         break;
1251         }
1252         allqueue(REDRAWVIEW3D, 0);
1253 }
1254
1255 static TBitem tb_transform_object_mirror[]= {
1256 {       0, "X Local|Ctrl M, 1",         1, NULL},
1257 {       0, "Y Local|Ctrl M, 2",         2, NULL},
1258 {       0, "Z Local|Ctrl M, 3",         3, NULL},
1259 {  -1, "",                      0, do_view3d_object_mirrormenu}};
1260
1261 static TBitem tb_transform[]= {
1262 {       0, "Grab/Move|G",       0, NULL},
1263 {       0, "Grab/Move on Axis| ",       0, tb_transform_moveaxis},
1264 {       0, "Rotate|R",          1, NULL},
1265 {       0, "Rotate on Axis",    0, tb_transform_rotateaxis},
1266 {       0, "Scale|S",           2, NULL},
1267 {       0, "Scale on Axis",     0, tb_transform_scaleaxis},
1268 {       0, "SEPR",                                      0, NULL},
1269 {       0, "ObData to Center",          10, NULL},
1270 {       0, "Center New",                        11, NULL},
1271 {       0, "Center Cursor",                     12, NULL},
1272 {       0, "SEPR",                                      0, NULL},
1273 {       ICON_MENU_PANEL, "Properties|N", 3, NULL},
1274 {       0, "SEPR",                                      0, NULL},
1275 {       0, "Mirror",    0, tb_transform_object_mirror},
1276 {       0, "SEPR",                                      0, NULL},
1277 {       0, "Snap",              0, tb_transform_snap},
1278 {       0, "SEPR",                                      0, NULL},
1279 {       0, "Clear/Apply",       0, tb_transform_clearapply},
1280 {  -1, "",                      0, tb_do_transform}};
1281
1282 static TBitem tb_transform_edit_mirror[]= {
1283 {       0, "X Global|Ctrl M, 1",        1, NULL},
1284 {       0, "Y Global|Ctrl M, 2",        2, NULL},
1285 {       0, "Z Global|Ctrl M, 3",        3, NULL},
1286 {       0, "SEPR",                                      0, NULL},
1287 {       0, "X Local|Ctrl M, 4",         4, NULL},
1288 {       0, "Y Local|Ctrl M, 5",         5, NULL},
1289 {       0, "Z Local|Ctrl M, 6",         6, NULL},
1290 {       0, "SEPR",                                      0, NULL},
1291 {       0, "X View|Ctrl M, 7",  7, NULL},
1292 {       0, "Y View|Ctrl M, 8",  8, NULL},
1293 {       0, "Z View|Ctrl M, 9",  9, NULL},
1294 {  -1, "",                      0, do_view3d_edit_mirrormenu}};
1295
1296 static TBitem tb_transform_editmode1[]= {
1297 {       0, "Grab/Move|G",       0, NULL},
1298 {       0, "Grab/Move on Axis| ",       0, tb_transform_moveaxis},
1299 {       0, "Rotate|R",          1, NULL},
1300 {       0, "Rotate on Axis",    0, tb_transform_rotateaxis},
1301 {       0, "Scale|S",           2, NULL},
1302 {       0, "Scale on Axis",     0, tb_transform_scaleaxis},
1303 {       0, "SEPR",                                      0, NULL},
1304 {       0, "Shrink/Fatten|Alt S", 5, NULL},
1305 {       0, "Shear|Ctrl S", 6, NULL},
1306 {       0, "Warp|Shift W",      7, NULL},
1307 {       0, "SEPR",                                      0, NULL},
1308 {       0, "ObData to Center",          10, NULL},
1309 {       0, "SEPR",                                      0, NULL},
1310 {       ICON_MENU_PANEL, "Properties|N", 3, NULL},
1311 {       0, "SEPR",                                      0, NULL},
1312 {       0, "Mirror",    0, tb_transform_edit_mirror},
1313 {       0, "SEPR",                                      0, NULL},
1314 {       0, "Snap",              0, tb_transform_snap},
1315 {       0, "SEPR",                                      0, NULL},
1316 {       0, "Proportional Edit|O",       8,              NULL},
1317 {  -1, "",                      0, tb_do_transform}};
1318
1319
1320 static TBitem tb_transform_editmode2[]= {
1321 {       0, "Grab/Move|G",       0, NULL},
1322 {       0, "Grab/Move on Axis| ",       0, tb_transform_moveaxis},
1323 {       0, "Rotate|R",          1, NULL},
1324 {       0, "Rotate on Axis",    0, tb_transform_rotateaxis},
1325 {       0, "Scale|S",           2, NULL},
1326 {       0, "Scale on Axis",     0, tb_transform_scaleaxis},
1327 {       0, "SEPR",                                      0, NULL},
1328 {       ICON_MENU_PANEL, "Properties|N", 3, NULL},
1329 {       0, "Snap",              0, tb_transform_snap},
1330 {  -1, "",                      0, tb_do_transform}};
1331
1332
1333 /* *************ADD ********** */
1334
1335 static TBitem addmenu_mesh[]= {
1336 {       0, "Plane",     0, NULL},
1337 {       0, "Cube",              1, NULL},
1338 {       0, "Circle",    2, NULL},
1339 {       0, "UVsphere",  3, NULL},
1340 {       0, "Icosphere", 4, NULL},
1341 {       0, "Cylinder",  5, NULL},
1342 {       0, "Tube",              6, NULL},
1343 {       0, "Cone",              7, NULL},
1344 {       0, "SEPR",              0, NULL},
1345 {       0, "Grid",              8, NULL},
1346 {       0, "Monkey",    9, NULL},
1347 {  -1, "",                      0, do_info_add_meshmenu}};
1348
1349 static TBitem addmenu_curve[]= {
1350 {       0, "Bezier Curve",      0, NULL},
1351 {       0, "Bezier Circle", 1, NULL},
1352 {       0, "NURBS Curve",       2, NULL},
1353 {       0, "NURBS Circle",      3, NULL},
1354 {       0, "Path",                      4, NULL},
1355 {  -1, "",                      0, do_info_add_curvemenu}};
1356
1357 static TBitem addmenu_surf[]= {
1358 {       0, "NURBS Curve",       0, NULL},
1359 {       0, "NURBS Circle",      1, NULL},
1360 {       0, "NURBS Surface", 2, NULL},
1361 {       0, "NURBS Tube",        3, NULL},
1362 {       0, "NURBS Sphere",      4, NULL},
1363 {       0, "NURBS Donut",       5, NULL},
1364 {  -1, "",                      0, do_info_add_surfacemenu}};
1365
1366 static TBitem addmenu_meta[]= {
1367 {       0, "Meta Ball",         0, NULL},
1368 {       0, "Meta Tube",         1, NULL},
1369 {       0, "Meta Plane",        2, NULL},
1370 {       0, "Meta Ellipsoid", 3, NULL},
1371 {       0, "Meta Cube",         4, NULL},
1372 {  -1, "",                      0, do_info_add_metamenu}};
1373
1374 static TBitem addmenu_lamp[]= {
1375 {       0, "Lamp",      0, NULL},
1376 {       0, "Sun",       1, NULL},
1377 {       0, "Spot",      2, NULL},
1378 {       0, "Hemi", 3, NULL},
1379 {       0, "Area",      4, NULL},
1380 {  -1, "",                      0, do_info_add_lampmenu}};
1381
1382 static TBitem addmenu_YF_lamp[]= {
1383 {       0, "Lamp",      0, NULL},
1384 {       0, "Sun",       1, NULL},
1385 {       0, "Spot",      2, NULL},
1386 {       0, "Hemi", 3, NULL},
1387 {       0, "Area",      4, NULL},
1388 {       0, "Photon",    5, NULL},
1389 {  -1, "",                      0, do_info_add_lampmenu}};
1390
1391
1392 static TBitem addmenu_armature[]= {
1393 {       0, "Bone",      8, NULL},
1394 {  -1, "",                      0, do_info_addmenu}};
1395
1396 /* dynamic items */
1397 #define TB_ADD_GROUP    7
1398 #define TB_ADD_LAMP             10
1399
1400 static TBitem tb_add[]= {
1401 {       0, "Mesh",              0, addmenu_mesh},
1402 {       0, "Curve",     1, addmenu_curve},
1403 {       0, "Surface",   2, addmenu_surf},
1404 {       0, "Meta",      3, addmenu_meta},
1405 {       0, "Text",              4, NULL},
1406 {       0, "Empty",     5, NULL},
1407 {       0, "SEPR",              0, NULL},
1408 {       0, "Group",     10, NULL},
1409 {       0, "SEPR",              0, NULL},
1410 {       0, "Camera",    6, NULL},
1411 {       0, "Lamp",              7, addmenu_lamp},
1412 {       0, "SEPR",              0, NULL},
1413 {       0, "Armature",  8, NULL},
1414 {       0, "Lattice",   9, NULL},
1415 {  -1, "",                      0, do_info_addmenu}};
1416
1417 static TBitem tb_empty[]= {
1418 {       0, "Nothing...",        0, NULL},
1419 {  -1, "",              0, NULL}};
1420
1421
1422 /* *************RENDER ********** */
1423
1424 static void tb_do_render(void *arg, int event){
1425         switch(event)
1426         {
1427                 case 1: /* set render border */
1428                         set_render_border();
1429                         break;
1430                 case 2: /* render */
1431                         BIF_do_render(0);
1432                         break;
1433                 case 3: /* render anim */
1434                         BIF_do_render(1);
1435                         break;
1436                 case 4: /* render anim */
1437                         if(G.scene->r.scemode & R_PASSEPARTOUT) G.scene->r.scemode &= ~R_PASSEPARTOUT;
1438                         else G.scene->r.scemode |= R_PASSEPARTOUT;
1439                         allqueue(REDRAWVIEW3D, 0);
1440                         break;
1441         }
1442 }
1443
1444 static TBitem tb_render[]= {
1445         {       0, "Passepartout",                      4, NULL},
1446         {       0, "Set Border",                        1, NULL},
1447         {       0, "SEPR",              0, NULL},
1448         {       0, "Render|F12",                        2, NULL},
1449         {       0, "Anim",                                      3, NULL},
1450         {  -1, "",                      0, tb_do_render}};
1451
1452 /* ************************* NODES *********************** */
1453
1454
1455 /* dynamic items */
1456 #define TB_SH_INPUTS            0
1457 #define TB_SH_OUTPUTS           1
1458 #define TB_SH_OP_COLOR          2
1459 #define TB_SH_OP_VECTOR         3
1460 #define TB_SH_CONVERTORS        4
1461 #define TB_SH_GENERATORS        5
1462 #define TB_SH_GROUPS            6
1463
1464 static TBitem tb_node_addsh[]= {
1465         {       0, "Inputs",            1, NULL},
1466         {       0, "Outputs",           2, NULL},
1467         {       0, "Color Ops",         3, NULL},
1468         {       0, "Vector Ops",        4, NULL},
1469         {       0, "Convertors",        5, NULL},
1470         {       0, "Generators",        6, NULL},
1471         {       0, "Groups",            7, NULL},
1472         {  -1, "",                      0, NULL}};
1473
1474
1475 #define TB_CMP_INPUTS           0
1476 #define TB_CMP_OUTPUTS          1
1477 #define TB_CMP_OP_COLOR         2
1478 #define TB_CMP_OP_VECTOR        3
1479 #define TB_CMP_OP_FILTER        4
1480 #define TB_CMP_CONVERTORS       5
1481 #define TB_CMP_GENERATORS       6
1482 #define TB_CMP_GROUPS           7
1483
1484 static TBitem tb_node_addcomp[]= {
1485         {       0, "Inputs",            1, NULL},
1486         {       0, "Outputs",           2, NULL},
1487         {       0, "Color Ops",         3, NULL},
1488         {       0, "Vector Ops",        4, NULL},
1489         {       0, "Filters",           5, NULL},
1490         {       0, "Convertors",        6, NULL},
1491         {       0, "Generators",        7, NULL},
1492         {       0, "Groups",            8, NULL},
1493         {  -1, "",                      0, NULL}};
1494
1495 static void do_node_addmenu(void *arg, int event)
1496 {
1497         SpaceNode *snode= curarea->spacedata.first;
1498         float locx, locy;
1499         short mval[2];
1500         
1501         getmouseco_areawin(mval);
1502         areamouseco_to_ipoco(G.v2d, mval, &locx, &locy);
1503         node_add_node(snode, event, locx, locy);
1504         
1505         addqueue(curarea->win, B_NODE_TREE_EXEC, 1);
1506         
1507         BIF_undo_push("Add Node");
1508         
1509 }
1510
1511 /* dynamic toolbox sublevel */
1512 static TBitem *node_add_sublevel(void **poin, bNodeTree *ntree, int nodeclass)
1513 {
1514         static TBitem _addmenu[]= { {   0, "Empty",     0, NULL}, {  -1, "",                    0, NULL}};
1515         bNodeType **typedefs;
1516         TBitem *addmenu;
1517         int tot= 0, a;
1518         
1519         if(ntree) {
1520                 if(nodeclass==NODE_CLASS_GROUP) {
1521                         bNodeTree *ngroup= G.main->nodetree.first;
1522                         for(; ngroup; ngroup= ngroup->id.next)
1523                                 if(ngroup->type==ntree->type)
1524                                         tot++;
1525                 }
1526                 else {
1527                         for(typedefs= ntree->alltypes; *typedefs; typedefs++)
1528                                 if( (*typedefs)->nclass == nodeclass )
1529                                         tot++;
1530                 }
1531         }       
1532         if(tot==0) {
1533                 *poin= _addmenu;
1534                 return NULL;
1535         }
1536         
1537         addmenu= MEM_callocN(sizeof(TBitem)*(tot+1), "types menu");
1538         
1539         if(nodeclass==NODE_CLASS_GROUP) {
1540                 bNodeTree *ngroup= G.main->nodetree.first;
1541                 for(tot=0, a=0; ngroup; ngroup= ngroup->id.next, tot++) {
1542                         if(ngroup->type==ntree->type) {
1543                                 addmenu[a].name= ngroup->id.name+2;
1544                                 addmenu[a].retval= NODE_GROUP_MENU+tot; /* so we can use BLI_findlink() */
1545                                 a++;
1546                         }
1547                 }
1548         }
1549         else {
1550                 for(a=0, typedefs= ntree->alltypes; *typedefs; typedefs++) {
1551                         if( (*typedefs)->nclass == nodeclass ) {
1552                                 addmenu[a].name= (*typedefs)->name;
1553                                 addmenu[a].retval= (*typedefs)->type;
1554                                 a++;
1555                         }
1556                 }
1557         }
1558
1559         addmenu[a].icon= -1;    /* end signal */
1560         addmenu[a].name= "";
1561         addmenu[a].retval= a;
1562         addmenu[a].poin= do_node_addmenu;
1563         
1564         *poin= addmenu;
1565         
1566         return addmenu;
1567 }
1568
1569
1570 static TBitem tb_node_edit[]= {
1571         {       0, "Duplicate|Shift D", TB_SHIFT|'d',           NULL},
1572         {       0, "Delete|X", 'x',             NULL},
1573         {       0, "SEPR",              0, NULL},
1574         {       0, "Make Group|Ctrl G", TB_CTRL|'g',            NULL},
1575         {       0, "Ungroup|Alt G", TB_ALT|'g',                 NULL},
1576         {       0, "Edit Group", TB_TAB, NULL},
1577         {       0, "SEPR",              0, NULL},
1578         {       0, "Hide/Unhide|H", 'h', NULL},
1579         {       0, "SEPR",              0, NULL},
1580         {       0, "Show Cyclic Dependencies", 'c', NULL},
1581         {  -1, "",                      0, tb_do_hotkey}};
1582
1583 static TBitem tb_node_select[]= {
1584         {       0, "Select/Deselect All|A",     'a', NULL},
1585         {       0, "Border Select|B",   'b', NULL},
1586         {  -1, "",                      0, tb_do_hotkey}};
1587
1588 static TBitem tb_node_transform[]= {
1589         {       0, "Grab/Move|G", 'g',          NULL},
1590         {  -1, "",                      0, tb_do_hotkey}};
1591
1592 static TBitem tb_node_view[]= {
1593         {       0, "Zoom in|NumPad +",  TB_PAD|'+', NULL},
1594         {       0, "Zoom out|NumPad -", TB_PAD|'-', NULL},
1595         {       0, "View all|Home",     TB_PAD|'h', NULL},
1596         {  -1, "",                      0, tb_do_hotkey}};
1597
1598
1599 /* *********************************************** */
1600
1601 static uiBlock *tb_makemenu(void *arg)
1602 {
1603         static int counter=0;
1604         TBitem *item= arg, *itemt;
1605         uiBlock *block;
1606         int yco= 0;
1607         char str[10];
1608         
1609         if(arg==NULL) return NULL;
1610         
1611         sprintf(str, "tb %d", counter++);
1612         block= uiNewBlock(&tb_listb, str, UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1613         uiBlockSetCol(block, TH_MENU_ITEM);
1614
1615         // last item has do_menu func, has to be stored in each button
1616         itemt= item;
1617         while(itemt->icon != -1) itemt++;
1618         uiBlockSetButmFunc(block, itemt->poin, NULL);
1619
1620         // now make the buttons
1621         while(item->icon != -1) {
1622
1623                 if(strcmp(item->name, "SEPR")==0) {
1624                         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 50, 6, NULL, 0.0, 0.0, 0, 0, "");
1625                 }
1626                 else if(item->icon) {
1627                         uiDefIconTextBut(block, BUTM, 1, item->icon, item->name, 0, yco-=20, 80, 19, NULL, 0.0, 0.0, 0, item->retval, "");
1628                 }
1629                 else if(item->poin) {
1630                         uiDefIconTextBlockBut(block, tb_makemenu, item->poin, ICON_RIGHTARROW_THIN, item->name, 0, yco-=20, 80, 19, "");
1631                 }
1632                 else {
1633                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, item->name, 0, yco-=20, 80, 19, NULL, 0.0, 0.0, 0, item->retval, "");
1634                 }
1635                 item++;
1636         }
1637         uiTextBoundsBlock(block, 60);
1638         
1639         /* direction is also set in the function that calls this */
1640         if(U.uiflag & USER_PLAINMENUS)
1641                 uiBlockSetDirection(block, UI_RIGHT);
1642         else
1643                 uiBlockSetDirection(block, UI_RIGHT|UI_CENTRE);
1644
1645         return block;
1646 }
1647
1648 static int tb_mainx= 1234, tb_mainy= 0;
1649 static void store_main(void *arg1, void *arg2)
1650 {
1651         tb_mainx= (int)arg1;
1652         tb_mainy= (int)arg2;
1653 }
1654
1655 static void do_group_addmenu(void *arg, int event)
1656 {
1657         Object *ob;
1658         
1659         add_object_draw(OB_EMPTY);
1660         ob= OBACT;
1661         
1662         ob->dup_group= BLI_findlink(&G.main->group, event);
1663         if(ob->dup_group) {
1664                 id_us_plus((ID *)ob->dup_group);
1665                 ob->transflag |= OB_DUPLIGROUP;
1666                 DAG_scene_sort(G.scene);
1667         }
1668 }
1669                                                          
1670 /* example of dynamic toolbox sublevel */
1671 static TBitem *create_group_sublevel(void)
1672 {
1673         static TBitem addmenu[]= { {    0, "No Groups",         0, NULL}, {  -1, "",                    0, NULL}};
1674         TBitem *groupmenu;
1675         Group *group;
1676         int a;
1677         
1678         int tot= BLI_countlist(&G.main->group);
1679         
1680         if(tot==0) {
1681                 tb_add[TB_ADD_GROUP].poin= addmenu;
1682                 return NULL;
1683         }
1684         
1685         groupmenu= MEM_callocN(sizeof(TBitem)*(tot+1), "group menu");
1686         for(a=0, group= G.main->group.first; group; group= group->id.next, a++) {
1687                 groupmenu[a].name= group->id.name+2;
1688                 groupmenu[a].retval= a;
1689         }
1690         groupmenu[a].icon= -1;  /* end signal */
1691         groupmenu[a].name= "";
1692         groupmenu[a].retval= a;
1693         groupmenu[a].poin= do_group_addmenu;
1694         
1695         tb_add[TB_ADD_GROUP].poin= groupmenu;
1696         
1697         return groupmenu;
1698 }
1699
1700 void toolbox_n(void)
1701 {
1702         uiBlock *block;
1703         uiBut *but;
1704         TBitem *menu1=NULL, *menu2=NULL, *menu3=NULL; 
1705         TBitem *menu4=NULL, *menu5=NULL, *menu6=NULL;
1706         TBitem *menu7=NULL, *groupmenu= NULL;
1707         TBitem *node_add_gen= NULL, *node_add_group= NULL, *node_add_out= NULL, *node_add_in= NULL;
1708         TBitem *node_add_op_col= NULL, *node_add_op_filt= NULL, *node_add_op_vec= NULL, *node_add_con= NULL;
1709         int dx=0;
1710         short event, mval[2], tot=0;
1711         char *str1=NULL, *str2=NULL, *str3=NULL, *str4=NULL, *str5=NULL, *str6=NULL, *str7=NULL;
1712         
1713         /* temporal too... when this flag is (was) saved, it should initialize OK */
1714         if(tb_mainx==1234) {
1715                 if(U.uiflag & USER_PLAINMENUS) {
1716                         tb_mainx= -32;
1717                         tb_mainy= -5;
1718                 } else {
1719                         tb_mainx= 0;
1720                         tb_mainy= -5;
1721                 }
1722         }
1723         
1724         mywinset(G.curscreen->mainwin); // we go to screenspace
1725         
1726         block= uiNewBlock(&tb_listb, "toolbox", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1727         uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
1728         uiBlockSetCol(block, TH_MENU_ITEM);
1729         
1730         /* select context for main items */
1731         if(curarea->spacetype==SPACE_VIEW3D) {
1732
1733                 /* dynamic menu entries */
1734                 groupmenu= create_group_sublevel();
1735                 
1736                 if (G.scene->r.renderer==R_YAFRAY)
1737                         tb_add[TB_ADD_LAMP].poin= addmenu_YF_lamp;
1738                 else
1739                         tb_add[TB_ADD_LAMP].poin= addmenu_lamp;
1740                 
1741                 if(U.uiflag & USER_PLAINMENUS) {
1742                         menu1= tb_add; str1= "Add";
1743                         menu2= tb_object_edit; str2= "Edit";
1744                         menu3= tb_object_select; str3= "Select";
1745                         menu4= tb_transform; str4= "Transform";
1746                         menu5= tb_object; str5= "Object";
1747                         menu6= tb_view; str6= "View";
1748                         menu7= tb_render; str7= "Render";
1749
1750                         dx= 96;
1751                         tot= 7;
1752                 } else {
1753                         /* 3x2 layout menu */
1754                         menu1= tb_object; str1= "Object";
1755                         menu2= tb_add; str2= "Add";
1756                         menu3= tb_object_select; str3= "Select";
1757                         menu4= tb_object_edit; str4= "Edit";
1758                         menu5= tb_transform; str5= "Transform";
1759                         menu6= tb_view; str6= "View";
1760
1761                         dx= 64;
1762                         tot= 6;
1763                 }
1764                 
1765                 if(G.obedit) {
1766                         if(U.uiflag & USER_PLAINMENUS) {
1767                                 switch(G.obedit->type){
1768                                 case OB_MESH:
1769                                         menu1= addmenu_mesh;
1770                                         menu2= tb_mesh_edit;
1771                                         menu3= tb_mesh_select;
1772                                         menu4= tb_transform_editmode1;
1773                                         menu5= tb_mesh; str5= "Mesh";
1774                                 break;
1775                                 case OB_CURVE:
1776                                         menu1= addmenu_curve;
1777                                         menu2= tb_curve_edit;
1778                                         menu3= tb_curve_select;
1779                                         menu4= tb_transform_editmode1;
1780                                         menu5= tb_curve; str5= "Curve";
1781                                 break;
1782                                 case OB_SURF:
1783                                         menu1= addmenu_surf;
1784                                         menu2= tb_curve_edit;
1785                                         menu3= tb_curve_select;
1786                                         menu4= tb_transform_editmode1;
1787                                         menu5= tb_curve; str5= "Surface";
1788                                 break;
1789                                 case OB_MBALL:
1790                                         menu1= addmenu_meta;
1791                                         menu2= tb_edit;
1792                                         menu3= tb__select;
1793                                         menu4= tb_transform_editmode2;
1794                                         menu5= tb_obdata; str5= "Meta";
1795                                 break;
1796                                 case OB_ARMATURE:
1797                                         menu1= addmenu_armature;
1798                                         menu2= tb_edit;
1799                                         menu3= tb__select;
1800                                         menu4= tb_transform_editmode2;
1801                                         menu5= tb_obdata;str5= "Armature";
1802                                 break;
1803                                 case OB_LATTICE:
1804                                         menu1= tb_empty;
1805                                         menu2= tb_edit;
1806                                         menu3= tb__select;
1807                                         menu4= tb_transform_editmode1;
1808                                         menu5= tb_empty;str5= "Lattice";
1809                                 break;
1810                                 }
1811                         } else {
1812                                 if(G.obedit->type==OB_MESH) {
1813                                         menu1= tb_mesh; str1= "Mesh";
1814                                         menu2= addmenu_mesh; 
1815                                         menu3= tb_mesh_select;
1816                                         menu4= tb_mesh_edit; 
1817                                         menu5= tb_transform_editmode1;
1818                                 }
1819                                 else if(G.obedit->type==OB_CURVE) {
1820                                         menu1= tb_curve; str1= "Curve";
1821                                         menu2= addmenu_curve;
1822                                         menu3= tb_curve_select;
1823                                         menu4= tb_curve_edit;
1824                                         menu5= tb_transform_editmode1;
1825                                 }
1826                                 else if(G.obedit->type==OB_SURF) {
1827                                         menu1= tb_curve; str1= "Surface";
1828                                         menu2= addmenu_surf; 
1829                                         menu3= tb_curve_select;
1830                                         menu4= tb_curve_edit;
1831                                         menu5= tb_transform_editmode1;
1832                                 }
1833                                 else if(G.obedit->type==OB_MBALL) {
1834                                         menu1= tb_obdata; str1= "Meta";
1835                                         menu2= addmenu_meta;
1836                                         menu3= tb__select;
1837                                         menu4= tb_edit;
1838                                         menu5= tb_transform_editmode2;
1839                                 }
1840                                 else if(G.obedit->type==OB_ARMATURE) {
1841                                         menu1= tb_obdata;str1= "Armature";
1842                                         menu2= addmenu_armature;
1843                                         menu3= tb__select;
1844                                         menu4= tb_edit;
1845                                         menu5= tb_transform_editmode2;
1846                                 }
1847                                 else if(G.obedit->type==OB_LATTICE) {
1848                                         menu1= tb_empty;str1= "Lattice";
1849                                         menu2= tb_empty;
1850                                         menu3= tb__select;
1851                                         menu4= tb_edit;
1852                                         menu5= tb_transform_editmode1;
1853                                 }
1854                         }
1855                 }
1856                 else {
1857                 }
1858         }
1859         else if(curarea->spacetype==SPACE_NODE) {
1860                 SpaceNode *snode= curarea->spacedata.first;
1861                 
1862                 if(snode->treetype==NTREE_COMPOSIT)
1863                         menu1= tb_node_addcomp; 
1864                 else
1865                         menu1= tb_node_addsh; 
1866                 str1= "Add";
1867                 menu2= tb_node_edit; str2= "Edit";
1868                 menu3= tb_node_select; str3= "Select";
1869                 menu4= tb_node_transform; str4= "Transform";
1870                 menu5= tb_node_view; str5= "View";
1871                 
1872                 if(snode->treetype==NTREE_SHADER) {
1873                         node_add_in= node_add_sublevel(&menu1[TB_SH_INPUTS].poin, snode->nodetree, NODE_CLASS_INPUT);
1874                         node_add_out= node_add_sublevel(&menu1[TB_SH_OUTPUTS].poin, snode->nodetree, NODE_CLASS_OUTPUT);
1875                         node_add_op_col= node_add_sublevel(&menu1[TB_SH_OP_COLOR].poin, snode->nodetree, NODE_CLASS_OP_COLOR);
1876                         node_add_op_vec= node_add_sublevel(&menu1[TB_SH_OP_VECTOR].poin, snode->nodetree, NODE_CLASS_OP_VECTOR);
1877                         node_add_con= node_add_sublevel(&menu1[TB_SH_CONVERTORS].poin, snode->nodetree, NODE_CLASS_CONVERTOR);
1878                         node_add_gen= node_add_sublevel(&menu1[TB_SH_GENERATORS].poin, snode->nodetree, NODE_CLASS_GENERATOR);
1879                         node_add_group= node_add_sublevel(&menu1[TB_SH_GROUPS].poin, snode->nodetree, NODE_CLASS_GROUP);
1880                 }
1881                 else if(snode->treetype==NTREE_COMPOSIT) {
1882                         node_add_in= node_add_sublevel(&menu1[TB_CMP_INPUTS].poin, snode->nodetree, NODE_CLASS_INPUT);
1883                         node_add_out= node_add_sublevel(&menu1[TB_CMP_OUTPUTS].poin, snode->nodetree, NODE_CLASS_OUTPUT);
1884                         node_add_op_col= node_add_sublevel(&menu1[TB_CMP_OP_COLOR].poin, snode->nodetree, NODE_CLASS_OP_COLOR);
1885                         node_add_op_filt= node_add_sublevel(&menu1[TB_CMP_OP_FILTER].poin, snode->nodetree, NODE_CLASS_OP_FILTER);
1886                         node_add_op_vec= node_add_sublevel(&menu1[TB_CMP_OP_VECTOR].poin, snode->nodetree, NODE_CLASS_OP_VECTOR);
1887                         node_add_con= node_add_sublevel(&menu1[TB_CMP_CONVERTORS].poin, snode->nodetree, NODE_CLASS_CONVERTOR);
1888                         node_add_gen= node_add_sublevel(&menu1[TB_CMP_GENERATORS].poin, snode->nodetree, NODE_CLASS_GENERATOR);
1889                         node_add_group= node_add_sublevel(&menu1[TB_CMP_GROUPS].poin, snode->nodetree, NODE_CLASS_GROUP);
1890                 }
1891                 
1892                 dx= 96;
1893                 tot= 5;
1894                 
1895         }
1896         
1897         getmouseco_sc(mval);
1898         
1899         /* create the main buttons menu */
1900         if(tot==6) {
1901         
1902                 /* check if it fits */
1903                 if(mval[0]-1.5*dx+tb_mainx < 6) mval[0]= 6 + 1.5*dx -tb_mainx;
1904                 else if(mval[0]+1.5*dx+tb_mainx > G.curscreen->sizex-6) 
1905                         mval[0]= G.curscreen->sizex-6-1.5*dx-tb_mainx;
1906
1907                 if(mval[1]-20+tb_mainy < 6) mval[1]= 6+20 -tb_mainy;
1908                 else if(mval[1]+20+tb_mainy > G.curscreen->sizey-6) 
1909                         mval[1]= G.curscreen->sizey-6-20-tb_mainy;
1910         
1911                 but=uiDefBlockBut(block, tb_makemenu, menu1, str1,      mval[0]-(1.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
1912                 uiButSetFlag(but, UI_MAKE_TOP|UI_MAKE_RIGHT);
1913                 uiButSetFunc(but, store_main, (void *)dx, (void *)-5);
1914
1915                 but=uiDefBlockBut(block, tb_makemenu, menu2, str2,      mval[0]-(0.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
1916                 uiButSetFlag(but, UI_MAKE_TOP);
1917                 uiButSetFunc(but, store_main, (void *)0, (void *)-5);
1918
1919                 but=uiDefBlockBut(block, tb_makemenu, menu3, str3,      mval[0]+(0.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
1920                 uiButSetFlag(but, UI_MAKE_TOP|UI_MAKE_LEFT);
1921                 uiButSetFunc(but, store_main, (void *)-dx, (void *)-5);
1922
1923                 but=uiDefBlockBut(block, tb_makemenu, menu4, str4,      mval[0]-(1.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
1924                 uiButSetFlag(but, UI_MAKE_DOWN|UI_MAKE_RIGHT);
1925                 uiButSetFunc(but, store_main, (void *)dx, (void *)5);
1926
1927                 but=uiDefBlockBut(block, tb_makemenu, menu5, str5,      mval[0]-(0.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
1928                 uiButSetFlag(but, UI_MAKE_DOWN);
1929                 uiButSetFunc(but, store_main, (void *)0, (void *)5);
1930
1931                 but=uiDefBlockBut(block, tb_makemenu, menu6, str6,      mval[0]+(0.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
1932                 uiButSetFlag(but, UI_MAKE_DOWN|UI_MAKE_LEFT);
1933                 uiButSetFunc(but, store_main, (void *)-dx, (void *)5);
1934         } else if (tot==5 || tot==7) {
1935                 /* check if it fits, dubious */
1936                 if(mval[0]-0.25*dx+tb_mainx < 6) mval[0]= 6 + 0.25*dx -tb_mainx;
1937                 else if(mval[0]+0.25*dx+tb_mainx > G.curscreen->sizex-6)
1938                 mval[0]= G.curscreen->sizex-6-0.25*dx-tb_mainx;
1939
1940                 if(mval[1]-20+tb_mainy < 6) mval[1]= 6+20 -tb_mainy;
1941                 else if(mval[1]+20+tb_mainy > G.curscreen->sizey-6)
1942                         mval[1]= G.curscreen->sizey-6-20-tb_mainy;
1943
1944                 but=uiDefIconTextBlockBut(block, tb_makemenu, menu1, ICON_RIGHTARROW_THIN, str1, mval[0]+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
1945                 uiButSetFlag(but, UI_MAKE_RIGHT);
1946                 uiButSetFunc(but, store_main, (void *)-32, (void *)-5);
1947
1948                 but=uiDefIconTextBlockBut(block, tb_makemenu, menu2, ICON_RIGHTARROW_THIN, str2, mval[0]+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
1949                 uiButSetFlag(but, UI_MAKE_RIGHT);
1950                 uiButSetFunc(but, store_main, (void *)-32, (void *)15);
1951
1952                 but=uiDefIconTextBlockBut(block, tb_makemenu, menu3, ICON_RIGHTARROW_THIN, str3, mval[0]+tb_mainx,mval[1]+tb_mainy-40, dx, 19, "");
1953                 uiButSetFlag(but, UI_MAKE_RIGHT);
1954                 uiButSetFunc(but, store_main, (void *)-32, (void *)35);
1955
1956                 but=uiDefIconTextBlockBut(block, tb_makemenu, menu4, ICON_RIGHTARROW_THIN, str4, mval[0]+tb_mainx,mval[1]+tb_mainy-60, dx, 19, "");
1957                 uiButSetFlag(but, UI_MAKE_RIGHT);
1958                 uiButSetFunc(but, store_main, (void *)-32, (void *)55);
1959
1960                 but=uiDefIconTextBlockBut(block, tb_makemenu, menu5, ICON_RIGHTARROW_THIN, str5, mval[0]+tb_mainx,mval[1]+tb_mainy-80, dx, 19, "");
1961                 uiButSetFlag(but, UI_MAKE_RIGHT);
1962                 uiButSetFunc(but, store_main, (void *)-32, (void *)75);
1963                 
1964                 if(tot>5) {
1965                         but=uiDefIconTextBlockBut(block, tb_makemenu, menu6, ICON_RIGHTARROW_THIN, str6, mval[0]+tb_mainx,mval[1]+tb_mainy-100, dx, 19, "");
1966                         uiButSetFlag(but, UI_MAKE_RIGHT);
1967                         uiButSetFunc(but, store_main, (void *)-32, (void *)95);
1968                 }
1969                 if(tot>6) {
1970                         but=uiDefIconTextBlockBut(block, tb_makemenu, menu7, ICON_RIGHTARROW_THIN, str7, mval[0]+tb_mainx,mval[1]+tb_mainy-120, dx, 19, "");
1971                         uiButSetFlag(but, UI_MAKE_RIGHT);
1972                         uiButSetFunc(but, store_main, (void *)-32, (void *)105);
1973                 }
1974         }
1975         
1976         uiBoundsBlock(block, 2);
1977         event= uiDoBlocks(&tb_listb, 0);
1978         
1979         /* free all dynamic entries... clumsy! */
1980         if(groupmenu) MEM_freeN(groupmenu);
1981         
1982         if(node_add_in) MEM_freeN(node_add_in);
1983         if(node_add_out) MEM_freeN(node_add_out);
1984         if(node_add_op_col) MEM_freeN(node_add_op_col);
1985         if(node_add_op_filt) MEM_freeN(node_add_op_filt);
1986         if(node_add_op_vec) MEM_freeN(node_add_op_vec);
1987         if(node_add_con) MEM_freeN(node_add_con);
1988         if(node_add_gen) MEM_freeN(node_add_gen);
1989         if(node_add_group) MEM_freeN(node_add_group);
1990         
1991         mywinset(curarea->win);
1992 }
1993
1994 void toolbox_n_add(void)
1995 {
1996         reset_toolbox();
1997         toolbox_n();
1998 }
1999
2000 void reset_toolbox(void)
2001 {
2002         if(U.uiflag & USER_PLAINMENUS) {
2003                 tb_mainx= -32;
2004                 tb_mainy= -5;
2005         } else {
2006                 tb_mainx= 0;
2007                 tb_mainy= -5;
2008         }
2009 }