More node goodies!
[blender.git] / source / blender / src / header_ipo.c
1 /**
2  * header_ipo.c oct-2003
3  *
4  * Functions to draw the "Ipo Curve Editor" 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 <stdlib.h>
39 #include <string.h>
40 #include <stdio.h>
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #include "DNA_action_types.h"
47 #include "DNA_camera_types.h"
48 #include "DNA_curve_types.h"
49 #include "DNA_constraint_types.h"
50 #include "DNA_ID.h"
51 #include "DNA_ipo_types.h"
52 #include "DNA_key_types.h"
53 #include "DNA_lamp_types.h"
54 #include "DNA_material_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_scene_types.h"
57 #include "DNA_screen_types.h"
58 #include "DNA_texture_types.h"
59 #include "DNA_space_types.h"
60 #include "DNA_sequence_types.h"
61 #include "DNA_sound_types.h"
62 #include "DNA_world_types.h"
63
64 #include "BKE_action.h"
65 #include "BKE_constraint.h"
66 #include "BKE_global.h"
67 #include "BKE_key.h"
68 #include "BKE_main.h"
69 #include "BKE_material.h"
70 #include "BKE_texture.h"
71 #include "BKE_utildefines.h"
72
73 #include "BLI_blenlib.h"
74
75 #include "BSE_drawipo.h"
76 #include "BSE_editipo_types.h"
77 #include "BSE_edit.h"
78 #include "BSE_editipo.h"
79 #include "BSE_headerbuttons.h"
80
81 #include "BIF_editaction.h"
82 #include "BIF_interface.h"
83 #include "BIF_mainqueue.h"
84 #include "BIF_resources.h"
85 #include "BIF_screen.h"
86 #include "BIF_space.h"
87
88 #include "nla.h"
89
90 #include "blendef.h"
91 #include "mydevice.h"
92
93 static int viewmovetemp = 0;
94 extern int totipo_edit, totipo_sel;
95
96 /* headerbutton call, assuming full context is set */
97 /* it aligns with editipo.c, verify_ipo */
98 void spaceipo_assign_ipo(SpaceIpo *si, Ipo *ipo)
99 {
100         if(si->from==NULL || si->from->lib) return;
101         
102         if(ipo) ipo->id.us++;
103
104         /* first check action ipos */
105         if(si->actname && si->actname[0]) {
106                 Object *ob= (Object *)si->from;
107                 bActionChannel *achan;
108                 
109                 if(ob->action) {
110                         achan= get_action_channel(ob->action, si->actname);
111                 
112                         if(achan) {
113                                 /* constraint exception */
114                                 if(si->blocktype==ID_CO) {
115                                         bConstraintChannel *conchan= get_constraint_channel(&achan->constraintChannels, si->constname);
116                                         if(conchan) {
117                                                 if(conchan->ipo)
118                                                         conchan->ipo->id.us--;
119                                                 conchan->ipo= ipo;
120                                         }
121                                 }
122                                 else {
123                                         if(achan->ipo)
124                                                 achan->ipo->id.us--;
125                                         achan->ipo= ipo;
126                                 }
127                         }
128                 }
129         }
130         else {
131                 switch(GS(si->from->name)) {
132                         case ID_OB:
133                         {
134                                 Object *ob= (Object *)si->from;
135                                 /* constraint exception */
136                                 if(si->blocktype==ID_CO) {
137                                         bConstraintChannel *conchan= get_constraint_channel(&ob->constraintChannels, si->constname);
138                                         if(conchan) {
139                                                 if(conchan->ipo)
140                                                         conchan->ipo->id.us--;
141                                                 conchan->ipo= ipo;
142                                         }
143                                 }
144                                 else if(si->blocktype==ID_OB) {
145                                         if(ob->ipo)
146                                                 ob->ipo->id.us--;
147                                         ob->ipo= ipo;
148                                 }
149                         }
150                                 break;
151                         case ID_MA:
152                         {
153                                 Material *ma= (Material *)si->from;
154                                 
155                                 if(ma->ipo)
156                                         ma->ipo->id.us--;
157                                 ma->ipo= ipo;
158                         }
159                                 break;
160                         case ID_TE:
161                         {
162                                 Tex *tex= (Tex *)si->from;
163                                 
164                                 if(tex->ipo)
165                                         tex->ipo->id.us--;
166                                 tex->ipo= ipo;
167                         }
168                                 break;
169                         case ID_SEQ:
170                         {
171                                 Sequence *seq= (Sequence *)si->from;    /* note, sequence is mimicing Id */
172                                 
173                                 if((seq->type & SEQ_EFFECT)||(seq->type == SEQ_SOUND)) {
174                                         if(seq->ipo)
175                                                 seq->ipo->id.us--;
176                                         seq->ipo= ipo;
177                                 }
178                         }
179                                 break;
180                         case ID_CU:
181                         {
182                                 Curve *cu= (Curve *)si->from;
183                                 
184                                 if(cu->ipo)
185                                         cu->ipo->id.us--;
186                                 cu->ipo= ipo;
187                         }
188                                 break;
189                         case ID_KE:
190                         {
191                                 Key *key= (Key *)si->from;
192                                 
193                                 if(key->ipo)
194                                         key->ipo->id.us--;
195                                 key->ipo= ipo;
196                         }
197                                 break;
198                         case ID_WO:
199                         {
200                                 World *wo= (World *)si->from;
201                                 
202                                 if(wo->ipo)
203                                         wo->ipo->id.us--;
204                                 wo->ipo= ipo;
205                         }
206                                 break;
207                         case ID_LA:
208                         {
209                                 Lamp *la= (Lamp *)si->from;
210                                 
211                                 if(la->ipo)
212                                         la->ipo->id.us--;
213                                 la->ipo= ipo;
214                         }
215                                 break;
216                         case ID_CA:
217                         {
218                                 Camera *ca= (Camera *)si->from;
219                                 
220                                 if(ca->ipo)
221                                         ca->ipo->id.us--;
222                                 ca->ipo= ipo;
223                         }
224                                 break;
225                         case ID_SO:
226                         {
227                                 bSound *snd= (bSound *)si->from;
228                                 
229                                 if(snd->ipo)
230                                         snd->ipo->id.us--;
231                                 snd->ipo= ipo;
232                         }
233                 }
234         }
235         
236         allqueue(REDRAWVIEW3D, 0);
237         allqueue(REDRAWIPO, 0);
238         allqueue(REDRAWACTION, 0);
239         allqueue(REDRAWNLA, 0);
240         allqueue(REDRAWBUTSALL, 0);
241         
242 }
243
244
245 static void do_ipo_editmenu_transformmenu(void *arg, int event)
246 {
247         switch(event)
248         {
249         case 0: /* grab/move */
250                 transform_ipo('g');
251                 break;
252         case 1: /* scale */
253                 transform_ipo('s');
254                 break;
255         }
256 }
257
258 static uiBlock *ipo_editmenu_transformmenu(void *arg_unused)
259 {
260         uiBlock *block;
261         short yco= 0, menuwidth=120;
262
263         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
264         uiBlockSetButmFunc(block, do_ipo_editmenu_transformmenu, NULL);
265
266         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
267         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
268
269         uiBlockSetDirection(block, UI_RIGHT);
270         uiTextBoundsBlock(block, 60);
271
272         return block;
273 }
274
275 static void do_ipo_editmenu_snapmenu(void *arg, int event)
276 {
277         switch(event) {
278         case 1: /* Horizontal */
279         case 2: /* To Next */
280         case 3: /* To Frame */
281         case 4: /* To Current Frame */
282                 ipo_snap(event);
283             break;
284         }
285         allqueue(REDRAWVIEW3D, 0);
286 }
287
288 static uiBlock *ipo_editmenu_snapmenu(void *arg_unused)
289 {
290         uiBlock *block;
291         short yco = 20, menuwidth = 120;
292
293         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_snapmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
294         uiBlockSetButmFunc(block, do_ipo_editmenu_snapmenu, NULL);
295         
296         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Horizontal|Shift S, 1",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
297         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "To Next|Shift S, 2",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
298         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "To Frame|Shift S, 3",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
299         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "To Current Frame|Shift S, 4",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");   
300         
301         uiBlockSetDirection(block, UI_RIGHT);
302         uiTextBoundsBlock(block, 60);
303         return block;
304 }
305
306 static void do_ipo_editmenu_joinmenu(void *arg, int event)
307 {
308         switch(event) {
309         case 1: /* All Selected */
310         case 2: /* Selected Doubles */
311                 join_ipo(event);
312             break;
313         }
314         allqueue(REDRAWVIEW3D, 0);
315 }
316
317 static uiBlock *ipo_editmenu_joinmenu(void *arg_unused)
318 {
319         uiBlock *block;
320         short yco = 20, menuwidth = 120;
321
322         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_joinmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
323         uiBlockSetButmFunc(block, do_ipo_editmenu_joinmenu, NULL);
324         
325         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "All Selected|J, 1",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
326         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Selected Doubles|J, 2",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
327
328         uiBlockSetDirection(block, UI_RIGHT);
329         uiTextBoundsBlock(block, 60);
330         return block;
331 }
332
333 static void do_ipo_editmenu_keymenu(void *arg, int event)
334 {
335         Key *key;
336         KeyBlock *kb;
337         Object *ob= OBACT;
338
339         if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0) {
340                 key= ob_get_key((Object *)G.sipo->from);
341                 if(key==NULL) return;
342
343                 kb= BLI_findlink(&key->block, ob->shapenr-1);
344                 kb->type= 0;
345                 switch(event){
346                         case 0:
347                                 kb->type= KEY_LINEAR;
348                                 break;
349                         case 1:
350                                 kb->type= KEY_CARDINAL;
351                                 break;
352                         case 2:
353                                 kb->type= KEY_BSPLINE;
354                                 break;
355                 }
356         }
357 }
358
359 static uiBlock *ipo_editmenu_keymenu(void *arg_unused)
360 {
361         uiBlock *block;
362         EditIpo *ei;
363         short yco= 0, menuwidth=120;
364
365         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_keymenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
366         uiBlockSetButmFunc(block, do_ipo_editmenu_keymenu, NULL);
367
368         ei = get_active_editipo();
369
370         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linear", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
371         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cardinal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
372         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "BSpline", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
373
374         uiBlockSetDirection(block, UI_RIGHT);
375         uiTextBoundsBlock(block, 60);
376
377         return block;
378
379 }
380
381 static void do_ipo_editmenu_handlemenu(void *arg, int event)
382 {
383         switch(event){
384         case 0:
385                 sethandles_ipo(HD_AUTO);
386                 break;
387         case 1:
388         case 2:
389                 sethandles_ipo(HD_ALIGN);
390                 break;
391         case 3:
392                 sethandles_ipo(HD_VECT);
393                 break;
394         case 4:
395                 sethandles_ipo(HD_AUTO_ANIM);
396                 break;
397         }
398 }
399
400 static uiBlock *ipo_editmenu_handlemenu(void *arg_unused)
401 {
402         uiBlock *block;
403         short yco= 0, menuwidth=120;
404
405         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_handlemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
406         uiBlockSetButmFunc(block, do_ipo_editmenu_handlemenu, NULL);
407
408         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto|Shift H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
409         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Clamped|Alt H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
410         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Aligned|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
411         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Free|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
412         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
413
414         uiBlockSetDirection(block, UI_RIGHT);
415         uiTextBoundsBlock(block, 60);
416
417         return block;
418 }
419
420 static void do_ipo_editmenu_intpolmenu(void *arg, int event)
421 {
422         EditIpo *ei;
423         int a;
424
425         get_status_editipo();
426
427         ei = G.sipo->editipo;
428
429         switch(event)
430         {
431         case 0:
432                 for(a=0; a<G.sipo->totipo; a++, ei++) {
433                         if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
434                                 ei->icu->ipo= IPO_CONST;
435                         }
436                 }
437                 break;
438         case 1:
439                 for(a=0; a<G.sipo->totipo; a++, ei++) {
440                         if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
441                                 ei->icu->ipo= IPO_LIN;
442                         }
443                 }
444                 break;
445         case 2:
446                 for(a=0; a<G.sipo->totipo; a++, ei++) {
447                         if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
448                                 ei->icu->ipo= IPO_BEZ;
449                         }
450                 }
451                 break;
452         }
453
454         scrarea_queue_winredraw(curarea);
455 }
456
457 static uiBlock *ipo_editmenu_intpolmenu(void *arg_unused)
458 {
459         uiBlock *block;
460         short yco= 0, menuwidth=120;
461
462         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_intpolmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
463         uiBlockSetButmFunc(block, do_ipo_editmenu_intpolmenu, NULL);
464
465         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Constant", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
466         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linear", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
467         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bezier", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
468
469         uiBlockSetDirection(block, UI_RIGHT);
470         uiTextBoundsBlock(block, 60);
471
472         return block;
473 }
474
475 static void do_ipo_editmenu_extendmenu(void *arg, int event)
476 {
477         switch(event)
478         {
479         case 0:
480                 do_ipo_buttons(B_IPOCONT);
481                 break;
482         case 1:
483                 do_ipo_buttons(B_IPOEXTRAP);
484                 break;
485         case 2:
486                 do_ipo_buttons(B_IPOCYCLIC);
487                 break;
488         case 3:
489                 do_ipo_buttons(B_IPOCYCLICX);
490                 break;
491         }
492 }
493
494 static uiBlock *ipo_editmenu_extendmenu(void *arg_unused)
495 {
496         uiBlock *block;
497         short yco= 0, menuwidth=120;
498
499         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_extendmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
500         uiBlockSetButmFunc(block, do_ipo_editmenu_extendmenu, NULL);
501
502         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Constant", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
503         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrapolation", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
504         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cyclic", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
505         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cyclic Extrapolation", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
506
507         uiBlockSetDirection(block, UI_RIGHT);
508         uiTextBoundsBlock(block, 60);
509
510         return block;
511 }
512
513
514 static void do_ipo_editmenu(void *arg, int event)
515 {
516         switch(event)
517         {
518         case 0:
519                 del_ipo();
520                 break;
521         case 1:
522                 add_duplicate_editipo();
523                 break;
524         case 2:
525                 ipo_record();
526                 break;
527         case 3:
528                 mainqenter(IKEY, 1);
529                 break;
530         case 4 :
531                 add_blockhandler(curarea, IPO_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
532                 break;
533         case 5:
534                 //join_ipo();
535                 break;
536         case 6:
537                 /*IPO Editmode*/
538                 set_editflag_editipo();
539                 break;
540         case 7:
541                 sethandles_ipo(HD_AUTO_ANIM);
542                 break;
543         }
544 }
545
546 static uiBlock *ipo_editmenu(void *arg_unused)
547 {
548         uiBlock *block;
549         EditIpo *ei;
550         short yco= 0, menuwidth=120;
551         int a,isedit = 0;
552
553         get_status_editipo();
554
555         ei = G.sipo->editipo;
556
557         block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
558         uiBlockSetButmFunc(block, do_ipo_editmenu, NULL);
559
560         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
561         
562         uiDefIconTextBlockBut(block, ipo_editmenu_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");     
563         
564         uiDefIconTextBlockBut(block, ipo_editmenu_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");       
565
566         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); 
567
568         /*Look to see if any ipos are being edited, so there can be a check next to the menu option*/
569         for(a=0; a<G.sipo->totipo; a++, ei++) {         
570                 if(ei->icu) {
571                         if(ei->flag & IPO_VISIBLE) {
572                                 if(totipo_edit && (ei->flag & IPO_EDIT)) {
573                                         isedit = 1;
574                                         break;
575                                 }
576                         }
577                 }
578         }
579         if(isedit)
580                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT,   "Edit Selected|TAB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");                
581         else
582                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Edit Selected|TAB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
583         
584         ei = get_active_editipo();
585         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
586         
587         if(ei && ei->icu && ei->icu->driver)
588                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert 1:1 Curve...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
589         else
590                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert Keyframe...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
591         
592         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
593
594         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
595         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
596         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
597         uiDefIconTextBlockBut(block, ipo_editmenu_joinmenu, NULL, ICON_RIGHTARROW_THIN, "Join", 0, yco-=20, 120, 19, "");       
598
599         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
600         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Clamped Handles|ALT H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
601         
602         if (!G.sipo->showkey){
603                 uiDefIconTextBlockBut(block, ipo_editmenu_extendmenu, NULL, ICON_RIGHTARROW_THIN, "Extend Mode", 0, yco-=20, 120, 19, "");      
604                 uiDefIconTextBlockBut(block, ipo_editmenu_intpolmenu, NULL, ICON_RIGHTARROW_THIN, "Interpolation Mode", 0, yco-=20, 120, 20, "");
605                 if(ei != NULL && (ei->flag & IPO_EDIT))
606                         uiDefIconTextBlockBut(block, ipo_editmenu_handlemenu, NULL, ICON_RIGHTARROW_THIN, "Handle Type", 0, yco-=20, 120, 19, "");
607                 if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0)
608                         uiDefIconTextBlockBut(block, ipo_editmenu_keymenu, NULL, ICON_RIGHTARROW_THIN, "Key Type", 0, yco-=20, 120, 19, "");
609         }
610         
611
612         if(curarea->headertype==HEADERTOP) {
613                 uiBlockSetDirection(block, UI_DOWN);
614         }
615         else {
616                 uiBlockSetDirection(block, UI_TOP);
617                 uiBlockFlipOrder(block);
618         }
619
620         uiTextBoundsBlock(block, 50);
621
622         return block;
623 }
624
625 static void do_ipo_viewmenu(void *arg, int event)
626 {
627         extern int play_anim(int mode);
628         
629         switch(event)
630         {
631         case 1:
632                 do_ipo_buttons(B_IPOHOME);
633                 break;
634         case 2:
635                 ipo_toggle_showkey();
636                 scrarea_queue_headredraw(curarea);
637                 scrarea_queue_winredraw(curarea);
638                 allqueue(REDRAWVIEW3D, 0);
639                 break;
640         case 3:
641                 move_to_frame();
642                 break;
643         case 4:
644                 mainqenter(PADPLUSKEY,1);
645                 break;
646         case 5:
647                 mainqenter(PADMINUS,1);
648                 break;
649         case 6: /* Play Animation */
650                 play_anim(0);
651                 break;
652         case 7: /* Play Animation in All */
653                 play_anim(1);
654                 break;  
655         case 8:
656                 add_blockhandler(curarea, IPO_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
657                 break;  
658         case 9:
659                 G.v2d->flag ^= V2D_VIEWLOCK;
660                 if(G.v2d->flag & V2D_VIEWLOCK)
661                         view2d_do_locks(curarea, 0);
662                 break;                  
663         }
664 }
665
666 static uiBlock *ipo_viewmenu(void *arg_unused)
667 {
668         uiBlock *block;
669         EditIpo *ei;
670         short yco= 0, menuwidth=120;
671
672         ei = get_active_editipo();
673
674         block= uiNewBlock(&curarea->uiblocks, "ipo_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
675         uiBlockSetButmFunc(block, do_ipo_viewmenu, NULL);
676
677         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Channel Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
678         
679         if (G.sipo->showkey)
680                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
681         else
682                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Show Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
683
684         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
685
686         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom Out|NumPad -", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
687         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom In|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
688
689         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
690         
691         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Animation|Alt A", 0, yco-=20, 
692                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
693         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Animation in 3D View|Alt Shift A", 0, yco-=20,
694                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
695
696         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
697
698         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
699         uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
700                                          "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
701
702         if (ei != NULL && (ei->flag & IPO_EDIT)) {
703                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Current Frame to Selected|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
704         }
705
706         if(!curarea->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,20, "");
707         else uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 20, "");
708
709         if(curarea->headertype==HEADERTOP) {
710                 uiBlockSetDirection(block, UI_DOWN);
711         }
712         else {
713                 uiBlockSetDirection(block, UI_TOP);
714                 uiBlockFlipOrder(block);
715         }
716
717         uiTextBoundsBlock(block, 50);
718
719         return block;
720 }
721
722 static void do_ipo_selectmenu(void *arg, int event)
723 {
724         switch(event)
725         {
726         case 0:
727                 borderselect_ipo();
728                 break;
729         case 1:
730                 swap_selectall_editipo();
731                 break;
732         }
733 }
734
735 static uiBlock *ipo_selectmenu(void *arg_unused)
736 {
737         uiBlock *block;
738         short yco= 0, menuwidth=120;
739
740         block= uiNewBlock(&curarea->uiblocks, "ipo_selectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
741         uiBlockSetButmFunc(block, do_ipo_selectmenu, NULL);
742
743         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
744         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
745         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
746
747         if(curarea->headertype==HEADERTOP) {
748                 uiBlockSetDirection(block, UI_DOWN);
749         }
750         else {
751                 uiBlockSetDirection(block, UI_TOP);
752                 uiBlockFlipOrder(block);
753         }
754
755         uiTextBoundsBlock(block, 50);
756
757         return block;
758 }
759
760
761 static char *ipo_modeselect_pup(void)
762 {
763         Object *ob= OBACT;
764         static char string[1024];
765         char tmpstr[1024];
766         char formatstring[1024];
767
768         strcpy(string, "Ipo type: %t");
769         
770         strcpy(formatstring, "|%s %%x%d %%i%d");
771
772         if(ob) {
773                 sprintf(tmpstr,formatstring,"Object",ID_OB, ICON_OBJECT);
774                 strcat(string,tmpstr);
775         }
776
777         if(ob && give_current_material(ob, ob->actcol)) { // check for material
778                 sprintf(tmpstr,formatstring,"Material",ID_MA, ICON_MATERIAL);
779                 strcat(string,tmpstr);
780         }
781
782         if(G.scene->world) {
783                 sprintf(tmpstr,formatstring,"World",ID_WO, ICON_WORLD);
784                 strcat(string,tmpstr);
785         }
786
787         if(ob && ob->type==OB_CURVE) {
788                 sprintf(tmpstr,formatstring,"Path",ID_CU, ICON_CURVE);
789                 strcat(string,tmpstr);
790         }
791
792         if(ob && ob->type==OB_CAMERA) {
793                 sprintf(tmpstr,formatstring,"Camera",ID_CA, ICON_CAMERA);
794                 strcat(string,tmpstr);
795         }
796         
797         if(ob && ob->type==OB_LAMP) {
798                 sprintf(tmpstr,formatstring,"Lamp",ID_LA, ICON_LAMP);
799                 strcat(string,tmpstr);
800         }
801
802         if(ob && give_current_texture(ob, ob->actcol)) {
803                 sprintf(tmpstr,formatstring,"Texture",ID_TE, ICON_TEXTURE);
804                 strcat(string,tmpstr);
805         }
806
807         if(ob){
808                 if ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE) {
809                         sprintf(tmpstr,formatstring,"Shape",ID_KE, ICON_EDIT);
810                         strcat(string,tmpstr);
811                 }
812                 if (ob->type==OB_ARMATURE){
813                         sprintf(tmpstr,formatstring,"Pose",ID_PO, ICON_POSE_HLT);
814                         strcat(string,tmpstr);
815                 }
816 #ifdef __CON_IPO
817                 sprintf(tmpstr,formatstring,"Constraint",ID_CO, ICON_CONSTRAINT);
818                 strcat(string,tmpstr);
819 #endif
820         }
821
822         sprintf(tmpstr,formatstring,"Sequence",ID_SEQ, ICON_SEQUENCE);
823         strcat(string,tmpstr);
824
825
826         return (string);
827 }
828
829 void do_ipo_buttons(short event)
830 {
831         EditIpo *ei;
832         View2D *v2d;
833         rcti rect;
834         Object *ob= OBACT;
835         float xmin, ymin, dx, dy;
836         int a, val, first;
837         short mval[2];
838
839         if(curarea->win==0) return;
840
841         switch(event) {
842         case B_IPOHOME:
843
844                 /* boundbox */
845
846                 v2d= &(G.sipo->v2d);
847                 first= 1;
848
849                 ei= G.sipo->editipo;
850                 if(ei==0) return;
851                 for(a=0; a<G.sipo->totipo; a++, ei++) {
852                         if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
853                         
854                                 boundbox_ipocurve(ei->icu);
855                                 
856                                 if(first) {
857                                         v2d->tot= ei->icu->totrct;
858                                         first= 0;
859                                 }
860                                 else BLI_union_rctf(&(v2d->tot), &(ei->icu->totrct));
861                         }
862                 }
863
864                 /* speciale home */
865                 if(G.qual & LR_SHIFTKEY) {
866                         v2d->tot.xmin= SFRA;
867                         v2d->tot.xmax= EFRA;
868                 }
869
870                 /* zoom out a bit */
871                 dx= 0.10*(v2d->tot.xmax-v2d->tot.xmin);
872                 dy= 0.10*(v2d->tot.ymax-v2d->tot.ymin);
873                 
874                 if(dx<v2d->min[0]) dx= v2d->min[0];
875                 if(dy<v2d->min[1]) dy= v2d->min[1];
876                 
877                 v2d->cur.xmin= v2d->tot.xmin- dx;
878                 v2d->cur.xmax= v2d->tot.xmax+ dx;
879                 v2d->cur.ymin= v2d->tot.ymin- dy;
880                 v2d->cur.ymax= v2d->tot.ymax+ dy;
881
882                 test_view2d(G.v2d, curarea->winx, curarea->winy);
883                 view2d_do_locks(curarea, V2D_LOCK_COPY);
884                 if(G.sipo->ipo) G.sipo->ipo->cur = G.v2d->cur;
885                 
886                 scrarea_queue_winredraw(curarea);
887                 break;
888         case B_IPOBORDER:
889                 val= get_border(&rect, 3);
890                 if(val) {
891                         mval[0]= rect.xmin;
892                         mval[1]= rect.ymin;
893                         areamouseco_to_ipoco(G.v2d, mval, &xmin, &ymin);
894                         mval[0]= rect.xmax;
895                         mval[1]= rect.ymax;
896                         areamouseco_to_ipoco(G.v2d, mval, &(G.v2d->cur.xmax), &(G.v2d->cur.ymax));
897                         G.v2d->cur.xmin= xmin;
898                         G.v2d->cur.ymin= ymin;
899                         
900                         test_view2d(G.v2d, curarea->winx, curarea->winy);
901                         view2d_do_locks(curarea, V2D_LOCK_COPY);
902                         scrarea_queue_winredraw(curarea);
903                 }
904                 break;
905
906         case B_IPOPIN:
907                 allqueue (REDRAWIPO, 0);
908                 break;
909
910         case B_IPOCOPY:
911                 copy_editipo();
912                 break;
913         case B_IPOPASTE:
914                 paste_editipo();
915                 break;
916         case B_IPOCONT:
917                 set_exprap_ipo(IPO_HORIZ);
918                 break;
919         case B_IPOEXTRAP:
920                 set_exprap_ipo(IPO_DIR);
921                 break;
922         case B_IPOCYCLIC:
923                 set_exprap_ipo(IPO_CYCL);
924                 break;
925         case B_IPOCYCLICX:
926                 set_exprap_ipo(IPO_CYCLX);
927                 break;
928         case B_IPOMAIN:
929                 /* pass 1 to enforce a refresh when there's no Ipo */
930                 test_editipo(1);
931                 scrarea_queue_winredraw(curarea);
932                 scrarea_queue_headredraw(curarea);
933                 if(ob) ob->ipowin= G.sipo->blocktype;
934                 break;
935         case B_IPOSHOWKEY:
936                 /* reverse value because of winqread */
937                 G.sipo->showkey= 1-G.sipo->showkey;
938                 ipo_toggle_showkey();
939                 scrarea_queue_headredraw(curarea);
940                 scrarea_queue_winredraw(curarea);
941                 allqueue(REDRAWVIEW3D, 0);
942                 break;
943         case B_VIEW2DZOOM:
944                 viewmovetemp= 0;
945                 view2dzoom(event);
946                 scrarea_queue_headredraw(curarea);
947                 break;
948         case B_IPO_ACTION_OB:
949                 if(ob && G.sipo->from && G.sipo->pin==0) {
950                         if(ob->ipoflag & OB_ACTION_OB) {        /* check if channel exists, and flip ipo link */
951                                 bActionChannel *achan;
952                                 
953                                 if(ob->action==NULL) 
954                                         ob->action= add_empty_action(ID_OB);
955                                 achan= verify_action_channel(ob->action, "Object");
956                                 if(achan->ipo==NULL && ob->ipo) {
957                                         achan->ipo= ob->ipo;
958                                         ob->ipo= NULL;
959                                 }
960                                 
961                                 /* object constraints */
962                                 if(ob->constraintChannels.first) {
963                                         free_constraint_channels(&achan->constraintChannels);
964                                         achan->constraintChannels= ob->constraintChannels;
965                                         ob->constraintChannels.first= ob->constraintChannels.last= NULL;
966                                 }
967                         }
968                         else if(ob->action) {
969                                 bActionChannel *achan= get_action_channel(ob->action, "Object");
970                                 if(achan) {
971                                         
972                                         if(achan->ipo && ob->ipo==NULL) {
973                                                 ob->ipo= achan->ipo;
974                                                 achan->ipo= NULL;
975                                         }
976                                         
977                                         /* object constraints */
978                                         if(achan->constraintChannels.first) {
979                                                 free_constraint_channels(&ob->constraintChannels);
980                                                 ob->constraintChannels= achan->constraintChannels;
981                                                 achan->constraintChannels.first= achan->constraintChannels.last= NULL;
982                                         }
983                                 }
984                         }
985                         allqueue(REDRAWVIEW3D, 0);
986                         allqueue(REDRAWIPO, 0);
987                         allqueue(REDRAWACTION, 0);
988                         allqueue(REDRAWOOPS, 0);
989                         allqueue(REDRAWNLA, 0);
990                 }
991                 break;
992                 
993         case B_IPO_ACTION_KEY:
994                 if(ob && G.sipo->from && G.sipo->pin==0) {
995                         Key *key= ob_get_key(ob);
996                         if(key) {
997                                 if(ob->ipoflag & OB_ACTION_KEY) {       /* check if channel exists, and flip ipo link */
998                                         bActionChannel *achan;
999                                         
1000                                         if(ob->action==NULL) 
1001                                                 ob->action= add_empty_action(ID_KE);
1002                                         achan= verify_action_channel(ob->action, "Shape");
1003                                         if(achan->ipo==NULL && key->ipo) {
1004                                                 achan->ipo= key->ipo;
1005                                                 key->ipo= NULL;
1006                                         }
1007                                 }
1008                                 else if(ob->action) {
1009                                         bActionChannel *achan= get_action_channel(ob->action, "Shape");
1010                                         if(achan) {
1011                                                 if(achan->ipo && key->ipo==NULL) {
1012                                                         key->ipo= achan->ipo;
1013                                                         achan->ipo= NULL;
1014                                                 }
1015                                         }
1016                                 }
1017                                 allqueue(REDRAWVIEW3D, 0);
1018                                 allqueue(REDRAWIPO, 0);
1019                                 allqueue(REDRAWACTION, 0);
1020                                 allqueue(REDRAWOOPS, 0);
1021                                 allqueue(REDRAWNLA, 0);
1022                         }
1023                 }
1024                 break;
1025         } 
1026 }
1027
1028 void ipo_buttons(void)
1029 {
1030         Object *ob;
1031         EditIpo *ei;
1032         uiBlock *block;
1033         short xco,xmax;
1034         char naam[20];
1035         int icon=0;
1036
1037         sprintf(naam, "header %d", curarea->headwin);
1038         block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin);
1039
1040         if(area_is_active_area(curarea)) uiBlockSetCol(block, TH_HEADER);
1041         else uiBlockSetCol(block, TH_HEADERDESEL);
1042
1043         curarea->butspacetype= SPACE_IPO;
1044
1045         xco = 8;
1046         uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), xco,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types.");
1047         xco+= XIC+14;
1048         
1049         test_editipo(0);        /* test if current editipo is OK, make_editipo sets v2d->cur */
1050
1051         uiBlockSetEmboss(block, UI_EMBOSSN);
1052         if(curarea->flag & HEADER_NO_PULLDOWN) {
1053                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_RIGHT,
1054                                 xco,2,XIC,YIC-2,
1055                                 &(curarea->flag), 0, 0, 0, 0, "Enables display of pulldown menus");
1056         } else {
1057                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_DOWN,
1058                                 xco,2,XIC,YIC-2,
1059                                 &(curarea->flag), 0, 0, 0, 0, "Hides pulldown menus");
1060         }
1061         uiBlockSetEmboss(block, UI_EMBOSS);
1062         xco+=XIC;
1063
1064         /* pull down menus */
1065         if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
1066                 uiBlockSetEmboss(block, UI_EMBOSSP);
1067         
1068                 ei = get_active_editipo();
1069         
1070                 xmax= GetButStringLength("View");
1071                 uiDefPulldownBut(block,ipo_viewmenu, NULL, "View", xco, -2, xmax-3, 24, "");
1072                 xco+=xmax;
1073         
1074                 xmax= GetButStringLength("Select");
1075                 uiDefPulldownBut(block,ipo_selectmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
1076                 xco+=xmax;
1077         
1078                 if (G.sipo->showkey) {
1079                         xmax= GetButStringLength("Key");
1080                         uiDefPulldownBut(block,ipo_editmenu, NULL, "Key", xco, -2, xmax-3, 24, "");
1081                 }
1082                 else if(ei != NULL && (ei->flag & IPO_EDIT)) {
1083                         xmax= GetButStringLength("Point");
1084                         uiDefPulldownBut(block,ipo_editmenu, NULL, "Point", xco, -2, xmax-3, 24, "");
1085                 }
1086                 else {
1087                         xmax= GetButStringLength("Curve");
1088                         uiDefPulldownBut(block,ipo_editmenu, NULL, "Curve", xco, -2, xmax-3, 24, "");
1089                 }
1090                         
1091                 xco+=xmax;
1092         }
1093
1094         /* end of pull down menus */
1095         uiBlockSetEmboss(block, UI_EMBOSS);
1096
1097         ob= OBACT;
1098         
1099         /* action switch option, only when active object is there and no pin */
1100         uiSetButLock(G.sipo->pin, "Can't change because of pinned data");
1101         
1102         /* define whether ipos are on Object or on action */
1103         if(ob) {
1104                 static short fake1= 1;
1105                 
1106                 uiBlockBeginAlign(block);
1107                 
1108                 if(G.sipo->blocktype==ID_OB) {
1109                         uiDefIconButBitS(block, TOG, OB_ACTION_OB, B_IPO_ACTION_OB, ICON_ACTION,        xco,0,XIC,YIC, &(ob->ipoflag), 0, 0, 0, 0, "Sets Ipo to be included in an Action or not");
1110                         xco+= XIC;
1111                 }
1112                 else if(G.sipo->blocktype==ID_KE) {
1113                         uiDefIconButBitS(block, TOG, OB_ACTION_KEY, B_IPO_ACTION_KEY, ICON_ACTION,      xco,0,XIC,YIC, &(ob->ipoflag), 0, 0, 0, 0, "Sets Ipo to be included in an Action or not");
1114                         xco+= XIC;
1115                 }
1116                 else if(G.sipo->blocktype==ID_CO) {
1117                         
1118                         if(G.sipo->from && G.sipo->actname[0]==0)
1119                                 uiDefIconButBitS(block, TOG, OB_ACTION_OB, B_IPO_ACTION_OB, ICON_ACTION,        xco,0,XIC,YIC, &(ob->ipoflag), 0, 0, 0, 0, "Sets Ipo to be included in an Action or not");
1120                         else {
1121                                 uiSetButLock(1, "Pose Constraint Ipo cannot be switched");
1122                                 uiDefIconButS(block, TOG, 1, ICON_ACTION,       xco,0,XIC,YIC, &fake1, 0, 0, 0, 0, "Ipo is connected to Pose Action");
1123                         }
1124                         xco+= XIC;
1125                 }
1126                 else if(G.sipo->blocktype==ID_PO) {     /* only to indicate we have action ipos */
1127                         uiSetButLock(1, "Pose Action Ipo cannot be switched");
1128                         uiDefIconButS(block, TOG, 1, ICON_ACTION,       xco,0,XIC,YIC, &fake1, 0, 0, 0, 0, "Ipo is connected to Pose Action");
1129                         xco+= XIC;
1130                 }
1131                 uiClearButLock();
1132         }
1133         
1134         /* mainmenu, only when data is there and no pin */
1135         uiSetButLock(G.sipo->pin, "Can't change because of pinned data");
1136
1137         if (G.sipo->blocktype == ID_OB)
1138                 icon = ICON_OBJECT;
1139         else if (G.sipo->blocktype == ID_MA)
1140                 icon = ICON_MATERIAL;
1141         else if (G.sipo->blocktype == ID_WO)
1142                 icon = ICON_WORLD;
1143         else if (G.sipo->blocktype == ID_CU)
1144                 icon = ICON_ANIM;
1145         else if (G.sipo->blocktype == ID_CA)
1146                 icon = ICON_CAMERA;
1147         else if (G.sipo->blocktype == ID_LA)
1148                 icon = ICON_LAMP;
1149         else if (G.sipo->blocktype == ID_KE)
1150                 icon = ICON_EDIT;
1151         else if (G.sipo->blocktype == ID_PO)
1152                 icon = ICON_POSE_HLT;
1153         else if (G.sipo->blocktype == ID_CO)
1154                 icon = ICON_CONSTRAINT;
1155         else if (G.sipo->blocktype == ID_SEQ)
1156                 icon = ICON_SEQUENCE;
1157         else if(G.sipo->blocktype == ID_TE)
1158                 icon = ICON_TEXTURE;
1159
1160         uiDefIconTextButS(block, MENU, B_IPOMAIN, icon, ipo_modeselect_pup(), xco,0,100,20, &(G.sipo->blocktype), 0, 0, 0, 0, "Show IPO type");
1161
1162         xco += 85;
1163
1164         if(G.sipo->blocktype==ID_MA) {
1165                 uiDefButS(block, NUM, B_IPOMAIN, "",    xco+=XIC,0,XIC-4,YIC, &G.sipo->channel, 0.0, MAX_MTEX-1.0, 0, 0, "Channel Number of the active Material texture.");
1166                 xco-= 4;
1167         }
1168         if(G.sipo->blocktype==ID_WO) {
1169                 uiDefButS(block, NUM, B_IPOMAIN, "",    xco+=XIC,0,XIC-4,YIC, &G.sipo->channel, 0.0, MAX_MTEX-1.0, 0, 0, "Channel Number of the active World texture.");
1170                 xco-= 4;
1171         }
1172         
1173         if(G.sipo->blocktype==ID_LA) {
1174                 uiDefButS(block, NUM, B_IPOMAIN, "",    xco+=XIC,0,XIC-4,YIC, &G.sipo->channel, 0.0, MAX_MTEX-1.0, 0, 0, "Channel Number of the active Lamp texture. ");
1175                 xco-= 4;
1176         }
1177         
1178         uiBlockEndAlign(block);
1179         
1180         uiClearButLock();
1181
1182         xco= std_libbuttons(block, (short)(xco+1.5*XIC), 0, B_IPOPIN, &G.sipo->pin, B_IPOBROWSE, ID_IP, G.sipo->blocktype, (ID*)G.sipo->ipo, G.sipo->from, &(G.sipo->menunr), B_IPOALONE, B_IPOLOCAL, B_IPODELETE, 0, B_KEEPDATA);
1183
1184         /* COPY PASTE */
1185         xco-= XIC/2;
1186         if(curarea->headertype==HEADERTOP) {
1187                 uiDefIconBut(block, BUT, B_IPOCOPY, ICON_COPYUP,        xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected curves to the buffer");
1188                 uiSetButLock(G.sipo->ipo && G.sipo->ipo->id.lib, "Can't edit library data");
1189                 uiDefIconBut(block, BUT, B_IPOPASTE, ICON_PASTEUP,      xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the curves from the buffer");
1190         }
1191         else {
1192                 uiDefIconBut(block, BUT, B_IPOCOPY, ICON_COPYDOWN,      xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected curves to the buffer");
1193                 uiSetButLock(G.sipo->ipo && G.sipo->ipo->id.lib, "Can't edit library data");
1194                 uiDefIconBut(block, BUT, B_IPOPASTE, ICON_PASTEDOWN,    xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the curves from the buffer");
1195         }
1196         xco+=XIC/2;
1197         
1198         uiClearButLock();
1199         /* ZOOMBORDER */
1200         uiDefIconBut(block, BUT, B_IPOBORDER, ICON_BORDERMOVE,  xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms view to area");
1201         
1202         /* draw LOCK */
1203         uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.sipo->lock), 0, 0, 0, 0, "Toggles forced redraw of other windows to reflect changes in real time");
1204
1205         /* always do as last */
1206         curarea->headbutlen= xco+2*XIC;
1207
1208         uiDrawBlock(block);
1209 }