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