* Volume Rendering: Voxel data
[blender.git] / source / blender / src / butspace.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 #include <time.h>
31 #include <math.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "blendef.h"
40 #include "MEM_guardedalloc.h"
41
42 #include "DNA_color_types.h"
43 #include "DNA_image_types.h"
44 #include "DNA_material_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_view3d_types.h"
49 #include "DNA_space_types.h"
50 #include "DNA_texture_types.h"
51
52 #include "BKE_colortools.h"
53 #include "BKE_global.h"
54 #include "BKE_main.h"
55 #include "BKE_material.h"
56 #include "BKE_library.h"
57 #include "BKE_utildefines.h"
58
59 #include "BLI_blenlib.h"
60
61 #include "BSE_drawview.h"       // for do_viewbuttons.c .... hurms
62 #include "BSE_node.h"
63
64 #include "BIF_gl.h"
65 #include "BIF_graphics.h"
66 #include "BIF_keyval.h"
67 #include "BIF_interface.h"
68 #include "BIF_toolbox.h"
69 #include "BIF_space.h"
70 #include "BIF_screen.h"
71 #include "BIF_butspace.h"
72 #include "BSE_headerbuttons.h"
73 #include "BIF_previewrender.h"
74 #include "BIF_mywindow.h"
75 #include "BIF_glutil.h"
76 #include "BIF_resources.h"
77
78 #include "IMB_imbuf_types.h"
79 #include "IMB_imbuf.h"
80
81 #include "mydevice.h"
82 #include "butspace.h" // own module
83
84 /************************ function prototypes ***************************/
85 void drawbutspace(ScrArea *, void *);
86
87
88 /* Local vars ---------------------------------------------------------- */
89 short bgpicmode=0, near=1000, far=1000;
90 MTex emptytex;
91 MTex mtexcopybuf;
92
93 char texstr[20][12]= {"None"  , "Clouds" , "Wood", "Marble", "Magic"  , "Blend",
94                                          "Stucci", "Noise"  , "Image", "Plugin", "EnvMap" , "Musgrave",
95                                          "Voronoi", "DistNoise", "", "PointDensity", "VoxelData", "", "", ""};
96 /*  ---------------------------------------------------------------------- */
97
98 void test_idbutton_cb(void *namev, void *arg2)
99 {
100         char *name= namev;
101         
102         test_idbutton(name+2);
103 }
104
105
106 void test_scriptpoin_but(char *name, ID **idpp)
107 {
108         ID *id;
109         
110         id= G.main->text.first;
111         while(id) {
112                 if( strcmp(name, id->name+2)==0 ) {
113                         *idpp= id;
114                         return;
115                 }
116                 id= id->next;
117         }
118         *idpp= NULL;
119 }
120
121 void test_actionpoin_but(char *name, ID **idpp)
122 {
123         ID *id;
124         
125         id= G.main->action.first;
126         while(id) {
127                 if( strcmp(name, id->name+2)==0 ) {
128                         id_us_plus(id);
129                         *idpp= id;
130                         return;
131                 }
132                 id= id->next;
133         }
134         *idpp= NULL;
135 }
136
137
138 void test_obpoin_but(char *name, ID **idpp)
139 {
140         ID *id;
141         
142         if(idpp == (ID **)&(emptytex.object)) {
143                 error("You must add a texture first");
144                 *idpp= 0;
145                 return;
146         }
147         
148         id= G.main->object.first;
149         while(id) {
150                 if( strcmp(name, id->name+2)==0 ) {
151                         *idpp= id;
152                         id_lib_extern(id);      /* checks lib data, sets correct flag for saving then */
153                         return;
154                 }
155                 id= id->next;
156         }
157         *idpp= NULL;
158 }
159
160 /* tests for an object of type OB_MESH */
161 void test_meshobpoin_but(char *name, ID **idpp)
162 {
163         ID *id;
164
165         id = G.main->object.first;
166         while(id) {
167                 Object *ob = (Object *)id;
168                 if(ob->type == OB_MESH && strcmp(name, id->name + 2) == 0) {
169                         *idpp = id;
170                         /* checks lib data, sets correct flag for saving then */
171                         id_lib_extern(id);
172                         return;
173                 }
174                 id = id->next;
175         }
176         *idpp = NULL;
177 }
178
179 void test_meshpoin_but(char *name, ID **idpp)
180 {
181         ID *id;
182
183         if( *idpp ) (*idpp)->us--;
184         
185         id= G.main->mesh.first;
186         while(id) {
187                 if( strcmp(name, id->name+2)==0 ) {
188                         *idpp= id;
189                         id_us_plus(id);
190                         return;
191                 }
192                 id= id->next;
193         }
194         *idpp= NULL;
195 }
196
197 void test_matpoin_but(char *name, ID **idpp)
198 {
199         ID *id;
200
201         if( *idpp ) (*idpp)->us--;
202         
203         id= G.main->mat.first;
204         while(id) {
205                 if( strcmp(name, id->name+2)==0 ) {
206                         *idpp= id;
207                         id_us_plus(id);
208                         return;
209                 }
210                 id= id->next;
211         }
212         *idpp= NULL;
213 }
214
215 void test_scenepoin_but(char *name, ID **idpp)
216 {
217         ID *id;
218         
219         if( *idpp ) (*idpp)->us--;
220         
221         id= G.main->scene.first;
222         while(id) {
223                 if( strcmp(name, id->name+2)==0 ) {
224                         *idpp= id;
225                         id_us_plus(id);
226                         return;
227                 }
228                 id= id->next;
229         }
230         *idpp= NULL;
231 }
232
233 void test_grouppoin_but(char *name, ID **idpp)
234 {
235         ID *id;
236         
237         if( *idpp ) (*idpp)->us--;
238         
239         id= G.main->group.first;
240         while(id) {
241                 if( strcmp(name, id->name+2)==0 ) {
242                         *idpp= id;
243                         id_us_plus(id);
244                         return;
245                 }
246                 id= id->next;
247         }
248         *idpp= NULL;
249 }
250
251 void test_texpoin_but(char *name, ID **idpp)
252 {
253         ID *id;
254         
255         if( *idpp ) (*idpp)->us--;
256         
257         id= G.main->tex.first;
258         while(id) {
259                 if( strcmp(name, id->name+2)==0 ) {
260                         *idpp= id;
261                         id_us_plus(id);
262                         return;
263                 }
264                 id= id->next;
265         }
266         *idpp= NULL;
267 }
268
269 void test_imapoin_but(char *name, ID **idpp)
270 {
271         ID *id;
272         
273         if( *idpp ) (*idpp)->us--;
274         
275         id= G.main->image.first;
276         while(id) {
277                 if( strcmp(name, id->name+2)==0 ) {
278                         *idpp= id;
279                         id_us_plus(id);
280                         return;
281                 }
282                 id= id->next;
283         }
284         *idpp= NULL;
285 }
286
287 /* ----------- custom button group ---------------------- */
288
289 static void curvemap_buttons_zoom_in(void *cumap_v, void *unused)
290 {
291         CurveMapping *cumap = cumap_v;
292         float d;
293         
294         /* we allow 20 times zoom */
295         if( (cumap->curr.xmax - cumap->curr.xmin) > 0.04f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
296                 d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin);
297                 cumap->curr.xmin+= d;
298                 cumap->curr.xmax-= d;
299                 d= 0.1154f*(cumap->curr.ymax - cumap->curr.ymin);
300                 cumap->curr.ymin+= d;
301                 cumap->curr.ymax-= d;
302         }
303 }
304
305 static void curvemap_buttons_zoom_out(void *cumap_v, void *unused)
306 {
307         CurveMapping *cumap = cumap_v;
308         float d, d1;
309         
310         /* we allow 20 times zoom, but dont view outside clip */
311         if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
312                 d= d1= 0.15f*(cumap->curr.xmax - cumap->curr.xmin);
313                 
314                 if(cumap->flag & CUMA_DO_CLIP) 
315                         if(cumap->curr.xmin-d < cumap->clipr.xmin)
316                                 d1= cumap->curr.xmin - cumap->clipr.xmin;
317                 cumap->curr.xmin-= d1;
318                 
319                 d1= d;
320                 if(cumap->flag & CUMA_DO_CLIP) 
321                         if(cumap->curr.xmax+d > cumap->clipr.xmax)
322                                 d1= -cumap->curr.xmax + cumap->clipr.xmax;
323                 cumap->curr.xmax+= d1;
324                 
325                 d= d1= 0.15f*(cumap->curr.ymax - cumap->curr.ymin);
326                 
327                 if(cumap->flag & CUMA_DO_CLIP) 
328                         if(cumap->curr.ymin-d < cumap->clipr.ymin)
329                                 d1= cumap->curr.ymin - cumap->clipr.ymin;
330                 cumap->curr.ymin-= d1;
331                 
332                 d1= d;
333                 if(cumap->flag & CUMA_DO_CLIP) 
334                         if(cumap->curr.ymax+d > cumap->clipr.ymax)
335                                 d1= -cumap->curr.ymax + cumap->clipr.ymax;
336                 cumap->curr.ymax+= d1;
337         }
338 }
339
340 static void curvemap_buttons_setclip(void *cumap_v, void *unused)
341 {
342         CurveMapping *cumap = cumap_v;
343         
344         curvemapping_changed(cumap, 0);
345 }       
346
347 static void curvemap_buttons_delete(void *cumap_v, void *unused)
348 {
349         CurveMapping *cumap = cumap_v;
350         
351         curvemap_remove(cumap->cm+cumap->cur, SELECT);
352         curvemapping_changed(cumap, 0);
353 }
354
355 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
356 static uiBlock *curvemap_clipping_func(void *cumap_v)
357 {
358         CurveMapping *cumap = cumap_v;
359         uiBlock *block;
360         uiBut *bt;
361         
362         block= uiNewBlock(&curarea->uiblocks, "curvemap_clipping_func", UI_EMBOSS, UI_HELV, curarea->win);
363         
364         /* use this for a fake extra empy space around the buttons */
365         uiDefBut(block, LABEL, 0, "",                   -4, 16, 128, 106, NULL, 0, 0, 0, 0, "");
366         
367         bt= uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, "Use Clipping",    
368                                                                                 0,100,120,18, &cumap->flag, 0.0, 0.0, 10, 0, "");
369         uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL);
370
371         uiBlockBeginAlign(block);
372         uiDefButF(block, NUM, 0, "Min X ",       0,74,120,18, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, "");
373         uiDefButF(block, NUM, 0, "Min Y ",       0,56,120,18, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, "");
374         uiDefButF(block, NUM, 0, "Max X ",       0,38,120,18, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, "");
375         uiDefButF(block, NUM, 0, "Max Y ",       0,20,120,18, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, "");
376         
377         uiBlockSetDirection(block, UI_RIGHT);
378         
379         return block;
380 }
381
382
383 static void curvemap_tools_dofunc(void *cumap_v, int event)
384 {
385         CurveMapping *cumap = cumap_v;
386         CurveMap *cuma= cumap->cm+cumap->cur;
387         
388         switch(event) {
389                 case 0:
390                         curvemap_reset(cuma, &cumap->clipr);
391                         curvemapping_changed(cumap, 0);
392                         break;
393                 case 1:
394                         cumap->curr= cumap->clipr;
395                         break;
396                 case 2: /* set vector */
397                         curvemap_sethandle(cuma, 1);
398                         curvemapping_changed(cumap, 0);
399                         break;
400                 case 3: /* set auto */
401                         curvemap_sethandle(cuma, 0);
402                         curvemapping_changed(cumap, 0);
403                         break;
404                 case 4: /* extend horiz */
405                         cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
406                         curvemapping_changed(cumap, 0);
407                         break;
408                 case 5: /* extend extrapolate */
409                         cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
410                         curvemapping_changed(cumap, 0);
411                         break;
412         }
413         addqueue(curarea->win, REDRAW, 1);
414 }
415
416 static uiBlock *curvemap_tools_func(void *cumap_v)
417 {
418         uiBlock *block;
419         short yco= 0, menuwidth=120;
420         
421         block= uiNewBlock(&curarea->uiblocks, "curvemap_tools_func", UI_EMBOSSP, UI_HELV, curarea->win);
422         uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
423         
424         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset View",                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
425         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector Handle",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
426         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Handle",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
427         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Horizontal",              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
428         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Extrapolated",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
429         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Curve",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
430         
431         uiBlockSetDirection(block, UI_RIGHT);
432         uiTextBoundsBlock(block, 50);
433         return block;
434 }
435
436 /* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
437 void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short event, short redraw, rctf *rect)
438 {
439         uiBut *bt;
440         float dx, fy= rect->ymax-18.0f;
441         int icon;
442         short xco, yco;
443         
444         yco= (short)(rect->ymax-18.0f);
445         
446         /* curve choice options + tools/settings, 8 icons + spacer */
447         dx= (rect->xmax-rect->xmin)/(9.0f);
448         
449         uiBlockBeginAlign(block);
450         if(labeltype=='v') {    /* vector */
451                 xco= (short)rect->xmin;
452                 if(cumap->cm[0].curve)
453                         uiDefButI(block, ROW, redraw, "X", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
454                 xco= (short)(rect->xmin+1.0f*dx);
455                 if(cumap->cm[1].curve)
456                         uiDefButI(block, ROW, redraw, "Y", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
457                 xco= (short)(rect->xmin+2.0f*dx);
458                 if(cumap->cm[2].curve)
459                         uiDefButI(block, ROW, redraw, "Z", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
460         }
461         else if(labeltype=='c') { /* color */
462                 xco= (short)rect->xmin;
463                 if(cumap->cm[3].curve)
464                         uiDefButI(block, ROW, redraw, "C", xco, yco+2, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
465                 xco= (short)(rect->xmin+1.0f*dx);
466                 if(cumap->cm[0].curve)
467                         uiDefButI(block, ROW, redraw, "R", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
468                 xco= (short)(rect->xmin+2.0f*dx);
469                 if(cumap->cm[1].curve)
470                         uiDefButI(block, ROW, redraw, "G", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
471                 xco= (short)(rect->xmin+3.0f*dx);
472                 if(cumap->cm[2].curve)
473                         uiDefButI(block, ROW, redraw, "B", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
474         }
475         /* else no channels ! */
476         uiBlockEndAlign(block);
477
478         xco= (short)(rect->xmin+4.5f*dx);
479         uiBlockSetEmboss(block, UI_EMBOSSN);
480         bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMIN, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in");
481         uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL);
482         
483         xco= (short)(rect->xmin+5.25f*dx);
484         bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMOUT, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out");
485         uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL);
486         
487         xco= (short)(rect->xmin+6.0f*dx);
488         bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, event, ICON_MODIFIER, xco, yco, dx, 18, "Tools");
489         
490         xco= (short)(rect->xmin+7.0f*dx);
491         if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT;
492         bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, event, icon, xco, yco, dx, 18, "Clipping Options");
493         
494         xco= (short)(rect->xmin+8.0f*dx);
495         bt= uiDefIconBut(block, BUT, event, ICON_X, xco, yco, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points");
496         uiButSetFunc(bt, curvemap_buttons_delete, cumap, NULL);
497         
498         uiBlockSetEmboss(block, UI_EMBOSS);
499         
500         uiDefBut(block, BUT_CURVE, event, "", 
501                           rect->xmin, rect->ymin, rect->xmax-rect->xmin, fy-rect->ymin, 
502                           cumap, 0.0f, 1.0f, 0, 0, "");
503         
504         
505 }
506
507
508 /* --------------------------------- */
509
510 /* nodes have button callbacks, that can draw in butspace too. need separate handling */
511 static void do_node_buts(unsigned short event)
512 {
513         Material *ma;
514         SpaceNode *snode = curarea->spacedata.first;
515         
516         /* all operations default on active material layer here */
517         /* but this also gets called for lamp and world... */
518         ma= G.buts->lockpoin;
519         if(ma && GS(ma->id.name)==ID_MA)
520                 ma = editnode_get_active_material(ma);
521         else
522                 ma= NULL;
523         
524         if(event>=B_NODE_EXEC) {
525                 if(ma) end_render_material(ma); /// temporal... 3d preview
526                 BIF_preview_changed(ID_MA);
527                 BIF_preview_changed(ID_TE);
528                 allqueue(REDRAWNODE, 0);
529                 allqueue(REDRAWBUTSSHADING, 0);
530         }               
531 }
532
533 void do_butspace(unsigned short event)
534 {
535         SpaceButs *buts;
536
537         /* redraw windows of the same type? */
538         buts= curarea->spacedata.first;
539         if(buts->mainb==CONTEXT_SCENE) allqueue(REDRAWBUTSSCENE, curarea->win);
540         if(buts->mainb==CONTEXT_OBJECT) allqueue(REDRAWBUTSOBJECT, curarea->win);
541         if(buts->mainb==CONTEXT_SHADING) allqueue(REDRAWBUTSSHADING, curarea->win);
542         if(buts->mainb==CONTEXT_EDITING) allqueue(REDRAWBUTSEDIT, curarea->win);
543         if(buts->mainb==CONTEXT_SCRIPT) allqueue(REDRAWBUTSSCRIPT, curarea->win);
544         if(buts->mainb==CONTEXT_LOGIC) allqueue(REDRAWBUTSLOGIC, curarea->win);
545
546         if (event <=50){
547                 do_global_buttons2(event);
548         }
549         else if(event<=100) {
550                 do_global_buttons(event);
551         }
552         else if(event < 1000) {
553                 do_headerbuttons(event);
554         }
555         else if(event<=B_VIEWBUTS) {
556                 do_viewbuts(event);
557         }
558         else if(event<=B_LAMPBUTS) {
559                 do_lampbuts(event);
560         }
561         else if(event<=B_MATBUTS) {
562                 do_matbuts(event);
563         }
564         else if(event<=B_TEXBUTS) {
565                 do_texbuts(event);
566         }
567         else if(event<=B_ANIMBUTS) {
568                 do_object_panels(event);
569         }
570         else if(event<=B_WORLDBUTS) {
571                 do_worldbuts(event);
572         }
573         else if(event<=B_RENDERBUTS) {
574                 do_render_panels(event);        // buttons_scene.c
575         }
576         else if(event<=B_SEQUENCERBUTS) {
577                 do_sequencer_panels(event);
578         }
579         else if(event<=B_COMMONEDITBUTS) {
580                 do_common_editbuts(event);
581         }
582         else if(event<=B_MESHBUTS) {
583                 do_meshbuts(event);
584         }
585         else if(event<=B_VGROUPBUTS) {
586                 do_vgroupbuts(event);
587         }
588         else if(event<=B_CURVEBUTS) {
589                 do_curvebuts(event);
590         }
591         else if(event<=B_FONTBUTS) {
592                 do_fontbuts(event);
593         }
594         else if(event<=B_ARMBUTS) {
595                 do_armbuts(event);
596         }
597         else if(event<=B_CAMBUTS) {
598                 do_cambuts(event);
599         }
600         else if(event<=B_MBALLBUTS) {
601                 do_mballbuts(event);
602         }
603         else if(event<=B_LATTBUTS) {
604                 do_latticebuts(event);
605         }
606         else if(event<=B_GAMEBUTS) {
607                 do_logic_buts(event);   // buttons_logic.c
608         }
609         else if(event<=B_FPAINTBUTS) {
610                 do_fpaintbuts(event);
611         }
612         else if(event<=B_RADIOBUTS) {
613                 do_radiobuts(event);
614         }
615         else if(event<=B_SCRIPTBUTS) {
616                 do_scriptbuts(event);
617         }
618         else if(event<=B_SOUNDBUTS) {
619                 do_soundbuts(event);
620         }
621         else if(event<=B_CONSTRAINTBUTS) {
622                 do_constraintbuts(event);
623         }
624         else if(event<=B_UVAUTOCALCBUTS) {
625                 do_uvcalculationbuts(event);
626         }
627         else if(event<=B_EFFECTSBUTS) {
628                 do_effects_panels(event);
629         }
630         else if(event<=B_MODIFIER_BUTS) {
631                 extern void do_modifier_panels(unsigned short event);
632                 do_modifier_panels(event);
633         }
634         else if(event<=B_NODE_BUTS) {
635                 do_node_buts(event);
636         }
637         else if(event==REDRAWVIEW3D) allqueue(event, 1);        // 1=do header too
638         else if(event>REDRAWVIEW3D) allqueue(event, 0);
639 }
640
641 static void butspace_context_switch(SpaceButs *buts, Object *new)
642 {
643         // change type automatically
644         if(new) {
645                 int tab= buts->tab[CONTEXT_SHADING];
646                 
647                 if(tab == TAB_SHADING_WORLD) {
648                         if(new->type==OB_CAMERA);
649                         else if(new->type==OB_LAMP) {
650                                 buts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
651                         }
652                         else buts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
653                         
654                 }
655                 else if(tab == TAB_SHADING_TEX) {
656                         if(new->type==OB_LAMP) buts->texfrom= 2;
657                         else if(new->type==OB_CAMERA) buts->texfrom= 1;
658                         else buts->texfrom= 0;
659                 }
660                 else if(tab == TAB_SHADING_RAD) {
661                 }
662                 else if(new->type==OB_CAMERA) {
663                         buts->tab[CONTEXT_SHADING]= TAB_SHADING_WORLD;
664                 }
665                 else if(new->type==OB_LAMP) {
666                         buts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
667                 }
668                 else {
669                         buts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
670                 }
671         }
672 }
673
674 /* new active object */
675 void redraw_test_buttons(Object *new)
676 {
677         ScrArea *sa;
678         SpaceButs *buts;
679         
680         sa= G.curscreen->areabase.first;
681         while(sa) {
682                 if(sa->spacetype==SPACE_BUTS) {
683                         buts= sa->spacedata.first;
684                         
685                         if(ELEM5(buts->mainb, CONTEXT_OBJECT, CONTEXT_EDITING, CONTEXT_SHADING, CONTEXT_LOGIC, CONTEXT_SCRIPT)) {
686                                 addqueue(sa->win, REDRAW, 1);
687                                 buts->re_align= 1;
688                         
689                                 if(new && buts->mainb==CONTEXT_SHADING) {
690                                         /* does node previews too... */
691                                         BIF_preview_changed(ID_TE);
692                                 }
693                         }
694                         // always do context switch
695                         if(new) butspace_context_switch(buts, new);
696
697                 }
698                 sa= sa->next;
699         }
700 }
701
702
703 /* callback */
704 void drawbutspace(ScrArea *sa, void *spacedata)
705 {
706         ID *id, *idfrom;
707         SpaceButs *sbuts= sa->spacedata.first;
708         View2D *v2d= &sbuts->v2d;
709         float col[3];
710         int tab, align=0;
711         
712         /* context */
713         buttons_active_id(&id, &idfrom);
714         G.buts->lockpoin= id;
715         
716         myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax);
717
718         BIF_GetThemeColor3fv(TH_BACK, col);
719         glClearColor(col[0], col[1], col[2], 0.0); 
720         glClear(GL_COLOR_BUFFER_BIT);
721
722         uiSetButLock(G.scene->id.lib!=0, ERROR_LIBDATA_MESSAGE);        
723         uiFreeBlocksWin(&sa->uiblocks, sa->win);
724  
725         /* select the context to be drawn, per contex/tab the actual context is tested */
726         switch(sbuts->mainb) {
727         case CONTEXT_SCENE:
728                 tab= sbuts->tab[CONTEXT_SCENE];
729
730                 if(tab== TAB_SCENE_RENDER) 
731                         render_panels();
732                 else if(tab == TAB_SCENE_SEQUENCER)
733                         sequencer_panels();
734                 else if(tab == TAB_SCENE_ANIM) 
735                         anim_panels();
736                 else if(tab == TAB_SCENE_SOUND) 
737                         sound_panels();
738
739                 break;
740         case CONTEXT_OBJECT:
741                 tab= sbuts->tab[CONTEXT_OBJECT];
742                 
743                 if(tab==TAB_OBJECT_OBJECT)
744                    object_panels();
745                 else if(tab==TAB_OBJECT_PHYSICS)
746                         physics_panels();
747                 else if(tab==TAB_OBJECT_PARTICLE)
748                         particle_panels();
749                    
750                 break;
751         case CONTEXT_SHADING:
752                 tab= sbuts->tab[CONTEXT_SHADING];
753                 
754                 if(tab==TAB_SHADING_MAT)
755                         material_panels();
756                 else if(tab==TAB_SHADING_LAMP)
757                         lamp_panels();
758                 else if(tab==TAB_SHADING_WORLD)
759                         world_panels();
760                 else if(tab==TAB_SHADING_RAD)
761                         radio_panels();
762                 else if(tab==TAB_SHADING_TEX)
763                         texture_panels();
764                         
765                 break;
766         case CONTEXT_EDITING:
767                 /* no tabs */
768                 editing_panels();
769
770                 break;
771         case CONTEXT_SCRIPT:
772                 script_panels();
773                 
774                 break;
775         case CONTEXT_LOGIC:
776                 /* no tabs */
777                 logic_buts();
778                 break;
779         }
780
781         uiClearButLock();
782
783         /* when align changes, also do this for new panels */
784         /* don't always align, this function is called during AnmatePanels too */
785         if(sbuts->align)
786                 if(sbuts->re_align || sbuts->mainbo!=sbuts->mainb || sbuts->tabo!=sbuts->tab[sbuts->mainb])
787                         align= 1;
788
789         uiDrawBlocksPanels(sa, align);  
790         
791         /* since panels give different layouts, we have to make sure v2d.tot matches */
792         uiMatchPanel_view2d(sa);
793
794         sbuts->re_align= 0;
795         // also for memory for finding which texture you'd like to see
796         sbuts->mainbo= sbuts->mainb;
797         sbuts->tabo= sbuts->tab[sbuts->mainb];
798
799         myortho2(-0.375, (float)(sa->winx)-0.375, -0.375, (float)(sa->winy)-0.375);
800         draw_area_emboss(sa);
801         myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax);
802
803         /* always in end */
804         sa->win_swap= WIN_BACK_OK;
805 }
806
807