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