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