87b76a084fe7da587a7b39a1ed37fbbc2e362eb6
[blender.git] / source / blender / src / toets.c
1 /**
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30
31  *
32  *
33  * General blender hot keys (toets = dutch), special hotkeys are in space.c
34  *
35  */
36
37 #include <string.h>
38 #include <math.h>
39
40 #ifdef WIN32
41 #include "BLI_winstuff.h"
42 #endif
43
44 #include "MEM_guardedalloc.h"
45
46 #include "PIL_time.h"
47
48 #include "nla.h"        /* Only for the #ifdef flag - To be removed later */
49
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
52
53 #include "DNA_object_types.h"
54 #include "DNA_screen_types.h"
55 #include "DNA_scene_types.h"
56 #include "DNA_space_types.h"
57 #include "DNA_view3d_types.h"
58 #include "DNA_userdef_types.h"
59
60 #include "BKE_action.h"
61 #include "BKE_anim.h"
62 #include "BKE_blender.h"
63 #include "BKE_depsgraph.h"
64 #include "BKE_displist.h"
65 #include "BKE_global.h"
66 #include "BKE_image.h"
67 #include "BKE_ipo.h"
68 #include "BKE_key.h"
69 #include "BKE_scene.h"
70 #include "BKE_utildefines.h"
71
72 #include "BIF_butspace.h"
73 #include "BIF_editseq.h"
74 #include "BIF_editsound.h"
75 #include "BIF_editmesh.h"
76 #include "BIF_interface.h"
77 #include "BKE_object.h"
78 #include "BIF_poseobject.h"
79 #include "BIF_previewrender.h"
80 #include "BIF_renderwin.h"
81 #include "BIF_retopo.h"
82 #include "BIF_screen.h"
83 #include "BIF_space.h"
84 #include "BIF_toets.h"
85 #include "BIF_toolbox.h"
86 #include "BIF_usiblender.h"
87 #include "BIF_writeimage.h"
88
89 #include "BDR_sculptmode.h"
90 #include "BDR_vpaint.h"
91 #include "BDR_editobject.h"
92 #include "BDR_editface.h"
93
94 #include "BSE_filesel.h"        /* For activate_fileselect */
95 #include "BSE_drawview.h"       /* For play_anim */
96 #include "BSE_view.h"
97 #include "BSE_edit.h"
98 #include "BSE_editipo.h"
99 #include "BSE_headerbuttons.h"
100 #include "BSE_seqaudio.h"
101
102 #include "blendef.h"
103
104 #include "IMB_imbuf.h"
105 #include "IMB_imbuf_types.h"
106
107 #include "mydevice.h"
108
109 #include "BIF_poseobject.h"
110
111 /* ------------------------------------------------------------------------- */
112
113 static int is_an_active_object(void *ob) {
114         Base *base;
115         
116         for (base= FIRSTBASE; base; base= base->next)
117                 if (base->object == ob)
118                         return 1;
119         
120         return 0;
121 }
122
123 void persptoetsen(unsigned short event)
124 {
125         static Object *oldcamera=0;
126         float phi, si, q1[4], vec[3];
127         static int perspo=1;
128         int preview3d_event= 1;
129         
130         if(event==PADENTER) {
131                 if (G.qual == LR_SHIFTKEY) {
132                         view3d_set_1_to_1_viewborder(G.vd);
133                 } else {
134                         if (G.vd->persp==2) {
135                                 G.vd->camzoom= 0;
136                         } else {
137                                 G.vd->dist= 10.0;
138                         }
139                 }
140         }
141         else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
142                 
143                 /* Indicate that this view is inverted,
144                  * but only if it actually _was_ inverted (jobbe) */
145                 if (event==PAD7 || event == PAD1 || event == PAD3)
146                         G.vd->flag2 |= V3D_OPP_DIRECTION_NAME;
147                 
148                 if(event==PAD0) {
149                         /* G.vd->persp= 3; */
150                 }
151                 else if(event==PAD7) {
152                         G.vd->viewquat[0]= 0.0;
153                         G.vd->viewquat[1]= -1.0;
154                         G.vd->viewquat[2]= 0.0;
155                         G.vd->viewquat[3]= 0.0;
156                         G.vd->view= 7;
157                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0; 
158                         else if(G.vd->persp>=2) G.vd->persp= perspo;
159                 }
160                 else if(event==PAD1) {
161                         G.vd->viewquat[0]= 0.0;
162                         G.vd->viewquat[1]= 0.0;
163                         G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
164                         G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
165                         G.vd->view=1;
166                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
167                         else if(G.vd->persp>=2) G.vd->persp= perspo;
168                 }
169                 else if(event==PAD3) {
170                         G.vd->viewquat[0]= 0.5;
171                         G.vd->viewquat[1]= -0.5;
172                         G.vd->viewquat[2]= 0.5;
173                         G.vd->viewquat[3]= 0.5;
174                         G.vd->view=3;
175                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
176                         else if(G.vd->persp>=2) G.vd->persp= perspo;
177                 }
178                 else if(event==PADMINUS) {
179                         /* this min and max is also in viewmove() */
180                         if(G.vd->persp==2) {
181                                 G.vd->camzoom-= 10;
182                                 if(G.vd->camzoom<-30) G.vd->camzoom= -30;
183                         }
184                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
185                 }
186                 else if(event==PADPLUSKEY) {
187                         if(G.vd->persp==2) {
188                                 G.vd->camzoom+= 10;
189                                 if(G.vd->camzoom>300) G.vd->camzoom= 300;
190                         }
191                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
192                 }
193                 else {
194
195                         initgrabz(0.0, 0.0, 0.0);
196                         
197                         if(event==PAD6) window_to_3d(vec, -32, 0);
198                         else if(event==PAD4) window_to_3d(vec, 32, 0);
199                         else if(event==PAD8) window_to_3d(vec, 0, -25);
200                         else if(event==PAD2) window_to_3d(vec, 0, 25);
201                         G.vd->ofs[0]+= vec[0];
202                         G.vd->ofs[1]+= vec[1];
203                         G.vd->ofs[2]+= vec[2];
204                 }
205         }
206         else {
207                 /* Indicate that this view is not inverted.
208                  * Don't do this for PADMINUS/PADPLUSKEY, though. (jobbe)*/
209                 if (event != PADMINUS && event != PADPLUSKEY)
210                         G.vd->flag2 &= ~V3D_OPP_DIRECTION_NAME;
211                 
212
213                 if(event==PAD7) {
214                         G.vd->viewquat[0]= 1.0;
215                         G.vd->viewquat[1]= 0.0;
216                         G.vd->viewquat[2]= 0.0;
217                         G.vd->viewquat[3]= 0.0;
218                         G.vd->view=7;
219                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
220                         else if(G.vd->persp>=2) G.vd->persp= perspo;
221                 }
222                 else if(event==PAD1) {
223                         G.vd->viewquat[0]= (float)cos(M_PI/4.0);
224                         G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
225                         G.vd->viewquat[2]= 0.0;
226                         G.vd->viewquat[3]= 0.0;
227                         G.vd->view=1;
228                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
229                         else if(G.vd->persp>=2) G.vd->persp= perspo;
230                 }
231                 else if(event==PAD3) {
232                         G.vd->viewquat[0]= 0.5;
233                         G.vd->viewquat[1]= -0.5;
234                         G.vd->viewquat[2]= -0.5;
235                         G.vd->viewquat[3]= -0.5;
236                         G.vd->view=3;
237                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
238                         else if(G.vd->persp>=2) G.vd->persp= perspo;
239                 }
240                 else if(event==PADMINUS) {
241                         /* this min and max is also in viewmove() */
242                         if(G.vd->persp==2) {
243                                 G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
244                         }
245                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
246                         if(G.vd->persp!=1) preview3d_event= 0;
247                 }
248                 else if(event==PADPLUSKEY) {
249                         if(G.vd->persp==2) {
250                                 G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
251                         }
252                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
253                         if(G.vd->persp!=1) preview3d_event= 0;
254                 }
255                 else if(event==PAD5) {
256                         if(G.vd->persp==1) G.vd->persp=0;
257                         else G.vd->persp=1;
258                 }
259                 else if(event==PAD0) {
260                         if(G.qual==LR_ALTKEY) {
261                                 if(oldcamera && is_an_active_object(oldcamera)) {
262                                         G.vd->camera= oldcamera;
263                                 }
264                                 
265                                 handle_view3d_lock();
266                         }
267                         else if(BASACT) {
268                                 /* check both G.vd as G.scene cameras */
269                                 if(G.qual==LR_CTRLKEY) {
270                                         if(G.vd->camera != OBACT || G.scene->camera != OBACT) {
271                                                 if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
272                                                         oldcamera= G.vd->camera;
273                                                 
274                                                 G.vd->camera= OBACT;
275                                                 handle_view3d_lock();
276                                         }
277                                 }
278                                 else if((G.vd->camera==NULL || G.scene->camera==NULL) && OBACT->type==OB_CAMERA) {
279                                         G.vd->camera= OBACT;
280                                         handle_view3d_lock();
281                                 }
282                         }
283                         if(G.vd->camera==0) {
284                                 G.vd->camera= scene_find_camera(G.scene);
285                                 handle_view3d_lock();
286                         }
287                         
288                         if(G.vd->camera) {
289                                 G.vd->persp= 2;
290                                 G.vd->view= 0;
291                                 if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
292                                         void setcameratoview3d(void);   // view.c
293                                         setcameratoview3d();
294                                         DAG_object_flush_update(G.scene, G.scene->camera, OB_RECALC_OB);
295                                         BIF_undo_push("View to Camera position");
296                                         allqueue(REDRAWVIEW3D, 0);
297                                 }                               
298                         }
299                 }
300                 else if(event==PAD9) {
301                         countall();
302                         update_for_newframe();
303                         
304                         reset_slowparents();    /* editobject.c */
305                 }
306                 else if(G.vd->persp<2) {
307                         if(event==PAD4 || event==PAD6) {
308                                 /* z-axis */
309                                 phi= (float)(M_PI/360.0)*U.pad_rot_angle;
310                                 if(event==PAD6) phi= -phi;
311                                 si= (float)sin(phi);
312                                 q1[0]= (float)cos(phi);
313                                 q1[1]= q1[2]= 0.0;
314                                 q1[3]= si;
315                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
316                                 G.vd->view= 0;
317                         }
318                         if(event==PAD2 || event==PAD8) {
319                                 
320                                 /* horizontal axis */
321                                 VECCOPY(q1+1, G.vd->viewinv[0]);
322                                 
323                                 Normalize(q1+1);
324                                 phi= (float)(M_PI/360.0)*U.pad_rot_angle;
325                                 if(event==PAD2) phi= -phi;
326                                 si= (float)sin(phi);
327                                 q1[0]= (float)cos(phi);
328                                 q1[1]*= si;
329                                 q1[2]*= si;
330                                 q1[3]*= si;
331                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
332                                 G.vd->view= 0;
333                         }
334                 }
335
336                 if(G.vd->persp<2) perspo= G.vd->persp;
337         }
338
339         if(G.vd->depths) G.vd->depths->damaged= 1;
340         retopo_queue_updates(G.vd);
341         retopo_force_update();
342         
343         if(preview3d_event) 
344                 BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
345         else
346                 BIF_view3d_previewrender_signal(curarea, PR_PROJECTED);
347
348         scrarea_queue_redraw(curarea);
349 }
350
351 int untitled(char * name)
352 {
353         if (G.save_over == 0 ) {
354                 char * c= BLI_last_slash(name);
355                 
356                 if (c)
357                         strcpy(&c[1], "untitled.blend");
358                 else
359                         strcpy(name, "untitled.blend");
360                         
361                 return(TRUE);
362         }
363         
364         return(FALSE);
365 }
366
367 char *recent_filelist(void)
368 {
369         struct RecentFile *recent;
370         int event, i, ofs;
371         char pup[2048], *p;
372
373         p= pup + sprintf(pup, "Open Recent%%t");
374         
375         if (G.sce[0]) {
376                 p+= sprintf(p, "|%s %%x%d", G.sce, 1);
377                 ofs = 1;
378         } else ofs = 0;
379
380         for (recent = G.recent_files.first, i=0; (i<U.recent_files) && (recent); recent = recent->next, i++) {
381                 if (strcmp(recent->filename, G.sce)) {
382                         p+= sprintf(p, "|%s %%x%d", recent->filename, i+ofs+1);
383                 }
384         }
385         event= pupmenu(pup);
386         if(event>0) {
387                 if (ofs && (event==1))
388                         return(G.sce);
389                 else
390                         recent = BLI_findlink(&(G.recent_files), event-1-ofs);
391                         if(recent) return(recent->filename);
392         }
393         
394         return(NULL);
395 }
396
397 int blenderqread(unsigned short event, short val)
398 {
399         /* here do the general keys handling (not screen/window/space) */
400         /* return 0: do not pass on to the other queues */
401         extern int textediting;
402         extern void playback_anim();
403         ScrArea *sa;
404         Object *ob;
405         int textspace=0;
406         /* Changed str and dir size to 160, to make sure there is enough
407          * space for filenames. */
408         char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
409         char *recentfile;
410         
411         if(val==0) return 1;
412         if(event==MOUSEY || event==MOUSEX) return 1;
413         if (G.flags & G_FILE_AUTOPLAY) return 1;
414
415         if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
416         else if (curarea && curarea->spacetype==SPACE_SCRIPT) textspace= 1;
417
418         switch(event) {
419
420         case F1KEY:
421                 if(G.qual==0) {
422                         /* this exception because of the '?' button */
423                         if(curarea->spacetype==SPACE_INFO) {
424                                 sa= closest_bigger_area();
425                                 areawinset(sa->win);
426                         }
427                         
428                         activate_fileselect(FILE_BLENDER, "Open File", G.sce, BIF_read_file);
429                         return 0;
430                 }
431                 else if(G.qual==LR_SHIFTKEY) {
432                         activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
433                         return 0;
434                 }
435                 break;
436         case F2KEY:
437                 if(G.qual==0) {
438                         strcpy(dir, G.sce);
439                         untitled(dir);
440                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
441                         return 0;
442                 }
443                 else if(G.qual==LR_CTRLKEY) {
444                         write_vrml_fs();
445                         return 0;
446                 }
447                 else if(G.qual==LR_SHIFTKEY) {
448                         write_dxf_fs();
449                         return 0;
450                 }
451                 break;
452         case F3KEY:
453                 if(G.qual==0) {
454                         BIF_save_rendered_image_fs();
455                         return 0;
456                 }
457                 else if(G.qual==LR_SHIFTKEY) {
458                         newspace(curarea, SPACE_NODE);
459                         return 0;
460                 }
461                 else if(G.qual & LR_CTRLKEY) {
462                         BIF_screendump(0);
463                 }
464                 break;
465         case F4KEY:
466                 if(G.qual==LR_SHIFTKEY) {
467
468                         memset(str, 0, 16);
469                         ob= OBACT;
470                         if(ob) strcpy(str, ob->id.name);
471
472                         activate_fileselect(FILE_MAIN, "Data Select", str, NULL);
473                         return 0;
474                 }
475                 else if(G.qual==0) {
476                         extern_set_butspace(event, 1);
477                 }
478                 break;
479         case F5KEY:
480                 if(G.qual==LR_SHIFTKEY) {
481                         newspace(curarea, SPACE_VIEW3D);
482                         return 0;
483                 }
484                 else if(G.qual==0) {
485                         extern_set_butspace(event, 1);
486                 }
487                 break;
488         case F6KEY:
489                 if(G.qual==LR_SHIFTKEY) {
490                         newspace(curarea, SPACE_IPO);
491                         return 0;
492                 }
493                 else if(G.qual==0) {
494                         extern_set_butspace(event, 1);
495                 }
496                 break;
497         case F7KEY:
498                 if(G.qual==LR_SHIFTKEY) {
499                         newspace(curarea, SPACE_BUTS);
500                         return 0;
501                 }
502                 else if(G.qual==0) {
503                         extern_set_butspace(event, 1);
504                 }
505                 break;
506         case F8KEY:
507                 if(G.qual==LR_SHIFTKEY) {
508                         newspace(curarea, SPACE_SEQ);
509                         return 0;
510                 }
511                 else if(G.qual==0) {
512                         extern_set_butspace(event, 1);
513                 }
514                 break;
515         case F9KEY:
516                 if(G.qual==LR_SHIFTKEY) {
517                         newspace(curarea, SPACE_OOPS);
518                         return 0;
519                 }
520                 else if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)) {
521                         newspace(curarea, SPACE_OOPS+256);
522                         return 0;
523                 }
524                 else if(G.qual==0) {
525                         extern_set_butspace(event, 1);
526                 }
527                 break;
528         case F10KEY:
529                 if(G.qual==LR_SHIFTKEY) {
530                         newspace(curarea, SPACE_IMAGE);
531                         return 0;
532                 }
533                 else if(G.qual==0) {
534                         extern_set_butspace(event, 1);
535                 }
536                 break;
537         case F11KEY:
538                 if(G.qual==LR_SHIFTKEY) {
539                         newspace(curarea, SPACE_TEXT);
540                         return 0;
541                 }
542                 else if (G.qual==LR_CTRLKEY) {
543                         playback_anim();
544                 }
545                 else if(G.qual==0) {
546                         BIF_toggle_render_display();
547                         return 0;
548                 }
549                 break;
550         case F12KEY:
551                 if(G.qual==LR_SHIFTKEY) {
552                         newspace(curarea, SPACE_ACTION);
553                         return 0;
554                 }
555                 else if (G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
556                         newspace(curarea, SPACE_NLA);
557                         return 0;
558                 }
559                 else if (G.qual==LR_CTRLKEY) {
560                         BIF_do_render(1);
561                 }
562                 else {
563                         /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
564                         BIF_do_render(0);
565                 }
566                 return 0;
567                 break;
568         
569         case WHEELUPMOUSE:
570                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
571                         if(CFRA>1) {
572                                 CFRA--;
573                                 update_for_newframe();
574                         }
575                         return 0;
576                 }
577                 break;
578         case WHEELDOWNMOUSE:
579                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
580                         CFRA++;
581                         update_for_newframe();
582                         return 0;
583                 }
584                 break;
585                 
586         case LEFTARROWKEY:
587         case DOWNARROWKEY:
588                 if(textediting==0 && textspace==0) {
589
590 #if 0
591 //#ifdef _WIN32 // FULLSCREEN
592                         if(event==DOWNARROWKEY){
593                                 if (G.qual==LR_ALTKEY)
594                                         mainwindow_toggle_fullscreen(0);
595                                 else if(G.qual==0)
596                                         CFRA-= G.scene->jumpframe;
597                         }
598 #else
599                         if((event==DOWNARROWKEY)&&(G.qual==0))
600                                 CFRA-= G.scene->jumpframe;
601 #endif
602                         else if((event==LEFTARROWKEY)&&(G.qual==0))
603                                 CFRA--;
604                         
605                         if(G.qual==LR_SHIFTKEY)
606                                 CFRA= PSFRA;
607                         if(CFRA<1) CFRA=1;
608         
609                         update_for_newframe();
610                         return 0;
611                 }
612                 break;
613
614         case RIGHTARROWKEY:
615         case UPARROWKEY:
616                 if(textediting==0 && textspace==0) {
617
618 #if 0
619 //#ifdef _WIN32 // FULLSCREEN
620                         if(event==UPARROWKEY){ 
621                                 if(G.qual==LR_ALTKEY)
622                                         mainwindow_toggle_fullscreen(1);
623                                 else if(G.qual==0)
624                                         CFRA+= G.scene->jumpframe;
625                         }
626 #else
627                         if((event==UPARROWKEY)&&(G.qual==0))
628                                 CFRA+= G.scene->jumpframe;
629 #endif
630                         else if((event==RIGHTARROWKEY)&&(G.qual==0))
631                                 CFRA++;
632
633                         if(G.qual==LR_SHIFTKEY)
634                                 CFRA= PEFRA;
635                         
636                         update_for_newframe();
637                 }
638                 break;
639
640         case ESCKEY:
641                 sound_stop_all_sounds();        // whats this?
642                 
643                 /* stop playback on ESC always */
644                 rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
645                 audiostream_stop();
646                 allqueue(REDRAWALL, 0);
647                 
648                 break;
649         case TABKEY:
650                 if(G.qual==0) {
651                         if(textspace==0) {
652                                 if(curarea->spacetype==SPACE_IPO)
653                                         set_editflag_editipo();
654                                 else if(curarea->spacetype==SPACE_SEQ)
655                                         enter_meta();
656                                 else if(curarea->spacetype==SPACE_NODE)
657                                         return 1;
658                                 else if(G.vd) {
659                                         /* also when Alt-E */
660                                         if(G.obedit==NULL) {
661                                                 enter_editmode(EM_WAITCURSOR);
662                                                 if(G.obedit) BIF_undo_push("Original"); // here, because all over code enter_editmode is abused
663                                         }
664                                         else
665                                                 exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
666                                 }
667                                 return 0;
668                         }
669                 }
670                 else if(G.qual==LR_CTRLKEY){
671                         Object *ob= OBACT;
672                         if(ob) {
673                                 if(ob->type==OB_ARMATURE) {
674                                         if(ob->flag & OB_POSEMODE) exit_posemode();
675                                         else enter_posemode();
676                                 }
677                                 else if(ob->type==OB_MESH) {
678                                         if(ob==G.obedit) EM_selectmode_menu();
679                                         else if(G.f & G_SCULPTMODE)
680                                                 sculptmode_selectbrush_menu();
681                                         else set_wpaint();
682                                 }
683                         }
684                 }
685                 break;
686
687         case BACKSPACEKEY:
688                 break;
689
690         case AKEY:
691                 if(textediting==0 && textspace==0) {
692                         if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){
693                                 play_anim(1);
694                                 return 0;
695                         }
696                         else if(G.qual==LR_ALTKEY) {
697                                 play_anim(0);
698                                 return 0;
699                         }
700                 }
701                 break;
702         case EKEY:
703                 if(G.qual==LR_ALTKEY) {
704                         if(G.vd && textspace==0) {
705                                 if(G.obedit==0) {
706                                         enter_editmode(EM_WAITCURSOR);
707                                         BIF_undo_push("Original");
708                                 }
709                                 else
710                                         exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
711                                 return 0;
712                         }                       
713                 }
714                 break;
715         case IKEY:
716                 if(textediting==0 && textspace==0 && !ELEM3(curarea->spacetype, SPACE_FILE, SPACE_IMASEL, SPACE_NODE)) {
717                         if(G.f & G_SCULPTMODE) return 1;
718                         else if(G.qual==0) {
719                                 common_insertkey();
720                                 return 0;
721                         }
722                 }
723                 break;
724         case JKEY:
725                 if(textediting==0 && textspace==0) {
726                         if (G.qual==0) {
727                                 BIF_swap_render_rects();
728                                 return 0;
729                         }
730                 }
731                 break;
732
733         case NKEY:
734                 if(textediting==0 && textspace==0) {
735                         if(G.qual & LR_CTRLKEY);
736                         else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
737                                 if(curarea->spacetype==SPACE_VIEW3D);           // is new panel, in view3d queue
738                                 else if(curarea->spacetype==SPACE_IPO);                 // is new panel, in ipo queue
739                                 else if(curarea->spacetype==SPACE_IMAGE);                       // is new panel, in ipo queue
740                                 else if(curarea->spacetype==SPACE_ACTION);                      // is own queue
741                                 else if(curarea->spacetype==SPACE_NLA);                 // is new panel
742                                 else if(curarea->spacetype==SPACE_SEQ);                 // is new panel
743                                 else {
744                                         clever_numbuts();
745                                         return 0;
746                                 }
747                         }
748                 }
749                 break;
750                 
751         case OKEY:
752                 if(textediting==0) {
753                         if(G.qual==LR_CTRLKEY) {
754                                 recentfile = recent_filelist();
755                                 if(recentfile) {
756                                         BIF_read_file(recentfile);
757                                 }
758                                 return 0;
759                         }
760                 }
761                 break;
762                 
763         case SKEY:
764                 if(G.obedit==NULL) {
765                         if(G.qual==LR_CTRLKEY) {
766                                 strcpy(dir, G.sce);
767                                 if (untitled(dir)) {
768                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
769                                 } else {
770                                         BIF_write_file(dir);
771                                         free_filesel_spec(dir);
772                                 }
773                                 return 0;
774                         }
775                 }
776                 break;
777         
778         case TKEY:
779                 if (G.qual==(LR_SHIFTKEY|LR_ALTKEY|LR_CTRLKEY)) {
780                         Object *ob = OBACT;
781                         int event = pupmenu(ob?"Time%t|draw|recalc ob|recalc data":"Time%t|draw");
782                         int a;
783                         double delta, stime;
784
785                         if (event < 0) return 0; /* cancelled by user */
786
787                         waitcursor(1);
788                         
789                         stime= PIL_check_seconds_timer();
790                         for(a=0; a<100000; a++) {
791                                 if (event==1) {
792                                         scrarea_do_windraw(curarea);
793                                 } else if (event==2) {
794                                         ob->recalc |= OB_RECALC_OB;
795                                         object_handle_update(ob);
796                                 } else if (event==3) {
797                                         ob->recalc |= OB_RECALC_DATA;
798                                         object_handle_update(ob);
799                                 }
800
801                                 delta= PIL_check_seconds_timer()-stime;
802                                 if (delta>5.0) break;
803                         }
804                         
805                         waitcursor(0);
806                         notice("%8.6f s/op - %6.2f ops/s - %d iterations", delta/a, a/delta, a);
807                         return 0;
808                 }
809                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
810                         int a;
811                         int event= pupmenu("10 Timer%t|draw|draw+swap|undo");
812                         if(event>0) {
813                                 double stime= PIL_check_seconds_timer();
814                                 char tmpstr[128];
815                                 int time;
816
817                                 waitcursor(1);
818                                 
819                                 for(a=0; a<10; a++) {
820                                         if (event==1) {
821                                                 scrarea_do_windraw(curarea);
822                                         } else if (event==2) {
823                                                 scrarea_do_windraw(curarea);
824                                                 screen_swapbuffers();
825                                         }
826                                         else if(event==3) {
827                                                 BIF_undo();
828                                                 BIF_redo();
829                                         }
830                                 }
831                         
832                                 time= (int) ((PIL_check_seconds_timer()-stime)*1000);
833                                 
834                                 if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time);
835                                 if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time);
836                                 if(event==3) sprintf(tmpstr, "undo %%t|%d ms", time);
837                         
838                                 waitcursor(0);
839                                 pupmenu(tmpstr);
840
841                         }
842                         return 0;
843                 }
844                 break;
845                                 
846         case UKEY:
847                 if(textediting==0) {
848                         if(G.qual==LR_CTRLKEY) {
849                                 if(okee("Save user defaults")) {
850                                         BIF_write_homefile();
851                                 }
852                                 return 0;
853                         }
854                         else if(G.qual==LR_ALTKEY) {
855                                 if(curarea->spacetype!=SPACE_TEXT) {
856                                         BIF_undo_menu();
857                                         return 0;
858                                 }
859                         }
860                 }
861                 break;
862                 
863         case WKEY:
864                 if(textediting==0) {
865                         if(G.qual==LR_CTRLKEY) {
866                                 strcpy(dir, G.sce);
867                                 if (untitled(dir)) {
868                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
869                                 } else {
870                                         BIF_write_file(dir);
871                                         free_filesel_spec(dir);
872                                 }
873                                 return 0;
874                         }
875                         /* Python specials? ;)
876                         else if(G.qual==LR_ALTKEY) {
877                                 write_videoscape_fs();
878                                 return 0;
879                         }*/ 
880                 }
881                 break;
882                 
883         case XKEY:
884                 if(textspace==0 && textediting==0) {
885                         if(G.qual==LR_CTRLKEY) {
886                                 if(okee("Erase all")) {
887                                         if( BIF_read_homefile(0)==0) error("No file ~/.B.blend");
888                                 }
889                                 return 0;
890                         }
891                 }
892                 break;
893         case YKEY:      // redo alternative
894                 if(textspace==0) {
895                         if(G.qual==LR_CTRLKEY) {
896                                 BIF_redo(); 
897                                 return 0;
898                         }
899                 }
900                 break;
901         case ZKEY:      // undo
902                 if(textspace==0) {
903                         if(G.qual & (LR_CTRLKEY|LR_COMMANDKEY)) { // all combos with ctrl/commandkey are accepted
904                                 if ELEM(G.qual, LR_CTRLKEY, LR_COMMANDKEY) BIF_undo();
905                                 else BIF_redo(); // all combos with ctrl is redo
906                                 return 0;
907                         }
908                 }
909                 break; 
910         }
911         
912         return 1;
913 }
914
915 /* eof */