ce8d21612bd836c9057fe456e0cb9130a2a9b230
[blender.git] / source / blender / src / header_info.c
1 /**
2  * header_info.c oct-2003
3  *
4  * Functions to draw the "User Preferences" window header
5  * and handle user events sent to it.
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
10  *
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
17  * about this.
18  *
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.
23  *
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.
27  *
28  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29  * All rights reserved.
30  *
31  * The Original Code is: all of this file.
32  *
33  * Contributor(s): none yet.
34  *
35  * ***** END GPL/BL DUAL LICENSE BLOCK *****
36  */
37  
38 #include <math.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #include "DNA_group_types.h"
47 #include "DNA_ID.h"
48 #include "DNA_image_types.h"
49 #include "DNA_lamp_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_packedFile_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_screen_types.h"
54 #include "DNA_space_types.h"
55 #include "DNA_userdef_types.h"
56 #include "DNA_world_types.h"
57
58 #include "BDR_editcurve.h"
59 #include "BDR_editmball.h"
60 #include "BDR_editobject.h"
61
62 #include "BIF_editarmature.h"
63 #include "BIF_editfont.h"
64 #include "BIF_editmesh.h"
65 #include "BIF_gl.h"
66 #include "BIF_interface.h"
67 #include "BIF_language.h"
68 #include "BIF_mainqueue.h"
69 #include "BIF_previewrender.h"
70 #include "BIF_renderwin.h"
71 #include "BIF_resources.h"
72 #include "BIF_screen.h"
73 #include "BIF_space.h"
74 #include "BIF_toets.h"
75 #include "BIF_toolbox.h"
76 #include "BIF_usiblender.h"
77 #include "BIF_writeimage.h"
78 #include "BIF_drawscene.h"
79
80 #include "BKE_blender.h"
81 #include "BKE_depsgraph.h"
82 #include "BKE_exotic.h"
83 #include "BKE_global.h"
84 #include "BKE_image.h"
85 #include "BKE_library.h"
86 #include "BKE_main.h"
87 #include "BKE_node.h"
88 #include "BKE_packedFile.h"
89 #include "BKE_scene.h"
90 #include "BKE_world.h"
91
92 #include "BLI_arithb.h"
93 #include "BLI_blenlib.h"
94 #include "BLO_writefile.h"
95
96 #include "BSE_editipo.h"
97 #include "BSE_filesel.h"
98 #include "BSE_headerbuttons.h"
99 #include "BSE_sequence.h"
100
101 #include "IMB_imbuf_types.h"
102
103 #include "MEM_guardedalloc.h"
104
105 #include "BPY_extern.h"
106 #include "BPY_menus.h"
107
108 #include "blendef.h"
109 #include "interface.h"
110 #include "mydevice.h"
111
112 extern char versionstr[]; /* from blender.c */
113
114 /*----------------------------------*/
115 /* Progress bar vars and functions: */
116
117 /* strubi shamelessly abused the status line as a progress bar...
118  * feel free to kill him after release */
119
120 static int g_progress_bar = 0;
121 static char *g_progress_info = 0;
122 static float g_done;
123
124 int start_progress_bar(void)
125 {
126         g_progress_bar = 1;
127         return 1;               // we never fail (yet)
128 }
129
130 void end_progress_bar(void)
131 {
132         g_progress_bar = 0;
133 }
134
135 static void update_progress_bar(float done, char *info)
136 {
137         g_done = done;
138         g_progress_info = info;
139 }
140
141 /** Progress bar
142         'done': a value between 0.0 and 1.0, showing progress
143         'info': a info text what is currently being done
144
145         Make sure that the progress bar is always called with:
146         done = 0.0 first
147                 and
148         done = 1.0 last -- or alternatively use:
149
150         start_progressbar();
151         do_stuff_and_callback_progress_bar();
152         end_progressbar();
153 */
154
155 int progress_bar(float done, char *busy_info)
156 {
157         ScrArea *sa;
158         short val; 
159
160         /* User break (ESC) */
161         while (qtest()) {
162                 if (extern_qread(&val) == ESCKEY) 
163                         return 0;
164         }
165         if (done == 0.0) {
166                 start_progress_bar();
167         } else if (done > 0.99) {
168                 end_progress_bar();
169         }
170
171         sa= G.curscreen->areabase.first;
172         while(sa) {
173                 if (sa->spacetype == SPACE_INFO) {
174                         update_progress_bar(done, busy_info);
175
176                         curarea = sa;
177
178                         scrarea_do_headdraw(curarea);
179                         areawinset(curarea->win);
180                         sa->head_swap= WIN_BACK_OK;
181                         screen_swapbuffers();
182                 }
183                 sa = sa->next;
184         }
185         return 1;
186 }
187 /* -- End of progress bar definitions ------- */
188
189 extern char videosc_dir[];      /* exotic.c */
190
191 void write_videoscape_fs()
192 {
193         if(G.obedit) {
194                 error("Can't save Videoscape. Press TAB to leave EditMode");
195         }
196         else {
197                 if(videosc_dir[0]==0) strcpy(videosc_dir, G.sce);
198                 activate_fileselect(FILE_SPECIAL, "Export Videoscape", videosc_dir,
199                                                                                 write_videoscape);
200         }
201 }
202
203 void write_vrml_fs()
204 {
205         if(G.obedit) {
206                 error("Can't save VRML. Press TAB to leave EditMode");
207         }
208         else {
209                 if(videosc_dir[0]==0) strcpy(videosc_dir, G.sce);
210         
211                 activate_fileselect(FILE_SPECIAL, "Export VRML 1.0", videosc_dir, write_vrml);
212         }  
213 }
214
215 void write_dxf_fs()
216 {
217         if(G.obedit) {
218                 error("Can't save DXF. Press TAB to leave EditMode");
219         }
220         else {
221
222                 if(videosc_dir[0]==0) strcpy(videosc_dir, G.sce);
223
224                 activate_fileselect(FILE_SPECIAL, "Export DXF", videosc_dir, write_dxf);        
225         }
226 }
227
228 void write_stl_fs()
229 {
230         if(G.obedit) {
231                 error("Can't save STL. Press TAB to leave EditMode");
232         }
233         else {
234
235                 if(videosc_dir[0]==0) strcpy(videosc_dir, G.sce);
236
237                 activate_fileselect(FILE_SPECIAL, "Export STL", videosc_dir, write_stl);
238         }
239 }
240 /* ------------ */
241
242 int buttons_do_unpack()
243 {
244         int how;
245         char menu[2048];
246         char line[128];
247         int ret_value = RET_OK, count = 0;
248
249         count = countPackedFiles();
250
251         if (count) {
252                 if (count == 1) {
253                         sprintf(menu, "Unpack 1 file%%t");
254                 } else {
255                         sprintf(menu, "Unpack %d files%%t", count);
256                 }
257                 
258                 sprintf(line, "|Use files in current directory (create when necessary)%%x%d", PF_USE_LOCAL);
259                 strcat(menu, line);
260         
261                 sprintf(line, "|Write files to current directory (overwrite existing files)%%x%d", PF_WRITE_LOCAL);
262                 strcat(menu, line);
263         
264                 sprintf(line, "|%%l|Use files in original location (create when necessary)%%x%d", PF_USE_ORIGINAL);
265                 strcat(menu, line);
266         
267                 sprintf(line, "|Write files to original location (overwrite existing files)%%x%d", PF_WRITE_ORIGINAL);
268                 strcat(menu, line);
269         
270                 sprintf(line, "|%%l|Disable AutoPack, keep all packed files %%x%d", PF_KEEP);
271                 strcat(menu, line);
272         
273                 sprintf(line, "|Ask for each file %%x%d", PF_ASK);
274                 strcat(menu, line);
275                 
276                 how = pupmenu(menu);
277                 
278                 if(how != -1) {
279                         if (how != PF_KEEP) {
280                                 unpackAll(how);
281                         }
282                         G.fileflags &= ~G_AUTOPACK;
283                 } else {
284                         ret_value = RET_CANCEL;
285                 }
286         } else {
287                 pupmenu("No packed files. Autopack disabled");
288         }
289         
290         return (ret_value);
291 }
292
293 /* here, because of all creator stuff */
294
295 Scene *copy_scene(Scene *sce, int level)
296 {
297         /* level 0: al objects shared
298          * level 1: al object-data shared
299          * level 2: full copy
300          */
301         Scene *scen;
302         Base *base, *obase;
303
304         /* level 0 */
305         scen= copy_libblock(sce);
306         duplicatelist(&(scen->base), &(sce->base));
307         
308         clear_id_newpoins();
309         
310         id_us_plus((ID *)scen->world);
311         id_us_plus((ID *)scen->set);
312
313         scen->ed= NULL;
314         scen->radio= NULL;
315         scen->theDag= NULL;
316         scen->toolsettings= MEM_dupallocN(sce->toolsettings);
317
318         duplicatelist(&(scen->markers), &(sce->markers));
319         duplicatelist(&(scen->r.layers), &(sce->r.layers));
320         
321         scen->nodetree= ntreeCopyTree(sce->nodetree, 0);
322         
323         obase= sce->base.first;
324         base= scen->base.first;
325         while(base) {
326                 base->object->id.us++;
327                 if(obase==sce->basact) scen->basact= base;
328
329                 obase= obase->next;
330                 base= base->next;
331         }
332
333         if(level==0) return scen;
334
335         /* level 1 */
336         G.scene= scen;
337         
338         single_object_users(0);
339
340         /*      camera */
341         ID_NEW(G.scene->camera);
342
343         /* level 2 */
344         if(level>=2) {
345                 if(scen->world) {
346                         scen->world->id.us--;
347                         scen->world= copy_world(scen->world);
348                 }
349                 single_obdata_users(0);
350                 single_mat_users_expand();
351                 single_tex_users_expand();
352                 
353                 scen->radio= MEM_dupallocN(sce->radio);
354                 
355         }
356
357         clear_id_newpoins();
358
359         BPY_copy_scriptlink(&sce->scriptlink);
360         // make a private copy of the avicodecdata
361
362         if (sce->r.avicodecdata) {
363
364                 scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
365                 scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
366                 scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
367         }
368
369         // make a private copy of the qtcodecdata
370
371         if (sce->r.qtcodecdata) {
372                 scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
373                 scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
374         }
375
376         return scen;
377 }
378
379 void do_info_buttons(unsigned short event)
380 {
381         bScreen *sc, *oldscreen;
382         Scene *sce, *sce1;
383         ScrArea *sa;
384         int nr;
385
386         switch(event) {
387         case B_INFOSCR:         /* menu select screen */
388
389                 if( G.curscreen->screennr== -2) {
390                         if(curarea->winy <50) {
391                                 sa= closest_bigger_area();
392                                 areawinset(sa->win);
393                         }
394                         activate_databrowse((ID *)G.curscreen, ID_SCR, 0, B_INFOSCR,
395                                                                                         &G.curscreen->screennr, do_info_buttons);
396                         return;
397                 }
398                 if( G.curscreen->screennr < 0) return;
399
400                 sc= G.main->screen.first;
401                 nr= 1;
402                 while(sc) {
403                         if(nr==G.curscreen->screennr) {
404                                 if(is_allowed_to_change_screen(sc)) setscreen(sc);
405                                 else error("Unable to perform function in EditMode");
406                                 break;
407                         }
408                         nr++;
409                         sc= sc->id.next;
410                 }
411                 /* last item: NEW SCREEN */
412                 if(sc==0) {
413                         duplicate_screen();
414                 }
415                 break;
416         case B_INFODELSCR:
417 /*do this event only with buttons, so it can never be called with full-window*/
418
419                 if(G.curscreen->id.prev) sc= G.curscreen->id.prev;
420                 else if(G.curscreen->id.next) sc= G.curscreen->id.next;
421                 else return;
422                 if(okee("Delete current screen")) {
423                         /* find new G.curscreen */
424
425                         oldscreen= G.curscreen;
426                         setscreen(sc);          /* this test if sc has a full */
427                         unlink_screen(oldscreen);
428                         free_libblock(&G.main->screen, oldscreen);
429                 }
430                 scrarea_queue_headredraw(curarea);
431
432                 break;
433         case B_INFOSCE:         /* menu select scene */
434
435                 if( G.curscreen->scenenr== -2) {
436                         if(curarea->winy <50) {
437                                 sa= closest_bigger_area();
438                                 areawinset(sa->win);
439                         }
440                         activate_databrowse((ID *)G.scene, ID_SCE, 0, B_INFOSCE,
441                                                                                         &G.curscreen->scenenr, do_info_buttons);
442                         return;
443                 }
444                 if( G.curscreen->scenenr < 0) return;
445
446                 sce= G.main->scene.first;
447                 nr= 1;
448                 while(sce) {
449                         if(nr==G.curscreen->scenenr) {
450                                 if(sce!=G.scene) set_scene(sce);
451                                 break;
452                         }
453                         nr++;
454                         sce= sce->id.next;
455                 }
456                 /* last item: NEW SCENE */
457                 if(sce==0) {
458                         nr= pupmenu("Add scene%t|Empty|Link Objects|Link ObData|Full Copy");
459                         if(nr<= 0) return;
460                         if(nr==1) {
461                                 sce= add_scene(G.scene->id.name+2);
462                                 sce->r= G.scene->r;
463 #ifdef _WIN32
464                                 if (sce->r.avicodecdata) {
465                                         sce->r.avicodecdata = MEM_dupallocN(G.scene->r.avicodecdata);
466                                         sce->r.avicodecdata->lpFormat = MEM_dupallocN(G.scene->r.avicodecdata->lpFormat);
467                                         sce->r.avicodecdata->lpParms = MEM_dupallocN(G.scene->r.avicodecdata->lpParms);
468                                 }
469 #endif
470 #ifdef WITH_QUICKTIME
471                                 if (sce->r.qtcodecdata) {
472                                         sce->r.qtcodecdata = MEM_dupallocN(G.scene->r.qtcodecdata);
473                                         sce->r.qtcodecdata->cdParms = MEM_dupallocN(G.scene->r.qtcodecdata->cdParms);
474                                 }
475 #endif
476                         }
477                         else sce= copy_scene(G.scene, nr-2);
478
479                         set_scene(sce);
480                 }
481                 BIF_preview_changed(ID_TE);
482
483                 break;
484         case B_INFODELSCE:
485
486                 if(G.scene->id.prev) sce= G.scene->id.prev;
487                 else if(G.scene->id.next) sce= G.scene->id.next;
488                 else return;
489                 if(okee("Delete current scene")) {
490
491                         /* check all sets */
492                         sce1= G.main->scene.first;
493                         while(sce1) {
494                                 if(sce1->set == G.scene) sce1->set= 0;
495                                 sce1= sce1->id.next;
496                         }
497
498                         /* check all sequences */
499                         clear_scene_in_allseqs(G.scene);
500
501                         /* al screens */
502                         sc= G.main->screen.first;
503                         while(sc) {
504                                 if(sc->scene == G.scene) sc->scene= sce;
505                                 sc= sc->id.next;
506                         }
507                         free_libblock(&G.main->scene, G.scene);
508                         set_scene(sce);
509                 }
510
511                 break;
512         }
513 }
514
515 static void check_packAll()
516 {
517         // first check for dirty images
518         Image *ima;
519
520         ima = G.main->image.first;
521         while (ima) {
522                 if (ima->ibuf && (ima->ibuf->userflags &= IB_BITMAPDIRTY)) {
523                         break;
524                 }
525                 ima= ima->id.next;
526                 }
527         
528         if (ima == 0 || okee("Some images are painted on. These changes will be lost. Continue ?")) {
529                 packAll();
530                 G.fileflags |= G_AUTOPACK;
531         }
532 }
533
534 static int write_runtime(char *str, char *exename)
535 {
536         char *freestr= NULL;
537         char *ext = 0;
538
539 #ifdef _WIN32
540         ext = ".exe";
541 #endif
542
543 #ifdef __APPLE__
544         ext = ".app";
545 #endif
546         if (ext && (!BLI_testextensie(str, ext))) {
547                 freestr= MEM_mallocN(strlen(str) + strlen(ext) + 1, "write_runtime_check");
548                 strcpy(freestr, str);
549                 strcat(freestr, ext);
550                 str= freestr;
551         }
552
553         if (!BLI_exists(str) || saveover(str))
554                 BLO_write_runtime(str, exename);
555
556         if (freestr)
557                 MEM_freeN(freestr);
558  
559         return 0;
560 }
561
562 static void write_runtime_check_dynamic(char *str) 
563 {
564         write_runtime(str, "blenderdynplayer.exe");
565 }
566
567 static void write_runtime_check(char *str) 
568 {
569         char player[128];
570
571         strcpy(player, "blenderplayer");
572
573 #ifdef _WIN32
574         strcat(player, ".exe");
575 #endif
576
577 #ifdef __APPLE__
578         strcat(player, ".app");
579 #endif
580
581         write_runtime(str, player);
582 }
583 /* end keyed functions */
584
585 /************************** MAIN MENU *****************************/
586 /************************** FILE *****************************/
587
588
589 static void do_info_file_importmenu(void *arg, int event)
590 {
591         ScrArea *sa;
592
593         if(curarea->spacetype==SPACE_INFO) {
594                 sa= find_biggest_area_of_type(SPACE_SCRIPT);
595                 if (!sa) sa= closest_bigger_area();
596                 areawinset(sa->win);
597         }
598
599         /* events >=4 are registered bpython scripts */
600         if (event >= 4) {
601                 BPY_menu_do_python(PYMENU_IMPORT, event - 4);
602                 BIF_undo_push("Import file");
603         }
604         else {
605                 switch(event) {
606                                                                         
607                 case 0: /* DXF */
608                         activate_fileselect(FILE_BLENDER, "Import DXF", G.sce, BIF_read_file);
609                         break;
610                 case 1: /* VRML 1.0 */
611                         activate_fileselect(FILE_BLENDER, "Import VRML 1.0", G.sce, BIF_read_file);
612                         break;
613                 case 2: /* VideoScape */
614                         activate_fileselect(FILE_BLENDER, "Import VideoScape", G.sce, BIF_read_file);
615                         break;
616                 case 3: /* STL */
617                         activate_fileselect(FILE_BLENDER, "Import STL", G.sce, BIF_read_file);
618                         break;
619
620                 }
621         }
622         allqueue(REDRAWINFO, 0);
623 }
624
625 static uiBlock *info_file_importmenu(void *arg_unused)
626 {
627         uiBlock *block;
628         short yco = 20, menuwidth = 120;
629         BPyMenu *pym;
630         int i = 0;
631
632         block= uiNewBlock(&curarea->uiblocks, "importmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
633         uiBlockSetButmFunc(block, do_info_file_importmenu, NULL);
634         //uiBlockSetXOfs(block, -50);  // offset to parent button
635         
636         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "VRML 1.0...",
637                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 1, "");
638         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "DXF...",
639                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 0, "");
640         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "VideoScape...",
641                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 2, "");
642         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "STL...",
643                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 3, "");
644
645         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
646
647         for (pym = BPyMenuTable[PYMENU_IMPORT]; pym; pym = pym->next, i++) {
648                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, i+4, pym->tooltip?pym->tooltip:pym->filename);
649         }
650
651         uiBlockSetDirection(block, UI_RIGHT);
652         uiTextBoundsBlock(block, 60);
653
654         return block;
655 }
656
657 static void do_info_file_exportmenu(void *arg, int event)
658 {
659         ScrArea *sa;
660
661         if(curarea->spacetype==SPACE_INFO) {
662                 sa= find_biggest_area_of_type(SPACE_SCRIPT);
663                 if (!sa) sa= closest_bigger_area();
664                 areawinset(sa->win);
665         }
666
667         /* events >=4 are registered bpython scripts */
668         if (event >= 4) BPY_menu_do_python(PYMENU_EXPORT, event - 4);
669
670         else switch(event) {
671                                                                         
672         case 0:
673                 write_vrml_fs();
674                 break;
675         case 1:
676                 write_dxf_fs();
677                 break;
678         case 2:
679                 write_videoscape_fs();
680                 break;
681         case 3:
682                 write_stl_fs();
683                 break;
684         }
685         allqueue(REDRAWINFO, 0);
686 }
687
688 static uiBlock *info_file_exportmenu(void *arg_unused)
689 {
690         uiBlock *block;
691         short yco = 20, menuwidth = 120;
692         BPyMenu *pym;
693         int i = 0;
694
695         block= uiNewBlock(&curarea->uiblocks, "exportmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
696         uiBlockSetButmFunc(block, do_info_file_exportmenu, NULL);
697         //uiBlockSetXOfs(block, -50);  // offset to parent button
698
699         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "VRML 1.0...|Ctrl F2",
700                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 0, "");
701         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "DXF...|Shift F2",
702                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 1, "");
703         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Videoscape...|Alt W",
704                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 2, "");
705         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "STL...",
706                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 3, "");
707
708         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
709
710         /* note that we acount for the 3 previous entries with i+3: */
711         for (pym = BPyMenuTable[PYMENU_EXPORT]; pym; pym = pym->next, i++) {
712                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, 
713                                  NULL, 0.0, 0.0, 1, i+4, 
714                                  pym->tooltip?pym->tooltip:pym->filename);
715         }
716
717
718         uiBlockSetDirection(block, UI_RIGHT);
719         uiTextBoundsBlock(block, 60);
720
721         return block;
722 }
723
724 static void do_info_filemenu(void *arg, int event)
725 {
726         ScrArea *sa;
727         char dir[FILE_MAXDIR];
728         
729         if(curarea->spacetype==SPACE_INFO) {
730                 sa= closest_bigger_area();
731                 areawinset(sa->win);
732         }
733
734         /* these are no defines, easier this way, the codes are in the function below */
735         switch(event) {
736         case 0:
737                 if (okee("Erase All")) {
738                         if (!BIF_read_homefile())
739                                 error("No file ~/.B.blend");
740                 }
741                 break;
742         case 1: /* open */
743                 activate_fileselect(FILE_BLENDER, "Open", G.sce, BIF_read_file);
744                 break;
745         case 2: /* reopen last */
746                 {
747                         char *s= MEM_mallocN(strlen(G.sce) + 11 + 1, "okee_reload");
748                         strcpy(s, "Open file: ");
749                         strcat(s, G.sce);
750                         if (okee(s)) BIF_read_file(G.sce);
751                         MEM_freeN(s);
752                 }
753                 break;
754         case 3: /* append */
755                 activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
756                 break;
757         case 4: /* save */
758                 strcpy(dir, G.sce);
759                 untitled(dir);
760                 activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file);
761                 break;
762         case 5:
763                 strcpy(dir, G.sce);
764                 if (untitled(dir)) {
765                         activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file);
766                 } else {
767                         BIF_write_file(dir);
768                         free_filesel_spec(dir);
769                 }
770                 break;
771         case 6: /* save image */
772                 BIF_save_rendered_image_fs();
773                 break;
774         case 22: /* save runtime */
775                 activate_fileselect(FILE_SPECIAL, "Save Runtime", "", write_runtime_check);
776                 break;
777         case 23: /* save dynamic runtime */
778                 activate_fileselect(FILE_SPECIAL, "Save Dynamic Runtime", "", write_runtime_check_dynamic);
779                 break;
780         case 24:
781                 BIF_screendump(0);
782                 break;
783         case 25:
784                 BIF_screendump(1);
785                 break;
786         case 10: /* pack data */
787                 check_packAll();
788                 break;
789         case 11: /* unpack to current dir */
790                 unpackAll(PF_WRITE_LOCAL);
791                 G.fileflags &= ~G_AUTOPACK;
792                 break;
793         case 12: /* unpack data */
794                 if (buttons_do_unpack() != RET_CANCEL) {
795                         /* Clear autopack bit only if user selected one of the unpack options */
796                         G.fileflags &= ~G_AUTOPACK;
797                 }
798                 break;
799         case 13:
800                 exit_usiblender();
801                 break;
802         case 15:        /* recover previous session */
803                 {
804                         extern short winqueue_break; /* editscreen.c */
805                         int save_over;
806                         char str[FILE_MAXDIR+FILE_MAXFILE];
807                         char scestr[FILE_MAXDIR+FILE_MAXFILE];
808                         
809                         strcpy(scestr, G.sce);  /* temporal store */
810                         save_over = G.save_over;
811                         BLI_make_file_string("/", str, U.tempdir, "quit.blend");
812                         BKE_read_file(str, NULL);
813                         G.save_over = save_over;
814                         strcpy(G.sce, scestr);
815
816                         winqueue_break= 1;      /* leave queues everywhere */
817                 
818                         BKE_reset_undo();
819                         BKE_write_undo("original");     /* save current state */
820                         refresh_interface_font();
821                 }
822                 break;
823         case 31: /* save default settings */
824                 BIF_write_homefile();
825                 break;
826
827         case 35: /* compress toggle */
828                 U.flag ^= (USER_FILECOMPRESS);
829                 break;
830         }
831         allqueue(REDRAWINFO, 0);
832 }
833
834 static uiBlock *info_filemenu(void *arg_unused)
835 {
836         uiBlock *block;
837         short yco=0;
838         short menuwidth=120;
839
840         block= uiNewBlock(&curarea->uiblocks, "info_filemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
841         uiBlockSetButmFunc(block, do_info_filemenu, NULL);
842         
843         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New|Ctrl X",                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
844         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...|F1",                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
845         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reopen Last|Ctrl O",                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
846         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session",                           0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
847
848         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
849
850         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save|Ctrl W",                            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
851         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save As...|F2",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
852         
853         if(U.flag & USER_FILECOMPRESS) {
854                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Compress File",     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
855         } else {
856                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Compress File",   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
857         }
858
859         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
860
861         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Image...|F3",                       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
862         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Dump Subwindow|Ctrl F3",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
863         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Dump Screen|Ctrl Shift F3",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
864 #if GAMEBLENDER == 1
865         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Runtime...",                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
866 #ifdef _WIN32
867         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Dynamic Runtime...",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, "");
868 #endif
869 #endif
870         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
871
872         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Default Settings|Ctrl U",                   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 31, "");
873
874
875         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
876
877         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append...|Shift F1",     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
878         uiDefIconTextBlockBut(block, info_file_importmenu, NULL, ICON_RIGHTARROW_THIN, "Import", 0, yco-=20, menuwidth, 19, "");
879         uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, "");
880         
881         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
882
883         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Data",                              0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
884 //      uiDefBut(block, BUTM, 1, "Unpack Data to current dir",          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "Removes all packed files from the project and saves them to the current directory");
885         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack Data...",                         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
886
887         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
888
889         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender| Q",                                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
890
891         uiBlockSetDirection(block, UI_DOWN);
892         uiTextBoundsBlock(block, 80);
893
894         return block;
895 }
896
897 /**************************** ADD ******************************/
898
899 void do_info_add_meshmenu(void *arg, int event)
900 {
901
902         switch(event) {         
903                 case 0:
904                         /* Plane */
905                         add_primitiveMesh(0);
906                         break;
907                 case 1:
908                         /* Cube */
909                         add_primitiveMesh(1);
910                         break;
911                 case 2:
912                         /* Circle */
913                         add_primitiveMesh(4);
914                         break;
915                 case 3:
916                         /* UVsphere */
917                         add_primitiveMesh(11);
918                         break;
919                 case 4:
920                         /* IcoSphere */
921                         add_primitiveMesh(12);
922                         break;
923                 case 5:
924                         /* Cylinder */
925                         add_primitiveMesh(5);
926                         break;
927                 case 6:
928                         /* Tube */
929                         add_primitiveMesh(6);
930                         break;
931                 case 7:
932                         /* Cone */
933                         add_primitiveMesh(7);
934                         break;
935                 case 8:
936                         /* Grid */
937                         add_primitiveMesh(10);
938                         break;
939                 case 9:
940                         /* Monkey */
941                         add_primitiveMesh(13);
942                         break;
943                 default:
944                         break;
945         }
946         allqueue(REDRAWINFO, 0);
947 }
948
949 static uiBlock *info_add_meshmenu(void *arg_unused)
950 {
951 /*              static short tog=0; */
952         uiBlock *block;
953         short yco= 0;
954         
955         block= uiNewBlock(&curarea->uiblocks, "add_meshmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
956         uiBlockSetButmFunc(block, do_info_add_meshmenu, NULL);
957         
958         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Plane|",                         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
959         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cube|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
960         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Circle|",                                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "");
961         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UVsphere",                       0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
962         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "IcoSphere|",                     0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "");
963         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cylinder|",                      0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 5, "");
964         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Tube|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 6, "");
965         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cone|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 7, "");
966         uiDefIconTextBut(block, SEPR, 0, ICON_BLANK1, "",                                       0, yco-=6,      160, 6,  NULL, 0.0, 0.0, 0, 0, "");
967         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grid|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 8, "");
968         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Monkey|",                        0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 9, "");
969
970         uiBlockSetDirection(block, UI_RIGHT);
971         uiTextBoundsBlock(block, 50);
972                 
973         return block;
974 }
975
976 void do_info_add_curvemenu(void *arg, int event)
977 {
978
979         switch(event) {         
980                 case 0:
981                         /* Bezier Curve */
982                         add_primitiveCurve(10);
983                         break;
984                 case 1:
985                         /* Bezier Circle */
986                         add_primitiveCurve(11);
987                         break;
988                 case 2:
989                         /* NURB Curve */
990                         add_primitiveCurve(40);
991                         break;
992                 case 3:
993                         /* NURB Circle */
994                         add_primitiveCurve(41);
995                         break;
996                 case 4:
997                         /* Path */
998                         add_primitiveCurve(46);
999                         break;
1000                 default:
1001                         break;
1002         }
1003         allqueue(REDRAWINFO, 0);
1004 }
1005
1006 static uiBlock *info_add_curvemenu(void *arg_unused)
1007 {
1008 /*              static short tog=0; */
1009         uiBlock *block;
1010         short yco= 0;
1011         
1012         block= uiNewBlock(&curarea->uiblocks, "add_curvemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1013         uiBlockSetButmFunc(block, do_info_add_curvemenu, NULL);
1014         
1015         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bezier Curve|",  0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1016         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bezier Circle|", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
1017         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Curve|",           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "");
1018         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Circle",           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
1019         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Path|",                  0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "");
1020
1021         uiBlockSetDirection(block, UI_RIGHT);
1022         uiTextBoundsBlock(block, 50);
1023                 
1024         return block;
1025 }
1026
1027
1028 void do_info_add_surfacemenu(void *arg, int event)
1029 {
1030
1031         switch(event) {         
1032                 case 0:
1033                         /* Curve */
1034                         add_primitiveNurb(0);
1035                         break;
1036                 case 1:
1037                         /* Circle */
1038                         add_primitiveNurb(1);
1039                         break;
1040                 case 2:
1041                         /* Surface */
1042                         add_primitiveNurb(2);
1043                         break;
1044                 case 3:
1045                         /* Tube */
1046                         add_primitiveNurb(3);
1047                         break;
1048                 case 4:
1049                         /* Sphere */
1050                         add_primitiveNurb(4);
1051                         break;
1052                 case 5:
1053                         /* Donut */
1054                         add_primitiveNurb(5);
1055                         break;
1056                 default:
1057                         break;
1058         }
1059         allqueue(REDRAWINFO, 0);
1060 }
1061
1062 static uiBlock *info_add_surfacemenu(void *arg_unused)
1063 {
1064 /*              static short tog=0; */
1065         uiBlock *block;
1066         short yco= 0;
1067         
1068         block= uiNewBlock(&curarea->uiblocks, "add_surfacemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1069         uiBlockSetButmFunc(block, do_info_add_surfacemenu, NULL);
1070         
1071         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Curve|",           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1072         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Circle|",          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
1073         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Surface|", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "");
1074         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Tube",             0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
1075         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Sphere|",          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "");
1076         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NURBS Donut|",           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 5, "");
1077         uiBlockSetDirection(block, UI_RIGHT);
1078         uiTextBoundsBlock(block, 50);
1079                 
1080         return block;
1081 }
1082
1083 void do_info_add_metamenu(void *arg, int event)
1084 {
1085
1086         switch(event) {         
1087                 case 0:
1088                         /* Ball */
1089                         add_primitiveMball(1);
1090                         break;
1091                 case 1:
1092                         /* Tube */
1093                         add_primitiveMball(2);
1094                         break;
1095                 case 2:
1096                         /* Plane */
1097                         add_primitiveMball(3);
1098                         break;
1099                 case 3:
1100                         /* Elipsoid */
1101                         add_primitiveMball(4);
1102                         break;
1103                 case 4:
1104                         /* Cube */
1105                         add_primitiveMball(5);
1106                         break;
1107                 default:
1108                         break;
1109         }
1110         allqueue(REDRAWINFO, 0);
1111 }
1112
1113
1114 static uiBlock *info_add_metamenu(void *arg_unused)
1115 {
1116 /*              static short tog=0; */
1117         uiBlock *block;
1118         short xco= 0;
1119         
1120         block= uiNewBlock(&curarea->uiblocks, "add_metamenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1121         uiBlockSetButmFunc(block, do_info_add_metamenu, NULL);
1122         
1123         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,"Meta Ball|",              0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1124         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Meta Tube|",             0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
1125         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Meta Plane|",            0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "");
1126         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Meta Ellipsoid|",        0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
1127         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Meta Cube|",             0, xco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "");
1128
1129         uiBlockSetDirection(block, UI_RIGHT);
1130         uiTextBoundsBlock(block, 50);
1131                 
1132         return block;
1133 }
1134
1135 void do_info_add_lampmenu(void *arg, int event)
1136 {
1137
1138         switch(event) {         
1139                 case 0: /* lamp */
1140                         add_objectLamp(LA_LOCAL);
1141                         break;
1142                 case 1: /* sun */
1143                         add_objectLamp(LA_SUN);
1144                         break;
1145                 case 2: /* spot */
1146                         add_objectLamp(LA_SPOT);
1147                         break;
1148                 case 3: /* hemi */
1149                         add_objectLamp(LA_HEMI);
1150                         break;
1151                 case 4: /* area */
1152                         add_objectLamp(LA_AREA);
1153                         break;
1154                 case 5: /* YafRay photon lamp */
1155                         if (G.scene->r.renderer==R_YAFRAY)
1156                                 add_objectLamp(LA_YF_PHOTON);
1157                         break;
1158                 default:
1159                         break;
1160         }
1161         allqueue(REDRAWINFO, 0);
1162 }
1163
1164 static uiBlock *info_add_lampmenu(void *arg_unused)
1165 {
1166 /*              static short tog=0; */
1167         uiBlock *block;
1168         short yco= 0;
1169         
1170         block= uiNewBlock(&curarea->uiblocks, "add_lampmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1171         uiBlockSetButmFunc(block, do_info_add_lampmenu, NULL);
1172         
1173         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Lamp|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1174         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Sun|",                           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
1175         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Spot|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "");
1176         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hemi|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
1177         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Area|",                          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "");
1178         if (G.scene->r.renderer==R_YAFRAY)
1179                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Photon|",                                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 5, "");
1180         
1181         uiBlockSetDirection(block, UI_RIGHT);
1182         uiTextBoundsBlock(block, 50);
1183                 
1184         return block;
1185 }
1186
1187 static void do_info_add_groupmenu(void *arg, int event)
1188 {
1189         Object *ob;
1190         
1191         add_object_draw(OB_EMPTY);
1192         ob= OBACT;
1193         
1194         ob->dup_group= BLI_findlink(&G.main->group, event);
1195         if(ob->dup_group) {
1196                 id_us_plus((ID *)ob->dup_group);
1197                 ob->transflag |= OB_DUPLIGROUP;
1198                 DAG_scene_sort(G.scene);
1199         }
1200 }
1201
1202
1203 static uiBlock *info_add_groupmenu(void *arg_unused)
1204 {
1205         uiBlock *block;
1206         short yco= 0;
1207         
1208         Group *group;
1209         int a;
1210         int tot= BLI_countlist(&G.main->group);
1211         
1212         block= uiNewBlock(&curarea->uiblocks, "add_groupmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1213         uiBlockSetButmFunc(block, do_info_add_groupmenu, NULL);
1214         
1215         for(a=0, group= G.main->group.first; group; group= group->id.next, a++) {
1216                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, group->id.name+2,                         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, a, "");
1217         }
1218         
1219         uiBlockSetDirection(block, UI_RIGHT);
1220         uiTextBoundsBlock(block, 50);
1221                 
1222         return block;
1223 }
1224
1225 void do_info_addmenu(void *arg, int event)
1226 {
1227         switch(event) {         
1228                 case 0:
1229                         /* Mesh */
1230                         break;
1231                 case 1:
1232                         /* Curve */
1233                         break;
1234                 case 2:
1235                         /* Surface */
1236                         break;
1237                 case 3:
1238                         /* Metaball */
1239                         break;
1240                 case 4:
1241                         /* Text (argument is discarded) */
1242                         add_primitiveFont(event);
1243                         break;
1244                 case 5:
1245                         /* Empty */
1246                         add_object_draw(OB_EMPTY);
1247                         break;
1248                 case 6:
1249                         /* Camera */
1250                         add_object_draw(OB_CAMERA);
1251                         break;
1252                 case 8:
1253                         /* Armature */
1254                         add_primitiveArmature(OB_ARMATURE);
1255                         break;
1256                 case 9:
1257                         /* Lattice */
1258                         add_object_draw(OB_LATTICE);
1259                         break;
1260                 case 10:
1261                         /* group instance not yet */
1262                         break;
1263                 default:
1264                         break;
1265         }
1266         allqueue(REDRAWINFO, 0);
1267 }
1268
1269
1270 static uiBlock *info_addmenu(void *arg_unused)
1271 {
1272 /*              static short tog=0; */
1273         uiBlock *block;
1274         short yco= 0;
1275
1276         block= uiNewBlock(&curarea->uiblocks, "addmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
1277         uiBlockSetButmFunc(block, do_info_addmenu, NULL);
1278         
1279         uiDefIconTextBlockBut(block, info_add_meshmenu, NULL, ICON_RIGHTARROW_THIN, "Mesh", 0, yco-=20, 120, 19, "");
1280         uiDefIconTextBlockBut(block, info_add_curvemenu, NULL, ICON_RIGHTARROW_THIN, "Curve", 0, yco-=20, 120, 19, "");
1281         uiDefIconTextBlockBut(block, info_add_surfacemenu, NULL, ICON_RIGHTARROW_THIN, "Surface", 0, yco-=20, 120, 19, "");
1282         uiDefIconTextBlockBut(block, info_add_metamenu, NULL, ICON_RIGHTARROW_THIN, "Meta", 0, yco-=20, 120, 19, "");
1283         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Text",                           0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 4, "");
1284         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Empty",                          0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 5, "");
1285         
1286         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
1287         
1288         uiDefIconTextBlockBut(block, info_add_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Group", 0, yco-=20, 120, 19, "");
1289         
1290         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
1291         
1292         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Camera",                         0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 6, "");
1293         uiDefIconTextBlockBut(block, info_add_lampmenu, NULL, ICON_RIGHTARROW_THIN, "Lamp", 0, yco-=20, 120, 19, "");
1294         
1295         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
1296         
1297         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Armature",                       0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 8, "");
1298         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Lattice",                        0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 9, "");
1299
1300         uiBlockSetDirection(block, UI_DOWN);
1301         uiTextBoundsBlock(block, 80);
1302                 
1303         return block;
1304 }
1305
1306 /************************** GAME *****************************/
1307
1308 static void do_info_gamemenu(void *arg, int event)
1309 {
1310         switch (event) {
1311         case G_FILE_ENABLE_ALL_FRAMES:
1312         case G_FILE_SHOW_FRAMERATE:
1313         case G_FILE_SHOW_DEBUG_PROPS:
1314         case G_FILE_AUTOPLAY:
1315         case G_FILE_GAME_TO_IPO:
1316         case G_FILE_GAME_MAT:
1317                 G.fileflags ^= event;
1318                 break;
1319         default:
1320                 ; /* ignore the rest */
1321         }
1322 }
1323
1324 static uiBlock *info_gamemenu(void *arg_unused)
1325 {
1326 /*              static short tog=0; */
1327         uiBlock *block;
1328         short yco= 0;
1329         short menuwidth=120;
1330         
1331         block= uiNewBlock(&curarea->uiblocks, "gamemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
1332         uiBlockSetButmFunc(block, do_info_gamemenu, NULL);
1333         
1334         uiDefIconTextBut(block, BUTM, B_STARTGAME, ICON_BLANK1, "Start Game|P",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
1335         
1336         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 1, 0, "");
1337
1338
1339         if(G.fileflags & G_FILE_ENABLE_ALL_FRAMES) {
1340                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Enable All Frames",         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_ENABLE_ALL_FRAMES, "");
1341         } else {
1342                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Enable All Frames",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_ENABLE_ALL_FRAMES, "");
1343         }
1344         
1345         if(G.fileflags & G_FILE_GAME_TO_IPO) {
1346                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Record Game Physics to IPO",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, "");
1347         } else {
1348                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Record Game Physics to IPO",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, "");
1349         }
1350         
1351         if(G.fileflags & G_FILE_GAME_MAT) {
1352                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Blender Materials",     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_MAT, "");
1353         } else {
1354                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Use Blender Materials",   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_MAT, "");
1355         }       
1356
1357
1358
1359         if(G.fileflags & G_FILE_SHOW_FRAMERATE) {
1360                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Framerate and Profile",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_SHOW_FRAMERATE, "");
1361         } else {
1362                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Show Framerate and Profile",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_SHOW_FRAMERATE, "");
1363         }
1364
1365         if(G.fileflags & G_FILE_SHOW_DEBUG_PROPS) {
1366                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Debug Properties",             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_SHOW_DEBUG_PROPS, "");
1367         } else {
1368                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Show Debug Properties",           0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_SHOW_DEBUG_PROPS, "");
1369         }
1370         
1371         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 1, 0, "");
1372
1373         if(G.fileflags & G_FILE_AUTOPLAY) {
1374                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Autostart",         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_AUTOPLAY, "");
1375         } else {
1376                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Autostart",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_AUTOPLAY, "");
1377         }
1378
1379         uiBlockSetDirection(block, UI_DOWN);
1380         uiTextBoundsBlock(block, 70);
1381         
1382         return block;
1383 }
1384 /************************** TIMELINE *****************************/
1385
1386 static void do_info_timelinemenu(void *arg, int event)
1387 {
1388         /* needed to check for valid selected objects */
1389         Base *base=NULL;
1390         Object *ob=NULL;
1391         //char file[FILE_MAXDIR+FILE_MAXFILE];
1392
1393         base= BASACT;
1394         if (base) ob= base->object;
1395
1396         switch(event) {
1397         case 1:
1398                 /* Show Keyframes */
1399                 if (!ob) error("Select an object before showing its keyframes");
1400                 else set_ob_ipoflags();
1401                 break;
1402         case 2:
1403                 /* Show and select Keyframes */
1404                 if (!ob) error("Select an object before showing and selecting its keyframes");
1405                 else select_select_keys();
1406                         break;
1407                 case 3:
1408                 /* select next keyframe */
1409                 if (!ob) error("Select an object before selecting its next keyframe");
1410                 else nextkey_obipo(1);
1411                         break;
1412                 case 4:
1413                 /* select previous keyframe */
1414                 if (!ob) error("Select an object before selecting its previous keyframe");
1415                 else nextkey_obipo(-1);
1416                 break;
1417                 case 5:
1418                 /* next keyframe */
1419                 if (!ob) error("Select an object before going to its next keyframe");
1420                 else movekey_obipo(1);
1421                         break;
1422                 case 6:
1423                 /* previous keyframe */
1424                 if (!ob) error("Select an object before going to its previous keyframe");
1425                 else movekey_obipo(-1);
1426                 break;
1427         case 7:
1428                 /* next frame */
1429                 CFRA++;
1430                 update_for_newframe();
1431                 break;
1432                 case 8:
1433                 /* previous frame */
1434                 CFRA--;
1435                 if(CFRA<1) CFRA=1;
1436                 update_for_newframe();
1437                 break;
1438         case 9:
1439                 /* forward 10 frames */
1440                 CFRA+= 10;
1441                 update_for_newframe();
1442                 break;
1443         case 10:
1444                 /* back 10 frames */
1445                 CFRA-= 10;
1446                 if(CFRA<1) CFRA=1;
1447                 update_for_newframe();
1448                 break;
1449         case 11:
1450                 /* end frame */
1451                 CFRA= EFRA;
1452                 update_for_newframe();
1453                 break;
1454         case 12:
1455                 /* start frame */
1456                 CFRA= SFRA;
1457                 update_for_newframe();
1458                 break;
1459         }
1460         allqueue(REDRAWINFO, 0);
1461 }
1462
1463 static uiBlock *info_timelinemenu(void *arg_unused)
1464 {
1465 /*              static short tog=0; */
1466         uiBlock *block;
1467         short yco= 0;
1468         short menuwidth=120;
1469
1470         block= uiNewBlock(&curarea->uiblocks, "timelinemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
1471         uiBlockSetButmFunc(block, do_info_timelinemenu, NULL);
1472         
1473         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Keyframes|K",               0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
1474         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show and Select Keyframes|Shift K",0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
1475         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Next Keyframe|PageUp",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
1476         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Previous Keyframe|PageDown",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
1477
1478         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1479
1480         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Next Keyframe|Ctrl PageUp",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
1481         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Previous Keyframe|Ctrl PageDown",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
1482
1483         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1484
1485         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Next Frame|RightArrow",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
1486         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Previous Frame|LeftArrow",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
1487         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Forward 10 Frames|UpArrow",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
1488         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Back 10 Frames|DownArrow",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
1489
1490         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1491
1492         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "End Frame|Shift RightArrow",     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
1493         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Start Frame|Shift LeftArrow",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
1494
1495         uiBlockSetDirection(block, UI_DOWN);
1496         uiTextBoundsBlock(block, 80);
1497
1498         return block;
1499 }
1500
1501 /************************** RENDER *****************************/
1502
1503 static void do_info_rendermenu(void *arg, int event)
1504 {
1505
1506         extern void playback_anim();
1507
1508         switch(event) {
1509                 
1510         case 0:
1511                 BIF_do_render(0);
1512                 break;
1513         case 1:
1514                 BIF_do_render(1);
1515                 break;
1516
1517                 /* note: dont use select_area() for setting active areas for opengl render */
1518                 /* its hackish and instable... code here was removed */
1519         
1520         case 4:
1521                 BIF_toggle_render_display();
1522                 break;
1523         case 5:
1524                 playback_anim();
1525                 break;
1526         case 6:
1527                 /* dodgy hack turning on SHIFT key to do a proper render border select
1528                 set_render_border(); only works when 3d window active
1529                 
1530                 This code copied from toolbox.c, only works when 3d window is cameraview */
1531
1532                 if(select_area(SPACE_VIEW3D)) {
1533                         mainqenter(LEFTSHIFTKEY, 1);
1534                         mainqenter(BKEY, 1);
1535                         mainqenter(BKEY, 0);
1536                         mainqenter(EXECUTE, 1);
1537                         mainqenter(LEFTSHIFTKEY, 0);
1538                 }
1539
1540                 break;
1541
1542                 case 7:
1543                 extern_set_butspace(F10KEY);
1544                 break;
1545         }
1546         allqueue(REDRAWINFO, 0);
1547 }
1548
1549 static uiBlock *info_rendermenu(void *arg_unused)
1550 {
1551 /*              static short tog=0; */
1552         uiBlock *block;
1553         short yco= 0;
1554         short menuwidth=120;
1555         
1556         block= uiNewBlock(&curarea->uiblocks, "rendermenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
1557         uiBlockSetButmFunc(block, do_info_rendermenu, NULL);
1558         
1559         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Render Current Frame|F12",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
1560         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Render Animation|Ctrl F12",              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
1561
1562         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1563
1564         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Render Buffer|F11",         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
1565         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Rendered Animation|Ctrl F11",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
1566
1567         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1568
1569         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Render Border|Shift B",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
1570
1571         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1572
1573         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Render Settings|F10",            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
1574
1575         uiBlockSetDirection(block, UI_DOWN);
1576         uiTextBoundsBlock(block, 80);
1577
1578         return block;
1579 }
1580
1581 /************************** HELP *****************************/
1582
1583 static void do_info_help_websitesmenu(void *arg, int event)
1584 {
1585         BPY_menu_do_python(PYMENU_HELPWEBSITES, event);
1586
1587         allqueue(REDRAWVIEW3D, 0);
1588 }
1589
1590
1591 static uiBlock *info_help_websitesmenu(void *arg_unused)
1592 {
1593         uiBlock *block;
1594         BPyMenu *pym;
1595         short yco = 20, menuwidth = 120;
1596         int i = 0;
1597
1598         block= uiNewBlock(&curarea->uiblocks, "info_help_websitesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1599         uiBlockSetButmFunc(block, do_info_help_websitesmenu, NULL);
1600         
1601         for (pym = BPyMenuTable[PYMENU_HELPWEBSITES]; pym; pym = pym->next, i++) {
1602                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, i, pym->tooltip?pym->tooltip:pym->filename);
1603         }
1604         
1605         uiBlockSetDirection(block, UI_RIGHT);
1606         uiTextBoundsBlock(block, 60);
1607                 
1608         return block;
1609 }
1610
1611 static void do_info_help_systemmenu(void *arg, int event)
1612 {
1613         /* events >=10 are registered bpython scripts */
1614         if (event >= 10) BPY_menu_do_python(PYMENU_HELPSYSTEM, event - 10);
1615         else {
1616                 switch(event) {
1617
1618                 case 1: /* Benchmark */
1619                         /* dodgy hack turning on CTRL ALT SHIFT key to do a benchmark 
1620                          *      rather than copying lines and lines of code from toets.c :( 
1621                          */
1622         
1623                         if(select_area(SPACE_VIEW3D)) {
1624                                 mainqenter(LEFTSHIFTKEY, 1);
1625                                 mainqenter(LEFTCTRLKEY, 1);
1626                                 mainqenter(LEFTALTKEY, 1);
1627                                 mainqenter(TKEY, 1);
1628                                 mainqenter(TKEY, 0);
1629                                 mainqenter(EXECUTE, 1);
1630                                 mainqenter(LEFTSHIFTKEY, 0);
1631                                 mainqenter(LEFTCTRLKEY, 0);
1632                                 mainqenter(LEFTALTKEY, 0);
1633                         }
1634                         break;
1635                 }
1636         }
1637
1638         allqueue(REDRAWVIEW3D, 0);
1639 }
1640
1641
1642 static uiBlock *info_help_systemmenu(void *arg_unused)
1643 {
1644         uiBlock *block;
1645         BPyMenu *pym;
1646         short yco = 20, menuwidth = 120;
1647         int i = 0;
1648
1649         block= uiNewBlock(&curarea->uiblocks, "info_help_systemmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1650         uiBlockSetButmFunc(block, do_info_help_systemmenu, NULL);
1651         
1652         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Benchmark",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
1653         
1654         for (pym = BPyMenuTable[PYMENU_HELPSYSTEM]; pym; pym = pym->next, i++) {
1655                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, i+10, pym->tooltip?pym->tooltip:pym->filename);
1656         }
1657         
1658         uiBlockSetDirection(block, UI_RIGHT);
1659         uiTextBoundsBlock(block, 60);
1660                 
1661         return block;
1662 }
1663
1664 static void do_info_helpmenu(void *arg, int event)
1665 {
1666         ScrArea *sa;
1667
1668         if(curarea->spacetype==SPACE_INFO) {
1669                 sa= find_biggest_area_of_type(SPACE_SCRIPT);
1670                 if (!sa) sa= closest_bigger_area();
1671                 areawinset(sa->win);
1672         }
1673
1674         /* events >=10 are registered bpython scripts */
1675         if (event >= 10) BPY_menu_do_python(PYMENU_HELP, event - 10);
1676         else {
1677                 switch(event) {
1678                                                                         
1679                 case 0: /* About Blender */
1680                         break;
1681                 }
1682         }
1683
1684         allqueue(REDRAWINFO, 0);
1685 }
1686
1687 static uiBlock *info_helpmenu(void *arg_unused)
1688 {
1689 /*              static short tog=0; */
1690         uiBlock *block;
1691         short yco= 0;
1692         short menuwidth=120;
1693         BPyMenu *pym;
1694         int i = 0;
1695         
1696         block= uiNewBlock(&curarea->uiblocks, "info_helpmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
1697         uiBlockSetButmFunc(block, do_info_helpmenu, NULL);
1698         
1699         uiDefIconTextBut(block, BUTM, B_SHOWSPLASH, ICON_BLANK1, "About Blender...",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
1700         
1701         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1702         
1703         for (pym = BPyMenuTable[PYMENU_HELP]; pym; pym = pym->next, i++) {
1704                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, i+10, pym->tooltip?pym->tooltip:pym->filename);
1705         }
1706         
1707         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1708         
1709         uiDefIconTextBlockBut(block, info_help_websitesmenu, NULL, ICON_RIGHTARROW_THIN, "Websites", 0, yco-=20, 120, 19, "");
1710         
1711         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1712         
1713         uiDefIconTextBlockBut(block, info_help_systemmenu, NULL, ICON_RIGHTARROW_THIN, "System", 0, yco-=20, 120, 19, "");
1714
1715         uiBlockSetDirection(block, UI_DOWN);
1716         uiTextBoundsBlock(block, 80);
1717
1718         return block;
1719 }
1720
1721 /************************** END MAIN MENU *****************************/
1722 /* ugly global yes, for renderwin.c to write to */
1723 char info_time_str[32]="";
1724
1725 static void info_text(int x, int y)
1726 {
1727         Object *ob= OBACT;
1728         extern float hashvectf[];
1729         extern int mem_in_use;
1730         unsigned int swatch_color;
1731         float fac1, fac2, fac3;
1732         char infostr[300];
1733         char *headerstr;
1734         int hsize;
1735
1736         if(G.obedit) {
1737                 char *s = infostr;
1738
1739                 s+= sprintf(s, "%s", G.editModeTitleExtra);
1740                 if(G.obedit->type==OB_MESH) {
1741                         if(G.scene->selectmode & SCE_SELECT_VERTEX)
1742                                 s+= sprintf(s,"Ve:%d-%d | Ed:%d-%d | Fa:%d-%d",
1743                                                 G.totvertsel, G.totvert, G.totedgesel, G.totedge, G.totfacesel, G.totface);
1744                         else if(G.scene->selectmode & SCE_SELECT_EDGE)
1745                                 s+= sprintf(s,"Ed:%d-%d | Fa:%d-%d",
1746                                                 G.totedgesel, G.totedge, G.totfacesel, G.totface);
1747                         else 
1748                                 s+= sprintf(s,"Fa:%d-%d", G.totfacesel, G.totface);
1749                 }
1750                 else if(G.obedit->type==OB_ARMATURE) {
1751                         s+= sprintf(s,"Ve:%d-%d | Bo:%d-%d", G.totvertsel, G.totvert, G.totbonesel, G.totbone);
1752                 }
1753                 else {
1754                         s+= sprintf(s,"Ve:%d-%d", G.totvertsel, G.totvert);
1755                 }
1756
1757                 sprintf(s," | Mem:%.2fM ", (mem_in_use>>10)/1024.0);
1758         }
1759         else if(ob && (ob->flag & OB_POSEMODE)) {
1760                 sprintf(infostr,"Bo:%d-%d | Mem:%.2fM ",
1761                                         G.totbonesel, G.totbone, (mem_in_use>>10)/1024.0);
1762         }
1763         else {
1764                 sprintf(infostr,"Ve:%d | Fa:%d | Ob:%d-%d | La:%d | Mem:%.2fM | Time:%s | ",
1765                         G.totvert, G.totface, G.totobj, G.totobjsel, G.totlamp,  (mem_in_use>>10)/1024.0, info_time_str);
1766         }
1767         if(ob) {
1768                 strcat(infostr, ob->id.name+2);
1769         }
1770
1771         if (g_progress_bar && g_progress_info) {
1772                 headerstr= g_progress_info;
1773         } else {
1774                 headerstr= versionstr; 
1775         }
1776
1777         if      (g_progress_bar) {
1778                 hsize = 4 + (138.0 * g_done);
1779                 fac1 = 0.5 * g_done; // do some rainbow colours on progress
1780                 fac2 = 1.0;
1781                 fac3 = 0.9;
1782         } else {
1783                 hsize= 30+BIF_GetStringWidth(G.font, headerstr, (U.transopts & USER_TR_BUTTONS));
1784
1785                 /* promise! Never change these lines again! (zr & ton did!) */
1786                 fac1= fabs(hashvectf[ 2*G.version+4]);
1787                 fac2= 0.5+0.1*hashvectf[ G.version+3];
1788                 fac3= 0.7;
1789         }
1790         
1791         swatch_color= hsv_to_cpack(fac1, fac2, fac3);
1792
1793         cpack( swatch_color );
1794         glRecti(x-24,  y-6,  x-30+hsize,        y+14);
1795
1796         glColor3ub(0, 0, 0); /* makes text black colored rect */
1797         
1798         glRasterPos2i(x, y);
1799         BIF_RasterPos(x, y);
1800
1801         BIF_DrawString(G.font, headerstr, (U.transopts & USER_TR_MENUS));
1802         hsize= BIF_GetStringWidth(G.font, headerstr, (U.transopts & USER_TR_BUTTONS));
1803         
1804         BIF_ThemeColor(TH_MENU_TEXT); /* makes text readable on dark theme */
1805         
1806         glRasterPos2i(x+hsize+10,       y);
1807         BIF_RasterPos(x+hsize+10,       y);
1808         
1809         BIF_DrawString(G.font, infostr, (U.transopts & USER_TR_MENUS));
1810 }
1811
1812 void info_buttons(void)
1813 {
1814         uiBlock *block;
1815         short xco= 42;
1816         int xmax;
1817
1818         block= uiNewBlock(&curarea->uiblocks, "header info", UI_EMBOSSN, UI_HELV, curarea->headwin);
1819
1820         if(area_is_active_area(curarea)) uiBlockSetCol(block, TH_HEADER);
1821         else uiBlockSetCol(block, TH_HEADERDESEL);
1822         
1823         if(curarea->flag & HEADER_NO_PULLDOWN) {
1824                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_RIGHT,
1825                                 xco,2,XIC,YIC-2,
1826                                 &(curarea->flag), 0, 0, 0, 0, "Enables display of pulldown menus");
1827         } else {
1828                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_DOWN,
1829                                 xco,2,XIC,YIC-2,
1830                                 &(curarea->flag), 0, 0, 0, 0, "Hides pulldown menus");
1831         }
1832         xco+=XIC;
1833
1834         if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
1835         
1836                 uiBlockSetEmboss(block, UI_EMBOSSP);
1837
1838                 /* the 'xmax - 3' rather than xmax is to prevent some weird flickering where the highlighted
1839                  * menu is drawn wider than it should be. The ypos of -1 is to make it properly fill the
1840                  * height of the header */
1841                 xmax= GetButStringLength("File");
1842                 uiDefPulldownBut(block, info_filemenu, NULL, "File",    xco, -1, xmax-3, 22, "");
1843                 xco+= xmax;
1844
1845                 xmax= GetButStringLength("Add");
1846                 uiDefPulldownBut(block, info_addmenu, NULL, "Add",      xco, -1, xmax-3, 22, "");
1847                 xco+= xmax;
1848
1849                 xmax= GetButStringLength("Timeline");
1850                 uiDefPulldownBut(block, info_timelinemenu, NULL, "Timeline",    xco, -1, xmax-3, 22, "");
1851                 xco+= xmax;
1852
1853                 xmax= GetButStringLength("Game");
1854                 uiDefPulldownBut(block, info_gamemenu, NULL, "Game",    xco, -1, xmax-3, 22, "");
1855                 xco+= xmax;
1856
1857                 xmax= GetButStringLength("Render");
1858                 uiDefPulldownBut(block, info_rendermenu, NULL, "Render",        xco, -1, xmax-3, 22, "");
1859                 xco+= xmax;
1860
1861                 xmax= GetButStringLength("Help");
1862                 uiDefPulldownBut(block, info_helpmenu, NULL, "Help",    xco, -1, xmax-3, 22, "");
1863                 xco+= xmax;
1864
1865         }
1866
1867         /* pack icon indicates a packed file */
1868         
1869         if (G.fileflags & G_AUTOPACK) {
1870                 uiBlockSetEmboss(block, UI_EMBOSSN);
1871                 uiDefIconBut(block, LABEL, 0, ICON_PACKAGE, xco, 0, XIC, YIC, &G.fileflags, 0.0, 0.0, 0, 0, "Indicates this is a Packed file. See File menu.");
1872                 xco += XIC;
1873         }
1874
1875         if (curarea->full == 0) {
1876                 curarea->butspacetype= SPACE_INFO;
1877                 uiBlockSetEmboss(block, UI_EMBOSS);
1878                 uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), 8,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types.");
1879                 
1880                 /* STD SCREEN BUTTONS */
1881                 xco= std_libbuttons(block, xco, 0, 0, NULL, B_INFOSCR, ID_SCR, 0, (ID *)G.curscreen, 0, &G.curscreen->screennr, 1, 1, B_INFODELSCR, 0, 0);
1882                 
1883                 xco +=8;
1884         
1885                 /* STD SCENE BUTTONS */
1886                 xco= std_libbuttons(block, xco, 0, 0, NULL, B_INFOSCE, ID_SCE, 0, (ID *)G.scene, 0, &G.curscreen->scenenr, 1, 1, B_INFODELSCE, 0, 0);
1887         }
1888         else xco= 430;
1889         
1890 BIF_SetScale(block->aspect);
1891         info_text(xco+24, 6);
1892         
1893         uiBlockSetEmboss(block, UI_EMBOSSN);
1894         uiDefIconBut(block, BUT, B_SHOWSPLASH, ICON_BLENDER, xco+2, 0,XIC,YIC, 0, 0, 0, 0, 0, "Click to display Splash Screen");
1895
1896         /* always do as last */
1897         curarea->headbutlen= xco+2*XIC;
1898
1899 #if 0
1900 // #ifdef _WIN32        // FULLSCREEN
1901         if(U.uiflag & USER_FLIPFULLSCREEN) {
1902                 uiDefIconBut(block, BUT, B_FLIPFULLSCREEN, ICON_WINDOW_WINDOW,
1903                                 (short)(curarea->winx-XIC-5), 0,XIC,YIC,
1904                                 0, 0, 0, 0, 0, "Toggles Blender to fullscreen mode");/* dir             */
1905         } else {
1906                 uiDefIconBut(block, BUT, B_FLIPFULLSCREEN, ICON_WINDOW_FULLSCREEN,
1907                                 (short)(curarea->winx-XIC-5), 0,XIC,YIC,
1908                                 0, 0, 0, 0, 0, "Toggles Blender to fullscreen mode");/* dir             */
1909         }
1910 #endif
1911         
1912         uiDrawBlock(block);
1913 }