2 * header_ipo.c oct-2003
4 * Functions to draw the "Ipo Curve Editor" window header
5 * and handle user events sent to it.
9 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version. The Blender
15 * Foundation also sells licenses for use in proprietary software under
16 * the Blender License. See http://www.blender.org/BL/ for information
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29 * All rights reserved.
31 * The Original Code is: all of this file.
33 * Contributor(s): none yet.
35 * ***** END GPL/BL DUAL LICENSE BLOCK *****
46 #include "DNA_action_types.h"
47 #include "DNA_camera_types.h"
48 #include "DNA_curve_types.h"
49 #include "DNA_constraint_types.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"
64 #include "BKE_action.h"
65 #include "BKE_constraint.h"
66 #include "BKE_global.h"
68 #include "BKE_material.h"
69 #include "BKE_texture.h"
70 #include "BKE_utildefines.h"
72 #include "BLI_blenlib.h"
74 #include "BSE_drawipo.h"
75 #include "BSE_editipo_types.h"
77 #include "BSE_editipo.h"
78 #include "BSE_headerbuttons.h"
80 #include "BIF_editaction.h"
81 #include "BIF_interface.h"
82 #include "BIF_mainqueue.h"
83 #include "BIF_resources.h"
84 #include "BIF_screen.h"
85 #include "BIF_space.h"
92 static int viewmovetemp = 0;
93 extern int totipo_edit, totipo_sel;
95 /* headerbutton call, assuming full context is set */
96 /* it aligns with editipo.c, verify_ipo */
97 void spaceipo_assign_ipo(SpaceIpo *si, Ipo *ipo)
99 if(si->from==NULL || si->from->lib) return;
101 if(ipo) ipo->id.us++;
103 /* first check action ipos */
104 if(si->actname && si->actname[0]) {
105 Object *ob= (Object *)si->from;
106 bActionChannel *achan;
109 achan= get_action_channel(ob->action, si->actname);
112 /* constraint exception */
113 if(si->blocktype==ID_CO) {
114 bConstraintChannel *conchan= get_constraint_channel(&achan->constraintChannels, si->constname);
117 conchan->ipo->id.us--;
130 switch(GS(si->from->name)) {
133 Object *ob= (Object *)si->from;
134 /* constraint exception */
135 if(si->blocktype==ID_CO) {
136 bConstraintChannel *conchan= get_constraint_channel(&ob->constraintChannels, si->constname);
139 conchan->ipo->id.us--;
143 else if(si->blocktype==ID_OB) {
152 Material *ma= (Material *)si->from;
161 Tex *tex= (Tex *)si->from;
170 Sequence *seq= (Sequence *)si->from; /* note, sequence is mimicing Id */
172 if((seq->type & SEQ_EFFECT)||(seq->type == SEQ_SOUND)) {
181 Curve *cu= (Curve *)si->from;
190 Key *key= (Key *)si->from;
199 World *wo= (World *)si->from;
208 Lamp *la= (Lamp *)si->from;
217 Camera *ca= (Camera *)si->from;
226 bSound *snd= (bSound *)si->from;
235 allqueue(REDRAWVIEW3D, 0);
236 allqueue(REDRAWIPO, 0);
237 allqueue(REDRAWACTION, 0);
238 allqueue(REDRAWNLA, 0);
239 allqueue(REDRAWBUTSALL, 0);
244 static void do_ipo_editmenu_transformmenu(void *arg, int event)
248 case 0: /* grab/move */
257 static uiBlock *ipo_editmenu_transformmenu(void *arg_unused)
260 short yco= 0, menuwidth=120;
262 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
263 uiBlockSetButmFunc(block, do_ipo_editmenu_transformmenu, NULL);
265 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
266 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
268 uiBlockSetDirection(block, UI_RIGHT);
269 uiTextBoundsBlock(block, 60);
274 static void do_ipo_editmenu_snapmenu(void *arg, int event)
277 case 1: /* Horizontal */
278 case 2: /* To Next */
279 case 3: /* To Frame */
280 case 4: /* To Current Frame */
284 allqueue(REDRAWVIEW3D, 0);
287 static uiBlock *ipo_editmenu_snapmenu(void *arg_unused)
290 short yco = 20, menuwidth = 120;
292 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_snapmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
293 uiBlockSetButmFunc(block, do_ipo_editmenu_snapmenu, NULL);
295 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Horizontal|Shift S, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
296 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "To Next|Shift S, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
297 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "To Frame|Shift S, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
298 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 uiBlockSetDirection(block, UI_RIGHT);
301 uiTextBoundsBlock(block, 60);
305 static void do_ipo_editmenu_joinmenu(void *arg, int event)
308 case 1: /* All Selected */
309 case 2: /* Selected Doubles */
313 allqueue(REDRAWVIEW3D, 0);
316 static uiBlock *ipo_editmenu_joinmenu(void *arg_unused)
319 short yco = 20, menuwidth = 120;
321 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_joinmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
322 uiBlockSetButmFunc(block, do_ipo_editmenu_joinmenu, NULL);
324 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "All Selected|J, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
325 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Selected Doubles|J, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
327 uiBlockSetDirection(block, UI_RIGHT);
328 uiTextBoundsBlock(block, 60);
332 static void do_ipo_editmenu_keymenu(void *arg, int event)
338 if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0) {
339 key= (Key *)G.sipo->from;
340 if(key==NULL) return;
342 kb= BLI_findlink(&key->block, ob->shapenr-1);
346 kb->type= KEY_LINEAR;
349 kb->type= KEY_CARDINAL;
352 kb->type= KEY_BSPLINE;
358 static uiBlock *ipo_editmenu_keymenu(void *arg_unused)
362 short yco= 0, menuwidth=120;
364 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_keymenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
365 uiBlockSetButmFunc(block, do_ipo_editmenu_keymenu, NULL);
367 ei = get_active_editipo();
369 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linear", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
370 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cardinal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
371 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "BSpline", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
373 uiBlockSetDirection(block, UI_RIGHT);
374 uiTextBoundsBlock(block, 60);
380 static void do_ipo_editmenu_handlemenu(void *arg, int event)
384 sethandles_ipo(HD_AUTO);
388 sethandles_ipo(HD_ALIGN);
391 sethandles_ipo(HD_VECT);
396 static uiBlock *ipo_editmenu_handlemenu(void *arg_unused)
399 short yco= 0, menuwidth=120;
401 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_handlemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
402 uiBlockSetButmFunc(block, do_ipo_editmenu_handlemenu, NULL);
404 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto|Shift H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
405 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Aligned|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
406 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Free|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
407 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
409 uiBlockSetDirection(block, UI_RIGHT);
410 uiTextBoundsBlock(block, 60);
415 static void do_ipo_editmenu_intpolmenu(void *arg, int event)
420 get_status_editipo();
422 ei = G.sipo->editipo;
427 for(a=0; a<G.sipo->totipo; a++, ei++) {
428 if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
429 ei->icu->ipo= IPO_CONST;
434 for(a=0; a<G.sipo->totipo; a++, ei++) {
435 if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
436 ei->icu->ipo= IPO_LIN;
441 for(a=0; a<G.sipo->totipo; a++, ei++) {
442 if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
443 ei->icu->ipo= IPO_BEZ;
449 scrarea_queue_winredraw(curarea);
452 static uiBlock *ipo_editmenu_intpolmenu(void *arg_unused)
455 short yco= 0, menuwidth=120;
457 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_intpolmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
458 uiBlockSetButmFunc(block, do_ipo_editmenu_intpolmenu, NULL);
460 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Constant", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
461 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linear", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
462 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bezier", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
464 uiBlockSetDirection(block, UI_RIGHT);
465 uiTextBoundsBlock(block, 60);
470 static void do_ipo_editmenu_extendmenu(void *arg, int event)
475 do_ipo_buttons(B_IPOCONT);
478 do_ipo_buttons(B_IPOEXTRAP);
481 do_ipo_buttons(B_IPOCYCLIC);
484 do_ipo_buttons(B_IPOCYCLICX);
489 static uiBlock *ipo_editmenu_extendmenu(void *arg_unused)
492 short yco= 0, menuwidth=120;
494 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_extendmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
495 uiBlockSetButmFunc(block, do_ipo_editmenu_extendmenu, NULL);
497 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Constant", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
498 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrapolation", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
499 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cyclic", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
500 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cyclic Extrapolation", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
502 uiBlockSetDirection(block, UI_RIGHT);
503 uiTextBoundsBlock(block, 60);
509 static void do_ipo_editmenu(void *arg, int event)
517 add_duplicate_editipo();
526 add_blockhandler(curarea, IPO_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
533 set_editflag_editipo();
537 static uiBlock *ipo_editmenu(void *arg_unused)
541 short yco= 0, menuwidth=120;
544 get_status_editipo();
546 ei = G.sipo->editipo;
548 block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
549 uiBlockSetButmFunc(block, do_ipo_editmenu, NULL);
551 uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
553 uiDefIconTextBlockBut(block, ipo_editmenu_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
555 uiDefIconTextBlockBut(block, ipo_editmenu_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
557 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
559 /*Look to see if any ipos are being edited, so there can be a check next to the menu option*/
560 for(a=0; a<G.sipo->totipo; a++, ei++) {
562 if(ei->flag & IPO_VISIBLE) {
563 if(totipo_edit && (ei->flag & IPO_EDIT)) {
571 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Edit Selected|TAB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
573 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Edit Selected|TAB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
575 ei = get_active_editipo();
576 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
578 if(ei && ei->icu && ei->icu->driver)
579 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert 1:1 Curve...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
581 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert Keyframe...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
583 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
585 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
586 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
587 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
588 uiDefIconTextBlockBut(block, ipo_editmenu_joinmenu, NULL, ICON_RIGHTARROW_THIN, "Join", 0, yco-=20, 120, 19, "");
590 if (!G.sipo->showkey){
591 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
593 uiDefIconTextBlockBut(block, ipo_editmenu_extendmenu, NULL, ICON_RIGHTARROW_THIN, "Extend Mode", 0, yco-=20, 120, 19, "");
594 uiDefIconTextBlockBut(block, ipo_editmenu_intpolmenu, NULL, ICON_RIGHTARROW_THIN, "Interpolation Mode", 0, yco-=20, 120, 20, "");
595 if(ei != NULL && (ei->flag & IPO_EDIT))
596 uiDefIconTextBlockBut(block, ipo_editmenu_handlemenu, NULL, ICON_RIGHTARROW_THIN, "Handle Type", 0, yco-=20, 120, 19, "");
597 if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0)
598 uiDefIconTextBlockBut(block, ipo_editmenu_keymenu, NULL, ICON_RIGHTARROW_THIN, "Key Type", 0, yco-=20, 120, 19, "");
602 if(curarea->headertype==HEADERTOP) {
603 uiBlockSetDirection(block, UI_DOWN);
606 uiBlockSetDirection(block, UI_TOP);
607 uiBlockFlipOrder(block);
610 uiTextBoundsBlock(block, 50);
615 static void do_ipo_viewmenu(void *arg, int event)
617 extern int play_anim(int mode);
622 do_ipo_buttons(B_IPOHOME);
625 ipo_toggle_showkey();
626 scrarea_queue_headredraw(curarea);
627 scrarea_queue_winredraw(curarea);
628 allqueue(REDRAWVIEW3D, 0);
634 mainqenter(PADPLUSKEY,1);
637 mainqenter(PADMINUS,1);
639 case 6: /* Play Animation */
642 case 7: /* Play Animation in All */
646 add_blockhandler(curarea, IPO_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
649 G.v2d->flag ^= V2D_VIEWLOCK;
650 if(G.v2d->flag & V2D_VIEWLOCK)
651 view2d_do_locks(curarea, 0);
656 static uiBlock *ipo_viewmenu(void *arg_unused)
660 short yco= 0, menuwidth=120;
662 ei = get_active_editipo();
664 block= uiNewBlock(&curarea->uiblocks, "ipo_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
665 uiBlockSetButmFunc(block, do_ipo_viewmenu, NULL);
667 uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Channel Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
670 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
672 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Show Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
674 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
676 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom Out|NumPad -", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
677 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom In|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
679 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
681 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Animation|Alt A", 0, yco-=20,
682 menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
683 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Animation in 3D View|Alt Shift A", 0, yco-=20,
684 menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
686 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
688 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
689 uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
690 "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
692 if (ei != NULL && (ei->flag & IPO_EDIT)) {
693 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Current Frame to Selected|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
696 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, "");
697 else uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 20, "");
699 if(curarea->headertype==HEADERTOP) {
700 uiBlockSetDirection(block, UI_DOWN);
703 uiBlockSetDirection(block, UI_TOP);
704 uiBlockFlipOrder(block);
707 uiTextBoundsBlock(block, 50);
712 static void do_ipo_selectmenu(void *arg, int event)
720 swap_selectall_editipo();
725 static uiBlock *ipo_selectmenu(void *arg_unused)
728 short yco= 0, menuwidth=120;
730 block= uiNewBlock(&curarea->uiblocks, "ipo_selectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
731 uiBlockSetButmFunc(block, do_ipo_selectmenu, NULL);
733 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
734 uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
735 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
737 if(curarea->headertype==HEADERTOP) {
738 uiBlockSetDirection(block, UI_DOWN);
741 uiBlockSetDirection(block, UI_TOP);
742 uiBlockFlipOrder(block);
745 uiTextBoundsBlock(block, 50);
751 static char *ipo_modeselect_pup(void)
754 static char string[1024];
756 char formatstring[1024];
758 strcpy(string, "Ipo type: %t");
760 strcpy(formatstring, "|%s %%x%d %%i%d");
763 sprintf(tmpstr,formatstring,"Object",ID_OB, ICON_OBJECT);
764 strcat(string,tmpstr);
767 if(ob && give_current_material(ob, ob->actcol)) { // check for material
768 sprintf(tmpstr,formatstring,"Material",ID_MA, ICON_MATERIAL);
769 strcat(string,tmpstr);
773 sprintf(tmpstr,formatstring,"World",ID_WO, ICON_WORLD);
774 strcat(string,tmpstr);
777 if(ob && ob->type==OB_CURVE) {
778 sprintf(tmpstr,formatstring,"Path",ID_CU, ICON_CURVE);
779 strcat(string,tmpstr);
782 if(ob && ob->type==OB_CAMERA) {
783 sprintf(tmpstr,formatstring,"Camera",ID_CA, ICON_CAMERA);
784 strcat(string,tmpstr);
787 if(ob && ob->type==OB_LAMP) {
788 sprintf(tmpstr,formatstring,"Lamp",ID_LA, ICON_LAMP);
789 strcat(string,tmpstr);
792 if(ob && give_current_texture(ob, ob->actcol)) {
793 sprintf(tmpstr,formatstring,"Texture",ID_TE, ICON_TEXTURE);
794 strcat(string,tmpstr);
798 if ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE) {
799 sprintf(tmpstr,formatstring,"Shape",ID_KE, ICON_EDIT);
800 strcat(string,tmpstr);
802 if (ob->type==OB_ARMATURE){
803 sprintf(tmpstr,formatstring,"Pose",ID_PO, ICON_POSE_HLT);
804 strcat(string,tmpstr);
807 sprintf(tmpstr,formatstring,"Constraint",ID_CO, ICON_CONSTRAINT);
808 strcat(string,tmpstr);
812 sprintf(tmpstr,formatstring,"Sequence",ID_SEQ, ICON_SEQUENCE);
813 strcat(string,tmpstr);
819 void do_ipo_buttons(short event)
825 float xmin, ymin, dx, dy;
829 if(curarea->win==0) return;
841 for(a=0; a<G.sipo->totipo; a++, ei++) {
842 if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
844 boundbox_ipocurve(ei->icu);
847 v2d->tot= ei->icu->totrct;
850 else BLI_union_rctf(&(v2d->tot), &(ei->icu->totrct));
855 if(G.qual & LR_SHIFTKEY) {
861 dx= 0.10*(v2d->tot.xmax-v2d->tot.xmin);
862 dy= 0.10*(v2d->tot.ymax-v2d->tot.ymin);
864 if(dx<v2d->min[0]) dx= v2d->min[0];
865 if(dy<v2d->min[1]) dy= v2d->min[1];
867 v2d->cur.xmin= v2d->tot.xmin- dx;
868 v2d->cur.xmax= v2d->tot.xmax+ dx;
869 v2d->cur.ymin= v2d->tot.ymin- dy;
870 v2d->cur.ymax= v2d->tot.ymax+ dy;
872 test_view2d(G.v2d, curarea->winx, curarea->winy);
873 view2d_do_locks(curarea, V2D_LOCK_COPY);
874 if(G.sipo->ipo) G.sipo->ipo->cur = G.v2d->cur;
876 scrarea_queue_winredraw(curarea);
879 val= get_border(&rect, 2);
883 areamouseco_to_ipoco(G.v2d, mval, &xmin, &ymin);
886 areamouseco_to_ipoco(G.v2d, mval, &(G.v2d->cur.xmax), &(G.v2d->cur.ymax));
887 G.v2d->cur.xmin= xmin;
888 G.v2d->cur.ymin= ymin;
890 test_view2d(G.v2d, curarea->winx, curarea->winy);
891 view2d_do_locks(curarea, V2D_LOCK_COPY);
892 scrarea_queue_winredraw(curarea);
897 allqueue (REDRAWIPO, 0);
907 set_exprap_ipo(IPO_HORIZ);
910 set_exprap_ipo(IPO_DIR);
913 set_exprap_ipo(IPO_CYCL);
916 set_exprap_ipo(IPO_CYCLX);
919 scrarea_queue_winredraw(curarea);
920 scrarea_queue_headredraw(curarea);
921 if(ob) ob->ipowin= G.sipo->blocktype;
924 /* reverse value because of winqread */
925 G.sipo->showkey= 1-G.sipo->showkey;
926 ipo_toggle_showkey();
927 scrarea_queue_headredraw(curarea);
928 scrarea_queue_winredraw(curarea);
929 allqueue(REDRAWVIEW3D, 0);
934 scrarea_queue_headredraw(curarea);
936 case B_IPO_ACTION_OB:
937 if(ob && G.sipo->from && G.sipo->pin==0) {
938 if(ob->ipoflag & OB_ACTION_OB) { /* check if channel exists, and flip ipo link */
939 bActionChannel *achan;
942 ob->action= add_empty_action(ID_OB);
943 achan= verify_action_channel(ob->action, "Object");
944 if(achan->ipo==NULL && ob->ipo) {
949 /* object constraints */
950 if(ob->constraintChannels.first) {
951 free_constraint_channels(&achan->constraintChannels);
952 achan->constraintChannels= ob->constraintChannels;
953 ob->constraintChannels.first= ob->constraintChannels.last= NULL;
956 else if(ob->action) {
957 bActionChannel *achan= get_action_channel(ob->action, "Object");
960 if(achan->ipo && ob->ipo==NULL) {
965 /* object constraints */
966 if(achan->constraintChannels.first) {
967 free_constraint_channels(&ob->constraintChannels);
968 ob->constraintChannels= achan->constraintChannels;
969 achan->constraintChannels.first= achan->constraintChannels.last= NULL;
973 allqueue(REDRAWVIEW3D, 0);
974 allqueue(REDRAWIPO, 0);
975 allqueue(REDRAWACTION, 0);
976 allqueue(REDRAWOOPS, 0);
977 allqueue(REDRAWNLA, 0);
980 case B_IPO_ACTION_KEY:
986 void ipo_buttons(void)
995 sprintf(naam, "header %d", curarea->headwin);
996 block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin);
998 if(area_is_active_area(curarea)) uiBlockSetCol(block, TH_HEADER);
999 else uiBlockSetCol(block, TH_HEADERDESEL);
1001 curarea->butspacetype= SPACE_IPO;
1004 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.");
1007 test_editipo(); /* test if current editipo is OK, make_editipo sets v2d->cur */
1009 uiBlockSetEmboss(block, UI_EMBOSSN);
1010 if(curarea->flag & HEADER_NO_PULLDOWN) {
1011 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_RIGHT,
1013 &(curarea->flag), 0, 0, 0, 0, "Enables display of pulldown menus");
1015 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_DOWN,
1017 &(curarea->flag), 0, 0, 0, 0, "Hides pulldown menus");
1019 uiBlockSetEmboss(block, UI_EMBOSS);
1022 /* pull down menus */
1023 if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
1024 uiBlockSetEmboss(block, UI_EMBOSSP);
1026 ei = get_active_editipo();
1028 xmax= GetButStringLength("View");
1029 uiDefPulldownBut(block,ipo_viewmenu, NULL, "View", xco, -2, xmax-3, 24, "");
1032 xmax= GetButStringLength("Select");
1033 uiDefPulldownBut(block,ipo_selectmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
1036 if (G.sipo->showkey) {
1037 xmax= GetButStringLength("Key");
1038 uiDefPulldownBut(block,ipo_editmenu, NULL, "Key", xco, -2, xmax-3, 24, "");
1040 else if(ei != NULL && (ei->flag & IPO_EDIT)) {
1041 xmax= GetButStringLength("Point");
1042 uiDefPulldownBut(block,ipo_editmenu, NULL, "Point", xco, -2, xmax-3, 24, "");
1045 xmax= GetButStringLength("Curve");
1046 uiDefPulldownBut(block,ipo_editmenu, NULL, "Curve", xco, -2, xmax-3, 24, "");
1052 /* end of pull down menus */
1053 uiBlockSetEmboss(block, UI_EMBOSS);
1057 /* action switch option, only when active object is there and no pin */
1058 uiSetButLock(G.sipo->pin, "Can't change because of pinned data");
1060 /* define whether ipos are on Object or on action */
1062 static short fake1= 1;
1064 uiBlockBeginAlign(block);
1066 if(G.sipo->blocktype==ID_OB) {
1067 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");
1070 else if(G.sipo->blocktype==ID_KE) {
1071 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");
1074 else if(G.sipo->blocktype==ID_CO) {
1076 if(G.sipo->from && G.sipo->actname[0]==0)
1077 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");
1079 uiSetButLock(1, "Pose Constraint Ipo cannot be switched");
1080 uiDefIconButS(block, TOG, 1, ICON_ACTION, xco,0,XIC,YIC, &fake1, 0, 0, 0, 0, "Ipo is connected to Pose Action");
1084 else if(G.sipo->blocktype==ID_PO) { /* only to indicate we have action ipos */
1085 uiSetButLock(1, "Pose Action Ipo cannot be switched");
1086 uiDefIconButS(block, TOG, 1, ICON_ACTION, xco,0,XIC,YIC, &fake1, 0, 0, 0, 0, "Ipo is connected to Pose Action");
1092 /* mainmenu, only when data is there and no pin */
1093 uiSetButLock(G.sipo->pin, "Can't change because of pinned data");
1095 if (G.sipo->blocktype == ID_OB)
1097 else if (G.sipo->blocktype == ID_MA)
1098 icon = ICON_MATERIAL;
1099 else if (G.sipo->blocktype == ID_WO)
1101 else if (G.sipo->blocktype == ID_CU)
1103 else if (G.sipo->blocktype == ID_CA)
1105 else if (G.sipo->blocktype == ID_LA)
1107 else if (G.sipo->blocktype == ID_KE)
1109 else if (G.sipo->blocktype == ID_PO)
1110 icon = ICON_POSE_HLT;
1111 else if (G.sipo->blocktype == ID_CO)
1112 icon = ICON_CONSTRAINT;
1113 else if (G.sipo->blocktype == ID_SEQ)
1114 icon = ICON_SEQUENCE;
1115 else if(G.sipo->blocktype == ID_TE)
1116 icon = ICON_TEXTURE;
1118 uiDefIconTextButS(block, MENU, B_IPOMAIN, icon, ipo_modeselect_pup(), xco,0,100,20, &(G.sipo->blocktype), 0, 0, 0, 0, "Show IPO type");
1122 if(G.sipo->blocktype==ID_MA) {
1123 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.");
1126 if(G.sipo->blocktype==ID_WO) {
1127 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.");
1131 if(G.sipo->blocktype==ID_LA) {
1132 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. ");
1136 uiBlockEndAlign(block);
1140 xco= std_libbuttons(block, (short)(xco+1.5*XIC), 0, B_IPOPIN, &G.sipo->pin, B_IPOBROWSE, (ID*)G.sipo->ipo, G.sipo->from, &(G.sipo->menunr), B_IPOALONE, B_IPOLOCAL, B_IPODELETE, 0, B_KEEPDATA);
1144 if(curarea->headertype==HEADERTOP) {
1145 uiDefIconBut(block, BUT, B_IPOCOPY, ICON_COPYUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected curves to the buffer");
1146 uiSetButLock(G.sipo->ipo && G.sipo->ipo->id.lib, "Can't edit library data");
1147 uiDefIconBut(block, BUT, B_IPOPASTE, ICON_PASTEUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the curves from the buffer");
1150 uiDefIconBut(block, BUT, B_IPOCOPY, ICON_COPYDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected curves to the buffer");
1151 uiSetButLock(G.sipo->ipo && G.sipo->ipo->id.lib, "Can't edit library data");
1152 uiDefIconBut(block, BUT, B_IPOPASTE, ICON_PASTEDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the curves from the buffer");
1158 uiDefIconBut(block, BUT, B_IPOBORDER, ICON_BORDERMOVE, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms view to area");
1161 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");
1163 /* always do as last */
1164 curarea->headbutlen= xco+2*XIC;