== Grease Pencil ==
[blender-staging.git] / source / blender / src / header_action.c
1 /**
2  * header_action.c oct-2003
3  *
4  * Functions to draw the "Action Editor" window header
5  * and handle user events sent to it.
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL 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.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): 2007, Joshua Leung (Action Editor recode) 
31  *
32  * ***** END GPL LICENSE BLOCK *****
33  */
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #include "DNA_action_types.h"
44 #include "DNA_curve_types.h"
45 #include "DNA_ID.h"
46 #include "DNA_ipo_types.h"
47 #include "DNA_key_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_scene_types.h"
50 #include "DNA_screen_types.h"
51 #include "DNA_space_types.h"
52
53 #include "BIF_gl.h"
54 #include "BIF_glutil.h"
55 #include "BIF_editaction.h"
56 #include "BIF_interface.h"
57 #include "BIF_language.h"
58 #include "BIF_poseobject.h"
59 #include "BIF_resources.h"
60 #include "BIF_screen.h"
61 #include "BIF_space.h"
62 #include "BIF_toolbox.h"
63
64 #include "BKE_action.h"
65 #include "BKE_armature.h"
66 #include "BKE_constraint.h"
67 #include "BKE_depsgraph.h"
68 #include "BKE_global.h"
69 #include "BKE_main.h"
70 #include "BKE_utildefines.h"
71
72 #include "BDR_drawaction.h"
73 #include "BSE_drawipo.h"
74 #include "BSE_headerbuttons.h"
75 #include "BSE_time.h"
76
77 #include "nla.h"
78
79 #include "blendef.h"
80 #include "mydevice.h"
81
82 /* ------------------------------- */
83 /* enums declaring constants that are used as menu event codes  */
84
85 enum {
86         ACTMENU_VIEW_CENTERVIEW= 0,
87         ACTMENU_VIEW_AUTOUPDATE,
88         ACTMENU_VIEW_PLAY3D,
89         ACTMENU_VIEW_PLAYALL,
90         ACTMENU_VIEW_ALL,
91         ACTMENU_VIEW_MAXIMIZE,
92         ACTMENU_VIEW_LOCK,
93         ACTMENU_VIEW_SLIDERS,
94         ACTMENU_VIEW_NEXTMARKER,
95         ACTMENU_VIEW_PREVMARKER,
96         ACTMENU_VIEW_NEXTKEYFRAME,
97         ACTMENU_VIEW_PREVKEYFRAME,
98         ACTMENU_VIEW_TIME,
99         ACTMENU_VIEW_NOHIDE,
100         ACTMENU_VIEW_TRANSDELDUPS,
101         ACTMENU_VIEW_HORIZOPTIMISE,
102         ACTMENU_VIEW_GCOLORS,
103         ACTMENU_VIEW_PREVRANGESET,
104         ACTMENU_VIEW_PREVRANGECLEAR,
105         ACTMENU_VIEW_PREVRANGEAUTO
106 };
107
108 enum {
109         ACTMENU_SEL_BORDER = 0,
110         ACTMENU_SEL_BORDERC,
111         ACTMENU_SEL_BORDERM,
112         ACTMENU_SEL_ALL_KEYS,
113         ACTMENU_SEL_ALL_CHAN,
114         ACTMENU_SEL_ALL_MARKERS,
115         ACTMENU_SEL_INVERSE_KEYS,
116         ACTMENU_SEL_INVERSE_MARKERS,
117         ACTMENU_SEL_INVERSE_CHANNELS,
118         ACTMENU_SEL_LEFTKEYS,
119         ACTMENU_SEL_RIGHTKEYS
120 };
121
122 enum {
123         ACTMENU_SEL_COLUMN_KEYS = 1,
124         ACTMENU_SEL_COLUMN_CFRA,
125         ACTMENU_SEL_COLUMN_MARKERSCOLUMN,
126         ACTMENU_SEL_COLUMN_MARKERSBETWEEN 
127 };
128
129 enum {
130         ACTMENU_CHANNELS_OPENLEVELS = 0,
131         ACTMENU_CHANNELS_CLOSELEVELS,
132         ACTMENU_CHANNELS_EXPANDALL,
133         ACTMENU_CHANNELS_SHOWACHANS,
134         ACTMENU_CHANNELS_DELETE
135 };
136
137 enum {
138         ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP        = 0,
139         ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN,
140         ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP,
141         ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM
142 };
143
144 enum {
145         ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE     = 0,
146         ACTMENU_CHANNELS_GROUP_ADD_TONEW,
147         ACTMENU_CHANNELS_GROUP_REMOVE,
148         ACTMENU_CHANNELS_GROUP_SYNCPOSE
149 };
150
151 enum {
152         ACTMENU_CHANNELS_SETTINGS_TOGGLE = 0,
153         ACTMENU_CHANNELS_SETTINGS_ENABLE,
154         ACTMENU_CHANNELS_SETTINGS_DISABLE,
155 };
156
157 enum {
158         ACTMENU_KEY_DUPLICATE = 0,
159         ACTMENU_KEY_DELETE,
160         ACTMENU_KEY_CLEAN,
161         ACTMENU_KEY_SAMPLEKEYS,
162         ACTMENU_KEY_INSERTKEY
163 };
164
165 enum {
166         ACTMENU_KEY_TRANSFORM_MOVE  = 0,
167         ACTMENU_KEY_TRANSFORM_SCALE,
168         ACTMENU_KEY_TRANSFORM_SLIDE,
169         ACTMENU_KEY_TRANSFORM_EXTEND
170 };
171
172 enum {
173         ACTMENU_KEY_HANDLE_AUTO = 0,
174         ACTMENU_KEY_HANDLE_ALIGN,
175         ACTMENU_KEY_HANDLE_FREE,
176         ACTMENU_KEY_HANDLE_VECTOR
177 };
178
179 enum {
180         ACTMENU_KEY_INTERP_CONST = 0,
181         ACTMENU_KEY_INTERP_LINEAR,
182         ACTMENU_KEY_INTERP_BEZIER
183 };
184
185 enum {
186         ACTMENU_KEY_EXTEND_CONST = 0,
187         ACTMENU_KEY_EXTEND_EXTRAPOLATION,
188         ACTMENU_KEY_EXTEND_CYCLIC,
189         ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION
190 };
191
192 enum {
193         ACTMENU_KEY_SNAP_NEARFRAME = 1,
194         ACTMENU_KEY_SNAP_CURFRAME,
195         ACTMENU_KEY_SNAP_NEARMARK,
196         ACTMENU_KEY_SNAP_NEARTIME,
197         ACTMENU_KEY_SNAP_CFRA2KEY,
198 };
199
200 enum {
201         ACTMENU_KEY_MIRROR_CURFRAME = 1,
202         ACTMENU_KEY_MIRROR_YAXIS,
203         ACTMENU_KEY_MIRROR_XAXIS,
204         ACTMENU_KEY_MIRROR_MARKER
205 };
206
207 enum {
208         ACTMENU_MARKERS_ADD = 0,
209         ACTMENU_MARKERS_DUPLICATE,
210         ACTMENU_MARKERS_DELETE,
211         ACTMENU_MARKERS_NAME,
212         ACTMENU_MARKERS_MOVE,
213         ACTMENU_MARKERS_LOCALADD,
214         ACTMENU_MARKERS_LOCALRENAME,
215         ACTMENU_MARKERS_LOCALDELETE,
216         ACTMENU_MARKERS_LOCALMOVE
217 };
218
219 /* ------------------------------- */
220 /* macros for easier state testing (only for use here) */
221
222 /* test if active action editor is showing any markers */
223 #define G_SACTION_HASMARKERS \
224         ((G.saction->action && G.saction->action->markers.first) \
225          || (G.scene->markers.first))
226
227 /* ------------------------------- */
228
229 void do_action_buttons(unsigned short event)
230 {
231         Object *ob= OBACT;
232
233         switch(event) {
234                 case B_ACTHOME: /* HOMEKEY in Action Editor */
235                         /*      Find X extents */
236                         G.v2d->cur.xmin = 0;
237                         G.v2d->cur.ymin=-SCROLLB;
238                         
239                         if (G.saction->action) {
240                                 float extra;
241                                 
242                                 calc_action_range(G.saction->action, &G.v2d->cur.xmin, &G.v2d->cur.xmax, 0);
243                                 if (G.saction->pin==0 && ob) {
244                                         G.v2d->cur.xmin= get_action_frame_inv(ob, G.v2d->cur.xmin);
245                                         G.v2d->cur.xmax= get_action_frame_inv(ob, G.v2d->cur.xmax);
246                                 }                               
247                                 extra= 0.05*(G.v2d->cur.xmax - G.v2d->cur.xmin);
248                                 G.v2d->cur.xmin-= extra;
249                                 G.v2d->cur.xmax+= extra;
250
251                                 if (G.v2d->cur.xmin==G.v2d->cur.xmax) {
252                                         G.v2d->cur.xmax= -5;
253                                         G.v2d->cur.xmax= 100;
254                                 }
255                         }
256                         else { /* shapekeys and/or no action */
257                                 G.v2d->cur.xmin= -5.0;
258                                 G.v2d->cur.xmax= 65.0;
259                         }
260                         
261                         G.v2d->cur.ymin= -75.0;
262                         G.v2d->cur.ymax= 5.0;
263                         
264                         G.v2d->tot= G.v2d->cur;
265                         test_view2d(G.v2d, curarea->winx, curarea->winy);
266                         view2d_do_locks(curarea, V2D_LOCK_COPY);
267                         
268                         addqueue (curarea->win, REDRAW, 1);
269                         
270                         break;
271                         
272                 /* copy/paste/paste-flip buttons in 3d-view header in PoseMode */
273                 case B_ACTCOPY:
274                         copy_posebuf();
275                         allqueue(REDRAWVIEW3D, 1);
276                         break;
277                 case B_ACTPASTE:
278                         paste_posebuf(0);
279                         allqueue(REDRAWVIEW3D, 1);
280                         break;
281                 case B_ACTPASTEFLIP:
282                         paste_posebuf(1);
283                         allqueue(REDRAWVIEW3D, 1);
284                         break;
285                         
286                 /* copy/paste buttons in Action Editor header */
287                 case B_ACTCOPYKEYS:
288                         copy_actdata();
289                         break;
290                 case B_ACTPASTEKEYS:
291                         paste_actdata();
292                         break;
293
294                 case B_ACTPIN:  /* __PINFAKE */
295 /*              if (G.saction->flag & SACTION_PIN) {
296                         if (G.saction->action)
297                                 G.saction->action->id.us ++;
298                 }
299                 else {
300                         if (G.saction->action)
301                                 G.saction->action->id.us --;
302                 }
303 */              /* end PINFAKE */
304                         allqueue(REDRAWACTION, 1);
305                         break;
306         }
307 }
308
309 static void do_action_viewmenu(void *arg, int event)
310 {
311         extern int play_anim(int mode);
312
313         switch(event) {
314                 case ACTMENU_VIEW_CENTERVIEW: /* Center View to Current Frame */
315                         center_currframe();
316                         break;
317                 case ACTMENU_VIEW_AUTOUPDATE: /* Update Automatically */
318                         if (BTST(G.saction->lock, 0)) 
319                                 G.saction->lock = BCLR(G.saction->lock, 0);
320                         else 
321                                 G.saction->lock = BSET(G.saction->lock, 0);
322                         break;
323                 case ACTMENU_VIEW_PLAY3D: /* Play Back Animation */
324                         play_anim(0);
325                         break;
326                 case ACTMENU_VIEW_PLAYALL: /* Play Back Animation in All */
327                         play_anim(1);
328                         break;  
329                 case ACTMENU_VIEW_ALL: /* View All */
330                         do_action_buttons(B_ACTHOME);
331                         break;
332                 case ACTMENU_VIEW_LOCK:
333                         G.v2d->flag ^= V2D_VIEWLOCK;
334                         if (G.v2d->flag & V2D_VIEWLOCK)
335                                 view2d_do_locks(curarea, 0);
336                         break;
337                 case ACTMENU_VIEW_SLIDERS:       /* Show sliders (when applicable) */
338                         G.saction->flag ^= SACTION_SLIDERS;
339                         break;
340                 case ACTMENU_VIEW_MAXIMIZE: /* Maximize Window */
341                         /* using event B_FULL */
342                         break;
343                 case ACTMENU_VIEW_NEXTMARKER: /* Jump to next marker */
344                         nextprev_marker(1);
345                         break;
346                 case ACTMENU_VIEW_PREVMARKER: /* Jump to previous marker */
347                         nextprev_marker(-1);
348                         break;
349                 case ACTMENU_VIEW_TIME: /* switch between frames and seconds display */
350                         G.saction->flag ^= SACTION_DRAWTIME;
351                         break;
352                 case ACTMENU_VIEW_NOHIDE: /* Show hidden channels */
353                         G.saction->flag ^= SACTION_NOHIDE;
354                         break;
355                 case ACTMENU_VIEW_NEXTKEYFRAME: /* Jump to next keyframe */
356                         nextprev_action_keyframe(1);
357                         break;
358                 case ACTMENU_VIEW_PREVKEYFRAME: /* Jump to previous keyframe */
359                         nextprev_action_keyframe(-1);
360                         break;
361                 case ACTMENU_VIEW_TRANSDELDUPS: /* Don't delete duplicate/overlapping keyframes after transform */
362                         G.saction->flag ^= SACTION_NOTRANSKEYCULL;
363                         break;
364                 case ACTMENU_VIEW_HORIZOPTIMISE: /* Include keyframes not in view (horizontally) when preparing to draw */
365                         G.saction->flag ^= SACTION_HORIZOPTIMISEON;
366                         break;
367                 case ACTMENU_VIEW_GCOLORS: /* Draw grouped-action channels using its group's color */
368                         G.saction->flag ^= SACTION_NODRAWGCOLORS;
369                         break;
370                 case ACTMENU_VIEW_PREVRANGESET: /* Set preview range */
371                         anim_previewrange_set();
372                         break;
373                 case ACTMENU_VIEW_PREVRANGECLEAR: /* Clear preview range */
374                         anim_previewrange_clear();
375                         break;
376                 case ACTMENU_VIEW_PREVRANGEAUTO: /* Auto preview-range length */
377                         action_previewrange_set(G.saction->action);
378                         break;
379         }
380         allqueue(REDRAWVIEW3D, 0);
381 }
382
383 static uiBlock *action_viewmenu(void *arg_unused)
384 {
385         uiBlock *block;
386         short yco= 0, menuwidth=120;
387         
388         block= uiNewBlock(&curarea->uiblocks, "action_viewmenu", 
389                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
390         uiBlockSetButmFunc(block, do_action_viewmenu, NULL);
391         
392         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
393                                          "Center View to Current Frame|C", 0, yco-=20, 
394                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
395                                          ACTMENU_VIEW_CENTERVIEW, "");
396                 
397         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
398                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
399                          
400         if (G.saction->flag & SACTION_DRAWTIME) {
401                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
402                                                 "Show Frames|Ctrl T", 0, yco-=20, 
403                                                 menuwidth, 19, NULL, 0.0, 0.0, 1, 
404                                                 ACTMENU_VIEW_TIME, "");
405         }
406         else {
407                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
408                                                 "Show Seconds|Ctrl T", 0, yco-=20, 
409                                                 menuwidth, 19, NULL, 0.0, 0.0, 1, 
410                                                 ACTMENU_VIEW_TIME, "");
411         }
412         
413         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
414         
415         if (G.saction->mode == SACTCONT_GPENCIL) {
416                         // this option may get removed in future
417                 uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_HORIZOPTIMISEON)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
418                                                  "Cull Out-of-View Keys (Time)|", 0, yco-=20, 
419                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
420                                                  ACTMENU_VIEW_HORIZOPTIMISE, "");
421         }
422         else {
423                 uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_SLIDERS)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
424                                                  "Show Sliders|", 0, yco-=20, 
425                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
426                                                  ACTMENU_VIEW_SLIDERS, "");
427                                                  
428                 uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_NOHIDE)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
429                                                  "Show Hidden Channels|", 0, yco-=20, 
430                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
431                                                  ACTMENU_VIEW_NOHIDE, "");
432                                                  
433                 uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_NODRAWGCOLORS)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT, 
434                                                  "Use Group Colors|", 0, yco-=20, 
435                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
436                                                  ACTMENU_VIEW_GCOLORS, "");
437                                                  
438                         // this option may get removed in future
439                 uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_HORIZOPTIMISEON)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
440                                                  "Cull Out-of-View Keys (Time)|", 0, yco-=20, 
441                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
442                                                  ACTMENU_VIEW_HORIZOPTIMISE, "");
443                 
444                 uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_NOTRANSKEYCULL)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT, 
445                                                  "AutoMerge Keyframes|", 0, yco-=20, 
446                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 
447                                                  ACTMENU_VIEW_TRANSDELDUPS, "");
448         }       
449         
450                 
451         uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
452                                          "Lock Time to Other Windows|", 0, yco-=20, 
453                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
454                                          ACTMENU_VIEW_LOCK, "");
455                                          
456         uiDefIconTextBut(block, BUTM, 1, BTST(G.saction->lock, 0)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, 
457                                          "Update Automatically|", 0, yco-=20, 
458                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
459                                          ACTMENU_VIEW_AUTOUPDATE, "");
460
461         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
462                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
463                 
464         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
465                                 "Jump To Next Marker|PageUp", 0, yco-=20,
466                                 menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_NEXTMARKER, "");
467         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
468                                 "Jump To Prev Marker|PageDown", 0, yco-=20, 
469                                 menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_PREVMARKER, "");
470                                 
471         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
472                                 "Jump To Next Keyframe|Ctrl PageUp", 0, yco-=20,
473                                 menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_NEXTKEYFRAME, "");
474         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
475                                 "Jump To Prev Keyframe|Ctrl PageDown", 0, yco-=20, 
476                                 menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_PREVKEYFRAME, "");
477                                          
478         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
479                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
480                         
481         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
482                                          "Play Back Animation|Alt A", 0, yco-=20, 
483                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
484                                          ACTMENU_VIEW_PLAY3D, "");
485         //uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
486         //                               "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
487         //                               menuwidth, 19, NULL, 0.0, 0.0, 1, 
488         //                               ACTMENU_VIEW_PLAYALL, "");
489         
490         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
491                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
492                 
493         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
494                                          "Set Preview Range|Ctrl P", 0, yco-=20, 
495                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
496                                          ACTMENU_VIEW_PREVRANGESET, "");
497         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
498                                          "Clear Preview Range|Alt P", 0, yco-=20,
499                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
500                                          ACTMENU_VIEW_PREVRANGECLEAR, "");
501                 
502         if ((G.saction->mode == SACTCONT_ACTION) && (G.saction->action)) {
503                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
504                                          "Preview Range from Action Length|Ctrl Alt P", 0, yco-=20, 
505                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
506                                          ACTMENU_VIEW_PREVRANGEAUTO, "");
507         }
508                 
509         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
510                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
511         
512         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
513                                          "View All|Home", 0, yco-=20, 
514                                          menuwidth, 19, NULL, 0.0, 0.0, 1, 
515                                          ACTMENU_VIEW_ALL, "");
516         
517         if (!curarea->full) 
518                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, 
519                                                  "Maximize Window|Ctrl UpArrow", 0, yco-=20, 
520                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
521                                                  ACTMENU_VIEW_MAXIMIZE, "");
522         else 
523                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, 
524                                                  "Tile Window|Ctrl DownArrow", 0, yco-=20, 
525                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
526                                                  ACTMENU_VIEW_MAXIMIZE, "");
527         
528         if(curarea->headertype==HEADERTOP) {
529                 uiBlockSetDirection(block, UI_DOWN);
530         }
531         else {
532                 uiBlockSetDirection(block, UI_TOP);
533                 uiBlockFlipOrder(block);
534         }
535
536         uiTextBoundsBlock(block, 50);
537         
538         return block;
539 }
540
541 static void do_action_selectmenu_columnmenu(void *arg, int event)
542 {
543         switch (event) {
544                 case ACTMENU_SEL_COLUMN_MARKERSBETWEEN:
545                         markers_selectkeys_between();
546                         break;
547                 case ACTMENU_SEL_COLUMN_KEYS:
548                         column_select_action_keys(1);
549                         break;
550                 case ACTMENU_SEL_COLUMN_MARKERSCOLUMN:
551                         column_select_action_keys(2);
552                         break;
553                 case ACTMENU_SEL_COLUMN_CFRA:
554                         column_select_action_keys(3);
555                         break;
556         }
557                 
558         allqueue(REDRAWMARKER, 0);
559 }
560
561 static uiBlock *action_selectmenu_columnmenu(void *arg_unused)
562 {
563         uiBlock *block;
564         short yco= 0, menuwidth=120;
565
566         block= uiNewBlock(&curarea->uiblocks, "action_selectmenu_columnmenu", 
567                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
568         uiBlockSetButmFunc(block, do_action_selectmenu_columnmenu, NULL);
569
570         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
571                                          "On Selected Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,  
572                                          ACTMENU_SEL_COLUMN_KEYS, "");
573         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
574                                          "On Current Frame|Ctrl K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,  
575                                          ACTMENU_SEL_COLUMN_CFRA, "");
576         
577         if (G_SACTION_HASMARKERS) {
578                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
579                                                  "On Selected Markers|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
580                                                  ACTMENU_SEL_COLUMN_MARKERSCOLUMN, "");
581                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
582                                                  "Between Selected Markers|Alt K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
583                                                  ACTMENU_SEL_COLUMN_MARKERSBETWEEN, "");
584         }
585         
586         uiBlockSetDirection(block, UI_RIGHT);
587         uiTextBoundsBlock(block, 60);
588
589         return block;
590 }
591
592 static void do_action_selectmenu(void *arg, int event)
593 {       
594         SpaceAction *saction;
595         bAction *act;
596         Key *key;
597         
598         saction = curarea->spacedata.first;
599         if (saction == NULL) return;
600
601         act = saction->action;
602         key = get_action_mesh_key();
603         
604         switch(event)
605         {
606                 case ACTMENU_SEL_BORDER: /* Border Select */
607                         borderselect_action();
608                         break;
609                         
610                 case ACTMENU_SEL_BORDERC: /* Border Select */
611                         borderselect_actionchannels();
612                         break;
613                         
614                 case ACTMENU_SEL_BORDERM: /* Border Select */
615                         borderselect_markers();
616                         break;
617                         
618                 case ACTMENU_SEL_ALL_KEYS: /* Select/Deselect All Keys */
619                         deselect_action_keys(1, 1);
620                         BIF_undo_push("(De)Select Keys");
621                         allqueue(REDRAWACTION, 0);
622                         allqueue(REDRAWNLA, 0);
623                         allqueue(REDRAWIPO, 0);
624                         break;
625                         
626                 case ACTMENU_SEL_ALL_CHAN: /* Select/Deselect All Channels */
627                         deselect_action_channels(1);
628                         BIF_undo_push("(De)Select Action Channels");
629                         allqueue(REDRAWVIEW3D, 0);
630                         allqueue(REDRAWACTION, 0);
631                         allqueue(REDRAWNLA, 0);
632                         allqueue(REDRAWIPO, 0);
633                         break;
634                         
635                 case ACTMENU_SEL_ALL_MARKERS: /* select/deselect all markers */
636                         deselect_markers(1, 0);
637                         BIF_undo_push("(De)Select Markers");
638                         allqueue(REDRAWMARKER, 0);
639                         break;
640                         
641                 case ACTMENU_SEL_INVERSE_KEYS: /* invert selection status of keys */
642                         deselect_action_keys(0, 2);
643                         BIF_undo_push("Inverse Keys");
644                         allqueue(REDRAWACTION, 0);
645                         allqueue(REDRAWNLA, 0);
646                         allqueue(REDRAWIPO, 0);
647                         break;
648                         
649                 case ACTMENU_SEL_INVERSE_CHANNELS: /* invert selection status of channels */
650                         deselect_action_channels(2);
651                         BIF_undo_push("Inverse Action Channels");
652                         allqueue(REDRAWVIEW3D, 0);
653                         allqueue(REDRAWACTION, 0);
654                         allqueue(REDRAWNLA, 0);
655                         allqueue(REDRAWIPO, 0);
656                         break;
657                         
658                 case ACTMENU_SEL_INVERSE_MARKERS: /* invert selection of markers */
659                         deselect_markers(0, 2);
660                         BIF_undo_push("Inverse Action Channels");
661                         allqueue(REDRAWMARKER, 0);
662                         break;
663                         
664                 case ACTMENU_SEL_LEFTKEYS:
665                         selectkeys_leftright(1, SELECT_REPLACE);
666                         break;
667                         
668                 case ACTMENU_SEL_RIGHTKEYS:
669                         selectkeys_leftright(0, SELECT_REPLACE);
670                         break;
671         }
672 }
673
674 static uiBlock *action_selectmenu(void *arg_unused)
675 {
676         uiBlock *block;
677         short yco= 0, menuwidth=120;
678
679         block= uiNewBlock(&curarea->uiblocks, "action_selectmenu", 
680                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
681         uiBlockSetButmFunc(block, do_action_selectmenu, NULL);
682
683         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
684                                          "Border Select Keys|B", 0, yco-=20, 
685                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
686                                          ACTMENU_SEL_BORDER, "");
687         if (G_SACTION_HASMARKERS) {
688                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
689                                                  "Border Select Markers|Ctrl B", 0, yco-=20, 
690                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
691                                                  ACTMENU_SEL_BORDERM, "");
692         }
693         if (G.saction->mode != SACTCONT_SHAPEKEY) {
694                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
695                                                  "Border Select Channels|B", 0, yco-=20, 
696                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
697                                                  ACTMENU_SEL_BORDERC, "");
698         }
699                                          
700         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
701                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
702                          
703         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
704                                          "Select/Deselect All Keys|A", 0, yco-=20, 
705                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
706                                          ACTMENU_SEL_ALL_KEYS, "");
707         if (G_SACTION_HASMARKERS) {
708                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
709                                                  "Select/Deselect All Markers|Ctrl A", 0, yco-=20, 
710                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
711                                                  ACTMENU_SEL_ALL_MARKERS, "");
712         }
713         if (G.saction->mode != SACTCONT_SHAPEKEY) {
714                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
715                                                  "Select/Deselect All Channels|A", 0, yco-=20, 
716                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
717                                                  ACTMENU_SEL_ALL_CHAN, "");
718         }
719                                          
720         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
721                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
722
723         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
724                                          "Inverse Keys|Ctrl I", 0, yco-=20, 
725                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
726                                          ACTMENU_SEL_INVERSE_KEYS, "");
727         if (G_SACTION_HASMARKERS) {
728                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
729                                                  "Inverse Markers|Ctrl Shift I", 0, yco-=20, 
730                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
731                                                  ACTMENU_SEL_INVERSE_MARKERS, "");
732         }
733         if (G.saction->mode != SACTCONT_SHAPEKEY) {
734                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
735                                                  "Inverse All Channels|Ctrl I", 0, yco-=20, 
736                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
737                                                  ACTMENU_SEL_INVERSE_CHANNELS, "");
738         }
739                 
740         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
741                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
742                          
743         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
744                                          "Back In Time|Alt RMB", 0, yco-=20, 
745                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
746                                          ACTMENU_SEL_LEFTKEYS, "");
747                                                                  
748         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
749                                          "Ahead In Time|Alt RMB", 0, yco-=20, 
750                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
751                                          ACTMENU_SEL_RIGHTKEYS, "");             
752                          
753         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
754                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
755                          
756         uiDefIconTextBlockBut(block, action_selectmenu_columnmenu, 
757                                                   NULL, ICON_RIGHTARROW_THIN, "Column Select Keys", 0, yco-=20, 120, 20, "");
758         
759         if (curarea->headertype==HEADERTOP) {
760                 uiBlockSetDirection(block, UI_DOWN);
761         }
762         else {
763                 uiBlockSetDirection(block, UI_TOP);
764                 uiBlockFlipOrder(block);
765         }
766
767         uiTextBoundsBlock(block, 50);
768
769         return block;
770 }
771
772
773 static void do_action_channelmenu_posmenu(void *arg, int event)
774 {
775         switch(event)
776         {
777                 case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN:
778                         rearrange_action_channels(REARRANGE_ACTCHAN_DOWN);
779                         break;
780                 case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP:
781                         rearrange_action_channels(REARRANGE_ACTCHAN_UP);
782                         break;
783                 case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP:
784                         rearrange_action_channels(REARRANGE_ACTCHAN_TOP);
785                         break;
786                 case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM:
787                         rearrange_action_channels(REARRANGE_ACTCHAN_BOTTOM);
788                         break;
789         }
790
791         scrarea_queue_winredraw(curarea);
792 }
793
794 static uiBlock *action_channelmenu_posmenu(void *arg_unused)
795 {
796         uiBlock *block;
797         short yco= 0, menuwidth=120;
798
799         block= uiNewBlock(&curarea->uiblocks, "action_channelmenu_posmenu", 
800                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
801         uiBlockSetButmFunc(block, do_action_channelmenu_posmenu, NULL);
802
803         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
804                                          "Move Up|Shift Page Up", 0, yco-=20, 
805                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
806                                          ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP, "");
807         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
808                                          "Move Down|Shift Page Down", 0, yco-=20, 
809                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
810                                          ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN, "");
811         
812         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
813                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
814                                         
815         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
816                                          "Move to Top|Ctrl Shift Page Up", 0, yco-=20, 
817                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
818                                          ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP, "");
819         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
820                                          "Move to Bottom|Ctrl Shift Page Down", 0, yco-=20, 
821                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
822                                          ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM, "");
823
824         uiBlockSetDirection(block, UI_RIGHT);
825         uiTextBoundsBlock(block, 60);
826
827         return block;
828 }
829
830 static void do_action_channelmenu_groupmenu(void *arg, int event)
831 {
832         switch(event)
833         {
834                 case ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE:
835                         action_groups_group(0);
836                         break;
837                 case ACTMENU_CHANNELS_GROUP_ADD_TONEW:
838                         action_groups_group(1);
839                         break;
840                 case ACTMENU_CHANNELS_GROUP_REMOVE:
841                         action_groups_ungroup();
842                         break;
843                 case ACTMENU_CHANNELS_GROUP_SYNCPOSE: /* Syncronise Pose-data and Action-data */
844                         sync_pchan2achan_grouping();
845                         break;
846         }
847 }
848
849 static uiBlock *action_channelmenu_groupmenu(void *arg_unused)
850 {
851         uiBlock *block;
852         short yco= 0, menuwidth=120;
853
854         block= uiNewBlock(&curarea->uiblocks, "action_channelmenu_groupmenu", 
855                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
856         uiBlockSetButmFunc(block, do_action_channelmenu_groupmenu, NULL);
857
858         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
859                                          "Add to Active Group|Shift G", 0, yco-=20, 
860                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
861                                          ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE, "");
862         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
863                                          "Add to New Group|Ctrl Shift G", 0, yco-=20, 
864                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
865                                          ACTMENU_CHANNELS_GROUP_ADD_TONEW, "");
866                 
867         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
868                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
869                                         
870         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
871                                          "Remove From Group|Alt G", 0, yco-=20, 
872                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
873                                          ACTMENU_CHANNELS_GROUP_REMOVE, "");
874                                          
875         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
876                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
877                                         
878         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
879                                          "Synchronise with Armature", 0, yco-=20, 
880                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
881                                          ACTMENU_CHANNELS_GROUP_SYNCPOSE, "");
882
883         uiBlockSetDirection(block, UI_RIGHT);
884         uiTextBoundsBlock(block, 60);
885
886         return block;
887 }
888
889 static void do_action_channelmenu_settingsmenu(void *arg, int event)
890 {
891         setflag_action_channels(event);
892 }
893
894 static uiBlock *action_channelmenu_settingsmenu(void *arg_unused)
895 {
896         uiBlock *block;
897         short yco= 0, menuwidth=120;
898
899         block= uiNewBlock(&curarea->uiblocks, "action_channelmenu_settingsmenu", 
900                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
901         uiBlockSetButmFunc(block, do_action_channelmenu_settingsmenu, NULL);
902
903         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
904                                          "Toggle a Setting|Shift W", 0, yco-=20, 
905                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
906                                          ACTMENU_CHANNELS_SETTINGS_TOGGLE, "");
907                                          
908         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
909                                          "Enable a Setting|Ctrl Shift W", 0, yco-=20, 
910                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
911                                          ACTMENU_CHANNELS_SETTINGS_ENABLE, "");
912                                         
913         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
914                                          "Disable a Setting|Alt W", 0, yco-=20, 
915                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
916                                          ACTMENU_CHANNELS_SETTINGS_DISABLE, "");
917
918         uiBlockSetDirection(block, UI_RIGHT);
919         uiTextBoundsBlock(block, 60);
920
921         return block;
922 }
923
924 static void do_action_channelmenu(void *arg, int event)
925 {       
926         SpaceAction *saction;
927         
928         saction = curarea->spacedata.first;
929         if (saction == NULL) return;
930         
931         switch(event)
932         {
933                 case ACTMENU_CHANNELS_OPENLEVELS: /* Unfold selected channels one step */
934                         openclose_level_action(1);
935                         break;
936                 case ACTMENU_CHANNELS_CLOSELEVELS: /* Fold selected channels one step */
937                         openclose_level_action(-1);
938                         break;
939                 case ACTMENU_CHANNELS_EXPANDALL: /* Expands all channels */
940                         expand_all_action();
941                         break;
942                 case ACTMENU_CHANNELS_SHOWACHANS: /* Unfold groups that are hiding selected achans */
943                         expand_obscuregroups_action();
944                         break;
945                 case ACTMENU_CHANNELS_DELETE: /* Deletes selected channels */
946                         delete_action_channels();
947                         break;
948         }
949 }
950
951 static uiBlock *action_channelmenu(void *arg_unused)
952 {
953         uiBlock *block;
954         short yco= 0, menuwidth=120;
955
956         block= uiNewBlock(&curarea->uiblocks, "action_channelmenu", 
957                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
958         uiBlockSetButmFunc(block, do_action_channelmenu, NULL);
959         
960         uiDefIconTextBlockBut(block, action_channelmenu_groupmenu, 
961                                                   NULL, ICON_RIGHTARROW_THIN, 
962                                                   "Grouping", 0, yco-=20, 120, 20, "");  
963                                                   
964         uiDefIconTextBlockBut(block, action_channelmenu_posmenu, 
965                                                   NULL, ICON_RIGHTARROW_THIN, 
966                                                   "Ordering", 0, yco-=20, 120, 20, "");
967         
968         uiDefIconTextBlockBut(block, action_channelmenu_settingsmenu, 
969                                                   NULL, ICON_RIGHTARROW_THIN, 
970                                                   "Settings", 0, yco-=20, 120, 20, ""); 
971         
972         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
973                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
974         
975         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
976                         "Delete|X", 0, yco-=20,
977                         menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_DELETE, "");
978         
979         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
980                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
981                 
982         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
983                         "Toggle Show Hierachy|~", 0, yco-=20,
984                         menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_EXPANDALL, "");
985                         
986         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
987                         "Show Group-Hidden Channels|Shift ~", 0, yco-=20,
988                         menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_SHOWACHANS, "");
989                         
990         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
991                         "Expand One Level|Ctrl NumPad+", 0, yco-=20,
992                         menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_OPENLEVELS, "");
993                         
994         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
995                         "Collapse One Level|Ctrl NumPad-", 0, yco-=20,
996                         menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_CLOSELEVELS, "");
997         
998         if (curarea->headertype==HEADERTOP) {
999                 uiBlockSetDirection(block, UI_DOWN);
1000         }
1001         else {
1002                 uiBlockSetDirection(block, UI_TOP);
1003                 uiBlockFlipOrder(block);
1004         }
1005
1006         uiTextBoundsBlock(block, 50);
1007
1008         return block;
1009 }
1010
1011 /* note: uses do_action_channelmenu too... */
1012 static uiBlock *action_gplayermenu(void *arg_unused)
1013 {
1014         uiBlock *block;
1015         short yco= 0, menuwidth=120;
1016
1017         block= uiNewBlock(&curarea->uiblocks, "action_gplayermenu", 
1018                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
1019         uiBlockSetButmFunc(block, do_action_channelmenu, NULL);
1020         
1021         uiDefIconTextBlockBut(block, action_channelmenu_settingsmenu, 
1022                                                   NULL, ICON_RIGHTARROW_THIN, 
1023                                                   "Settings", 0, yco-=20, 120, 20, ""); 
1024         
1025         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1026                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1027         
1028         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1029                         "Delete|X", 0, yco-=20,
1030                         menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_DELETE, "");
1031         
1032         if (curarea->headertype==HEADERTOP) {
1033                 uiBlockSetDirection(block, UI_DOWN);
1034         }
1035         else {
1036                 uiBlockSetDirection(block, UI_TOP);
1037                 uiBlockFlipOrder(block);
1038         }
1039
1040         uiTextBoundsBlock(block, 50);
1041
1042         return block;
1043 }
1044
1045 static void do_action_keymenu_transformmenu(void *arg, int event)
1046 {       
1047         switch (event)
1048         {
1049                 case ACTMENU_KEY_TRANSFORM_MOVE:
1050                         transform_action_keys('g', 0);
1051                         break;
1052                 case ACTMENU_KEY_TRANSFORM_SCALE:
1053                         transform_action_keys('s', 0);
1054                         break;
1055                 case ACTMENU_KEY_TRANSFORM_SLIDE:
1056                         transform_action_keys('t', 0);
1057                         break;
1058                 case ACTMENU_KEY_TRANSFORM_EXTEND:
1059                         transform_action_keys('e', 0);
1060                         break;
1061         }
1062
1063         scrarea_queue_winredraw(curarea);
1064 }
1065
1066 static uiBlock *action_keymenu_transformmenu(void *arg_unused)
1067 {
1068         uiBlock *block;
1069         short yco= 0, menuwidth=120;
1070
1071         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_transformmenu", 
1072                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1073         uiBlockSetButmFunc(block, do_action_keymenu_transformmenu, NULL);
1074
1075         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1076                                          "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,  
1077                                          ACTMENU_KEY_TRANSFORM_MOVE, "");
1078         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1079                                          "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
1080                                          ACTMENU_KEY_TRANSFORM_EXTEND, "");
1081         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1082                                          "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
1083                                          ACTMENU_KEY_TRANSFORM_SCALE, "");
1084         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1085                                          "Time Slide|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 
1086                                          ACTMENU_KEY_TRANSFORM_SLIDE, "");
1087         
1088         
1089         uiBlockSetDirection(block, UI_RIGHT);
1090         uiTextBoundsBlock(block, 60);
1091
1092         return block;
1093 }
1094
1095 static void do_action_keymenu_handlemenu(void *arg, int event)
1096 {
1097         switch (event) {
1098                 case ACTMENU_KEY_HANDLE_AUTO:
1099                         sethandles_action_keys(HD_AUTO);
1100                         break;
1101
1102                 case ACTMENU_KEY_HANDLE_ALIGN:
1103                 case ACTMENU_KEY_HANDLE_FREE:
1104                         /* OK, this is kinda dumb, need to fix the
1105                          * toggle crap in sethandles_ipo_keys() 
1106                          */
1107                         sethandles_action_keys(HD_ALIGN);
1108                         break;
1109
1110                 case ACTMENU_KEY_HANDLE_VECTOR:
1111                         sethandles_action_keys(HD_VECT);        
1112                         break;
1113         }
1114 }
1115
1116 static uiBlock *action_keymenu_handlemenu(void *arg_unused)
1117 {
1118         uiBlock *block;
1119         short yco= 0, menuwidth=120;
1120
1121         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_handlemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1122         uiBlockSetButmFunc(block, do_action_keymenu_handlemenu, NULL);
1123
1124         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1125                                          "Auto|Shift H", 0, yco-=20, 
1126                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1127                                          ACTMENU_KEY_HANDLE_AUTO, "");
1128         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1129                                          "Aligned|H", 0, yco-=20, 
1130                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1131                                          ACTMENU_KEY_HANDLE_ALIGN, "");
1132         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1133                                          "Free|H", 0, yco-=20, menuwidth, 
1134                                          19, NULL, 0.0, 0.0, 0, 
1135                                          ACTMENU_KEY_HANDLE_FREE, "");
1136         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1137                                          "Vector|V", 0, yco-=20, 
1138                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1139                                          ACTMENU_KEY_HANDLE_VECTOR, "");
1140
1141         uiBlockSetDirection(block, UI_RIGHT);
1142         uiTextBoundsBlock(block, 60);
1143
1144         return block;
1145 }
1146
1147 static void do_action_keymenu_intpolmenu(void *arg, int event)
1148 {
1149         switch(event)
1150         {
1151                 case ACTMENU_KEY_INTERP_CONST:
1152                         action_set_ipo_flags(SET_IPO_MENU, SET_IPO_CONSTANT);
1153                         break;
1154                 case ACTMENU_KEY_INTERP_LINEAR:
1155                         action_set_ipo_flags(SET_IPO_MENU, SET_IPO_LINEAR);
1156                         break;
1157                 case ACTMENU_KEY_INTERP_BEZIER:
1158                         action_set_ipo_flags(SET_IPO_MENU, SET_IPO_BEZIER);
1159                         break;
1160         }
1161
1162         scrarea_queue_winredraw(curarea);
1163 }
1164
1165 static uiBlock *action_keymenu_intpolmenu(void *arg_unused)
1166 {
1167         uiBlock *block;
1168         short yco= 0, menuwidth=120;
1169
1170         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_intpolmenu", 
1171                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1172         uiBlockSetButmFunc(block, do_action_keymenu_intpolmenu, NULL);
1173
1174         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1175                                          "Constant|Shift T, 1", 0, yco-=20, 
1176                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1177                                          ACTMENU_KEY_INTERP_CONST, "");
1178         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1179                                          "Linear|Shift T, 2", 0, yco-=20, 
1180                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1181                                          ACTMENU_KEY_INTERP_LINEAR, "");
1182         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1183                                          "Bezier|Shift T, 3", 0, yco-=20, 
1184                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1185                                          ACTMENU_KEY_INTERP_BEZIER, "");
1186
1187         uiBlockSetDirection(block, UI_RIGHT);
1188         uiTextBoundsBlock(block, 60);
1189
1190         return block;
1191 }
1192
1193 static void do_action_keymenu_extendmenu(void *arg, int event)
1194 {
1195         switch(event)
1196         {
1197                 case ACTMENU_KEY_EXTEND_CONST:
1198                         action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_CONSTANT);
1199                         break;
1200                 case ACTMENU_KEY_EXTEND_EXTRAPOLATION:
1201                         action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_EXTRAPOLATION);
1202                         break;
1203                 case ACTMENU_KEY_EXTEND_CYCLIC:
1204                         action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_CYCLIC);
1205                         break;
1206                 case ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION:
1207                         action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_CYCLICEXTRAPOLATION);
1208                         break;
1209         }
1210
1211         scrarea_queue_winredraw(curarea);
1212 }
1213
1214 static uiBlock *action_keymenu_extendmenu(void *arg_unused)
1215 {
1216         uiBlock *block;
1217         short yco= 0, menuwidth=120;
1218
1219         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_extendmenu", 
1220                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1221         uiBlockSetButmFunc(block, do_action_keymenu_extendmenu, NULL);
1222
1223         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1224                                          "Constant", 0, yco-=20, 
1225                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1226                                          ACTMENU_KEY_EXTEND_CONST, "");
1227         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1228                                          "Extrapolation", 0, yco-=20, 
1229                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1230                                          ACTMENU_KEY_EXTEND_EXTRAPOLATION, "");
1231         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1232                                          "Cyclic", 0, yco-=20, 
1233                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1234                                          ACTMENU_KEY_EXTEND_CYCLIC, "");
1235         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1236                                          "Cyclic Extrapolation", 0, yco-=20, 
1237                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1238                                          ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION, "");
1239
1240         uiBlockSetDirection(block, UI_RIGHT);
1241         uiTextBoundsBlock(block, 60);
1242
1243         return block;
1244 }
1245
1246 static void do_action_keymenu_snapmenu(void *arg, int event)
1247 {
1248         switch(event)
1249         {
1250                 case ACTMENU_KEY_SNAP_NEARFRAME:
1251                 case ACTMENU_KEY_SNAP_CURFRAME:
1252                 case ACTMENU_KEY_SNAP_NEARMARK:
1253                 case ACTMENU_KEY_SNAP_NEARTIME:
1254                         snap_action_keys(event);
1255                         break;
1256                         
1257                 case ACTMENU_KEY_SNAP_CFRA2KEY:
1258                         snap_cfra_action();
1259                         break;
1260         }
1261
1262         scrarea_queue_winredraw(curarea);
1263 }
1264
1265 static uiBlock *action_keymenu_snapmenu(void *arg_unused)
1266 {
1267         uiBlock *block;
1268         short yco= 0, menuwidth=120;
1269
1270         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_snapmenu", 
1271                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1272         uiBlockSetButmFunc(block, do_action_keymenu_snapmenu, NULL);
1273
1274         if (G.saction->flag & SACTION_DRAWTIME) {
1275                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1276                                                  "Key -> Nearest Second|Shift S, 1", 0, yco-=20, 
1277                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
1278                                                  ACTMENU_KEY_SNAP_NEARTIME, "");
1279                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1280                                                  "Key -> Current Time|Shift S, 2", 0, yco-=20, 
1281                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
1282                                                  ACTMENU_KEY_SNAP_CURFRAME, "");
1283
1284         }
1285         else {
1286                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1287                                                  "Key -> Nearest Frame|Shift S, 1", 0, yco-=20, 
1288                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
1289                                                  ACTMENU_KEY_SNAP_NEARFRAME, "");
1290                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1291                                                  "Key -> Current Frame|Shift S, 2", 0, yco-=20, 
1292                                                  menuwidth, 19, NULL, 0.0, 0.0, 0, 
1293                                                  ACTMENU_KEY_SNAP_CURFRAME, "");
1294         }
1295         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1296                                          "Key -> Nearest Marker|Shift S, 3", 0, yco-=20, 
1297                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1298                                          ACTMENU_KEY_SNAP_NEARMARK, "");
1299                                          
1300         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1301                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1302                          
1303         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1304                                          "Current Frame -> Key|Ctrl Shift S", 0, yco-=20, 
1305                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1306                                          ACTMENU_KEY_SNAP_NEARMARK, "");
1307
1308         uiBlockSetDirection(block, UI_RIGHT);
1309         uiTextBoundsBlock(block, 60);
1310
1311         return block;
1312 }
1313
1314 static void do_action_keymenu_mirrormenu(void *arg, int event)
1315 {
1316         switch(event)
1317         {
1318                 case ACTMENU_KEY_MIRROR_CURFRAME:
1319                 case ACTMENU_KEY_MIRROR_YAXIS:
1320                         mirror_action_keys(event);
1321                         break;
1322         }
1323
1324         scrarea_queue_winredraw(curarea);
1325 }
1326
1327 static uiBlock *action_keymenu_mirrormenu(void *arg_unused)
1328 {
1329         uiBlock *block;
1330         short yco= 0, menuwidth=120;
1331
1332         block= uiNewBlock(&curarea->uiblocks, "action_keymenu_mirrormenu", 
1333                                           UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
1334         uiBlockSetButmFunc(block, do_action_keymenu_mirrormenu, NULL);
1335
1336         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1337                                          "Current Frame|Shift M, 1", 0, yco-=20, 
1338                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1339                                          ACTMENU_KEY_MIRROR_CURFRAME, "");
1340         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1341                                          "Vertical Axis|Shift M, 2", 0, yco-=20, 
1342                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1343                                          ACTMENU_KEY_MIRROR_YAXIS, "");
1344         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1345                                          "Horizontal Axis|Shift M, 3", 0, yco-=20, 
1346                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1347                                          ACTMENU_KEY_MIRROR_XAXIS, "");
1348         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1349                                          "Selected Marker|Shift M, 4", 0, yco-=20, 
1350                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1351                                          ACTMENU_KEY_MIRROR_MARKER, "");
1352
1353         uiBlockSetDirection(block, UI_RIGHT);
1354         uiTextBoundsBlock(block, 60);
1355
1356         return block;
1357 }
1358
1359 static void do_action_keymenu(void *arg, int event)
1360 {       
1361         SpaceAction *saction;
1362         bAction *act;
1363         Key *key;
1364         
1365         saction = curarea->spacedata.first;
1366         if (!saction) return;
1367
1368         act = saction->action;
1369         key = get_action_mesh_key();
1370
1371         switch(event)
1372         {
1373                 case ACTMENU_KEY_DUPLICATE:
1374                         duplicate_action_keys();
1375                         break;
1376                 case ACTMENU_KEY_DELETE:
1377                         delete_action_keys();
1378                         break;
1379                 case ACTMENU_KEY_CLEAN:
1380                         clean_action();
1381                         break;
1382                 case ACTMENU_KEY_SAMPLEKEYS:
1383                         sample_action_keys();
1384                         break;
1385                 case ACTMENU_KEY_INSERTKEY:
1386                         insertkey_action();
1387                         break;
1388         }
1389 }
1390
1391 static uiBlock *action_keymenu(void *arg_unused)
1392 {
1393         uiBlock *block;
1394         short yco= 0, menuwidth=120;
1395
1396         block= uiNewBlock(&curarea->uiblocks, "action_keymenu", 
1397                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
1398         uiBlockSetButmFunc(block, do_action_keymenu, NULL);
1399         
1400         uiDefIconTextBlockBut(block, action_keymenu_transformmenu, 
1401                                                   NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 20, "");
1402         
1403         uiDefIconTextBlockBut(block, action_keymenu_snapmenu, 
1404                                                   NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 20, "");
1405         
1406         uiDefIconTextBlockBut(block, action_keymenu_mirrormenu, 
1407                                                   NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 20, "");
1408         
1409         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1410                                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1411         
1412         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1413                                         "Insert Key|I", 0, yco-=20, 
1414                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
1415                                         ACTMENU_KEY_INSERTKEY, "");
1416
1417         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1418                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1419                                         
1420         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1421                                         "Duplicate|Shift D", 0, yco-=20, 
1422                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
1423                                         ACTMENU_KEY_DUPLICATE, "");
1424         
1425         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1426                                         "Delete|X", 0, yco-=20, 
1427                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
1428                                         ACTMENU_KEY_DELETE, "");
1429
1430         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1431                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1432
1433         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1434                                          "Clean Action|O", 0, yco-=20, 
1435                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1436                                          ACTMENU_KEY_CLEAN, "");
1437                                          
1438         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1439                                          "Sample Keys|Alt O", 0, yco-=20, 
1440                                          menuwidth, 19, NULL, 0.0, 0.0, 0, 
1441                                          ACTMENU_KEY_SAMPLEKEYS, "");
1442
1443         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1444                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1445
1446         uiDefIconTextBlockBut(block, action_keymenu_handlemenu, 
1447                                                   NULL, ICON_RIGHTARROW_THIN, 
1448                                                   "Handle Type", 0, yco-=20, 120, 20, "");
1449         
1450         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1451                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1452
1453         uiDefIconTextBlockBut(block, action_keymenu_extendmenu, 
1454                                                   NULL, ICON_RIGHTARROW_THIN, 
1455                                                   "Extend Mode", 0, yco-=20, 120, 20, "");
1456         uiDefIconTextBlockBut(block, action_keymenu_intpolmenu, 
1457                                                   NULL, ICON_RIGHTARROW_THIN, 
1458                                                   "Interpolation Mode", 0, yco-=20, 120, 20, "");
1459
1460         
1461         if(curarea->headertype==HEADERTOP) {
1462                 uiBlockSetDirection(block, UI_DOWN);
1463         }
1464         else {
1465                 uiBlockSetDirection(block, UI_TOP);
1466                 uiBlockFlipOrder(block);
1467         }
1468
1469         uiTextBoundsBlock(block, 50);
1470
1471         return block;
1472 }
1473
1474 /* note: uses do_action_keymenu too! */
1475 static uiBlock *action_framemenu(void *arg_unused)
1476 {
1477         uiBlock *block;
1478         short yco= 0, menuwidth=120;
1479
1480         block= uiNewBlock(&curarea->uiblocks, "action_framemenu", 
1481                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
1482         uiBlockSetButmFunc(block, do_action_keymenu, NULL);
1483         
1484         uiDefIconTextBlockBut(block, action_keymenu_transformmenu, 
1485                                                   NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 20, "");
1486         
1487         uiDefIconTextBlockBut(block, action_keymenu_snapmenu, 
1488                                                   NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 20, "");
1489         
1490         uiDefIconTextBlockBut(block, action_keymenu_mirrormenu, 
1491                                                   NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 20, "");
1492         
1493         uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
1494                          menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1495                                         
1496         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1497                                         "Duplicate|Shift D", 0, yco-=20, 
1498                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
1499                                         ACTMENU_KEY_DUPLICATE, "");
1500         
1501         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
1502                                         "Delete|X", 0, yco-=20, 
1503                                         menuwidth, 19, NULL, 0.0, 0.0, 0, 
1504                                         ACTMENU_KEY_DELETE, "");
1505         
1506         if(curarea->headertype==HEADERTOP) {
1507                 uiBlockSetDirection(block, UI_DOWN);
1508         }
1509         else {
1510                 uiBlockSetDirection(block, UI_TOP);
1511                 uiBlockFlipOrder(block);
1512         }
1513
1514         uiTextBoundsBlock(block, 50);
1515
1516         return block;
1517 }
1518
1519 static void do_action_markermenu(void *arg, int event)
1520 {       
1521         switch(event)
1522         {
1523                 case ACTMENU_MARKERS_ADD:
1524                         add_marker(CFRA);
1525                         break;
1526                 case ACTMENU_MARKERS_DUPLICATE:
1527                         duplicate_marker();
1528                         break;
1529                 case ACTMENU_MARKERS_DELETE:
1530                         remove_marker();
1531                         break;
1532                 case ACTMENU_MARKERS_NAME:
1533                         rename_marker();
1534                         break;
1535                 case ACTMENU_MARKERS_MOVE:
1536                         transform_markers('g', 0);
1537                         break;
1538                         
1539                 case ACTMENU_MARKERS_LOCALADD:
1540                         action_add_localmarker(G.saction->action, CFRA);
1541                         break;
1542                 case ACTMENU_MARKERS_LOCALDELETE:
1543                         action_remove_localmarkers(G.saction->action);
1544                         break;
1545                 case ACTMENU_MARKERS_LOCALRENAME:
1546                         action_rename_localmarker(G.saction->action);
1547                         break;
1548                 case ACTMENU_MARKERS_LOCALMOVE:
1549                         G.saction->flag |= SACTION_POSEMARKERS_MOVE;
1550                         transform_markers('g', 0);
1551                         G.saction->flag &= ~SACTION_POSEMARKERS_MOVE;
1552                         break;
1553         }
1554         
1555         allqueue(REDRAWMARKER, 0);
1556 }
1557
1558 static uiBlock *action_markermenu(void *arg_unused)
1559 {
1560         uiBlock *block;
1561         short yco= 0, menuwidth=120;
1562
1563         block= uiNewBlock(&curarea->uiblocks, "action_markermenu", 
1564                                           UI_EMBOSSP, UI_HELV, curarea->headwin);
1565         uiBlockSetButmFunc(block, do_action_markermenu, NULL);
1566
1567         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Marker|M", 0, yco-=20, 
1568                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_ADD, "");
1569         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate Marker|Ctrl Shift D", 0, yco-=20, 
1570                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_DUPLICATE, "");
1571         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete Marker|X", 0, yco-=20,
1572                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_DELETE, "");
1573                                         
1574         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1575                                         
1576         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "(Re)Name Marker|Ctrl M", 0, yco-=20,
1577                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_NAME, "");
1578         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move Marker|Ctrl G", 0, yco-=20,
1579                                          menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_MOVE, "");
1580                 
1581         if (G.saction->mode == SACTCONT_ACTION) {
1582                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1583                 
1584                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Pose Marker|Shift L", 0, yco-=20, 
1585                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALADD, "");
1586                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename Pose Marker|Ctrl Shift L", 0, yco-=20, 
1587                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALRENAME, "");
1588                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete Pose Marker|Alt L", 0, yco-=20,
1589                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALDELETE, "");
1590                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move Pose Marker|Ctrl L", 0, yco-=20, 
1591                                                  menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALMOVE, "");
1592         }
1593         
1594         if(curarea->headertype==HEADERTOP) {
1595                 uiBlockSetDirection(block, UI_DOWN);
1596         }
1597         else {
1598                 uiBlockSetDirection(block, UI_TOP);
1599                 uiBlockFlipOrder(block);
1600         }
1601
1602         uiTextBoundsBlock(block, 50);
1603
1604         return block;
1605 }
1606
1607 void action_buttons(void)
1608 {
1609         uiBlock *block;
1610         short xco, xmax;
1611         char name[256];
1612         Object *ob;
1613         ID *from;
1614
1615         if (G.saction == NULL)
1616                 return;
1617
1618         /* copied from drawactionspace.... */
1619         // FIXME: do for gpencil too?
1620         if (!G.saction->pin) {
1621                 if (OBACT)
1622                         G.saction->action = OBACT->action;
1623                 else
1624                         G.saction->action= NULL;
1625         }
1626
1627         sprintf(name, "header %d", curarea->headwin);
1628         block= uiNewBlock(&curarea->uiblocks, name, 
1629                                           UI_EMBOSS, UI_HELV, curarea->headwin);
1630
1631         if (area_is_active_area(curarea)) 
1632                 uiBlockSetCol(block, TH_HEADER);
1633         else 
1634                 uiBlockSetCol(block, TH_HEADERDESEL);
1635
1636         curarea->butspacetype= SPACE_ACTION;
1637         
1638         xco = 8;
1639         
1640         uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, 
1641                                           windowtype_pup(), xco, 0, XIC+10, YIC, 
1642                                           &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, 
1643                                           "Displays Current Window Type. "
1644                                           "Click for menu of available types.");
1645
1646         xco += XIC + 14;
1647
1648         uiBlockSetEmboss(block, UI_EMBOSSN);
1649         if (curarea->flag & HEADER_NO_PULLDOWN) {
1650                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, 
1651                                           ICON_DISCLOSURE_TRI_RIGHT,
1652                                           xco,2,XIC,YIC-2,
1653                                           &(curarea->flag), 0, 0, 0, 0, 
1654                                           "Show pulldown menus");
1655         }
1656         else {
1657                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, 
1658                                           ICON_DISCLOSURE_TRI_DOWN,
1659                                           xco,2,XIC,YIC-2,
1660                                           &(curarea->flag), 0, 0, 0, 0, 
1661                                           "Hide pulldown menus");
1662         }
1663         uiBlockSetEmboss(block, UI_EMBOSS);
1664         xco+=XIC;
1665
1666         if ((curarea->flag & HEADER_NO_PULLDOWN)==0) {
1667                 /* pull down menus */
1668                 uiBlockSetEmboss(block, UI_EMBOSSP);
1669                 
1670                 xmax= GetButStringLength("View");
1671                 uiDefPulldownBut(block, action_viewmenu, NULL, 
1672                                           "View", xco, -2, xmax-3, 24, "");
1673                 xco+= xmax;
1674                 
1675                 xmax= GetButStringLength("Select");
1676                 uiDefPulldownBut(block, action_selectmenu, NULL, 
1677                                           "Select", xco, -2, xmax-3, 24, "");
1678                 xco+= xmax;
1679                 
1680                 if ((G.saction->action) && (G.saction->mode==SACTCONT_ACTION)) {
1681                         xmax= GetButStringLength("Channel");
1682                         uiDefPulldownBut(block, action_channelmenu, NULL, 
1683                                                   "Channel", xco, -2, xmax-3, 24, "");
1684                         xco+= xmax;
1685                 }
1686                 else if ((G.saction->gpd) && (G.saction->mode==SACTCONT_GPENCIL)) {
1687                         xmax= GetButStringLength("Channel");
1688                         uiDefPulldownBut(block, action_gplayermenu, NULL, 
1689                                                   "Channel", xco, -2, xmax-3, 24, "");
1690                         xco+= xmax;
1691                 }
1692                 
1693                 xmax= GetButStringLength("Marker");
1694                 uiDefPulldownBut(block, action_markermenu, NULL, 
1695                                           "Marker", xco, -2, xmax-3, 24, "");
1696                 xco+= xmax;
1697                 
1698                 if (G.saction->mode == SACTCONT_GPENCIL) {
1699                         xmax= GetButStringLength("Frame");
1700                         uiDefPulldownBut(block, action_framemenu, NULL, 
1701                                                   "Frame", xco, -2, xmax-3, 24, "");
1702                         xco+= xmax;
1703
1704                 }
1705                 else {
1706                         xmax= GetButStringLength("Key");
1707                         uiDefPulldownBut(block, action_keymenu, NULL, 
1708                                                   "Key", xco, -2, xmax-3, 24, "");
1709                         xco+= xmax;
1710                 }
1711         }
1712
1713         uiBlockSetEmboss(block, UI_EMBOSS);
1714         
1715         /* MODE SELECTOR */
1716         uiDefButC(block, MENU, B_REDR, 
1717                         "Editor Mode %t|Action Editor %x0|ShapeKey Editor %x1|Grease Pencil %x2", 
1718                         xco,0,90,YIC, &(G.saction->mode), 0, 1, 0, 0, 
1719                         "Editing modes for this editor");
1720
1721         
1722         xco += (90 + 8);
1723         
1724         /* MODE-DEPENDENT DRAWING */
1725         if (G.saction->mode == SACTCONT_GPENCIL) {
1726                 char gp_name[64];
1727                 
1728                 /* pin button */
1729                 uiDefIconButS(block, ICONTOG, B_ACTPIN, ICON_PIN_DEHLT, xco,0,XIC,YIC, &G.saction->pin, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what Grease Pencil set is active");
1730                 xco += (XIC + 5);
1731                 
1732                 /* just a simple string to help identify if any content */
1733                 glRasterPos2f((float)xco, 5.0);
1734                 BIF_RasterPos((float)xco, 5.0); // stupid texture fonts
1735                 BIF_ThemeColor(TH_TEXT);
1736                 
1737                 sprintf(gp_name, (G.saction->gpd)?"Grease Pencil Data":"<None>");
1738                 xmax= GetButStringLength(gp_name);
1739                 BIF_DrawString(uiBlockGetCurFont(block), gp_name, (U.transopts & USER_TR_BUTTONS));
1740                 xco += xmax;
1741         }
1742         else {
1743                 /* NAME ETC */
1744                 ob= OBACT;
1745                 from = (ID *)ob;
1746                 
1747                 xco= std_libbuttons(block, xco, 0, B_ACTPIN, &G.saction->pin, 
1748                                                         B_ACTIONBROWSE, ID_AC, 0, (ID*)G.saction->action, 
1749                                                         from, &(G.saction->actnr), B_ACTALONE, 
1750                                                         B_ACTLOCAL, B_ACTIONDELETE, 0, B_KEEPDATA);     
1751                 
1752                 uiClearButLock();
1753                 
1754                 xco += 8;
1755                 
1756                 /* COPY PASTE */
1757                 uiBlockBeginAlign(block);
1758                 if (curarea->headertype==HEADERTOP) {
1759                         uiDefIconBut(block, BUT, B_ACTCOPYKEYS, ICON_COPYUP,    xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected keyframes from the selected channel(s) to the buffer");
1760                         uiDefIconBut(block, BUT, B_ACTPASTEKEYS, ICON_PASTEUP,  xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the keyframes from the buffer");
1761                 }
1762                 else {
1763                         uiDefIconBut(block, BUT, B_ACTCOPYKEYS, ICON_COPYDOWN,  xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected keyframes from the selected channel(s) to the buffer");
1764                         uiDefIconBut(block, BUT, B_ACTPASTEKEYS, ICON_PASTEDOWN,        xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the keyframes from the buffer");
1765                 }
1766                 uiBlockEndAlign(block);
1767                 xco += (XIC + 8);
1768                 
1769                 /* draw AUTOSNAP */
1770                 if (G.saction->flag & SACTION_DRAWTIME) {
1771                         uiDefButC(block, MENU, B_REDR,
1772                                         "Auto-Snap Keyframes %t|No Snap %x0|Second Step %x1|Nearest Second %x2|Nearest Marker %x3", 
1773                                         xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, 
1774                                         "Auto-snapping mode for keyframes when transforming");
1775                 }
1776                 else {
1777                         uiDefButC(block, MENU, B_REDR, 
1778                                         "Auto-Snap Keyframes %t|No Snap %x0|Frame Step %x1|Nearest Frame %x2|Nearest Marker %x3", 
1779                                         xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, 
1780                                         "Auto-snapping mode for keyframes when transforming");
1781                 }
1782                 
1783                 xco += (70 + 8);
1784         }
1785         
1786         /* draw LOCK */
1787         uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco, 0, XIC, YIC, 
1788                                   &(G.saction->lock), 0, 0, 0, 0, 
1789                                   "Updates other affected window spaces automatically "
1790                                   "to reflect changes in real time");
1791         
1792         /* always as last  */
1793         curarea->headbutlen = xco + 2*XIC;
1794
1795         uiDrawBlock(block);
1796 }