2 * header_buttonswin.c oct-2003
4 * Functions to draw the "Buttons Window" window header
5 * and handle user events sent to it.
9 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version. The Blender
15 * Foundation also sells licenses for use in proprietary software under
16 * the Blender License. See http://www.blender.org/BL/ for information
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29 * All rights reserved.
31 * The Original Code is: all of this file.
33 * Contributor(s): none yet.
35 * ***** END GPL/BL DUAL LICENSE BLOCK *****
46 #include "BLI_winstuff.h"
50 #include "BIF_language.h"
56 #include "DNA_armature_types.h"
57 #include "DNA_lamp_types.h"
58 #include "DNA_material_types.h"
59 #include "DNA_object_types.h"
60 #include "DNA_scene_types.h"
61 #include "DNA_screen_types.h"
62 #include "DNA_space_types.h"
63 #include "DNA_texture_types.h"
64 #include "DNA_world_types.h"
66 #include "BIF_editconstraint.h"
67 #include "BIF_interface.h"
68 #include "BIF_previewrender.h"
69 #include "BIF_resources.h"
70 #include "BIF_screen.h"
71 #include "BIF_space.h"
72 #include "BIF_butspace.h"
74 #include "BKE_armature.h"
75 #include "BKE_global.h"
76 #include "BKE_library.h"
78 #include "BKE_material.h"
79 #include "BKE_texture.h"
80 #include "BKE_utildefines.h"
81 #include "BSE_drawipo.h"
82 #include "BSE_headerbuttons.h"
84 #include "MEM_guardedalloc.h"
92 void clear_matcopybuf(void)
94 memset(&matcopybuf, 0, sizeof(Material));
97 void free_matcopybuf(void)
99 extern MTex mtexcopybuf; /* buttons.c */
103 if(matcopybuf.mtex[a]) {
104 MEM_freeN(matcopybuf.mtex[a]);
105 matcopybuf.mtex[a]= 0;
109 default_mtex(&mtexcopybuf);
112 void do_buts_buttons(short event)
114 static short matcopied=0;
120 if(curarea->win==0) return;
124 uiSetPanel_view2d(curarea);
125 G.v2d->cur= G.v2d->tot;
126 test_view2d(G.v2d, curarea->winx, curarea->winy);
128 /* we always put in left/top */
129 dy= G.v2d->tot.ymax - G.v2d->cur.ymax;
130 G.v2d->cur.ymin += dy;
131 G.v2d->cur.ymax += dy;
132 dx= G.v2d->tot.xmin - G.v2d->cur.xmin;
133 G.v2d->cur.xmin += dx;
134 G.v2d->cur.xmax += dx;
136 scrarea_queue_winredraw(curarea);
139 BIF_preview_changed(G.buts);
140 scrarea_queue_headredraw(curarea);
141 scrarea_queue_winredraw(curarea);
144 if(G.buts->lockpoin) {
146 if(matcopied) free_matcopybuf();
148 memcpy(&matcopybuf, G.buts->lockpoin, sizeof(Material));
150 mtex= matcopybuf.mtex[a];
152 matcopybuf.mtex[a]= MEM_dupallocN(mtex);
159 if(matcopied && G.buts->lockpoin) {
160 ma= G.buts->lockpoin;
161 /* free current mat */
164 if(mtex && mtex->tex) mtex->tex->id.us--;
165 if(mtex) MEM_freeN(mtex);
169 memcpy(G.buts->lockpoin, &matcopybuf, sizeof(Material));
175 ma->mtex[a]= MEM_dupallocN(mtex);
176 if(mtex->tex) id_us_plus((ID *)mtex->tex);
179 BIF_preview_changed(G.buts);
180 scrarea_queue_winredraw(curarea);
184 allqueue(REDRAWBUTSEDIT, 0);
185 allqueue(REDRAWVIEW3D, 0);
190 void buttons_active_id(ID **id, ID **idfrom)
198 if(G.buts->mainb==CONTEXT_SCENE) {
199 int tab= G.buts->tab[CONTEXT_SCENE];
201 if(tab==TAB_SCENE_RENDER) *id= (ID *)G.scene;
202 else if(tab==TAB_SCENE_SOUND) {
205 // validate lockpoin, maybe its not a sound
206 if (G.buts->lockpoin) {
207 search = G.main->sound.first;
209 if (search == G.buts->lockpoin) {
212 search = search->next;
214 if (search == NULL) {
215 *id = G.main->sound.first;
221 *id = G.main->sound.first;
226 else if(G.buts->mainb==CONTEXT_SHADING) {
227 int tab= G.buts->tab[CONTEXT_SHADING];
229 if(tab==TAB_SHADING_LAMP) {
230 if(ob && ob->type==OB_LAMP) {
234 else if(tab==TAB_SHADING_MAT) {
235 if(ob && (ob->type<OB_LAMP) && ob->type) {
236 *id= (ID *)give_current_material(ob, ob->actcol);
237 *idfrom= material_from(ob, ob->actcol);
240 else if(tab==TAB_SHADING_WORLD) {
241 *id= (ID *)G.scene->world;
242 *idfrom= (ID *)G.scene;
244 else if(tab==TAB_SHADING_TEX) {
247 if(G.buts->mainbo==G.buts->mainb && G.buts->tabo!=tab) {
248 if(G.buts->tabo==TAB_SHADING_LAMP) G.buts->texfrom= 2;
249 else if(G.buts->tabo==TAB_SHADING_WORLD) G.buts->texfrom= 1;
250 else if(G.buts->tabo==TAB_SHADING_MAT) G.buts->texfrom= 0;
253 if(G.buts->texfrom==0) {
254 if(ob && ob->type<OB_LAMP && ob->type) {
255 ma= give_current_material(ob, ob->actcol);
258 mtex= ma->mtex[ ma->texact ];
259 if(mtex) *id= (ID *)mtex->tex;
263 else if(G.buts->texfrom==1) {
264 World *wrld= G.scene->world;
267 mtex= wrld->mtex[ wrld->texact];
268 if(mtex) *id= (ID *)mtex->tex;
271 else if(G.buts->texfrom==2) {
273 if(ob && ob->type==OB_LAMP) {
276 mtex= la->mtex[ la->texact];
277 if(mtex) *id= (ID *)mtex->tex;
282 else if(G.buts->mainb==CONTEXT_OBJECT || G.buts->mainb==CONTEXT_LOGIC) {
284 *idfrom= (ID *)G.scene;
288 else if(G.buts->mainb==CONTEXT_EDITING) {
296 static void validate_bonebutton(void *bonev, void *data2_unused){
300 arm = get_armature(G.obpose);
301 unique_bone_name(bone, arm);
305 static int bonename_exists(Bone *orig, char *name, ListBase *list)
309 for (curbone=list->first; curbone; curbone=curbone->next){
310 /* Check this bone */
312 if (!strcmp(curbone->name, name))
317 if (bonename_exists(orig, name, &curbone->childbase))
325 static void unique_bone_name (Bone *bone, bArmature *arm)
335 strcpy(oldname, bone->name);
337 /* See if we even need to do this */
338 if (!bonename_exists(bone, bone->name, &arm->bonebase))
341 /* Strip off the suffix */
342 dot=strchr(bone->name, '.');
346 for (number = 1; number <=999; number++){
347 sprintf (tempname, "%s.%03d", bone->name, number);
349 if (!bonename_exists(bone, tempname, &arm->bonebase)){
350 strcpy (bone->name, tempname);
356 static uiBlock *sbuts_context_menu(void *arg_unused)
361 block= uiNewBlock(&curarea->uiblocks, "context_options", UI_EMBOSSP, UI_HELV, curarea->headwin);
363 /* should be branches from tree */
364 uiDefIconTextButS(block, BUTM, B_REDR, ICON_SCENE_DEHLT, "Scene|F10", 0, yco-=22, 100, 20, &G.buts->mainb, 0.0, 0.0, 0, 0, "");
365 uiDefIconTextButS(block, BUTM, B_REDR, ICON_EDIT, "Editing|F9", 0, yco-=22, 100, 20, &G.buts->mainb, 4.0, 0.0, 0, 0, "");
366 uiDefIconTextButS(block, BUTM, B_REDR, ICON_OBJECT, "Object|F6", 0, yco-=22, 100, 20, &G.buts->mainb, 1.0, 0.0, 0, 0, "");
367 uiDefIconTextButS(block, BUTM, B_REDR, ICON_MATERIAL_DEHLT, "Shading|F5", 0, yco-=22, 100, 20, &G.buts->mainb, 3.0, 0.0, 0, 0, "");
368 uiDefIconTextButS(block, BUTM, B_REDR, ICON_GAME, "Logic|F4", 0, yco-=22, 100, 20, &G.buts->mainb, 6.0, 0.0, 0, 0, "");
369 uiDefIconTextButS(block, BUTM, B_REDR, ICON_SCRIPT, "Script", 0, yco-=22, 100, 20, &G.buts->mainb, 5.0, 0.0, 0, 0, "");
371 if(curarea->headertype==HEADERTOP) {
372 uiBlockSetDirection(block, UI_DOWN);
375 uiBlockSetDirection(block, UI_TOP);
376 uiBlockFlipOrder(block);
383 static void do_buts_viewmenu(void *arg, int event)
385 SpaceButs *sbuts= curarea->spacedata.first;
388 case 0: /* panel alignment */
393 uiAlignPanelStep(curarea, 1.0);
394 do_buts_buttons(B_BUTSHOME);
397 case 3: /* View All */
398 do_buts_buttons(B_BUTSHOME);
400 case 4: /* Maximize Window */
401 /* using event B_FULL */
404 allqueue(REDRAWVIEW3D, 0);
407 static uiBlock *buts_viewmenu(void *arg_unused)
409 SpaceButs *sbuts= curarea->spacedata.first;
411 short yco= 0, menuwidth=120;
413 block= uiNewBlock(&curarea->uiblocks, "buts_viewmenu",
414 UI_EMBOSSP, UI_HELV, curarea->headwin);
415 uiBlockSetButmFunc(block, do_buts_viewmenu, NULL);
417 if (sbuts->align == 1) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Horizontal Align", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
418 else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Horizontal Align", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
420 if (sbuts->align == 2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Vertical Align", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
421 else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Vertical Align", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
423 if (sbuts->align == 0) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Free Align", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
424 else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Free Align", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
426 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
428 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
431 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
433 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
435 if(curarea->headertype==HEADERTOP) {
436 uiBlockSetDirection(block, UI_DOWN);
439 uiBlockSetDirection(block, UI_TOP);
440 uiBlockFlipOrder(block);
443 uiTextBoundsBlock(block, 50);
448 void buts_buttons(void)
452 short xco, xmax, t_base= 0;
455 sprintf(naam, "header %d", curarea->headwin);
456 block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin);
458 if(area_is_active_area(curarea)) uiBlockSetCol(block, TH_HEADER);
459 else uiBlockSetCol(block, TH_HEADERDESEL);
461 curarea->butspacetype= SPACE_BUTS;
465 uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D,
466 windowtype_pup(), xco, 0, XIC+10, YIC,
467 &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0,
468 "Displays Current Window Type. "
469 "Click for menu of available types.");
473 uiBlockSetEmboss(block, UI_EMBOSSN);
474 if (curarea->flag & HEADER_NO_PULLDOWN) {
475 uiDefIconButS(block, TOG|BIT|0, B_FLIPINFOMENU,
476 ICON_DISCLOSURE_TRI_RIGHT,
478 &(curarea->flag), 0, 0, 0, 0,
479 "Show pulldown menus");
482 uiDefIconButS(block, TOG|BIT|0, B_FLIPINFOMENU,
483 ICON_DISCLOSURE_TRI_DOWN,
485 &(curarea->flag), 0, 0, 0, 0,
486 "Hide pulldown menus");
488 uiBlockSetEmboss(block, UI_EMBOSS);
491 if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
492 /* pull down menus */
493 uiBlockSetEmboss(block, UI_EMBOSSP);
495 xmax= GetButStringLength("Panels");
496 uiDefBlockBut(block, buts_viewmenu, NULL,
497 "Panels", xco, -2, xmax-3, 24, "");
502 uiBlockSetEmboss(block, UI_EMBOSSX);
506 // if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Returns to multiple views window (CTRL+Up arrow)");
507 // else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Makes current window full screen (CTRL+Down arrow)");
510 // uiDefIconBut(block, BUT, B_BUTSHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms window to home view showing all items (HOMEKEY)");
514 /* (this could be done later with a dynamic tree and branches, also for python) */
516 // char mainbname[8][12]= {" Scene", " Object", " Types", " Shading", " Editing", " Script", " Logic"};
517 // char mainbicon[8]= {ICON_SCENE_DEHLT, ICON_OBJECT, ICON_BBOX, ICON_MATERIAL_DEHLT, ICON_EDIT, ICON_SCRIPT, ICON_GAME};
518 // uiBut *but= uiDefIconTextBlockBut(block, sbuts_context_menu, NULL, mainbicon[G.buts->mainb], mainbname[G.buts->mainb], xco, 0, 90, YIC, "Set main context for button panels");
519 // uiButClearFlag(but, UI_ICON_RIGHT); // this type has both flags set, and draws icon right.. uhh
522 uiBlockBeginAlign(block);
523 uiDefIconButS(block, ROW, B_REDR, ICON_GAME, xco, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_LOGIC, 0, 0, "Logic (F4) ");
524 uiDefIconButS(block, ROW, B_REDR, ICON_SCRIPT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_SCRIPT, 0, 0, "Script ");
525 uiDefIconButS(block, ROW, B_REDR, ICON_MATERIAL_DEHLT,xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_SHADING, 0, 0, "Shading (F5) ");
526 uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_OBJECT, 0, 0, "Object (F7) ");
527 uiDefIconButS(block, ROW, B_REDR, ICON_EDIT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_EDITING, 0, 0, "Editing (F9) ");
528 uiDefIconButS(block, ROW, B_REDR, ICON_SCENE_DEHLT, xco+=XIC, 0, XIC, YIC, &(G.buts->mainb), 0.0, (float)CONTEXT_SCENE, 0, 0, "Scene (F10) ");
532 // if(curarea->headertype==HEADERTOP) t_base= -3; else t_base= 4;
534 /* select the context to be drawn, per contex/tab the actual context is tested */
535 uiBlockSetEmboss(block, UI_EMBOSS); // normal
536 switch(G.buts->mainb) {
538 uiBlockBeginAlign(block);
539 uiDefIconButC(block, ROW, B_REDR, ICON_SCENE, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_RENDER, 0, 0, "Render buttons ");
540 uiDefIconButC(block, ROW, B_REDR, ICON_ANIM, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_ANIM, 0, 0, "Anim/playback buttons");
541 uiDefIconButC(block, ROW, B_REDR, ICON_SOUND, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_SOUND, 0, 0, "Sound block buttons");
547 case CONTEXT_SHADING:
548 uiBlockBeginAlign(block);
549 uiDefIconButC(block, ROW, B_BUTSPREVIEW, ICON_LAMP, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SHADING]), 1.0, (float)TAB_SHADING_LAMP, 0, 0, "Lamp buttons");
550 uiDefIconButC(block, ROW, B_BUTSPREVIEW, ICON_MATERIAL, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SHADING]), 1.0, (float)TAB_SHADING_MAT, 0, 0, "Material buttons");
551 uiDefIconButC(block, ROW, B_BUTSPREVIEW, ICON_TEXTURE, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SHADING]), 1.0, (float)TAB_SHADING_TEX, 0, 0, "Texture buttons(F6)");
552 uiDefIconButC(block, ROW, B_REDR, ICON_RADIO,xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SHADING]), 1.0, (float)TAB_SHADING_RAD, 0, 0, "Radiosity buttons");
553 uiDefIconButC(block, ROW, B_BUTSPREVIEW, ICON_WORLD, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SHADING]), 1.0, (float)TAB_SHADING_WORLD, 0, 0, "World buttons");
556 case CONTEXT_EDITING:
567 uiBlockEndAlign(block);
570 uiDefButS(block, NUM, B_NEWFRAME, "", (short)(xco+20),0,60,YIC, &(G.scene->r.cfra), 1.0, 18000.0, 0, 0, "Displays Current Frame of animation. Click to change.");
573 buttons_active_id(&id, &idfrom);
574 G.buts->lockpoin= id;
576 /* always do as last */
578 curarea->headbutlen= xco;