4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
42 #include "MEM_guardedalloc.h"
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"
53 #include "BKE_colortools.h"
54 #include "BKE_global.h"
56 #include "BKE_material.h"
57 #include "BKE_library.h"
58 #include "BKE_utildefines.h"
60 #include "BLI_blenlib.h"
62 #include "BSE_drawview.h" // for do_viewbuttons.c .... hurms
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"
80 #include "butspace.h" // own module
82 /************************ function prototypes ***************************/
83 void drawbutspace(ScrArea *, void *);
86 /* Local vars ---------------------------------------------------------- */
87 short bgpicmode=0, near=1000, far=1000;
91 char texstr[20][12]= {"None" , "Clouds" , "Wood", "Marble", "Magic" , "Blend",
92 "Stucci", "Noise" , "Image", "Plugin", "EnvMap" , "Musgrave",
93 "Voronoi", "DistNoise", "", "", "", "", "", ""};
94 /* ---------------------------------------------------------------------- */
96 void test_idbutton_cb(void *namev, void *arg2_unused)
99 test_idbutton(name+2);
103 void test_scriptpoin_but(char *name, ID **idpp)
107 id= G.main->text.first;
109 if( strcmp(name, id->name+2)==0 ) {
118 void test_actionpoin_but(char *name, ID **idpp)
122 id= G.main->action.first;
124 if( strcmp(name, id->name+2)==0 ) {
125 id_lib_extern(id); /* checks lib data, sets correct flag for saving then */
135 void test_obpoin_but(char *name, ID **idpp)
139 if(idpp == (ID **)&(emptytex.object)) {
140 error("You must add a texture first");
145 id= G.main->object.first;
147 if( strcmp(name, id->name+2)==0 ) {
149 id_lib_extern(id); /* checks lib data, sets correct flag for saving then */
157 void test_meshpoin_but(char *name, ID **idpp)
161 if( *idpp ) (*idpp)->us--;
163 id= G.main->mesh.first;
165 if( strcmp(name, id->name+2)==0 ) {
175 void test_matpoin_but(char *name, ID **idpp)
179 if( *idpp ) (*idpp)->us--;
181 id= G.main->mat.first;
183 if( strcmp(name, id->name+2)==0 ) {
193 void test_scenepoin_but(char *name, ID **idpp)
197 if( *idpp ) (*idpp)->us--;
199 id= G.main->scene.first;
201 if( strcmp(name, id->name+2)==0 ) {
211 void test_grouppoin_but(char *name, ID **idpp)
215 if( *idpp ) (*idpp)->us--;
217 id= G.main->group.first;
219 if( strcmp(name, id->name+2)==0 ) {
229 void test_texpoin_but(char *name, ID **idpp)
233 if( *idpp ) (*idpp)->us--;
235 id= G.main->tex.first;
237 if( strcmp(name, id->name+2)==0 ) {
247 void test_imapoin_but(char *name, ID **idpp)
251 if( *idpp ) (*idpp)->us--;
253 id= G.main->image.first;
255 if( strcmp(name, id->name+2)==0 ) {
265 /* ----------- custom button group ---------------------- */
267 static void curvemap_buttons_zoom_in(void *cumap_v, void *unused)
269 CurveMapping *cumap = cumap_v;
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;
283 static void curvemap_buttons_zoom_out(void *cumap_v, void *unused)
285 CurveMapping *cumap = cumap_v;
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);
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;
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;
302 d= d1= 0.15f*(cumap->curr.ymax - cumap->curr.ymin);
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;
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;
316 static void curvemap_buttons_setclip(void *cumap_v, void *unused)
318 CurveMapping *cumap = cumap_v;
320 curvemapping_changed(cumap, 0);
323 static void curvemap_buttons_delete(void *cumap_v, void *unused)
325 CurveMapping *cumap = cumap_v;
327 curvemap_remove(cumap->cm+cumap->cur, SELECT);
328 curvemapping_changed(cumap, 0);
331 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
332 static uiBlock *curvemap_clipping_func(void *cumap_v)
334 CurveMapping *cumap = cumap_v;
338 block= uiNewBlock(&curarea->uiblocks, "curvemap_clipping_func", UI_EMBOSS, UI_HELV, curarea->win);
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, "");
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);
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, "");
353 uiBlockSetDirection(block, UI_RIGHT);
359 static void curvemap_tools_dofunc(void *cumap_v, int event)
361 CurveMapping *cumap = cumap_v;
362 CurveMap *cuma= cumap->cm+cumap->cur;
366 curvemap_reset(cuma, &cumap->clipr);
367 curvemapping_changed(cumap, 0);
370 cumap->curr= cumap->clipr;
372 case 2: /* set vector */
373 curvemap_sethandle(cuma, 1);
374 curvemapping_changed(cumap, 0);
376 case 3: /* set auto */
377 curvemap_sethandle(cuma, 0);
378 curvemapping_changed(cumap, 0);
381 addqueue(curarea->win, REDRAW, 1);
384 static uiBlock *curvemap_tools_func(void *cumap_v)
387 short yco= 0, menuwidth=120;
389 block= uiNewBlock(&curarea->uiblocks, "curvemap_tools_func", UI_EMBOSSP, UI_HELV, curarea->win);
390 uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
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, "");
397 uiBlockSetDirection(block, UI_RIGHT);
398 uiTextBoundsBlock(block, 50);
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)
406 float dx, fy= rect->ymax-18.0f;
410 yco= (short)(rect->ymax-18.0f);
412 /* curve choice options + tools/settings, 8 icons + spacer */
413 dx= (rect->xmax-rect->xmin)/(9.0f);
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, "");
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, "");
441 /* else no channels ! */
442 uiBlockEndAlign(block);
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);
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);
453 xco= (short)(rect->xmin+6.0f*dx);
454 bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, event, ICON_MODIFIER, xco, yco, dx, 18, "Tools");
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");
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);
464 uiBlockSetEmboss(block, UI_EMBOSS);
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, "");
474 /* --------------------------------- */
476 /* nodes have button callbacks, that can draw in butspace too. need separate handling */
477 static void do_node_buts(unsigned short event)
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);
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);
497 void do_butspace(unsigned short event)
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);
511 do_global_buttons2(event);
513 else if(event<=100) {
514 do_global_buttons(event);
516 else if(event < 1000) {
517 do_headerbuttons(event);
519 else if(event<=B_VIEWBUTS) {
522 else if(event<=B_LAMPBUTS) {
525 else if(event<=B_MATBUTS) {
528 else if(event<=B_TEXBUTS) {
531 else if(event<=B_ANIMBUTS) {
532 do_object_panels(event);
534 else if(event<=B_WORLDBUTS) {
537 else if(event<=B_RENDERBUTS) {
538 do_render_panels(event); // buttons_scene.c
540 else if(event<=B_COMMONEDITBUTS) {
541 do_common_editbuts(event);
543 else if(event<=B_MESHBUTS) {
546 else if(event<=B_CURVEBUTS) {
549 else if(event<=B_FONTBUTS) {
552 else if(event<=B_ARMBUTS) {
555 else if(event<=B_CAMBUTS) {
558 else if(event<=B_MBALLBUTS) {
561 else if(event<=B_LATTBUTS) {
562 do_latticebuts(event);
564 else if(event<=B_GAMEBUTS) {
565 do_logic_buts(event); // buttons_logic.c
567 else if(event<=B_FPAINTBUTS) {
568 do_fpaintbuts(event);
570 else if(event<=B_RADIOBUTS) {
573 else if(event<=B_SCRIPTBUTS) {
574 do_scriptbuts(event);
576 else if(event<=B_SOUNDBUTS) {
579 else if(event<=B_CONSTRAINTBUTS) {
580 do_constraintbuts(event);
582 else if(event<=B_UVAUTOCALCBUTS) {
583 do_uvcalculationbuts(event);
585 else if(event<=B_EFFECTSBUTS) {
586 do_effects_panels(event);
588 else if(event<=B_MODIFIER_BUTS) {
589 extern void do_modifier_panels(unsigned short event);
590 do_modifier_panels(event);
592 else if(event<=B_NODE_BUTS) {
595 else if(event==REDRAWVIEW3D) allqueue(event, 1); // 1=do header too
596 else if(event>REDRAWVIEW3D) allqueue(event, 0);
599 static void butspace_context_switch(SpaceButs *buts, Object *new)
601 // change type automatically
603 int tab= buts->tab[CONTEXT_SHADING];
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;
610 else buts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
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;
618 else if(tab == TAB_SHADING_RAD) {
620 else if(new->type==OB_CAMERA) {
621 buts->tab[CONTEXT_SHADING]= TAB_SHADING_WORLD;
623 else if(new->type==OB_LAMP) {
624 buts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
627 buts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
632 /* new active object */
633 void redraw_test_buttons(Object *new)
638 sa= G.curscreen->areabase.first;
640 if(sa->spacetype==SPACE_BUTS) {
641 buts= sa->spacedata.first;
643 if(ELEM5(buts->mainb, CONTEXT_OBJECT, CONTEXT_EDITING, CONTEXT_SHADING, CONTEXT_LOGIC, CONTEXT_SCRIPT)) {
644 addqueue(sa->win, REDRAW, 1);
647 if(new && buts->mainb==CONTEXT_SHADING) {
648 /* does node previews too... */
649 BIF_preview_changed(ID_TE);
652 // always do context switch
653 if(new) butspace_context_switch(buts, new);
662 void drawbutspace(ScrArea *sa, void *spacedata)
664 SpaceButs *sbuts= sa->spacedata.first;
665 View2D *v2d= &sbuts->v2d;
669 myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax);
671 BIF_GetThemeColor3fv(TH_BACK, col);
672 glClearColor(col[0], col[1], col[2], 0.0);
673 glClear(GL_COLOR_BUFFER_BIT);
675 uiSetButLock(G.scene->id.lib!=0, "Can't edit library data");
676 uiFreeBlocksWin(&sa->uiblocks, sa->win);
678 /* select the context to be drawn, per contex/tab the actual context is tested */
679 switch(sbuts->mainb) {
681 tab= sbuts->tab[CONTEXT_SCENE];
683 if(tab== TAB_SCENE_RENDER)
685 else if(tab == TAB_SCENE_ANIM)
687 else if(tab == TAB_SCENE_SOUND)
692 tab= sbuts->tab[CONTEXT_OBJECT];
694 if(tab==TAB_OBJECT_OBJECT)
696 else if(tab==TAB_OBJECT_PHYSICS)
700 case CONTEXT_SHADING:
701 tab= sbuts->tab[CONTEXT_SHADING];
703 if(tab==TAB_SHADING_MAT)
705 else if(tab==TAB_SHADING_LAMP)
707 else if(tab==TAB_SHADING_WORLD)
709 else if(tab==TAB_SHADING_RAD)
711 else if(tab==TAB_SHADING_TEX)
715 case CONTEXT_EDITING:
732 /* when align changes, also do this for new panels */
733 /* don't always align, this function is called during AnmatePanels too */
735 if(sbuts->re_align || sbuts->mainbo!=sbuts->mainb || sbuts->tabo!=sbuts->tab[sbuts->mainb])
738 uiDrawBlocksPanels(sa, align);
740 /* since panels give different layouts, we have to make sure v2d.tot matches */
741 uiMatchPanel_view2d(sa);
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];
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);
753 sa->win_swap= WIN_BACK_OK;