1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup edanimation
22 */
23
24 #include <stdio.h>
25
26 #include "MEM_guardedalloc.h"
27
28 #include "BLI_blenlib.h"
29 #include "BLI_math.h"
30 #include "BLI_utildefines.h"
31
32 #include "BLT_translation.h"
33
34 #include "DNA_anim_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_cachefile_types.h"
37 #include "DNA_camera_types.h"
38 #include "DNA_gpencil_types.h"
39 #include "DNA_hair_types.h"
40 #include "DNA_key_types.h"
41 #include "DNA_lattice_types.h"
42 #include "DNA_light_types.h"
43 #include "DNA_linestyle_types.h"
44 #include "DNA_mask_types.h"
45 #include "DNA_material_types.h"
46 #include "DNA_mesh_types.h"
47 #include "DNA_meta_types.h"
48 #include "DNA_node_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_particle_types.h"
51 #include "DNA_pointcloud_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_screen_types.h"
54 #include "DNA_simulation_types.h"
55 #include "DNA_space_types.h"
56 #include "DNA_speaker_types.h"
57 #include "DNA_volume_types.h"
58 #include "DNA_world_types.h"
59
60 #include "RNA_access.h"
61
62 #include "BKE_anim_data.h"
63 #include "BKE_animsys.h"
64 #include "BKE_context.h"
65 #include "BKE_curve.h"
66 #include "BKE_gpencil.h"
67 #include "BKE_key.h"
68 #include "BKE_main.h"
69 #include "BKE_nla.h"
70
71 #include "GPU_immediate.h"
72 #include "GPU_state.h"
73
74 #include "DEG_depsgraph.h"
75
76 #include "UI_interface.h"
77 #include "UI_interface_icons.h"
78 #include "UI_resources.h"
79 #include "UI_view2d.h"
80
81 #include "ED_anim_api.h"
82 #include "ED_keyframing.h"
83
84 #include "WM_api.h"
85 #include "WM_types.h"
86
87 /* *********************************************** */
88 /* XXX constant defines to be moved elsewhere? */
89
90 /* extra padding for lengths (to go under scrollers) */
91 #define EXTRA_SCROLL_PAD 100.0f
92
93 /* size of indent steps */
94 #define INDENT_STEP_SIZE (0.35f * U.widget_unit)
95
96 /* size of string buffers used for animation channel displayed names */
97 #define ANIM_CHAN_NAME_SIZE 256
98
99 /* get the pointer used for some flag */
100 #define GET_ACF_FLAG_PTR(ptr, type) ((*(type) = sizeof((ptr))), &(ptr))
101
102 /* *********************************************** */
103 /* Generic Functions (Type independent) */
104
105 /* Draw Backdrop ---------------------------------- */
106
107 /* get backdrop color for top-level widgets (Scene and Object only) */
acf_generic_root_color(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),float r_color[3])108 static void acf_generic_root_color(bAnimContext *UNUSED(ac),
109 bAnimListElem *UNUSED(ale),
110 float r_color[3])
111 {
112 /* darker blue for top-level widgets */
113 UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELOB, r_color);
114 }
115
116 /* backdrop for top-level widgets (Scene and Object only) */
acf_generic_root_backdrop(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc)117 static void acf_generic_root_backdrop(bAnimContext *ac,
118 bAnimListElem *ale,
119 float yminc,
120 float ymaxc)
121 {
122 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
123 View2D *v2d = &ac->region->v2d;
124 short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
125 short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
126 float color[3];
127
128 /* set backdrop drawing color */
129 acf->get_backdrop_color(ac, ale, color);
130
131 /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
132 UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT :
133 (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
134 UI_draw_roundbox_3fv_alpha(
135 true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
136 }
137
138 /* get backdrop color for data expanders under top-level Scene/Object */
acf_generic_dataexpand_color(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),float r_color[3])139 static void acf_generic_dataexpand_color(bAnimContext *UNUSED(ac),
140 bAnimListElem *UNUSED(ale),
141 float r_color[3])
142 {
143 /* lighter color than top-level widget */
144 UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELSUBOB, r_color);
145 }
146
147 /* backdrop for data expanders under top-level Scene/Object */
acf_generic_dataexpand_backdrop(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc)148 static void acf_generic_dataexpand_backdrop(bAnimContext *ac,
149 bAnimListElem *ale,
150 float yminc,
151 float ymaxc)
152 {
153 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
154 View2D *v2d = &ac->region->v2d;
155 short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
156 float color[3];
157
158 uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
159
160 /* set backdrop drawing color */
161 acf->get_backdrop_color(ac, ale, color);
162
163 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
164 immUniformColor3fv(color);
165
166 /* no rounded corner - just rectangular box */
167 immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
168
169 immUnbindProgram();
170 }
171
172 /* helper method to test if group colors should be drawn */
acf_show_channel_colors(bAnimContext * ac)173 static bool acf_show_channel_colors(bAnimContext *ac)
174 {
175 bool showGroupColors = false;
176
177 if (ac->sl) {
178 switch (ac->spacetype) {
179 case SPACE_ACTION: {
180 SpaceAction *saction = (SpaceAction *)ac->sl;
181 showGroupColors = !(saction->flag & SACTION_NODRAWGCOLORS);
182
183 break;
184 }
185 case SPACE_GRAPH: {
186 SpaceGraph *sipo = (SpaceGraph *)ac->sl;
187 showGroupColors = !(sipo->flag & SIPO_NODRAWGCOLORS);
188
189 break;
190 }
191 }
192 }
193
194 return showGroupColors;
195 }
196
197 /* get backdrop color for generic channels */
acf_generic_channel_color(bAnimContext * ac,bAnimListElem * ale,float r_color[3])198 static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3])
199 {
200 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
201 bActionGroup *grp = NULL;
202 short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
203 bool showGroupColors = acf_show_channel_colors(ac);
204
205 if (ale->type == ANIMTYPE_FCURVE) {
206 FCurve *fcu = (FCurve *)ale->data;
207 grp = fcu->grp;
208 }
209
210 /* set color for normal channels
211 * - use 3 shades of color group/standard color for 3 indention level
212 * - only use group colors if allowed to, and if actually feasible
213 */
214 if (showGroupColors && (grp) && (grp->customCol)) {
215 uchar cp[3];
216
217 if (indent == 2) {
218 copy_v3_v3_uchar(cp, grp->cs.solid);
219 }
220 else if (indent == 1) {
221 copy_v3_v3_uchar(cp, grp->cs.select);
222 }
223 else {
224 copy_v3_v3_uchar(cp, grp->cs.active);
225 }
226
227 /* copy the colors over, transforming from bytes to floats */
228 rgb_uchar_to_float(r_color, cp);
229 }
230 else {
231 /* FIXME: what happens when the indention is 1 greater than what it should be
232 * (due to grouping)? */
233 int colOfs = 10 - 10 * indent;
234 UI_GetThemeColorShade3fv(TH_SHADE2, colOfs, r_color);
235 }
236 }
237
238 /* get backdrop color for grease pencil channels */
acf_gpencil_channel_color(bAnimContext * ac,bAnimListElem * ale,float r_color[3])239 static void acf_gpencil_channel_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3])
240 {
241 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
242 short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
243 bool showGroupColors = acf_show_channel_colors(ac);
244
245 if ((showGroupColors) && (ale->type == ANIMTYPE_GPLAYER)) {
246 bGPDlayer *gpl = (bGPDlayer *)ale->data;
247 copy_v3_v3(r_color, gpl->color);
248 }
249 else {
250 int colOfs = 10 - 10 * indent;
251 UI_GetThemeColorShade3fv(TH_SHADE2, colOfs, r_color);
252 }
253 }
254
255 /* backdrop for generic channels */
acf_generic_channel_backdrop(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc)256 static void acf_generic_channel_backdrop(bAnimContext *ac,
257 bAnimListElem *ale,
258 float yminc,
259 float ymaxc)
260 {
261 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
262 View2D *v2d = &ac->region->v2d;
263 short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
264 float color[3];
265
266 uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
267
268 /* set backdrop drawing color */
269 acf->get_backdrop_color(ac, ale, color);
270
271 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
272 immUniformColor3fv(color);
273
274 /* no rounded corners - just rectangular box */
275 immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
276
277 immUnbindProgram();
278 }
279
280 /* Indention + Offset ------------------------------------------- */
281
282 /* indention level is always the value in the name */
acf_generic_indention_0(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale))283 static short acf_generic_indention_0(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
284 {
285 return 0;
286 }
acf_generic_indention_1(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale))287 static short acf_generic_indention_1(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
288 {
289 return 1;
290 }
291 #if 0 /* XXX not used */
292 static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale)
293 {
294 return 2;
295 }
296 #endif
297
298 /* indention which varies with the grouping status */
acf_generic_indention_flexible(bAnimContext * UNUSED (ac),bAnimListElem * ale)299 static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListElem *ale)
300 {
301 short indent = 0;
302
303 /* grouped F-Curves need extra level of indention */
304 if (ale->type == ANIMTYPE_FCURVE) {
305 FCurve *fcu = (FCurve *)ale->data;
306
307 /* TODO: we need some way of specifying that the indention color should be one less. */
308 if (fcu->grp) {
309 indent++;
310 }
311 }
312
313 /* no indention */
314 return indent;
315 }
316
317 /* basic offset for channels derived from indention */
acf_generic_basic_offset(bAnimContext * ac,bAnimListElem * ale)318 static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
319 {
320 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
321
322 if (acf && acf->get_indent_level) {
323 return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
324 }
325 return 0;
326 }
327
328 /* offset based on nodetree type */
acf_nodetree_rootType_offset(bNodeTree * ntree)329 static short acf_nodetree_rootType_offset(bNodeTree *ntree)
330 {
331 if (ntree) {
332 switch (ntree->type) {
333 case NTREE_SHADER:
334 /* 1 additional level (i.e. is indented one level in from material,
335 * so shift all right by one step)
336 */
337 return INDENT_STEP_SIZE;
338
339 case NTREE_COMPOSIT:
340 /* no additional levels needed */
341 return 0;
342
343 case NTREE_TEXTURE:
344 /* 2 additional levels */
345 return INDENT_STEP_SIZE * 2;
346 }
347 }
348
349 /* unknown */
350 return 0;
351 }
352
353 /* offset for groups + grouped entities */
acf_generic_group_offset(bAnimContext * ac,bAnimListElem * ale)354 static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
355 {
356 short offset = acf_generic_basic_offset(ac, ale);
357
358 if (ale->id) {
359 /* texture animdata */
360 if (GS(ale->id->name) == ID_TE) {
361 offset += U.widget_unit;
362 }
363 /* materials and particles animdata */
364 else if (ELEM(GS(ale->id->name), ID_MA, ID_PA)) {
365 offset += (short)(0.7f * U.widget_unit);
366
367 /* If not in Action Editor mode, action-groups (and their children)
368 * must carry some offset too. */
369 }
370 else if (ac->datatype != ANIMCONT_ACTION) {
371 offset += (short)(0.7f * U.widget_unit);
372 }
373
374 /* nodetree animdata */
375 if (GS(ale->id->name) == ID_NT) {
376 offset += acf_nodetree_rootType_offset((bNodeTree *)ale->id);
377 }
378 }
379
380 /* offset is just the normal type - i.e. based on indention */
381 return offset;
382 }
383
384 /* Name ------------------------------------------- */
385
386 /* name for ID block entries */
acf_generic_idblock_name(bAnimListElem * ale,char * name)387 static void acf_generic_idblock_name(bAnimListElem *ale, char *name)
388 {
389 ID *id = (ID *)ale->data; /* data pointed to should be an ID block */
390
391 /* just copy the name... */
392 if (id && name) {
393 BLI_strncpy(name, id->name + 2, ANIM_CHAN_NAME_SIZE);
394 }
395 }
396
397 /* name property for ID block entries */
acf_generic_idblock_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)398 static bool acf_generic_idblock_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
399 {
400 RNA_id_pointer_create(ale->data, ptr);
401 *prop = RNA_struct_name_property(ptr->type);
402
403 return (*prop != NULL);
404 }
405
406 /* name property for ID block entries which are just subheading "fillers" */
acf_generic_idfill_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)407 static bool acf_generic_idfill_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
408 {
409 /* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */
410 RNA_id_pointer_create(ale->data, ptr);
411 *prop = RNA_struct_name_property(ptr->type);
412
413 return (*prop != NULL);
414 }
415
416 /* Settings ------------------------------------------- */
417
418 #if 0
419 /* channel type has no settings */
420 static bool acf_generic_none_setting_valid(bAnimContext *ac,
421 bAnimListElem *ale,
422 eAnimChannel_Settings setting)
423 {
424 return false;
425 }
426 #endif
427
428 /* check if some setting exists for this object-based data-expander (datablock only) */
acf_generic_dataexpand_setting_valid(bAnimContext * ac,bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)429 static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac,
430 bAnimListElem *UNUSED(ale),
431 eAnimChannel_Settings setting)
432 {
433 switch (setting) {
434 /* expand is always supported */
435 case ACHANNEL_SETTING_EXPAND:
436 return true;
437
438 /* mute is only supported for NLA */
439 case ACHANNEL_SETTING_MUTE:
440 return ((ac) && (ac->spacetype == SPACE_NLA));
441
442 /* select is ok for most "ds*" channels (e.g. dsmat) */
443 case ACHANNEL_SETTING_SELECT:
444 return true;
445
446 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
447 return true;
448
449 /* other flags are never supported */
450 default:
451 return false;
452 }
453 }
454
455 /* *********************************************** */
456 /* Type Specific Functions + Defines */
457
458 /* Animation Summary ----------------------------------- */
459
460 /* get backdrop color for summary widget */
acf_summary_color(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),float r_color[3])461 static void acf_summary_color(bAnimContext *UNUSED(ac),
462 bAnimListElem *UNUSED(ale),
463 float r_color[3])
464 {
465 /* reddish color - same as the 'action' line in NLA */
466 UI_GetThemeColor3fv(TH_ANIM_ACTIVE, r_color);
467 }
468
469 /* backdrop for summary widget */
acf_summary_backdrop(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc)470 static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
471 {
472 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
473 View2D *v2d = &ac->region->v2d;
474 float color[3];
475
476 /* set backdrop drawing color */
477 acf->get_backdrop_color(ac, ale, color);
478
479 /* rounded corners on LHS only
480 * - top and bottom
481 * - special hack: make the top a bit higher, since we are first...
482 */
483 UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
484 UI_draw_roundbox_3fv_alpha(
485 true, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
486 }
487
488 /* name for summary entries */
acf_summary_name(bAnimListElem * UNUSED (ale),char * name)489 static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
490 {
491 if (name) {
492 BLI_strncpy(name, IFACE_("Summary"), ANIM_CHAN_NAME_SIZE);
493 }
494 }
495
496 /* check if some setting exists for this channel */
acf_summary_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)497 static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac),
498 bAnimListElem *UNUSED(ale),
499 eAnimChannel_Settings setting)
500 {
501 /* only expanded is supported, as it is used for hiding all stuff which the summary covers */
502 return (setting == ACHANNEL_SETTING_EXPAND);
503 }
504
505 /* get the appropriate flag(s) for the setting when it is valid */
acf_summary_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)506 static int acf_summary_setting_flag(bAnimContext *UNUSED(ac),
507 eAnimChannel_Settings setting,
508 bool *neg)
509 {
510 if (setting == ACHANNEL_SETTING_EXPAND) {
511 /* expanded */
512 *neg = true;
513 return ADS_FLAG_SUMMARY_COLLAPSED;
514 }
515
516 /* unsupported */
517 *neg = false;
518 return 0;
519 }
520
521 /* get pointer to the setting */
acf_summary_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)522 static void *acf_summary_setting_ptr(bAnimListElem *ale,
523 eAnimChannel_Settings setting,
524 short *type)
525 {
526 bAnimContext *ac = (bAnimContext *)ale->data;
527
528 /* if data is valid, return pointer to active dopesheet's relevant flag
529 * - this is restricted to DopeSheet/Action Editor only
530 */
531 if ((ac->sl) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) {
532 SpaceAction *saction = (SpaceAction *)ac->sl;
533 bDopeSheet *ads = &saction->ads;
534
535 /* return pointer to DopeSheet's flag */
536 return GET_ACF_FLAG_PTR(ads->flag, type);
537 }
538
539 /* can't return anything useful - unsupported */
540 *type = 0;
541 return NULL;
542 }
543
544 /* all animation summary (DopeSheet only) type define */
545 static bAnimChannelType ACF_SUMMARY = {
546 "Summary", /* type name */
547 ACHANNEL_ROLE_EXPANDER, /* role */
548
549 acf_summary_color, /* backdrop color */
550 acf_summary_backdrop, /* backdrop */
551 acf_generic_indention_0, /* indent level */
552 NULL, /* offset */
553
554 acf_summary_name, /* name */
555 NULL, /* name prop */
556 NULL, /* icon */
557
558 acf_summary_setting_valid, /* has setting */
559 acf_summary_setting_flag, /* flag for setting */
560 acf_summary_setting_ptr, /* pointer for setting */
561 };
562
563 /* Scene ------------------------------------------- */
564
565 /* TODO: just get this from RNA? */
acf_scene_icon(bAnimListElem * UNUSED (ale))566 static int acf_scene_icon(bAnimListElem *UNUSED(ale))
567 {
568 return ICON_SCENE_DATA;
569 }
570
571 /* check if some setting exists for this channel */
acf_scene_setting_valid(bAnimContext * ac,bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)572 static bool acf_scene_setting_valid(bAnimContext *ac,
573 bAnimListElem *UNUSED(ale),
574 eAnimChannel_Settings setting)
575 {
576 switch (setting) {
577 /* muted only in NLA */
578 case ACHANNEL_SETTING_MUTE:
579 return ((ac) && (ac->spacetype == SPACE_NLA));
580
581 /* visible only in Graph Editor */
582 case ACHANNEL_SETTING_VISIBLE:
583 return ((ac) && (ac->spacetype == SPACE_GRAPH));
584
585 /* only select and expand supported otherwise */
586 case ACHANNEL_SETTING_SELECT:
587 case ACHANNEL_SETTING_EXPAND:
588 return true;
589
590 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
591 return false;
592
593 default:
594 return false;
595 }
596 }
597
598 /* get the appropriate flag(s) for the setting when it is valid */
acf_scene_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)599 static int acf_scene_setting_flag(bAnimContext *UNUSED(ac),
600 eAnimChannel_Settings setting,
601 bool *neg)
602 {
603 /* clear extra return data first */
604 *neg = false;
605
606 switch (setting) {
607 case ACHANNEL_SETTING_SELECT: /* selected */
608 return SCE_DS_SELECTED;
609
610 case ACHANNEL_SETTING_EXPAND: /* expanded */
611 *neg = true;
612 return SCE_DS_COLLAPSED;
613
614 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
615 return ADT_NLA_EVAL_OFF;
616
617 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
618 *neg = true;
619 return ADT_CURVES_NOT_VISIBLE;
620
621 default: /* unsupported */
622 return 0;
623 }
624 }
625
626 /* get pointer to the setting */
acf_scene_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)627 static void *acf_scene_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
628 {
629 Scene *scene = (Scene *)ale->data;
630
631 /* clear extra return data first */
632 *type = 0;
633
634 switch (setting) {
635 case ACHANNEL_SETTING_SELECT: /* selected */
636 return GET_ACF_FLAG_PTR(scene->flag, type);
637
638 case ACHANNEL_SETTING_EXPAND: /* expanded */
639 return GET_ACF_FLAG_PTR(scene->flag, type);
640
641 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
642 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
643 if (scene->adt) {
644 return GET_ACF_FLAG_PTR(scene->adt->flag, type);
645 }
646 return NULL;
647
648 default: /* unsupported */
649 return NULL;
650 }
651 }
652
653 /* scene type define */
654 static bAnimChannelType ACF_SCENE = {
655 "Scene", /* type name */
656 ACHANNEL_ROLE_EXPANDER, /* role */
657
658 acf_generic_root_color, /* backdrop color */
659 acf_generic_root_backdrop, /* backdrop */
660 acf_generic_indention_0, /* indent level */
661 NULL, /* offset */
662
663 acf_generic_idblock_name, /* name */
664 acf_generic_idblock_name_prop, /* name prop */
665 acf_scene_icon, /* icon */
666
667 acf_scene_setting_valid, /* has setting */
668 acf_scene_setting_flag, /* flag for setting */
669 acf_scene_setting_ptr, /* pointer for setting */
670 };
671
672 /* Object ------------------------------------------- */
673
acf_object_icon(bAnimListElem * ale)674 static int acf_object_icon(bAnimListElem *ale)
675 {
676 Base *base = (Base *)ale->data;
677 Object *ob = base->object;
678
679 /* icon depends on object-type */
680 switch (ob->type) {
681 case OB_LAMP:
682 return ICON_OUTLINER_OB_LIGHT;
683 case OB_MESH:
684 return ICON_OUTLINER_OB_MESH;
685 case OB_CAMERA:
686 return ICON_OUTLINER_OB_CAMERA;
687 case OB_CURVE:
688 return ICON_OUTLINER_OB_CURVE;
689 case OB_MBALL:
690 return ICON_OUTLINER_OB_META;
691 case OB_LATTICE:
692 return ICON_OUTLINER_OB_LATTICE;
693 case OB_SPEAKER:
694 return ICON_OUTLINER_OB_SPEAKER;
695 case OB_LIGHTPROBE:
696 return ICON_OUTLINER_OB_LIGHTPROBE;
697 case OB_ARMATURE:
698 return ICON_OUTLINER_OB_ARMATURE;
699 case OB_FONT:
700 return ICON_OUTLINER_OB_FONT;
701 case OB_SURF:
702 return ICON_OUTLINER_OB_SURFACE;
703 case OB_HAIR:
704 return ICON_OUTLINER_OB_HAIR;
705 case OB_POINTCLOUD:
706 return ICON_OUTLINER_OB_POINTCLOUD;
707 case OB_VOLUME:
708 return ICON_OUTLINER_OB_VOLUME;
709 case OB_EMPTY:
710 return ICON_OUTLINER_OB_EMPTY;
711 case OB_GPENCIL:
712 return ICON_OUTLINER_OB_GREASEPENCIL;
713 default:
714 return ICON_OBJECT_DATA;
715 }
716 }
717
718 /* name for object */
acf_object_name(bAnimListElem * ale,char * name)719 static void acf_object_name(bAnimListElem *ale, char *name)
720 {
721 Base *base = (Base *)ale->data;
722 Object *ob = base->object;
723
724 /* just copy the name... */
725 if (ob && name) {
726 BLI_strncpy(name, ob->id.name + 2, ANIM_CHAN_NAME_SIZE);
727 }
728 }
729
730 /* name property for object */
acf_object_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)731 static bool acf_object_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
732 {
733 RNA_id_pointer_create(ale->id, ptr);
734 *prop = RNA_struct_name_property(ptr->type);
735
736 return (*prop != NULL);
737 }
738
739 /* check if some setting exists for this channel */
acf_object_setting_valid(bAnimContext * ac,bAnimListElem * ale,eAnimChannel_Settings setting)740 static bool acf_object_setting_valid(bAnimContext *ac,
741 bAnimListElem *ale,
742 eAnimChannel_Settings setting)
743 {
744 Base *base = (Base *)ale->data;
745 Object *ob = base->object;
746
747 switch (setting) {
748 /* muted only in NLA */
749 case ACHANNEL_SETTING_MUTE:
750 return ((ac) && (ac->spacetype == SPACE_NLA));
751
752 /* visible only in Graph Editor */
753 case ACHANNEL_SETTING_VISIBLE:
754 return ((ac) && (ac->spacetype == SPACE_GRAPH) && (ob->adt));
755
756 /* only select and expand supported otherwise */
757 case ACHANNEL_SETTING_SELECT:
758 case ACHANNEL_SETTING_EXPAND:
759 return true;
760
761 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
762 return ((ac) && (ac->spacetype == SPACE_GRAPH) && (ob->adt));
763
764 default:
765 return false;
766 }
767 }
768
769 /* get the appropriate flag(s) for the setting when it is valid */
acf_object_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)770 static int acf_object_setting_flag(bAnimContext *UNUSED(ac),
771 eAnimChannel_Settings setting,
772 bool *neg)
773 {
774 /* clear extra return data first */
775 *neg = false;
776
777 switch (setting) {
778 case ACHANNEL_SETTING_SELECT: /* selected */
779 return BASE_SELECTED;
780
781 case ACHANNEL_SETTING_EXPAND: /* expanded */
782 *neg = 1;
783 return OB_ADS_COLLAPSED;
784
785 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
786 return ADT_NLA_EVAL_OFF;
787
788 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
789 *neg = true;
790 return ADT_CURVES_NOT_VISIBLE;
791
792 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
793 return ADT_CURVES_ALWAYS_VISIBLE;
794
795 default: /* unsupported */
796 return 0;
797 }
798 }
799
800 /* get pointer to the setting */
acf_object_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)801 static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
802 {
803 Base *base = (Base *)ale->data;
804 Object *ob = base->object;
805
806 /* clear extra return data first */
807 *type = 0;
808
809 switch (setting) {
810 case ACHANNEL_SETTING_SELECT: /* selected */
811 return GET_ACF_FLAG_PTR(base->flag, type);
812
813 case ACHANNEL_SETTING_EXPAND: /* expanded */
814 return GET_ACF_FLAG_PTR(ob->nlaflag, type); /* XXX */
815
816 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
817 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
818 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
819 if (ob->adt) {
820 return GET_ACF_FLAG_PTR(ob->adt->flag, type);
821 }
822 return NULL;
823
824 default: /* unsupported */
825 return NULL;
826 }
827 }
828
829 /* object type define */
830 static bAnimChannelType ACF_OBJECT = {
831 "Object", /* type name */
832 ACHANNEL_ROLE_EXPANDER, /* role */
833
834 acf_generic_root_color, /* backdrop color */
835 acf_generic_root_backdrop, /* backdrop */
836 acf_generic_indention_0, /* indent level */
837 NULL, /* offset */
838
839 acf_object_name, /* name */
840 acf_object_name_prop, /* name prop */
841 acf_object_icon, /* icon */
842
843 acf_object_setting_valid, /* has setting */
844 acf_object_setting_flag, /* flag for setting */
845 acf_object_setting_ptr, /* pointer for setting */
846 };
847
848 /* Group ------------------------------------------- */
849
850 /* get backdrop color for group widget */
acf_group_color(bAnimContext * ac,bAnimListElem * ale,float r_color[3])851 static void acf_group_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3])
852 {
853 bActionGroup *agrp = (bActionGroup *)ale->data;
854 bool showGroupColors = acf_show_channel_colors(ac);
855
856 if (showGroupColors && agrp->customCol) {
857 uchar cp[3];
858
859 /* highlight only for active */
860 if (ale->flag & AGRP_ACTIVE) {
861 copy_v3_v3_uchar(cp, agrp->cs.select);
862 }
863 else {
864 copy_v3_v3_uchar(cp, agrp->cs.solid);
865 }
866
867 /* copy the colors over, transforming from bytes to floats */
868 rgb_uchar_to_float(r_color, cp);
869 }
870 else {
871 /* highlight only for active */
872 if (ale->flag & AGRP_ACTIVE) {
873 UI_GetThemeColor3fv(TH_GROUP_ACTIVE, r_color);
874 }
875 else {
876 UI_GetThemeColor3fv(TH_GROUP, r_color);
877 }
878 }
879 }
880
881 /* backdrop for group widget */
acf_group_backdrop(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc)882 static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
883 {
884 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
885 View2D *v2d = &ac->region->v2d;
886 short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
887 short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
888 float color[3];
889
890 /* set backdrop drawing color */
891 acf->get_backdrop_color(ac, ale, color);
892
893 /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
894 UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
895 UI_draw_roundbox_3fv_alpha(
896 true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
897 }
898
899 /* name for group entries */
acf_group_name(bAnimListElem * ale,char * name)900 static void acf_group_name(bAnimListElem *ale, char *name)
901 {
902 bActionGroup *agrp = (bActionGroup *)ale->data;
903
904 /* just copy the name... */
905 if (agrp && name) {
906 BLI_strncpy(name, agrp->name, ANIM_CHAN_NAME_SIZE);
907 }
908 }
909
910 /* name property for group entries */
acf_group_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)911 static bool acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
912 {
913 RNA_pointer_create(ale->id, &RNA_ActionGroup, ale->data, ptr);
914 *prop = RNA_struct_name_property(ptr->type);
915
916 return (*prop != NULL);
917 }
918
919 /* check if some setting exists for this channel */
acf_group_setting_valid(bAnimContext * ac,bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)920 static bool acf_group_setting_valid(bAnimContext *ac,
921 bAnimListElem *UNUSED(ale),
922 eAnimChannel_Settings setting)
923 {
924 /* for now, all settings are supported, though some are only conditionally */
925 switch (setting) {
926 /* unsupported */
927 case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */
928 case ACHANNEL_SETTING_PINNED: /* Only for NLA actions */
929 return false;
930
931 /* conditionally supported */
932 case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
933 return (ac->spacetype == SPACE_GRAPH);
934
935 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
936 return (ac->spacetype == SPACE_GRAPH);
937
938 default: /* always supported */
939 return true;
940 }
941 }
942
943 /* get the appropriate flag(s) for the setting when it is valid */
acf_group_setting_flag(bAnimContext * ac,eAnimChannel_Settings setting,bool * neg)944 static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg)
945 {
946 /* clear extra return data first */
947 *neg = false;
948
949 switch (setting) {
950 case ACHANNEL_SETTING_SELECT: /* selected */
951 return AGRP_SELECTED;
952
953 case ACHANNEL_SETTING_EXPAND: /* expanded */
954 {
955 /* NOTE: Graph Editor uses a different flag to everywhere else for this,
956 * allowing different collapsing of groups there, since sharing the flag
957 * proved to be a hazard for workflows...
958 */
959 return (ac->spacetype == SPACE_GRAPH) ? AGRP_EXPANDED_G : /* Graph Editor case */
960 AGRP_EXPANDED; /* DopeSheet and elsewhere */
961 }
962
963 case ACHANNEL_SETTING_MUTE: /* muted */
964 return AGRP_MUTED;
965
966 case ACHANNEL_SETTING_MOD_OFF: /* muted */
967 *neg = 1;
968 return AGRP_MODIFIERS_OFF;
969
970 case ACHANNEL_SETTING_PROTECT: /* protected */
971 return AGRP_PROTECTED;
972
973 case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
974 *neg = 1;
975 return AGRP_NOTVISIBLE;
976
977 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
978 return ADT_CURVES_ALWAYS_VISIBLE;
979
980 default:
981 /* this shouldn't happen */
982 return 0;
983 }
984 }
985
986 /* get pointer to the setting */
acf_group_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)987 static void *acf_group_setting_ptr(bAnimListElem *ale,
988 eAnimChannel_Settings UNUSED(setting),
989 short *type)
990 {
991 bActionGroup *agrp = (bActionGroup *)ale->data;
992
993 /* all flags are just in agrp->flag for now... */
994 return GET_ACF_FLAG_PTR(agrp->flag, type);
995 }
996
997 /* group type define */
998 static bAnimChannelType ACF_GROUP = {
999 "Group", /* type name */
1000 ACHANNEL_ROLE_CHANNEL, /* role */
1001
1002 acf_group_color, /* backdrop color */
1003 acf_group_backdrop, /* backdrop */
1004 acf_generic_indention_0, /* indent level */
1005 acf_generic_group_offset, /* offset */
1006
1007 acf_group_name, /* name */
1008 acf_group_name_prop, /* name prop */
1009 NULL, /* icon */
1010
1011 acf_group_setting_valid, /* has setting */
1012 acf_group_setting_flag, /* flag for setting */
1013 acf_group_setting_ptr, /* pointer for setting */
1014 };
1015
1016 /* F-Curve ------------------------------------------- */
1017
1018 /* name for fcurve entries */
acf_fcurve_name(bAnimListElem * ale,char * name)1019 static void acf_fcurve_name(bAnimListElem *ale, char *name)
1020 {
1021 getname_anim_fcurve(name, ale->id, ale->data);
1022 }
1023
1024 /* "name" property for fcurve entries */
acf_fcurve_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)1025 static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
1026 {
1027 FCurve *fcu = (FCurve *)ale->data;
1028
1029 /* Ctrl-Click Usability Convenience Hack:
1030 * For disabled F-Curves, allow access to the RNA Path
1031 * as our "name" so that user can perform quick fixes
1032 */
1033 if (fcu->flag & FCURVE_DISABLED) {
1034 RNA_pointer_create(ale->id, &RNA_FCurve, ale->data, ptr);
1035 *prop = RNA_struct_find_property(ptr, "data_path");
1036 }
1037 else {
1038 /* for "normal" F-Curves - no editable name, but *prop may not be set properly yet... */
1039 *prop = NULL;
1040 }
1041
1042 return (*prop != NULL);
1043 }
1044
1045 /* check if some setting exists for this channel */
acf_fcurve_setting_valid(bAnimContext * ac,bAnimListElem * ale,eAnimChannel_Settings setting)1046 static bool acf_fcurve_setting_valid(bAnimContext *ac,
1047 bAnimListElem *ale,
1048 eAnimChannel_Settings setting)
1049 {
1050 FCurve *fcu = (FCurve *)ale->data;
1051
1052 switch (setting) {
1053 /* unsupported */
1054 case ACHANNEL_SETTING_SOLO: /* Solo Flag is only for NLA */
1055 case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */
1056 case ACHANNEL_SETTING_PINNED: /* This is only for NLA Actions */
1057 return false;
1058
1059 /* conditionally available */
1060 case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */
1061 if (fcu->bezt) {
1062 return true;
1063 }
1064 else {
1065 return false; /* NOTE: in this special case, we need to draw ICON_ZOOMOUT */
1066 }
1067
1068 case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
1069 return (ac->spacetype == SPACE_GRAPH);
1070
1071 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
1072 return false;
1073
1074 /* always available */
1075 default:
1076 return true;
1077 }
1078 }
1079
1080 /* get the appropriate flag(s) for the setting when it is valid */
acf_fcurve_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1081 static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac),
1082 eAnimChannel_Settings setting,
1083 bool *neg)
1084 {
1085 /* clear extra return data first */
1086 *neg = false;
1087
1088 switch (setting) {
1089 case ACHANNEL_SETTING_SELECT: /* selected */
1090 return FCURVE_SELECTED;
1091
1092 case ACHANNEL_SETTING_MUTE: /* muted */
1093 return FCURVE_MUTED;
1094
1095 case ACHANNEL_SETTING_PROTECT: /* protected */
1096 return FCURVE_PROTECTED;
1097
1098 case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
1099 return FCURVE_VISIBLE;
1100
1101 case ACHANNEL_SETTING_MOD_OFF:
1102 *neg = 1;
1103 return FCURVE_MOD_OFF;
1104
1105 default: /* unsupported */
1106 return 0;
1107 }
1108 }
1109
1110 /* get pointer to the setting */
acf_fcurve_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)1111 static void *acf_fcurve_setting_ptr(bAnimListElem *ale,
1112 eAnimChannel_Settings UNUSED(setting),
1113 short *type)
1114 {
1115 FCurve *fcu = (FCurve *)ale->data;
1116
1117 /* all flags are just in agrp->flag for now... */
1118 return GET_ACF_FLAG_PTR(fcu->flag, type);
1119 }
1120
1121 /* fcurve type define */
1122 static bAnimChannelType ACF_FCURVE = {
1123 "F-Curve", /* type name */
1124 ACHANNEL_ROLE_CHANNEL, /* role */
1125
1126 acf_generic_channel_color, /* backdrop color */
1127 acf_generic_channel_backdrop, /* backdrop */
1128 acf_generic_indention_flexible,
1129 /* indent level */ /* XXX rename this to f-curves only? */
1130 acf_generic_group_offset, /* offset */
1131
1132 acf_fcurve_name, /* name */
1133 acf_fcurve_name_prop, /* name prop */
1134 NULL, /* icon */
1135
1136 acf_fcurve_setting_valid, /* has setting */
1137 acf_fcurve_setting_flag, /* flag for setting */
1138 acf_fcurve_setting_ptr, /* pointer for setting */
1139 };
1140
1141 /* NLA Control FCurves Expander ----------------------- */
1142
1143 /* get backdrop color for nla controls widget */
acf_nla_controls_color(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),float r_color[3])1144 static void acf_nla_controls_color(bAnimContext *UNUSED(ac),
1145 bAnimListElem *UNUSED(ale),
1146 float r_color[3])
1147 {
1148 /* TODO: give this its own theme setting? */
1149 UI_GetThemeColorShade3fv(TH_GROUP, 55, r_color);
1150 }
1151
1152 /* backdrop for nla controls expander widget */
acf_nla_controls_backdrop(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc)1153 static void acf_nla_controls_backdrop(bAnimContext *ac,
1154 bAnimListElem *ale,
1155 float yminc,
1156 float ymaxc)
1157 {
1158 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
1159 View2D *v2d = &ac->region->v2d;
1160 short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
1161 short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
1162 float color[3];
1163
1164 /* set backdrop drawing color */
1165 acf->get_backdrop_color(ac, ale, color);
1166
1167 /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
1168 UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
1169 UI_draw_roundbox_3fv_alpha(
1170 true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5, color, 1.0f);
1171 }
1172
1173 /* name for nla controls expander entries */
acf_nla_controls_name(bAnimListElem * UNUSED (ale),char * name)1174 static void acf_nla_controls_name(bAnimListElem *UNUSED(ale), char *name)
1175 {
1176 BLI_strncpy(name, IFACE_("NLA Strip Controls"), ANIM_CHAN_NAME_SIZE);
1177 }
1178
1179 /* check if some setting exists for this channel */
acf_nla_controls_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)1180 static bool acf_nla_controls_setting_valid(bAnimContext *UNUSED(ac),
1181 bAnimListElem *UNUSED(ale),
1182 eAnimChannel_Settings setting)
1183 {
1184 /* for now, all settings are supported, though some are only conditionally */
1185 switch (setting) {
1186 /* supported */
1187 case ACHANNEL_SETTING_EXPAND:
1188 return true;
1189
1190 /* TODO: selected? */
1191
1192 default: /* unsupported */
1193 return false;
1194 }
1195 }
1196
1197 /* get the appropriate flag(s) for the setting when it is valid */
acf_nla_controls_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1198 static int acf_nla_controls_setting_flag(bAnimContext *UNUSED(ac),
1199 eAnimChannel_Settings setting,
1200 bool *neg)
1201 {
1202 /* clear extra return data first */
1203 *neg = false;
1204
1205 switch (setting) {
1206 case ACHANNEL_SETTING_EXPAND: /* expanded */
1207 *neg = true;
1208 return ADT_NLA_SKEYS_COLLAPSED;
1209
1210 default:
1211 /* this shouldn't happen */
1212 return 0;
1213 }
1214 }
1215
1216 /* get pointer to the setting */
acf_nla_controls_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)1217 static void *acf_nla_controls_setting_ptr(bAnimListElem *ale,
1218 eAnimChannel_Settings UNUSED(setting),
1219 short *type)
1220 {
1221 AnimData *adt = (AnimData *)ale->data;
1222
1223 /* all flags are just in adt->flag for now... */
1224 return GET_ACF_FLAG_PTR(adt->flag, type);
1225 }
1226
acf_nla_controls_icon(bAnimListElem * UNUSED (ale))1227 static int acf_nla_controls_icon(bAnimListElem *UNUSED(ale))
1228 {
1229 return ICON_NLA;
1230 }
1231
1232 /* NLA Control FCurves Expander type define */
1233 static bAnimChannelType ACF_NLACONTROLS = {
1234 "NLA Controls Expander", /* type name */
1235 ACHANNEL_ROLE_EXPANDER, /* role */
1236
1237 acf_nla_controls_color, /* backdrop color */
1238 acf_nla_controls_backdrop, /* backdrop */
1239 acf_generic_indention_0, /* indent level */
1240 acf_generic_group_offset, /* offset */
1241
1242 acf_nla_controls_name, /* name */
1243 NULL, /* name prop */
1244 acf_nla_controls_icon, /* icon */
1245
1246 acf_nla_controls_setting_valid, /* has setting */
1247 acf_nla_controls_setting_flag, /* flag for setting */
1248 acf_nla_controls_setting_ptr, /* pointer for setting */
1249 };
1250
1251 /* NLA Control F-Curve -------------------------------- */
1252
1253 /* name for nla control fcurve entries */
acf_nla_curve_name(bAnimListElem * ale,char * name)1254 static void acf_nla_curve_name(bAnimListElem *ale, char *name)
1255 {
1256 NlaStrip *strip = ale->owner;
1257 FCurve *fcu = ale->data;
1258 PropertyRNA *prop;
1259
1260 /* try to get RNA property that this shortened path (relative to the strip) refers to */
1261 prop = RNA_struct_type_find_property(&RNA_NlaStrip, fcu->rna_path);
1262 if (prop) {
1263 /* "name" of this strip displays the UI identifier + the name of the NlaStrip */
1264 BLI_snprintf(name, 256, "%s (%s)", RNA_property_ui_name(prop), strip->name);
1265 }
1266 else {
1267 /* unknown property... */
1268 BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
1269 }
1270 }
1271
1272 /* NLA Control F-Curve type define */
1273 static bAnimChannelType ACF_NLACURVE = {
1274 "NLA Control F-Curve", /* type name */
1275 ACHANNEL_ROLE_CHANNEL, /* role */
1276
1277 acf_generic_channel_color, /* backdrop color */
1278 acf_generic_channel_backdrop, /* backdrop */
1279 acf_generic_indention_1, /* indent level */
1280 acf_generic_group_offset, /* offset */
1281
1282 acf_nla_curve_name, /* name */
1283 acf_fcurve_name_prop, /* name prop */
1284 NULL, /* icon */
1285
1286 acf_fcurve_setting_valid, /* has setting */
1287 acf_fcurve_setting_flag, /* flag for setting */
1288 acf_fcurve_setting_ptr, /* pointer for setting */
1289 };
1290
1291 /* Object Action Expander ------------------------------------------- */
1292
1293 /* TODO: just get this from RNA? */
acf_fillactd_icon(bAnimListElem * UNUSED (ale))1294 static int acf_fillactd_icon(bAnimListElem *UNUSED(ale))
1295 {
1296 return ICON_ACTION;
1297 }
1298
1299 /* check if some setting exists for this channel */
acf_fillactd_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)1300 static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac),
1301 bAnimListElem *UNUSED(ale),
1302 eAnimChannel_Settings setting)
1303 {
1304 switch (setting) {
1305 /* only select and expand supported */
1306 case ACHANNEL_SETTING_SELECT:
1307 case ACHANNEL_SETTING_EXPAND:
1308 return true;
1309
1310 default:
1311 return false;
1312 }
1313 }
1314
1315 /* get the appropriate flag(s) for the setting when it is valid */
acf_fillactd_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1316 static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac),
1317 eAnimChannel_Settings setting,
1318 bool *neg)
1319 {
1320 /* clear extra return data first */
1321 *neg = false;
1322
1323 switch (setting) {
1324 case ACHANNEL_SETTING_SELECT: /* selected */
1325 return ADT_UI_SELECTED;
1326
1327 case ACHANNEL_SETTING_EXPAND: /* expanded */
1328 *neg = true;
1329 return ACT_COLLAPSED;
1330
1331 default: /* unsupported */
1332 return 0;
1333 }
1334 }
1335
1336 /* get pointer to the setting */
acf_fillactd_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1337 static void *acf_fillactd_setting_ptr(bAnimListElem *ale,
1338 eAnimChannel_Settings setting,
1339 short *type)
1340 {
1341 bAction *act = (bAction *)ale->data;
1342 AnimData *adt = ale->adt;
1343
1344 /* clear extra return data first */
1345 *type = 0;
1346
1347 switch (setting) {
1348 case ACHANNEL_SETTING_SELECT: /* selected */
1349 if (adt) {
1350 return GET_ACF_FLAG_PTR(adt->flag, type);
1351 }
1352 return NULL;
1353
1354 case ACHANNEL_SETTING_EXPAND: /* expanded */
1355 return GET_ACF_FLAG_PTR(act->flag, type);
1356
1357 default: /* unsupported */
1358 return NULL;
1359 }
1360 }
1361
1362 /* object action expander type define */
1363 static bAnimChannelType ACF_FILLACTD = {
1364 "Ob-Action Filler", /* type name */
1365 ACHANNEL_ROLE_EXPANDER, /* role */
1366
1367 acf_generic_dataexpand_color, /* backdrop color */
1368 acf_generic_dataexpand_backdrop, /* backdrop */
1369 acf_generic_indention_1, /* indent level */
1370 acf_generic_basic_offset, /* offset */
1371
1372 acf_generic_idblock_name, /* name */
1373 acf_generic_idfill_name_prop, /* name prop */
1374 acf_fillactd_icon, /* icon */
1375
1376 acf_fillactd_setting_valid, /* has setting */
1377 acf_fillactd_setting_flag, /* flag for setting */
1378 acf_fillactd_setting_ptr, /* pointer for setting */
1379 };
1380
1381 /* Drivers Expander ------------------------------------------- */
1382
1383 /* TODO: just get this from RNA? */
acf_filldrivers_icon(bAnimListElem * UNUSED (ale))1384 static int acf_filldrivers_icon(bAnimListElem *UNUSED(ale))
1385 {
1386 return ICON_DRIVER;
1387 }
1388
acf_filldrivers_name(bAnimListElem * UNUSED (ale),char * name)1389 static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name)
1390 {
1391 BLI_strncpy(name, IFACE_("Drivers"), ANIM_CHAN_NAME_SIZE);
1392 }
1393
1394 /* check if some setting exists for this channel */
1395 /* TODO: this could be made more generic */
acf_filldrivers_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)1396 static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac),
1397 bAnimListElem *UNUSED(ale),
1398 eAnimChannel_Settings setting)
1399 {
1400 switch (setting) {
1401 /* only expand supported */
1402 case ACHANNEL_SETTING_EXPAND:
1403 return true;
1404
1405 default:
1406 return false;
1407 }
1408 }
1409
1410 /* get the appropriate flag(s) for the setting when it is valid */
acf_filldrivers_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1411 static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac),
1412 eAnimChannel_Settings setting,
1413 bool *neg)
1414 {
1415 /* clear extra return data first */
1416 *neg = false;
1417
1418 switch (setting) {
1419 case ACHANNEL_SETTING_EXPAND: /* expanded */
1420 *neg = true;
1421 return ADT_DRIVERS_COLLAPSED;
1422
1423 default: /* unsupported */
1424 return 0;
1425 }
1426 }
1427
1428 /* get pointer to the setting */
acf_filldrivers_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1429 static void *acf_filldrivers_setting_ptr(bAnimListElem *ale,
1430 eAnimChannel_Settings setting,
1431 short *type)
1432 {
1433 AnimData *adt = (AnimData *)ale->data;
1434
1435 /* clear extra return data first */
1436 *type = 0;
1437
1438 switch (setting) {
1439 case ACHANNEL_SETTING_EXPAND: /* expanded */
1440 return GET_ACF_FLAG_PTR(adt->flag, type);
1441
1442 default: /* unsupported */
1443 return NULL;
1444 }
1445 }
1446
1447 /* drivers expander type define */
1448 static bAnimChannelType ACF_FILLDRIVERS = {
1449 "Drivers Filler", /* type name */
1450 ACHANNEL_ROLE_EXPANDER, /* role */
1451
1452 acf_generic_dataexpand_color, /* backdrop color */
1453 acf_generic_dataexpand_backdrop, /* backdrop */
1454 acf_generic_indention_1, /* indent level */
1455 acf_generic_basic_offset, /* offset */
1456
1457 acf_filldrivers_name, /* name */
1458 NULL, /* name prop */
1459 acf_filldrivers_icon, /* icon */
1460
1461 acf_filldrivers_setting_valid, /* has setting */
1462 acf_filldrivers_setting_flag, /* flag for setting */
1463 acf_filldrivers_setting_ptr, /* pointer for setting */
1464 };
1465
1466 /* Material Expander ------------------------------------------- */
1467
1468 /* TODO: just get this from RNA? */
acf_dsmat_icon(bAnimListElem * UNUSED (ale))1469 static int acf_dsmat_icon(bAnimListElem *UNUSED(ale))
1470 {
1471 return ICON_MATERIAL_DATA;
1472 }
1473
1474 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsmat_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1475 static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac),
1476 eAnimChannel_Settings setting,
1477 bool *neg)
1478 {
1479 /* clear extra return data first */
1480 *neg = false;
1481
1482 switch (setting) {
1483 case ACHANNEL_SETTING_EXPAND: /* expanded */
1484 return MA_DS_EXPAND;
1485
1486 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1487 return ADT_NLA_EVAL_OFF;
1488
1489 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1490 *neg = true;
1491 return ADT_CURVES_NOT_VISIBLE;
1492
1493 case ACHANNEL_SETTING_SELECT: /* selected */
1494 return ADT_UI_SELECTED;
1495
1496 default: /* unsupported */
1497 return 0;
1498 }
1499 }
1500
1501 /* get pointer to the setting */
acf_dsmat_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1502 static void *acf_dsmat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
1503 {
1504 Material *ma = (Material *)ale->data;
1505
1506 /* clear extra return data first */
1507 *type = 0;
1508
1509 switch (setting) {
1510 case ACHANNEL_SETTING_EXPAND: /* expanded */
1511 return GET_ACF_FLAG_PTR(ma->flag, type);
1512
1513 case ACHANNEL_SETTING_SELECT: /* selected */
1514 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1515 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1516 if (ma->adt) {
1517 return GET_ACF_FLAG_PTR(ma->adt->flag, type);
1518 }
1519 return NULL;
1520
1521 default: /* unsupported */
1522 return NULL;
1523 }
1524 }
1525
1526 /* material expander type define */
1527 static bAnimChannelType ACF_DSMAT = {
1528 "Material Data Expander", /* type name */
1529 ACHANNEL_ROLE_EXPANDER, /* role */
1530
1531 acf_generic_dataexpand_color, /* backdrop color */
1532 acf_generic_dataexpand_backdrop, /* backdrop */
1533 acf_generic_indention_1, /* indent level */
1534 acf_generic_basic_offset, /* offset */
1535
1536 acf_generic_idblock_name, /* name */
1537 acf_generic_idblock_name_prop, /* name prop */
1538 acf_dsmat_icon, /* icon */
1539
1540 acf_generic_dataexpand_setting_valid, /* has setting */
1541 acf_dsmat_setting_flag, /* flag for setting */
1542 acf_dsmat_setting_ptr, /* pointer for setting */
1543 };
1544
1545 /* Light Expander ------------------------------------------- */
1546
1547 /* TODO: just get this from RNA? */
acf_dslight_icon(bAnimListElem * UNUSED (ale))1548 static int acf_dslight_icon(bAnimListElem *UNUSED(ale))
1549 {
1550 return ICON_LIGHT_DATA;
1551 }
1552
1553 /* get the appropriate flag(s) for the setting when it is valid */
acf_dslight_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1554 static int acf_dslight_setting_flag(bAnimContext *UNUSED(ac),
1555 eAnimChannel_Settings setting,
1556 bool *neg)
1557 {
1558 /* clear extra return data first */
1559 *neg = false;
1560
1561 switch (setting) {
1562 case ACHANNEL_SETTING_EXPAND: /* expanded */
1563 return LA_DS_EXPAND;
1564
1565 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1566 return ADT_NLA_EVAL_OFF;
1567
1568 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1569 *neg = true;
1570 return ADT_CURVES_NOT_VISIBLE;
1571
1572 case ACHANNEL_SETTING_SELECT: /* selected */
1573 return ADT_UI_SELECTED;
1574
1575 default: /* unsupported */
1576 return 0;
1577 }
1578 }
1579
1580 /* get pointer to the setting */
acf_dslight_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1581 static void *acf_dslight_setting_ptr(bAnimListElem *ale,
1582 eAnimChannel_Settings setting,
1583 short *type)
1584 {
1585 Light *la = (Light *)ale->data;
1586
1587 /* clear extra return data first */
1588 *type = 0;
1589
1590 switch (setting) {
1591 case ACHANNEL_SETTING_EXPAND: /* expanded */
1592 return GET_ACF_FLAG_PTR(la->flag, type);
1593
1594 case ACHANNEL_SETTING_SELECT: /* selected */
1595 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1596 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1597 if (la->adt) {
1598 return GET_ACF_FLAG_PTR(la->adt->flag, type);
1599 }
1600 return NULL;
1601
1602 default: /* unsupported */
1603 return NULL;
1604 }
1605 }
1606
1607 /* light expander type define */
1608 static bAnimChannelType ACF_DSLIGHT = {
1609 "Light Expander", /* type name */
1610 ACHANNEL_ROLE_EXPANDER, /* role */
1611
1612 acf_generic_dataexpand_color, /* backdrop color */
1613 acf_generic_dataexpand_backdrop, /* backdrop */
1614 acf_generic_indention_1, /* indent level */
1615 acf_generic_basic_offset, /* offset */
1616
1617 acf_generic_idblock_name, /* name */
1618 acf_generic_idblock_name_prop, /* name prop */
1619 acf_dslight_icon, /* icon */
1620
1621 acf_generic_dataexpand_setting_valid, /* has setting */
1622 acf_dslight_setting_flag, /* flag for setting */
1623 acf_dslight_setting_ptr, /* pointer for setting */
1624 };
1625
1626 /* Texture Expander ------------------------------------------- */
1627
1628 /* TODO: just get this from RNA? */
acf_dstex_icon(bAnimListElem * UNUSED (ale))1629 static int acf_dstex_icon(bAnimListElem *UNUSED(ale))
1630 {
1631 return ICON_TEXTURE_DATA;
1632 }
1633
1634 /* offset for texture expanders */
1635 /* FIXME: soon to be obsolete? */
acf_dstex_offset(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale))1636 static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
1637 {
1638 return 14; /* XXX: simply include this in indention instead? */
1639 }
1640
1641 /* get the appropriate flag(s) for the setting when it is valid */
acf_dstex_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1642 static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac),
1643 eAnimChannel_Settings setting,
1644 bool *neg)
1645 {
1646 /* clear extra return data first */
1647 *neg = false;
1648
1649 switch (setting) {
1650 case ACHANNEL_SETTING_EXPAND: /* expanded */
1651 return TEX_DS_EXPAND;
1652
1653 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1654 return ADT_NLA_EVAL_OFF;
1655
1656 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1657 *neg = true;
1658 return ADT_CURVES_NOT_VISIBLE;
1659
1660 case ACHANNEL_SETTING_SELECT: /* selected */
1661 return ADT_UI_SELECTED;
1662
1663 default: /* unsupported */
1664 return 0;
1665 }
1666 }
1667
1668 /* get pointer to the setting */
acf_dstex_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1669 static void *acf_dstex_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
1670 {
1671 Tex *tex = (Tex *)ale->data;
1672
1673 /* clear extra return data first */
1674 *type = 0;
1675
1676 switch (setting) {
1677 case ACHANNEL_SETTING_EXPAND: /* expanded */
1678 return GET_ACF_FLAG_PTR(tex->flag, type);
1679
1680 case ACHANNEL_SETTING_SELECT: /* selected */
1681 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1682 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1683 if (tex->adt) {
1684 return GET_ACF_FLAG_PTR(tex->adt->flag, type);
1685 }
1686 return NULL;
1687
1688 default: /* unsupported */
1689 return NULL;
1690 }
1691 }
1692
1693 /* texture expander type define */
1694 static bAnimChannelType ACF_DSTEX = {
1695 "Texture Data Expander", /* type name */
1696 ACHANNEL_ROLE_EXPANDER, /* role */
1697
1698 acf_generic_dataexpand_color, /* backdrop color */
1699 acf_generic_dataexpand_backdrop, /* backdrop */
1700 acf_generic_indention_1, /* indent level */
1701 acf_dstex_offset, /* offset */
1702
1703 acf_generic_idblock_name, /* name */
1704 acf_generic_idfill_name_prop, /* name prop */
1705 acf_dstex_icon, /* icon */
1706
1707 acf_generic_dataexpand_setting_valid, /* has setting */
1708 acf_dstex_setting_flag, /* flag for setting */
1709 acf_dstex_setting_ptr, /* pointer for setting */
1710 };
1711
1712 /* Camera Expander ------------------------------------------- */
1713
1714 /* TODO: just get this from RNA? */
acf_dscachefile_icon(bAnimListElem * ale)1715 static int acf_dscachefile_icon(bAnimListElem *ale)
1716 {
1717 UNUSED_VARS(ale);
1718 return ICON_FILE;
1719 }
1720
1721 /* get the appropriate flag(s) for the setting when it is valid */
acf_dscachefile_setting_flag(bAnimContext * ac,eAnimChannel_Settings setting,bool * neg)1722 static int acf_dscachefile_setting_flag(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg)
1723 {
1724 /* clear extra return data first */
1725 *neg = false;
1726
1727 switch (setting) {
1728 case ACHANNEL_SETTING_EXPAND: /* expanded */
1729 return CACHEFILE_DS_EXPAND;
1730
1731 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1732 return ADT_NLA_EVAL_OFF;
1733
1734 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1735 *neg = true;
1736 return ADT_CURVES_NOT_VISIBLE;
1737
1738 case ACHANNEL_SETTING_SELECT: /* selected */
1739 return ADT_UI_SELECTED;
1740
1741 default: /* unsupported */
1742 return 0;
1743 }
1744
1745 UNUSED_VARS(ac);
1746 }
1747
1748 /* get pointer to the setting */
acf_dscachefile_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1749 static void *acf_dscachefile_setting_ptr(bAnimListElem *ale,
1750 eAnimChannel_Settings setting,
1751 short *type)
1752 {
1753 CacheFile *cache_file = (CacheFile *)ale->data;
1754
1755 /* clear extra return data first */
1756 *type = 0;
1757
1758 switch (setting) {
1759 case ACHANNEL_SETTING_EXPAND: /* expanded */
1760 return GET_ACF_FLAG_PTR(cache_file->flag, type);
1761
1762 case ACHANNEL_SETTING_SELECT: /* selected */
1763 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1764 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1765 if (cache_file->adt) {
1766 return GET_ACF_FLAG_PTR(cache_file->adt->flag, type);
1767 }
1768
1769 return NULL;
1770
1771 default: /* unsupported */
1772 return NULL;
1773 }
1774 }
1775
1776 /* CacheFile expander type define. */
1777 static bAnimChannelType ACF_DSCACHEFILE = {
1778 "Cache File Expander", /* type name */
1779 ACHANNEL_ROLE_EXPANDER, /* role */
1780
1781 acf_generic_dataexpand_color, /* backdrop color */
1782 acf_generic_dataexpand_backdrop, /* backdrop */
1783 acf_generic_indention_1, /* indent level */
1784 acf_generic_basic_offset, /* offset */
1785
1786 acf_generic_idblock_name, /* name */
1787 acf_generic_idfill_name_prop, /* name prop */
1788 acf_dscachefile_icon, /* icon */
1789
1790 acf_generic_dataexpand_setting_valid, /* has setting */
1791 acf_dscachefile_setting_flag, /* flag for setting */
1792 acf_dscachefile_setting_ptr, /* pointer for setting */
1793 };
1794
1795 /* Camera Expander ------------------------------------------- */
1796
1797 /* TODO: just get this from RNA? */
acf_dscam_icon(bAnimListElem * UNUSED (ale))1798 static int acf_dscam_icon(bAnimListElem *UNUSED(ale))
1799 {
1800 return ICON_CAMERA_DATA;
1801 }
1802
1803 /* get the appropriate flag(s) for the setting when it is valid */
acf_dscam_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1804 static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac),
1805 eAnimChannel_Settings setting,
1806 bool *neg)
1807 {
1808 /* clear extra return data first */
1809 *neg = false;
1810
1811 switch (setting) {
1812 case ACHANNEL_SETTING_EXPAND: /* expanded */
1813 return CAM_DS_EXPAND;
1814
1815 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1816 return ADT_NLA_EVAL_OFF;
1817
1818 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1819 *neg = true;
1820 return ADT_CURVES_NOT_VISIBLE;
1821
1822 case ACHANNEL_SETTING_SELECT: /* selected */
1823 return ADT_UI_SELECTED;
1824
1825 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
1826 return ADT_CURVES_ALWAYS_VISIBLE;
1827
1828 default: /* unsupported */
1829 return 0;
1830 }
1831 }
1832
1833 /* get pointer to the setting */
acf_dscam_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1834 static void *acf_dscam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
1835 {
1836 Camera *ca = (Camera *)ale->data;
1837
1838 /* clear extra return data first */
1839 *type = 0;
1840
1841 switch (setting) {
1842 case ACHANNEL_SETTING_EXPAND: /* expanded */
1843 return GET_ACF_FLAG_PTR(ca->flag, type);
1844
1845 case ACHANNEL_SETTING_SELECT: /* selected */
1846 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1847 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1848 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
1849 if (ca->adt) {
1850 return GET_ACF_FLAG_PTR(ca->adt->flag, type);
1851 }
1852 return NULL;
1853
1854 default: /* unsupported */
1855 return NULL;
1856 }
1857 }
1858
1859 /* camera expander type define */
1860 static bAnimChannelType ACF_DSCAM = {
1861 "Camera Expander", /* type name */
1862 ACHANNEL_ROLE_EXPANDER, /* role */
1863
1864 acf_generic_dataexpand_color, /* backdrop color */
1865 acf_generic_dataexpand_backdrop, /* backdrop */
1866 acf_generic_indention_1, /* indent level */
1867 acf_generic_basic_offset, /* offset */
1868
1869 acf_generic_idblock_name, /* name */
1870 acf_generic_idfill_name_prop, /* name prop */
1871 acf_dscam_icon, /* icon */
1872
1873 acf_generic_dataexpand_setting_valid, /* has setting */
1874 acf_dscam_setting_flag, /* flag for setting */
1875 acf_dscam_setting_ptr, /* pointer for setting */
1876 };
1877
1878 /* Curve Expander ------------------------------------------- */
1879
1880 /* TODO: just get this from RNA? */
acf_dscur_icon(bAnimListElem * ale)1881 static int acf_dscur_icon(bAnimListElem *ale)
1882 {
1883 Curve *cu = (Curve *)ale->data;
1884 short obtype = BKE_curve_type_get(cu);
1885
1886 switch (obtype) {
1887 case OB_FONT:
1888 return ICON_FONT_DATA;
1889 case OB_SURF:
1890 return ICON_SURFACE_DATA;
1891 default:
1892 return ICON_CURVE_DATA;
1893 }
1894 }
1895
1896 /* get the appropriate flag(s) for the setting when it is valid */
acf_dscur_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1897 static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac),
1898 eAnimChannel_Settings setting,
1899 bool *neg)
1900 {
1901 /* clear extra return data first */
1902 *neg = false;
1903
1904 switch (setting) {
1905 case ACHANNEL_SETTING_EXPAND: /* expanded */
1906 return CU_DS_EXPAND;
1907
1908 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1909 return ADT_NLA_EVAL_OFF;
1910
1911 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1912 *neg = true;
1913 return ADT_CURVES_NOT_VISIBLE;
1914
1915 case ACHANNEL_SETTING_SELECT: /* selected */
1916 return ADT_UI_SELECTED;
1917
1918 default: /* unsupported */
1919 return 0;
1920 }
1921 }
1922
1923 /* get pointer to the setting */
acf_dscur_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)1924 static void *acf_dscur_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
1925 {
1926 Curve *cu = (Curve *)ale->data;
1927
1928 /* clear extra return data first */
1929 *type = 0;
1930
1931 switch (setting) {
1932 case ACHANNEL_SETTING_EXPAND: /* expanded */
1933 return GET_ACF_FLAG_PTR(cu->flag, type);
1934
1935 case ACHANNEL_SETTING_SELECT: /* selected */
1936 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1937 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1938 if (cu->adt) {
1939 return GET_ACF_FLAG_PTR(cu->adt->flag, type);
1940 }
1941 return NULL;
1942
1943 default: /* unsupported */
1944 return NULL;
1945 }
1946 }
1947
1948 /* curve expander type define */
1949 static bAnimChannelType ACF_DSCUR = {
1950 "Curve Expander", /* type name */
1951 ACHANNEL_ROLE_EXPANDER, /* role */
1952
1953 acf_generic_dataexpand_color, /* backdrop color */
1954 acf_generic_dataexpand_backdrop, /* backdrop */
1955 acf_generic_indention_1, /* indent level */
1956 acf_generic_basic_offset, /* offset */
1957
1958 acf_generic_idblock_name, /* name */
1959 acf_generic_idblock_name_prop, /* name prop */
1960 acf_dscur_icon, /* icon */
1961
1962 acf_generic_dataexpand_setting_valid, /* has setting */
1963 acf_dscur_setting_flag, /* flag for setting */
1964 acf_dscur_setting_ptr, /* pointer for setting */
1965 };
1966
1967 /* Shape Key Expander ------------------------------------------- */
1968
1969 /* TODO: just get this from RNA? */
acf_dsskey_icon(bAnimListElem * UNUSED (ale))1970 static int acf_dsskey_icon(bAnimListElem *UNUSED(ale))
1971 {
1972 return ICON_SHAPEKEY_DATA;
1973 }
1974
1975 /* check if some setting exists for this channel */
acf_dsskey_setting_valid(bAnimContext * ac,bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)1976 static bool acf_dsskey_setting_valid(bAnimContext *ac,
1977 bAnimListElem *UNUSED(ale),
1978 eAnimChannel_Settings setting)
1979 {
1980 switch (setting) {
1981 case ACHANNEL_SETTING_SELECT:
1982 case ACHANNEL_SETTING_EXPAND:
1983 return true;
1984
1985 /* mute is only supported for NLA */
1986 case ACHANNEL_SETTING_MUTE:
1987 return ((ac) && (ac->spacetype == SPACE_NLA));
1988
1989 default:
1990 return false;
1991 }
1992 }
1993
1994 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsskey_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)1995 static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac),
1996 eAnimChannel_Settings setting,
1997 bool *neg)
1998 {
1999 /* clear extra return data first */
2000 *neg = false;
2001
2002 switch (setting) {
2003 case ACHANNEL_SETTING_EXPAND: /* expanded */
2004 return KEY_DS_EXPAND;
2005
2006 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2007 return ADT_NLA_EVAL_OFF;
2008
2009 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2010 *neg = true;
2011 return ADT_CURVES_NOT_VISIBLE;
2012
2013 case ACHANNEL_SETTING_SELECT: /* selected */
2014 return ADT_UI_SELECTED;
2015
2016 default: /* unsupported */
2017 return 0;
2018 }
2019 }
2020
2021 /* get pointer to the setting */
acf_dsskey_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2022 static void *acf_dsskey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2023 {
2024 Key *key = (Key *)ale->data;
2025
2026 /* clear extra return data first */
2027 *type = 0;
2028
2029 switch (setting) {
2030 case ACHANNEL_SETTING_EXPAND: /* expanded */
2031 return GET_ACF_FLAG_PTR(key->flag, type);
2032
2033 case ACHANNEL_SETTING_SELECT: /* selected */
2034 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2035 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2036 if (key->adt) {
2037 return GET_ACF_FLAG_PTR(key->adt->flag, type);
2038 }
2039 return NULL;
2040
2041 default: /* unsupported */
2042 return NULL;
2043 }
2044 }
2045
2046 /* shapekey expander type define */
2047 static bAnimChannelType ACF_DSSKEY = {
2048 "Shape Key Expander", /* type name */
2049 ACHANNEL_ROLE_EXPANDER, /* role */
2050
2051 acf_generic_dataexpand_color, /* backdrop color */
2052 acf_generic_dataexpand_backdrop, /* backdrop */
2053 acf_generic_indention_1, /* indent level */
2054 acf_generic_basic_offset, /* offset */
2055
2056 acf_generic_idblock_name, /* name */
2057 acf_generic_idblock_name_prop, /* name prop */
2058 acf_dsskey_icon, /* icon */
2059
2060 acf_dsskey_setting_valid, /* has setting */
2061 acf_dsskey_setting_flag, /* flag for setting */
2062 acf_dsskey_setting_ptr, /* pointer for setting */
2063 };
2064
2065 /* World Expander ------------------------------------------- */
2066
2067 /* TODO: just get this from RNA? */
acf_dswor_icon(bAnimListElem * UNUSED (ale))2068 static int acf_dswor_icon(bAnimListElem *UNUSED(ale))
2069 {
2070 return ICON_WORLD_DATA;
2071 }
2072
2073 /* get the appropriate flag(s) for the setting when it is valid */
acf_dswor_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2074 static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac),
2075 eAnimChannel_Settings setting,
2076 bool *neg)
2077 {
2078 /* clear extra return data first */
2079 *neg = false;
2080
2081 switch (setting) {
2082 case ACHANNEL_SETTING_EXPAND: /* expanded */
2083 return WO_DS_EXPAND;
2084
2085 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2086 return ADT_NLA_EVAL_OFF;
2087
2088 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2089 *neg = true;
2090 return ADT_CURVES_NOT_VISIBLE;
2091
2092 case ACHANNEL_SETTING_SELECT: /* selected */
2093 return ADT_UI_SELECTED;
2094
2095 default: /* unsupported */
2096 return 0;
2097 }
2098 }
2099
2100 /* get pointer to the setting */
acf_dswor_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2101 static void *acf_dswor_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2102 {
2103 World *wo = (World *)ale->data;
2104
2105 /* clear extra return data first */
2106 *type = 0;
2107
2108 switch (setting) {
2109 case ACHANNEL_SETTING_EXPAND: /* expanded */
2110 return GET_ACF_FLAG_PTR(wo->flag, type);
2111
2112 case ACHANNEL_SETTING_SELECT: /* selected */
2113 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2114 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2115 if (wo->adt) {
2116 return GET_ACF_FLAG_PTR(wo->adt->flag, type);
2117 }
2118 return NULL;
2119
2120 default: /* unsupported */
2121 return NULL;
2122 }
2123 }
2124
2125 /* world expander type define */
2126 static bAnimChannelType ACF_DSWOR = {
2127 "World Expander", /* type name */
2128 ACHANNEL_ROLE_EXPANDER, /* role */
2129
2130 acf_generic_dataexpand_color, /* backdrop color */
2131 acf_generic_dataexpand_backdrop, /* backdrop */
2132 acf_generic_indention_1, /* indent level */
2133 acf_generic_basic_offset, /* offset */
2134
2135 acf_generic_idblock_name, /* name */
2136 acf_generic_idfill_name_prop, /* name prop */
2137 acf_dswor_icon, /* icon */
2138
2139 acf_generic_dataexpand_setting_valid, /* has setting */
2140 acf_dswor_setting_flag, /* flag for setting */
2141 acf_dswor_setting_ptr, /* pointer for setting */
2142 };
2143
2144 /* Particle Expander ------------------------------------------- */
2145
2146 /* TODO: just get this from RNA? */
acf_dspart_icon(bAnimListElem * UNUSED (ale))2147 static int acf_dspart_icon(bAnimListElem *UNUSED(ale))
2148 {
2149 return ICON_PARTICLE_DATA;
2150 }
2151
2152 /* get the appropriate flag(s) for the setting when it is valid */
acf_dspart_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2153 static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac),
2154 eAnimChannel_Settings setting,
2155 bool *neg)
2156 {
2157 /* clear extra return data first */
2158 *neg = false;
2159
2160 switch (setting) {
2161 case ACHANNEL_SETTING_EXPAND: /* expanded */
2162 return PART_DS_EXPAND;
2163
2164 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2165 return ADT_NLA_EVAL_OFF;
2166
2167 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2168 *neg = true;
2169 return ADT_CURVES_NOT_VISIBLE;
2170
2171 case ACHANNEL_SETTING_SELECT: /* selected */
2172 return ADT_UI_SELECTED;
2173
2174 default: /* unsupported */
2175 return 0;
2176 }
2177 }
2178
2179 /* get pointer to the setting */
acf_dspart_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2180 static void *acf_dspart_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2181 {
2182 ParticleSettings *part = (ParticleSettings *)ale->data;
2183
2184 /* clear extra return data first */
2185 *type = 0;
2186
2187 switch (setting) {
2188 case ACHANNEL_SETTING_EXPAND: /* expanded */
2189 return GET_ACF_FLAG_PTR(part->flag, type);
2190
2191 case ACHANNEL_SETTING_SELECT: /* selected */
2192 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2193 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2194 if (part->adt) {
2195 return GET_ACF_FLAG_PTR(part->adt->flag, type);
2196 }
2197 return NULL;
2198
2199 default: /* unsupported */
2200 return NULL;
2201 }
2202 }
2203
2204 /* particle expander type define */
2205 static bAnimChannelType ACF_DSPART = {
2206 "Particle Data Expander", /* type name */
2207 ACHANNEL_ROLE_EXPANDER, /* role */
2208
2209 acf_generic_dataexpand_color, /* backdrop color */
2210 acf_generic_dataexpand_backdrop, /* backdrop */
2211 acf_generic_indention_1, /* indent level */
2212 acf_generic_basic_offset, /* offset */
2213
2214 acf_generic_idblock_name, /* name */
2215 acf_generic_idblock_name_prop, /* name prop */
2216 acf_dspart_icon, /* icon */
2217
2218 acf_generic_dataexpand_setting_valid, /* has setting */
2219 acf_dspart_setting_flag, /* flag for setting */
2220 acf_dspart_setting_ptr, /* pointer for setting */
2221 };
2222
2223 /* MetaBall Expander ------------------------------------------- */
2224
2225 /* TODO: just get this from RNA? */
acf_dsmball_icon(bAnimListElem * UNUSED (ale))2226 static int acf_dsmball_icon(bAnimListElem *UNUSED(ale))
2227 {
2228 return ICON_META_DATA;
2229 }
2230
2231 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsmball_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2232 static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac),
2233 eAnimChannel_Settings setting,
2234 bool *neg)
2235 {
2236 /* clear extra return data first */
2237 *neg = false;
2238
2239 switch (setting) {
2240 case ACHANNEL_SETTING_EXPAND: /* expanded */
2241 return MB_DS_EXPAND;
2242
2243 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2244 return ADT_NLA_EVAL_OFF;
2245
2246 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2247 *neg = true;
2248 return ADT_CURVES_NOT_VISIBLE;
2249
2250 case ACHANNEL_SETTING_SELECT: /* selected */
2251 return ADT_UI_SELECTED;
2252
2253 default: /* unsupported */
2254 return 0;
2255 }
2256 }
2257
2258 /* get pointer to the setting */
acf_dsmball_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2259 static void *acf_dsmball_setting_ptr(bAnimListElem *ale,
2260 eAnimChannel_Settings setting,
2261 short *type)
2262 {
2263 MetaBall *mb = (MetaBall *)ale->data;
2264
2265 /* clear extra return data first */
2266 *type = 0;
2267
2268 switch (setting) {
2269 case ACHANNEL_SETTING_EXPAND: /* expanded */
2270 return GET_ACF_FLAG_PTR(mb->flag2, type);
2271
2272 case ACHANNEL_SETTING_SELECT: /* selected */
2273 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2274 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2275 if (mb->adt) {
2276 return GET_ACF_FLAG_PTR(mb->adt->flag, type);
2277 }
2278 return NULL;
2279
2280 default: /* unsupported */
2281 return NULL;
2282 }
2283 }
2284
2285 /* metaball expander type define */
2286 static bAnimChannelType ACF_DSMBALL = {
2287 "Metaball Expander", /* type name */
2288 ACHANNEL_ROLE_EXPANDER, /* role */
2289
2290 acf_generic_dataexpand_color, /* backdrop color */
2291 acf_generic_dataexpand_backdrop, /* backdrop */
2292 acf_generic_indention_1, /* indent level */
2293 acf_generic_basic_offset, /* offset */
2294
2295 acf_generic_idblock_name, /* name */
2296 acf_generic_idblock_name_prop, /* name prop */
2297 acf_dsmball_icon, /* icon */
2298
2299 acf_generic_dataexpand_setting_valid, /* has setting */
2300 acf_dsmball_setting_flag, /* flag for setting */
2301 acf_dsmball_setting_ptr, /* pointer for setting */
2302 };
2303
2304 /* Armature Expander ------------------------------------------- */
2305
2306 /* TODO: just get this from RNA? */
acf_dsarm_icon(bAnimListElem * UNUSED (ale))2307 static int acf_dsarm_icon(bAnimListElem *UNUSED(ale))
2308 {
2309 return ICON_ARMATURE_DATA;
2310 }
2311
2312 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsarm_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2313 static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac),
2314 eAnimChannel_Settings setting,
2315 bool *neg)
2316 {
2317 /* clear extra return data first */
2318 *neg = false;
2319
2320 switch (setting) {
2321 case ACHANNEL_SETTING_EXPAND: /* expanded */
2322 return ARM_DS_EXPAND;
2323
2324 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2325 return ADT_NLA_EVAL_OFF;
2326
2327 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2328 *neg = true;
2329 return ADT_CURVES_NOT_VISIBLE;
2330
2331 case ACHANNEL_SETTING_SELECT: /* selected */
2332 return ADT_UI_SELECTED;
2333
2334 default: /* unsupported */
2335 return 0;
2336 }
2337 }
2338
2339 /* get pointer to the setting */
acf_dsarm_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2340 static void *acf_dsarm_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2341 {
2342 bArmature *arm = (bArmature *)ale->data;
2343
2344 /* clear extra return data first */
2345 *type = 0;
2346
2347 switch (setting) {
2348 case ACHANNEL_SETTING_EXPAND: /* expanded */
2349 return GET_ACF_FLAG_PTR(arm->flag, type);
2350
2351 case ACHANNEL_SETTING_SELECT: /* selected */
2352 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2353 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2354 if (arm->adt) {
2355 return GET_ACF_FLAG_PTR(arm->adt->flag, type);
2356 }
2357 return NULL;
2358
2359 default: /* unsupported */
2360 return NULL;
2361 }
2362 }
2363
2364 /* metaball expander type define */
2365 static bAnimChannelType ACF_DSARM = {
2366 "Armature Expander", /* type name */
2367 ACHANNEL_ROLE_EXPANDER, /* role */
2368
2369 acf_generic_dataexpand_color, /* backdrop color */
2370 acf_generic_dataexpand_backdrop, /* backdrop */
2371 acf_generic_indention_1, /* indent level */
2372 acf_generic_basic_offset, /* offset */
2373
2374 acf_generic_idblock_name, /* name */
2375 acf_generic_idblock_name_prop, /* name prop */
2376 acf_dsarm_icon, /* icon */
2377
2378 acf_generic_dataexpand_setting_valid, /* has setting */
2379 acf_dsarm_setting_flag, /* flag for setting */
2380 acf_dsarm_setting_ptr, /* pointer for setting */
2381 };
2382
2383 /* NodeTree Expander ------------------------------------------- */
2384
2385 /* TODO: just get this from RNA? */
acf_dsntree_icon(bAnimListElem * UNUSED (ale))2386 static int acf_dsntree_icon(bAnimListElem *UNUSED(ale))
2387 {
2388 return ICON_NODETREE;
2389 }
2390
2391 /* offset for nodetree expanders */
acf_dsntree_offset(bAnimContext * ac,bAnimListElem * ale)2392 static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale)
2393 {
2394 bNodeTree *ntree = (bNodeTree *)ale->data;
2395 short offset = acf_generic_basic_offset(ac, ale);
2396
2397 offset += acf_nodetree_rootType_offset(ntree);
2398
2399 return offset;
2400 }
2401
2402 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsntree_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2403 static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac),
2404 eAnimChannel_Settings setting,
2405 bool *neg)
2406 {
2407 /* clear extra return data first */
2408 *neg = false;
2409
2410 switch (setting) {
2411 case ACHANNEL_SETTING_EXPAND: /* expanded */
2412 return NTREE_DS_EXPAND;
2413
2414 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2415 return ADT_NLA_EVAL_OFF;
2416
2417 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2418 *neg = true;
2419 return ADT_CURVES_NOT_VISIBLE;
2420
2421 case ACHANNEL_SETTING_SELECT: /* selected */
2422 return ADT_UI_SELECTED;
2423
2424 default: /* unsupported */
2425 return 0;
2426 }
2427 }
2428
2429 /* get pointer to the setting */
acf_dsntree_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2430 static void *acf_dsntree_setting_ptr(bAnimListElem *ale,
2431 eAnimChannel_Settings setting,
2432 short *type)
2433 {
2434 bNodeTree *ntree = (bNodeTree *)ale->data;
2435
2436 /* clear extra return data first */
2437 *type = 0;
2438
2439 switch (setting) {
2440 case ACHANNEL_SETTING_EXPAND: /* expanded */
2441 return GET_ACF_FLAG_PTR(ntree->flag, type);
2442
2443 case ACHANNEL_SETTING_SELECT: /* selected */
2444 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2445 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2446 if (ntree->adt) {
2447 return GET_ACF_FLAG_PTR(ntree->adt->flag, type);
2448 }
2449 return NULL;
2450
2451 default: /* unsupported */
2452 return NULL;
2453 }
2454 }
2455
2456 /* node tree expander type define */
2457 static bAnimChannelType ACF_DSNTREE = {
2458 "Node Tree Expander", /* type name */
2459 ACHANNEL_ROLE_EXPANDER, /* role */
2460
2461 acf_generic_dataexpand_color, /* backdrop color */
2462 acf_generic_dataexpand_backdrop, /* backdrop */
2463 acf_generic_indention_1, /* indent level */
2464 acf_dsntree_offset, /* offset */
2465
2466 acf_generic_idblock_name, /* name */
2467 acf_generic_idblock_name_prop, /* name prop */
2468 acf_dsntree_icon, /* icon */
2469
2470 acf_generic_dataexpand_setting_valid, /* has setting */
2471 acf_dsntree_setting_flag, /* flag for setting */
2472 acf_dsntree_setting_ptr, /* pointer for setting */
2473 };
2474
2475 /* LineStyle Expander ------------------------------------------- */
2476
2477 /* TODO: just get this from RNA? */
acf_dslinestyle_icon(bAnimListElem * UNUSED (ale))2478 static int acf_dslinestyle_icon(bAnimListElem *UNUSED(ale))
2479 {
2480 return ICON_LINE_DATA;
2481 }
2482
2483 /* get the appropriate flag(s) for the setting when it is valid */
acf_dslinestyle_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2484 static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac),
2485 eAnimChannel_Settings setting,
2486 bool *neg)
2487 {
2488 /* clear extra return data first */
2489 *neg = false;
2490
2491 switch (setting) {
2492 case ACHANNEL_SETTING_EXPAND: /* expanded */
2493 return LS_DS_EXPAND;
2494
2495 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2496 return ADT_NLA_EVAL_OFF;
2497
2498 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2499 *neg = true;
2500 return ADT_CURVES_NOT_VISIBLE;
2501
2502 case ACHANNEL_SETTING_SELECT: /* selected */
2503 return ADT_UI_SELECTED;
2504
2505 default: /* unsupported */
2506 return 0;
2507 }
2508 }
2509
2510 /* get pointer to the setting */
acf_dslinestyle_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2511 static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale,
2512 eAnimChannel_Settings setting,
2513 short *type)
2514 {
2515 FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ale->data;
2516
2517 /* clear extra return data first */
2518 *type = 0;
2519
2520 switch (setting) {
2521 case ACHANNEL_SETTING_EXPAND: /* expanded */
2522 return GET_ACF_FLAG_PTR(linestyle->flag, type);
2523
2524 case ACHANNEL_SETTING_SELECT: /* selected */
2525 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2526 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2527 if (linestyle->adt) {
2528 return GET_ACF_FLAG_PTR(linestyle->adt->flag, type);
2529 }
2530 return NULL;
2531
2532 default: /* unsupported */
2533 return NULL;
2534 }
2535 }
2536
2537 /* node tree expander type define */
2538 static bAnimChannelType ACF_DSLINESTYLE = {
2539 "Line Style Expander", /* type name */
2540 ACHANNEL_ROLE_EXPANDER, /* role */
2541
2542 acf_generic_dataexpand_color, /* backdrop color */
2543 acf_generic_dataexpand_backdrop, /* backdrop */
2544 acf_generic_indention_1, /* indent level */
2545 acf_generic_basic_offset, /* offset */
2546
2547 acf_generic_idblock_name, /* name */
2548 acf_generic_idblock_name_prop, /* name prop */
2549 acf_dslinestyle_icon, /* icon */
2550
2551 acf_generic_dataexpand_setting_valid, /* has setting */
2552 acf_dslinestyle_setting_flag, /* flag for setting */
2553 acf_dslinestyle_setting_ptr, /* pointer for setting */
2554 };
2555
2556 /* Mesh Expander ------------------------------------------- */
2557
2558 /* TODO: just get this from RNA? */
acf_dsmesh_icon(bAnimListElem * UNUSED (ale))2559 static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale))
2560 {
2561 return ICON_MESH_DATA;
2562 }
2563
2564 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsmesh_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2565 static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac),
2566 eAnimChannel_Settings setting,
2567 bool *neg)
2568 {
2569 /* clear extra return data first */
2570 *neg = false;
2571
2572 switch (setting) {
2573 case ACHANNEL_SETTING_EXPAND: /* expanded */
2574 return ME_DS_EXPAND;
2575
2576 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2577 return ADT_NLA_EVAL_OFF;
2578
2579 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2580 *neg = true;
2581 return ADT_CURVES_NOT_VISIBLE;
2582
2583 case ACHANNEL_SETTING_SELECT: /* selected */
2584 return ADT_UI_SELECTED;
2585
2586 default: /* unsupported */
2587 return 0;
2588 }
2589 }
2590
2591 /* get pointer to the setting */
acf_dsmesh_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2592 static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2593 {
2594 Mesh *me = (Mesh *)ale->data;
2595
2596 /* clear extra return data first */
2597 *type = 0;
2598
2599 switch (setting) {
2600 case ACHANNEL_SETTING_EXPAND: /* expanded */
2601 return GET_ACF_FLAG_PTR(me->flag, type);
2602
2603 case ACHANNEL_SETTING_SELECT: /* selected */
2604 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2605 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2606 if (me->adt) {
2607 return GET_ACF_FLAG_PTR(me->adt->flag, type);
2608 }
2609 return NULL;
2610
2611 default: /* unsupported */
2612 return NULL;
2613 }
2614 }
2615
2616 /* node tree expander type define */
2617 static bAnimChannelType ACF_DSMESH = {
2618 "Mesh Expander", /* type name */
2619 ACHANNEL_ROLE_EXPANDER, /* role */
2620
2621 acf_generic_dataexpand_color, /* backdrop color */
2622 acf_generic_dataexpand_backdrop, /* backdrop */
2623 acf_generic_indention_1,
2624 /* indent level */ /* XXX this only works for compositing */
2625 acf_generic_basic_offset, /* offset */
2626
2627 acf_generic_idblock_name, /* name */
2628 acf_generic_idblock_name_prop, /* name prop */
2629 acf_dsmesh_icon, /* icon */
2630
2631 acf_generic_dataexpand_setting_valid, /* has setting */
2632 acf_dsmesh_setting_flag, /* flag for setting */
2633 acf_dsmesh_setting_ptr, /* pointer for setting */
2634 };
2635
2636 /* Lattice Expander ------------------------------------------- */
2637
2638 /* TODO: just get this from RNA? */
acf_dslat_icon(bAnimListElem * UNUSED (ale))2639 static int acf_dslat_icon(bAnimListElem *UNUSED(ale))
2640 {
2641 return ICON_LATTICE_DATA;
2642 }
2643
2644 /* get the appropriate flag(s) for the setting when it is valid */
acf_dslat_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2645 static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac),
2646 eAnimChannel_Settings setting,
2647 bool *neg)
2648 {
2649 /* clear extra return data first */
2650 *neg = false;
2651
2652 switch (setting) {
2653 case ACHANNEL_SETTING_EXPAND: /* expanded */
2654 return LT_DS_EXPAND;
2655
2656 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2657 return ADT_NLA_EVAL_OFF;
2658
2659 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2660 *neg = true;
2661 return ADT_CURVES_NOT_VISIBLE;
2662
2663 case ACHANNEL_SETTING_SELECT: /* selected */
2664 return ADT_UI_SELECTED;
2665
2666 default: /* unsupported */
2667 return 0;
2668 }
2669 }
2670
2671 /* get pointer to the setting */
acf_dslat_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2672 static void *acf_dslat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2673 {
2674 Lattice *lt = (Lattice *)ale->data;
2675
2676 /* clear extra return data first */
2677 *type = 0;
2678
2679 switch (setting) {
2680 case ACHANNEL_SETTING_EXPAND: /* expanded */
2681 return GET_ACF_FLAG_PTR(lt->flag, type);
2682
2683 case ACHANNEL_SETTING_SELECT: /* selected */
2684 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2685 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2686 if (lt->adt) {
2687 return GET_ACF_FLAG_PTR(lt->adt->flag, type);
2688 }
2689 return NULL;
2690
2691 default: /* unsupported */
2692 return NULL;
2693 }
2694 }
2695
2696 /* node tree expander type define */
2697 static bAnimChannelType ACF_DSLAT = {
2698 "Lattice Expander", /* type name */
2699 ACHANNEL_ROLE_EXPANDER, /* role */
2700
2701 acf_generic_dataexpand_color, /* backdrop color */
2702 acf_generic_dataexpand_backdrop, /* backdrop */
2703 acf_generic_indention_1,
2704 /* indent level */ /* XXX this only works for compositing */
2705 acf_generic_basic_offset, /* offset */
2706
2707 acf_generic_idblock_name, /* name */
2708 acf_generic_idblock_name_prop, /* name prop */
2709 acf_dslat_icon, /* icon */
2710
2711 acf_generic_dataexpand_setting_valid, /* has setting */
2712 acf_dslat_setting_flag, /* flag for setting */
2713 acf_dslat_setting_ptr, /* pointer for setting */
2714 };
2715
2716 /* Speaker Expander ------------------------------------------- */
2717
2718 /* TODO: just get this from RNA? */
acf_dsspk_icon(bAnimListElem * UNUSED (ale))2719 static int acf_dsspk_icon(bAnimListElem *UNUSED(ale))
2720 {
2721 return ICON_SPEAKER;
2722 }
2723
2724 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsspk_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2725 static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac),
2726 eAnimChannel_Settings setting,
2727 bool *neg)
2728 {
2729 /* clear extra return data first */
2730 *neg = false;
2731
2732 switch (setting) {
2733 case ACHANNEL_SETTING_EXPAND: /* expanded */
2734 return SPK_DS_EXPAND;
2735
2736 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2737 return ADT_NLA_EVAL_OFF;
2738
2739 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2740 *neg = true;
2741 return ADT_CURVES_NOT_VISIBLE;
2742
2743 case ACHANNEL_SETTING_SELECT: /* selected */
2744 return ADT_UI_SELECTED;
2745
2746 default: /* unsupported */
2747 return 0;
2748 }
2749 }
2750
2751 /* get pointer to the setting */
acf_dsspk_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2752 static void *acf_dsspk_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2753 {
2754 Speaker *spk = (Speaker *)ale->data;
2755
2756 /* clear extra return data first */
2757 *type = 0;
2758
2759 switch (setting) {
2760 case ACHANNEL_SETTING_EXPAND: /* expanded */
2761 return GET_ACF_FLAG_PTR(spk->flag, type);
2762
2763 case ACHANNEL_SETTING_SELECT: /* selected */
2764 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2765 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2766 if (spk->adt) {
2767 return GET_ACF_FLAG_PTR(spk->adt->flag, type);
2768 }
2769 return NULL;
2770
2771 default: /* unsupported */
2772 return NULL;
2773 }
2774 }
2775
2776 /* speaker expander type define */
2777 static bAnimChannelType ACF_DSSPK = {
2778 "Speaker Expander", /* type name */
2779 ACHANNEL_ROLE_EXPANDER, /* role */
2780
2781 acf_generic_dataexpand_color, /* backdrop color */
2782 acf_generic_dataexpand_backdrop, /* backdrop */
2783 acf_generic_indention_1, /* indent level */
2784 acf_generic_basic_offset, /* offset */
2785
2786 acf_generic_idblock_name, /* name */
2787 acf_generic_idblock_name_prop, /* name prop */
2788 acf_dsspk_icon, /* icon */
2789
2790 acf_generic_dataexpand_setting_valid, /* has setting */
2791 acf_dsspk_setting_flag, /* flag for setting */
2792 acf_dsspk_setting_ptr, /* pointer for setting */
2793 };
2794
2795 /* Hair Expander ------------------------------------------- */
2796
2797 /* TODO: just get this from RNA? */
acf_dshair_icon(bAnimListElem * UNUSED (ale))2798 static int acf_dshair_icon(bAnimListElem *UNUSED(ale))
2799 {
2800 return ICON_HAIR_DATA;
2801 }
2802
2803 /* get the appropriate flag(s) for the setting when it is valid */
acf_dshair_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2804 static int acf_dshair_setting_flag(bAnimContext *UNUSED(ac),
2805 eAnimChannel_Settings setting,
2806 bool *neg)
2807 {
2808 /* clear extra return data first */
2809 *neg = false;
2810
2811 switch (setting) {
2812 case ACHANNEL_SETTING_EXPAND: /* expanded */
2813 return VO_DS_EXPAND;
2814
2815 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2816 return ADT_NLA_EVAL_OFF;
2817
2818 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2819 *neg = true;
2820 return ADT_CURVES_NOT_VISIBLE;
2821
2822 case ACHANNEL_SETTING_SELECT: /* selected */
2823 return ADT_UI_SELECTED;
2824
2825 default: /* unsupported */
2826 return 0;
2827 }
2828 }
2829
2830 /* get pointer to the setting */
acf_dshair_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2831 static void *acf_dshair_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
2832 {
2833 Hair *hair = (Hair *)ale->data;
2834
2835 /* clear extra return data first */
2836 *type = 0;
2837
2838 switch (setting) {
2839 case ACHANNEL_SETTING_EXPAND: /* expanded */
2840 return GET_ACF_FLAG_PTR(hair->flag, type);
2841
2842 case ACHANNEL_SETTING_SELECT: /* selected */
2843 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2844 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2845 if (hair->adt) {
2846 return GET_ACF_FLAG_PTR(hair->adt->flag, type);
2847 }
2848 return NULL;
2849
2850 default: /* unsupported */
2851 return NULL;
2852 }
2853 }
2854
2855 /* hair expander type define */
2856 static bAnimChannelType ACF_DSHAIR = {
2857 "Hair Expander", /* type name */
2858 ACHANNEL_ROLE_EXPANDER, /* role */
2859
2860 acf_generic_dataexpand_color, /* backdrop color */
2861 acf_generic_dataexpand_backdrop, /* backdrop */
2862 acf_generic_indention_1, /* indent level */
2863 acf_generic_basic_offset, /* offset */
2864
2865 acf_generic_idblock_name, /* name */
2866 acf_generic_idblock_name_prop, /* name prop */
2867 acf_dshair_icon, /* icon */
2868
2869 acf_generic_dataexpand_setting_valid, /* has setting */
2870 acf_dshair_setting_flag, /* flag for setting */
2871 acf_dshair_setting_ptr /* pointer for setting */
2872 };
2873
2874 /* PointCloud Expander ------------------------------------------- */
2875
2876 /* TODO: just get this from RNA? */
acf_dspointcloud_icon(bAnimListElem * UNUSED (ale))2877 static int acf_dspointcloud_icon(bAnimListElem *UNUSED(ale))
2878 {
2879 return ICON_POINTCLOUD_DATA;
2880 }
2881
2882 /* get the appropriate flag(s) for the setting when it is valid */
acf_dspointcloud_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2883 static int acf_dspointcloud_setting_flag(bAnimContext *UNUSED(ac),
2884 eAnimChannel_Settings setting,
2885 bool *neg)
2886 {
2887 /* clear extra return data first */
2888 *neg = false;
2889
2890 switch (setting) {
2891 case ACHANNEL_SETTING_EXPAND: /* expanded */
2892 return VO_DS_EXPAND;
2893
2894 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2895 return ADT_NLA_EVAL_OFF;
2896
2897 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2898 *neg = true;
2899 return ADT_CURVES_NOT_VISIBLE;
2900
2901 case ACHANNEL_SETTING_SELECT: /* selected */
2902 return ADT_UI_SELECTED;
2903
2904 default: /* unsupported */
2905 return 0;
2906 }
2907 }
2908
2909 /* get pointer to the setting */
acf_dspointcloud_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2910 static void *acf_dspointcloud_setting_ptr(bAnimListElem *ale,
2911 eAnimChannel_Settings setting,
2912 short *type)
2913 {
2914 PointCloud *pointcloud = (PointCloud *)ale->data;
2915
2916 /* clear extra return data first */
2917 *type = 0;
2918
2919 switch (setting) {
2920 case ACHANNEL_SETTING_EXPAND: /* expanded */
2921 return GET_ACF_FLAG_PTR(pointcloud->flag, type);
2922
2923 case ACHANNEL_SETTING_SELECT: /* selected */
2924 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2925 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2926 if (pointcloud->adt) {
2927 return GET_ACF_FLAG_PTR(pointcloud->adt->flag, type);
2928 }
2929 return NULL;
2930
2931 default: /* unsupported */
2932 return NULL;
2933 }
2934 }
2935
2936 /* pointcloud expander type define */
2937 static bAnimChannelType ACF_DSPOINTCLOUD = {
2938 "PointCloud Expander", /* type name */
2939 ACHANNEL_ROLE_EXPANDER, /* role */
2940
2941 acf_generic_dataexpand_color, /* backdrop color */
2942 acf_generic_dataexpand_backdrop, /* backdrop */
2943 acf_generic_indention_1, /* indent level */
2944 acf_generic_basic_offset, /* offset */
2945
2946 acf_generic_idblock_name, /* name */
2947 acf_generic_idblock_name_prop, /* name prop */
2948 acf_dspointcloud_icon, /* icon */
2949
2950 acf_generic_dataexpand_setting_valid, /* has setting */
2951 acf_dspointcloud_setting_flag, /* flag for setting */
2952 acf_dspointcloud_setting_ptr /* pointer for setting */
2953 };
2954
2955 /* Volume Expander ------------------------------------------- */
2956
2957 /* TODO: just get this from RNA? */
acf_dsvolume_icon(bAnimListElem * UNUSED (ale))2958 static int acf_dsvolume_icon(bAnimListElem *UNUSED(ale))
2959 {
2960 return ICON_VOLUME_DATA;
2961 }
2962
2963 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsvolume_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)2964 static int acf_dsvolume_setting_flag(bAnimContext *UNUSED(ac),
2965 eAnimChannel_Settings setting,
2966 bool *neg)
2967 {
2968 /* clear extra return data first */
2969 *neg = false;
2970
2971 switch (setting) {
2972 case ACHANNEL_SETTING_EXPAND: /* expanded */
2973 return VO_DS_EXPAND;
2974
2975 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2976 return ADT_NLA_EVAL_OFF;
2977
2978 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2979 *neg = true;
2980 return ADT_CURVES_NOT_VISIBLE;
2981
2982 case ACHANNEL_SETTING_SELECT: /* selected */
2983 return ADT_UI_SELECTED;
2984
2985 default: /* unsupported */
2986 return 0;
2987 }
2988 }
2989
2990 /* get pointer to the setting */
acf_dsvolume_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)2991 static void *acf_dsvolume_setting_ptr(bAnimListElem *ale,
2992 eAnimChannel_Settings setting,
2993 short *type)
2994 {
2995 Volume *volume = (Volume *)ale->data;
2996
2997 /* clear extra return data first */
2998 *type = 0;
2999
3000 switch (setting) {
3001 case ACHANNEL_SETTING_EXPAND: /* expanded */
3002 return GET_ACF_FLAG_PTR(volume->flag, type);
3003
3004 case ACHANNEL_SETTING_SELECT: /* selected */
3005 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
3006 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
3007 if (volume->adt) {
3008 return GET_ACF_FLAG_PTR(volume->adt->flag, type);
3009 }
3010 return NULL;
3011
3012 default: /* unsupported */
3013 return NULL;
3014 }
3015 }
3016
3017 /* volume expander type define */
3018 static bAnimChannelType ACF_DSVOLUME = {
3019 "Volume Expander", /* type name */
3020 ACHANNEL_ROLE_EXPANDER, /* role */
3021
3022 acf_generic_dataexpand_color, /* backdrop color */
3023 acf_generic_dataexpand_backdrop, /* backdrop */
3024 acf_generic_indention_1, /* indent level */
3025 acf_generic_basic_offset, /* offset */
3026
3027 acf_generic_idblock_name, /* name */
3028 acf_generic_idblock_name_prop, /* name prop */
3029 acf_dsvolume_icon, /* icon */
3030
3031 acf_generic_dataexpand_setting_valid, /* has setting */
3032 acf_dsvolume_setting_flag, /* flag for setting */
3033 acf_dsvolume_setting_ptr /* pointer for setting */
3034 };
3035
3036 /* Simulation Expander ----------------------------------------- */
3037
acf_dssimulation_icon(bAnimListElem * UNUSED (ale))3038 static int acf_dssimulation_icon(bAnimListElem *UNUSED(ale))
3039 {
3040 /* TODO: Use correct icon. */
3041 return ICON_PHYSICS;
3042 }
3043
acf_dssimulation_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3044 static int acf_dssimulation_setting_flag(bAnimContext *UNUSED(ac),
3045 eAnimChannel_Settings setting,
3046 bool *neg)
3047 {
3048 /* clear extra return data first */
3049 *neg = false;
3050
3051 switch (setting) {
3052 case ACHANNEL_SETTING_EXPAND: /* expanded */
3053 return SIM_DS_EXPAND;
3054
3055 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
3056 return ADT_NLA_EVAL_OFF;
3057
3058 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
3059 *neg = true;
3060 return ADT_CURVES_NOT_VISIBLE;
3061
3062 case ACHANNEL_SETTING_SELECT: /* selected */
3063 return ADT_UI_SELECTED;
3064
3065 default: /* unsupported */
3066 return 0;
3067 }
3068 }
3069
acf_dssimulation_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)3070 static void *acf_dssimulation_setting_ptr(bAnimListElem *ale,
3071 eAnimChannel_Settings setting,
3072 short *type)
3073 {
3074 Simulation *simulation = (Simulation *)ale->data;
3075
3076 /* clear extra return data first */
3077 *type = 0;
3078
3079 switch (setting) {
3080 case ACHANNEL_SETTING_EXPAND: /* expanded */
3081 return GET_ACF_FLAG_PTR(simulation->flag, type);
3082
3083 case ACHANNEL_SETTING_SELECT: /* selected */
3084 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
3085 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
3086 if (simulation->adt) {
3087 return GET_ACF_FLAG_PTR(simulation->adt->flag, type);
3088 }
3089 return NULL;
3090
3091 default: /* unsupported */
3092 return NULL;
3093 }
3094 }
3095
3096 static bAnimChannelType ACF_DSSIMULATION = {
3097 "Simulation Expander", /* type name */
3098 ACHANNEL_ROLE_EXPANDER, /* role */
3099
3100 acf_generic_dataexpand_color, /* backdrop color */
3101 acf_generic_dataexpand_backdrop, /* backdrop */
3102 acf_generic_indention_1, /* indent level */
3103 acf_generic_basic_offset, /* offset */
3104
3105 acf_generic_idblock_name, /* name */
3106 acf_generic_idblock_name_prop, /* name prop */
3107 acf_dssimulation_icon, /* icon */
3108
3109 acf_generic_dataexpand_setting_valid, /* has setting */
3110 acf_dssimulation_setting_flag, /* flag for setting */
3111 acf_dssimulation_setting_ptr /* pointer for setting */
3112 };
3113
3114 /* GPencil Expander ------------------------------------------- */
3115
3116 /* TODO: just get this from RNA? */
acf_dsgpencil_icon(bAnimListElem * UNUSED (ale))3117 static int acf_dsgpencil_icon(bAnimListElem *UNUSED(ale))
3118 {
3119 return ICON_GREASEPENCIL;
3120 }
3121
3122 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsgpencil_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3123 static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac),
3124 eAnimChannel_Settings setting,
3125 bool *neg)
3126 {
3127 /* clear extra return data first */
3128 *neg = false;
3129
3130 switch (setting) {
3131 case ACHANNEL_SETTING_EXPAND: /* expanded */
3132 return GP_DATA_EXPAND;
3133
3134 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
3135 return ADT_NLA_EVAL_OFF;
3136
3137 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
3138 *neg = true;
3139 return ADT_CURVES_NOT_VISIBLE;
3140
3141 case ACHANNEL_SETTING_SELECT: /* selected */
3142 return ADT_UI_SELECTED;
3143
3144 default: /* unsupported */
3145 return 0;
3146 }
3147 }
3148
3149 /* get pointer to the setting */
acf_dsgpencil_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)3150 static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale,
3151 eAnimChannel_Settings setting,
3152 short *type)
3153 {
3154 bGPdata *gpd = (bGPdata *)ale->data;
3155
3156 /* clear extra return data first */
3157 *type = 0;
3158
3159 switch (setting) {
3160 case ACHANNEL_SETTING_EXPAND: /* expanded */
3161 return GET_ACF_FLAG_PTR(gpd->flag, type);
3162
3163 case ACHANNEL_SETTING_SELECT: /* selected */
3164 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
3165 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
3166 if (gpd->adt) {
3167 return GET_ACF_FLAG_PTR(gpd->adt->flag, type);
3168 }
3169 return NULL;
3170
3171 default: /* unsupported */
3172 return NULL;
3173 }
3174 }
3175
3176 /* grease pencil expander type define */
3177 static bAnimChannelType ACF_DSGPENCIL = {
3178 "GPencil DS Expander", /* type name */
3179 ACHANNEL_ROLE_EXPANDER, /* role */
3180
3181 acf_generic_dataexpand_color, /* backdrop color */
3182 acf_generic_dataexpand_backdrop, /* backdrop */
3183 acf_generic_indention_1, /* indent level */
3184 acf_generic_basic_offset, /* offset */
3185
3186 acf_generic_idblock_name, /* name */
3187 acf_generic_idblock_name_prop, /* name prop */
3188 acf_dsgpencil_icon, /* icon */
3189
3190 acf_generic_dataexpand_setting_valid, /* has setting */
3191 acf_dsgpencil_setting_flag, /* flag for setting */
3192 acf_dsgpencil_setting_ptr, /* pointer for setting */
3193 };
3194
3195 /* World Expander ------------------------------------------- */
3196
3197 /* TODO: just get this from RNA? */
acf_dsmclip_icon(bAnimListElem * UNUSED (ale))3198 static int acf_dsmclip_icon(bAnimListElem *UNUSED(ale))
3199 {
3200 return ICON_SEQUENCE;
3201 }
3202
3203 /* get the appropriate flag(s) for the setting when it is valid */
acf_dsmclip_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3204 static int acf_dsmclip_setting_flag(bAnimContext *UNUSED(ac),
3205 eAnimChannel_Settings setting,
3206 bool *neg)
3207 {
3208 /* clear extra return data first */
3209 *neg = false;
3210
3211 switch (setting) {
3212 case ACHANNEL_SETTING_EXPAND: /* expanded */
3213 return MCLIP_DATA_EXPAND;
3214
3215 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
3216 return ADT_NLA_EVAL_OFF;
3217
3218 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
3219 *neg = true;
3220 return ADT_CURVES_NOT_VISIBLE;
3221
3222 case ACHANNEL_SETTING_SELECT: /* selected */
3223 return ADT_UI_SELECTED;
3224
3225 default: /* unsupported */
3226 return 0;
3227 }
3228 }
3229
3230 /* get pointer to the setting */
acf_dsmclip_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)3231 static void *acf_dsmclip_setting_ptr(bAnimListElem *ale,
3232 eAnimChannel_Settings setting,
3233 short *type)
3234 {
3235 MovieClip *clip = (MovieClip *)ale->data;
3236
3237 /* clear extra return data first */
3238 *type = 0;
3239
3240 switch (setting) {
3241 case ACHANNEL_SETTING_EXPAND: /* expanded */
3242 return GET_ACF_FLAG_PTR(clip->flag, type);
3243
3244 case ACHANNEL_SETTING_SELECT: /* selected */
3245 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
3246 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
3247 if (clip->adt != NULL) {
3248 return GET_ACF_FLAG_PTR(clip->adt->flag, type);
3249 }
3250 return NULL;
3251
3252 default: /* unsupported */
3253 return NULL;
3254 }
3255 }
3256
3257 /* world expander type define */
3258 static bAnimChannelType ACF_DSMCLIP = {
3259 "Movieclip Expander", /* type name */
3260 ACHANNEL_ROLE_EXPANDER, /* role */
3261
3262 acf_generic_dataexpand_color, /* backdrop color */
3263 acf_generic_dataexpand_backdrop, /* backdrop */
3264 acf_generic_indention_1, /* indent level */
3265 acf_generic_basic_offset, /* offset */
3266
3267 acf_generic_idblock_name, /* name */
3268 acf_generic_idfill_name_prop, /* name prop */
3269 acf_dsmclip_icon, /* icon */
3270
3271 acf_generic_dataexpand_setting_valid, /* has setting */
3272 acf_dsmclip_setting_flag, /* flag for setting */
3273 acf_dsmclip_setting_ptr, /* pointer for setting */
3274 };
3275
3276 /* ShapeKey Entry ------------------------------------------- */
3277
3278 /* name for ShapeKey */
acf_shapekey_name(bAnimListElem * ale,char * name)3279 static void acf_shapekey_name(bAnimListElem *ale, char *name)
3280 {
3281 KeyBlock *kb = (KeyBlock *)ale->data;
3282
3283 /* just copy the name... */
3284 if (kb && name) {
3285 /* if the KeyBlock had a name, use it, otherwise use the index */
3286 if (kb->name[0]) {
3287 BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE);
3288 }
3289 else {
3290 BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, IFACE_("Key %d"), ale->index);
3291 }
3292 }
3293 }
3294
3295 /* name property for ShapeKey entries */
acf_shapekey_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)3296 static bool acf_shapekey_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
3297 {
3298 KeyBlock *kb = (KeyBlock *)ale->data;
3299
3300 /* if the KeyBlock had a name, use it, otherwise use the index */
3301 if (kb && kb->name[0]) {
3302 RNA_pointer_create(ale->id, &RNA_ShapeKey, kb, ptr);
3303 *prop = RNA_struct_name_property(ptr->type);
3304
3305 return (*prop != NULL);
3306 }
3307
3308 return false;
3309 }
3310
3311 /* check if some setting exists for this channel */
acf_shapekey_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)3312 static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac),
3313 bAnimListElem *UNUSED(ale),
3314 eAnimChannel_Settings setting)
3315 {
3316 switch (setting) {
3317 case ACHANNEL_SETTING_SELECT: /* selected */
3318 case ACHANNEL_SETTING_MUTE: /* muted */
3319 case ACHANNEL_SETTING_PROTECT: /* protected */
3320 return true;
3321
3322 /* nothing else is supported */
3323 default:
3324 return false;
3325 }
3326 }
3327
3328 /* get the appropriate flag(s) for the setting when it is valid */
acf_shapekey_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3329 static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac),
3330 eAnimChannel_Settings setting,
3331 bool *neg)
3332 {
3333 /* clear extra return data first */
3334 *neg = false;
3335
3336 switch (setting) {
3337 case ACHANNEL_SETTING_MUTE: /* mute */
3338 return KEYBLOCK_MUTE;
3339
3340 case ACHANNEL_SETTING_SELECT: /* selected */
3341 return KEYBLOCK_SEL;
3342
3343 case ACHANNEL_SETTING_PROTECT: /* locked */
3344 return KEYBLOCK_LOCKED;
3345
3346 default: /* unsupported */
3347 return 0;
3348 }
3349 }
3350
3351 /* get pointer to the setting */
acf_shapekey_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings setting,short * type)3352 static void *acf_shapekey_setting_ptr(bAnimListElem *ale,
3353 eAnimChannel_Settings setting,
3354 short *type)
3355 {
3356 KeyBlock *kb = (KeyBlock *)ale->data;
3357
3358 /* clear extra return data first */
3359 *type = 0;
3360
3361 switch (setting) {
3362 case ACHANNEL_SETTING_SELECT: /* selected */
3363 case ACHANNEL_SETTING_MUTE: /* muted */
3364 case ACHANNEL_SETTING_PROTECT: /* protected */
3365 return GET_ACF_FLAG_PTR(kb->flag, type);
3366
3367 default: /* unsupported */
3368 return NULL;
3369 }
3370 }
3371
3372 /* shapekey expander type define */
3373 static bAnimChannelType ACF_SHAPEKEY = {
3374 "Shape Key", /* type name */
3375 ACHANNEL_ROLE_CHANNEL, /* role */
3376
3377 acf_generic_channel_color, /* backdrop color */
3378 acf_generic_channel_backdrop, /* backdrop */
3379 acf_generic_indention_0, /* indent level */
3380 acf_generic_basic_offset, /* offset */
3381
3382 acf_shapekey_name, /* name */
3383 acf_shapekey_name_prop, /* name prop */
3384 NULL, /* icon */
3385
3386 acf_shapekey_setting_valid, /* has setting */
3387 acf_shapekey_setting_flag, /* flag for setting */
3388 acf_shapekey_setting_ptr, /* pointer for setting */
3389 };
3390
3391 /* GPencil Datablock ------------------------------------------- */
3392
3393 /* get backdrop color for gpencil datablock widget */
acf_gpd_color(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),float r_color[3])3394 static void acf_gpd_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
3395 {
3396 /* these are ID-blocks, but not exactly standalone... */
3397 UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
3398 }
3399
3400 /* TODO: just get this from RNA? */
acf_gpd_icon(bAnimListElem * UNUSED (ale))3401 static int acf_gpd_icon(bAnimListElem *UNUSED(ale))
3402 {
3403 return ICON_GREASEPENCIL;
3404 }
3405
3406 /* check if some setting exists for this channel */
acf_gpd_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)3407 static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac),
3408 bAnimListElem *UNUSED(ale),
3409 eAnimChannel_Settings setting)
3410 {
3411 switch (setting) {
3412 /* only select and expand supported */
3413 case ACHANNEL_SETTING_SELECT:
3414 case ACHANNEL_SETTING_EXPAND:
3415 return true;
3416
3417 default:
3418 return false;
3419 }
3420 }
3421
3422 /* get the appropriate flag(s) for the setting when it is valid */
acf_gpd_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3423 static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
3424 {
3425 /* clear extra return data first */
3426 *neg = false;
3427
3428 switch (setting) {
3429 case ACHANNEL_SETTING_SELECT: /* selected */
3430 return AGRP_SELECTED;
3431
3432 case ACHANNEL_SETTING_EXPAND: /* expanded */
3433 return GP_DATA_EXPAND;
3434
3435 default:
3436 /* these shouldn't happen */
3437 return 0;
3438 }
3439 }
3440
3441 /* get pointer to the setting */
acf_gpd_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)3442 static void *acf_gpd_setting_ptr(bAnimListElem *ale,
3443 eAnimChannel_Settings UNUSED(setting),
3444 short *type)
3445 {
3446 bGPdata *gpd = (bGPdata *)ale->data;
3447
3448 /* all flags are just in gpd->flag for now... */
3449 return GET_ACF_FLAG_PTR(gpd->flag, type);
3450 }
3451
3452 /* gpencil datablock type define */
3453 static bAnimChannelType ACF_GPD = {
3454 "GPencil Datablock", /* type name */
3455 ACHANNEL_ROLE_EXPANDER, /* role */
3456
3457 acf_gpd_color, /* backdrop color */
3458 acf_group_backdrop, /* backdrop */
3459 acf_generic_indention_0, /* indent level */
3460 acf_generic_group_offset, /* offset */
3461
3462 acf_generic_idblock_name, /* name */
3463 acf_generic_idfill_name_prop, /* name prop */
3464 acf_gpd_icon, /* icon */
3465
3466 acf_gpd_setting_valid, /* has setting */
3467 acf_gpd_setting_flag, /* flag for setting */
3468 acf_gpd_setting_ptr, /* pointer for setting */
3469 };
3470
3471 /* GPencil Layer ------------------------------------------- */
3472
3473 /* name for grease pencil layer entries */
acf_gpl_name(bAnimListElem * ale,char * name)3474 static void acf_gpl_name(bAnimListElem *ale, char *name)
3475 {
3476 bGPDlayer *gpl = (bGPDlayer *)ale->data;
3477
3478 if (gpl && name) {
3479 BLI_strncpy(name, gpl->info, ANIM_CHAN_NAME_SIZE);
3480 }
3481 }
3482
3483 /* name property for grease pencil layer entries */
acf_gpl_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)3484 static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
3485 {
3486 if (ale->data) {
3487 RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr);
3488 *prop = RNA_struct_name_property(ptr->type);
3489
3490 return (*prop != NULL);
3491 }
3492
3493 return false;
3494 }
3495
3496 /* check if some setting exists for this channel */
acf_gpl_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)3497 static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac),
3498 bAnimListElem *UNUSED(ale),
3499 eAnimChannel_Settings setting)
3500 {
3501 switch (setting) {
3502 /* unsupported */
3503 case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */
3504 case ACHANNEL_SETTING_SOLO: /* nla editor only */
3505 case ACHANNEL_SETTING_MOD_OFF:
3506 case ACHANNEL_SETTING_PINNED: /* nla actions only */
3507 return false;
3508
3509 /* always available */
3510 default:
3511 return true;
3512 }
3513 }
3514
3515 /* get the appropriate flag(s) for the setting when it is valid */
acf_gpl_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3516 static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
3517 {
3518 /* clear extra return data first */
3519 *neg = false;
3520
3521 switch (setting) {
3522 case ACHANNEL_SETTING_SELECT: /* selected */
3523 return GP_LAYER_SELECT;
3524
3525 case ACHANNEL_SETTING_MUTE: /* animation muting - similar to frame lock... */
3526 return GP_LAYER_FRAMELOCK;
3527
3528 case ACHANNEL_SETTING_VISIBLE: /* visibility of the layers (NOT muting) */
3529 *neg = true;
3530 return GP_LAYER_HIDE;
3531
3532 case ACHANNEL_SETTING_PROTECT: /* protected */
3533 return GP_LAYER_LOCKED;
3534
3535 default: /* unsupported */
3536 return 0;
3537 }
3538 }
3539
3540 /* get pointer to the setting */
acf_gpl_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)3541 static void *acf_gpl_setting_ptr(bAnimListElem *ale,
3542 eAnimChannel_Settings UNUSED(setting),
3543 short *type)
3544 {
3545 bGPDlayer *gpl = (bGPDlayer *)ale->data;
3546
3547 /* all flags are just in gpl->flag for now... */
3548 return GET_ACF_FLAG_PTR(gpl->flag, type);
3549 }
3550
3551 /* grease pencil layer type define */
3552 static bAnimChannelType ACF_GPL = {
3553 "GPencil Layer", /* type name */
3554 ACHANNEL_ROLE_CHANNEL, /* role */
3555
3556 acf_gpencil_channel_color, /* backdrop color */
3557 acf_generic_channel_backdrop, /* backdrop */
3558 acf_generic_indention_flexible, /* indent level */
3559 acf_generic_group_offset, /* offset */
3560
3561 acf_gpl_name, /* name */
3562 acf_gpl_name_prop, /* name prop */
3563 NULL, /* icon */
3564
3565 acf_gpl_setting_valid, /* has setting */
3566 acf_gpl_setting_flag, /* flag for setting */
3567 acf_gpl_setting_ptr, /* pointer for setting */
3568 };
3569
3570 /* Mask Datablock ------------------------------------------- */
3571
3572 /* get backdrop color for mask datablock widget */
acf_mask_color(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),float r_color[3])3573 static void acf_mask_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
3574 {
3575 /* these are ID-blocks, but not exactly standalone... */
3576 UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
3577 }
3578
3579 /* TODO: just get this from RNA? */
acf_mask_icon(bAnimListElem * UNUSED (ale))3580 static int acf_mask_icon(bAnimListElem *UNUSED(ale))
3581 {
3582 return ICON_MOD_MASK;
3583 }
3584
3585 /* check if some setting exists for this channel */
acf_mask_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)3586 static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac),
3587 bAnimListElem *UNUSED(ale),
3588 eAnimChannel_Settings setting)
3589 {
3590 switch (setting) {
3591 /* only select and expand supported */
3592 case ACHANNEL_SETTING_SELECT:
3593 case ACHANNEL_SETTING_EXPAND:
3594 return true;
3595
3596 default:
3597 return false;
3598 }
3599 }
3600
3601 /* get the appropriate flag(s) for the setting when it is valid */
acf_mask_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3602 static int acf_mask_setting_flag(bAnimContext *UNUSED(ac),
3603 eAnimChannel_Settings setting,
3604 bool *neg)
3605 {
3606 /* clear extra return data first */
3607 *neg = false;
3608
3609 switch (setting) {
3610 case ACHANNEL_SETTING_SELECT: /* selected */
3611 return AGRP_SELECTED;
3612
3613 case ACHANNEL_SETTING_EXPAND: /* expanded */
3614 return MASK_ANIMF_EXPAND;
3615
3616 default:
3617 /* this shouldn't happen */
3618 return 0;
3619 }
3620 }
3621
3622 /* get pointer to the setting */
acf_mask_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)3623 static void *acf_mask_setting_ptr(bAnimListElem *ale,
3624 eAnimChannel_Settings UNUSED(setting),
3625 short *type)
3626 {
3627 Mask *mask = (Mask *)ale->data;
3628
3629 /* all flags are just in mask->flag for now... */
3630 return GET_ACF_FLAG_PTR(mask->flag, type);
3631 }
3632
3633 /* mask datablock type define */
3634 static bAnimChannelType ACF_MASKDATA = {
3635 "Mask Datablock", /* type name */
3636 ACHANNEL_ROLE_EXPANDER, /* role */
3637
3638 acf_mask_color, /* backdrop color */
3639 acf_group_backdrop, /* backdrop */
3640 acf_generic_indention_0, /* indent level */
3641 acf_generic_group_offset, /* offset */
3642
3643 acf_generic_idblock_name, /* name */
3644 acf_generic_idfill_name_prop, /* name prop */
3645 acf_mask_icon, /* icon */
3646
3647 acf_mask_setting_valid, /* has setting */
3648 acf_mask_setting_flag, /* flag for setting */
3649 acf_mask_setting_ptr, /* pointer for setting */
3650 };
3651
3652 /* Mask Layer ------------------------------------------- */
3653
3654 /* name for grease pencil layer entries */
acf_masklay_name(bAnimListElem * ale,char * name)3655 static void acf_masklay_name(bAnimListElem *ale, char *name)
3656 {
3657 MaskLayer *masklay = (MaskLayer *)ale->data;
3658
3659 if (masklay && name) {
3660 BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE);
3661 }
3662 }
3663
3664 /* name property for grease pencil layer entries */
acf_masklay_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)3665 static bool acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
3666 {
3667 if (ale->data) {
3668 RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr);
3669 *prop = RNA_struct_name_property(ptr->type);
3670
3671 return (*prop != NULL);
3672 }
3673
3674 return false;
3675 }
3676
3677 /* check if some setting exists for this channel */
acf_masklay_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * UNUSED (ale),eAnimChannel_Settings setting)3678 static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac),
3679 bAnimListElem *UNUSED(ale),
3680 eAnimChannel_Settings setting)
3681 {
3682 switch (setting) {
3683 /* unsupported */
3684 case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */
3685 case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
3686 case ACHANNEL_SETTING_SOLO: /* nla editor only */
3687 case ACHANNEL_SETTING_MOD_OFF:
3688 case ACHANNEL_SETTING_PINNED: /* nla actions only */
3689 case ACHANNEL_SETTING_MUTE:
3690 return false;
3691
3692 /* always available */
3693 default:
3694 return true;
3695 }
3696 }
3697
3698 /* get the appropriate flag(s) for the setting when it is valid */
acf_masklay_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3699 static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac),
3700 eAnimChannel_Settings setting,
3701 bool *neg)
3702 {
3703 /* clear extra return data first */
3704 *neg = false;
3705
3706 switch (setting) {
3707 case ACHANNEL_SETTING_SELECT: /* selected */
3708 return MASK_LAYERFLAG_SELECT;
3709
3710 case ACHANNEL_SETTING_PROTECT: /* protected */
3711 return MASK_LAYERFLAG_LOCKED;
3712
3713 default: /* unsupported */
3714 return 0;
3715 }
3716 }
3717
3718 /* get pointer to the setting */
acf_masklay_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)3719 static void *acf_masklay_setting_ptr(bAnimListElem *ale,
3720 eAnimChannel_Settings UNUSED(setting),
3721 short *type)
3722 {
3723 MaskLayer *masklay = (MaskLayer *)ale->data;
3724
3725 /* all flags are just in masklay->flag for now... */
3726 return GET_ACF_FLAG_PTR(masklay->flag, type);
3727 }
3728
3729 /* grease pencil layer type define */
3730 static bAnimChannelType ACF_MASKLAYER = {
3731 "Mask Layer", /* type name */
3732 ACHANNEL_ROLE_CHANNEL, /* role */
3733
3734 acf_generic_channel_color, /* backdrop color */
3735 acf_generic_channel_backdrop, /* backdrop */
3736 acf_generic_indention_flexible, /* indent level */
3737 acf_generic_group_offset, /* offset */
3738
3739 acf_masklay_name, /* name */
3740 acf_masklay_name_prop, /* name prop */
3741 NULL, /* icon */
3742
3743 acf_masklay_setting_valid, /* has setting */
3744 acf_masklay_setting_flag, /* flag for setting */
3745 acf_masklay_setting_ptr, /* pointer for setting */
3746 };
3747
3748 /* NLA Track ----------------------------------------------- */
3749
3750 /* get backdrop color for nla track channels */
acf_nlatrack_color(bAnimContext * UNUSED (ac),bAnimListElem * ale,float r_color[3])3751 static void acf_nlatrack_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float r_color[3])
3752 {
3753 NlaTrack *nlt = (NlaTrack *)ale->data;
3754 AnimData *adt = ale->adt;
3755 bool nonSolo = false;
3756
3757 /* is track enabled for solo drawing? */
3758 if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) {
3759 if ((nlt->flag & NLATRACK_SOLO) == 0) {
3760 /* tag for special non-solo handling */
3761 nonSolo = true;
3762 }
3763 }
3764
3765 /* set color for nla track */
3766 UI_GetThemeColorShade3fv(TH_NLA_TRACK, ((nonSolo == false) ? 20 : -20), r_color);
3767 }
3768
3769 /* name for nla track entries */
acf_nlatrack_name(bAnimListElem * ale,char * name)3770 static void acf_nlatrack_name(bAnimListElem *ale, char *name)
3771 {
3772 NlaTrack *nlt = (NlaTrack *)ale->data;
3773
3774 if (nlt && name) {
3775 BLI_strncpy(name, nlt->name, ANIM_CHAN_NAME_SIZE);
3776 }
3777 }
3778
3779 /* name property for nla track entries */
acf_nlatrack_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)3780 static bool acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
3781 {
3782 if (ale->data) {
3783 RNA_pointer_create(ale->id, &RNA_NlaTrack, ale->data, ptr);
3784 *prop = RNA_struct_name_property(ptr->type);
3785
3786 return (*prop != NULL);
3787 }
3788
3789 return false;
3790 }
3791
3792 /* check if some setting exists for this channel */
acf_nlatrack_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * ale,eAnimChannel_Settings setting)3793 static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac),
3794 bAnimListElem *ale,
3795 eAnimChannel_Settings setting)
3796 {
3797 NlaTrack *nlt = (NlaTrack *)ale->data;
3798 AnimData *adt = ale->adt;
3799
3800 /* visibility of settings depends on various states... */
3801 switch (setting) {
3802 /* always supported */
3803 case ACHANNEL_SETTING_SELECT:
3804 case ACHANNEL_SETTING_SOLO:
3805 return true;
3806
3807 /* conditionally supported... */
3808 case ACHANNEL_SETTING_PROTECT:
3809 case ACHANNEL_SETTING_MUTE:
3810 /* if this track is active and we're tweaking it, don't draw these toggles */
3811 if (((nlt->flag & NLATRACK_ACTIVE) && (nlt->flag & NLATRACK_DISABLED)) == 0) {
3812 /* is track enabled for solo drawing? */
3813 if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) {
3814 if (nlt->flag & NLATRACK_SOLO) {
3815 /* ok - we've got a solo track, and this is it */
3816 return true;
3817 }
3818 /* not ok - we've got a solo track, but this isn't it, so make it more obvious */
3819 return false;
3820 }
3821
3822 /* ok - no tracks are solo'd, and this isn't being tweaked */
3823 return true;
3824 }
3825 /* unsupported - this track is being tweaked */
3826 return false;
3827
3828 /* unsupported */
3829 default:
3830 return false;
3831 }
3832 }
3833
3834 /* get the appropriate flag(s) for the setting when it is valid */
acf_nlatrack_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)3835 static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac),
3836 eAnimChannel_Settings setting,
3837 bool *neg)
3838 {
3839 /* clear extra return data first */
3840 *neg = false;
3841
3842 switch (setting) {
3843 case ACHANNEL_SETTING_SELECT: /* selected */
3844 return NLATRACK_SELECTED;
3845
3846 case ACHANNEL_SETTING_MUTE: /* muted */
3847 return NLATRACK_MUTED;
3848
3849 case ACHANNEL_SETTING_PROTECT: /* protected */
3850 return NLATRACK_PROTECTED;
3851
3852 case ACHANNEL_SETTING_SOLO: /* solo */
3853 return NLATRACK_SOLO;
3854
3855 default: /* unsupported */
3856 return 0;
3857 }
3858 }
3859
3860 /* get pointer to the setting */
acf_nlatrack_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)3861 static void *acf_nlatrack_setting_ptr(bAnimListElem *ale,
3862 eAnimChannel_Settings UNUSED(setting),
3863 short *type)
3864 {
3865 NlaTrack *nlt = (NlaTrack *)ale->data;
3866 return GET_ACF_FLAG_PTR(nlt->flag, type);
3867 }
3868
3869 /* nla track type define */
3870 static bAnimChannelType ACF_NLATRACK = {
3871 "NLA Track", /* type name */
3872 ACHANNEL_ROLE_CHANNEL, /* role */
3873
3874 acf_nlatrack_color, /* backdrop color */
3875 acf_generic_channel_backdrop, /* backdrop */
3876 acf_generic_indention_flexible, /* indent level */
3877 acf_generic_group_offset,
3878 /* offset */ /* XXX? */
3879
3880 acf_nlatrack_name, /* name */
3881 acf_nlatrack_name_prop, /* name prop */
3882 NULL, /* icon */
3883
3884 acf_nlatrack_setting_valid, /* has setting */
3885 acf_nlatrack_setting_flag, /* flag for setting */
3886 acf_nlatrack_setting_ptr, /* pointer for setting */
3887 };
3888
3889 /* NLA Action ----------------------------------------------- */
3890
3891 /* icon for action depends on whether it's in tweaking mode */
acf_nlaaction_icon(bAnimListElem * ale)3892 static int acf_nlaaction_icon(bAnimListElem *ale)
3893 {
3894 AnimData *adt = ale->adt;
3895
3896 /* indicate tweaking-action state by changing the icon... */
3897 if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
3898 return ICON_ACTION_TWEAK;
3899 }
3900
3901 return ICON_ACTION;
3902 }
3903
3904 /* Backdrop color for nla action channel
3905 * Although this can't be used directly for NLA Action drawing,
3906 * it is still needed for use behind the RHS toggles
3907 */
acf_nlaaction_color(bAnimContext * UNUSED (ac),bAnimListElem * ale,float r_color[3])3908 static void acf_nlaaction_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float r_color[3])
3909 {
3910 float color[4];
3911
3912 /* Action Line
3913 * The alpha values action_get_color returns are only useful for drawing
3914 * strips backgrounds but here we're doing channel list backgrounds instead
3915 * so we ignore that and use our own when needed
3916 */
3917 nla_action_get_color(ale->adt, (bAction *)ale->data, color);
3918
3919 /* NOTE: since the return types only allow rgb, we cannot do the alpha-blending we'd
3920 * like for the solo-drawing case. Hence, this method isn't actually used for drawing
3921 * most of the channel...
3922 */
3923 copy_v3_v3(r_color, color);
3924 }
3925
3926 /* backdrop for nla action channel */
acf_nlaaction_backdrop(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc)3927 static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
3928 {
3929 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
3930 View2D *v2d = &ac->region->v2d;
3931 AnimData *adt = ale->adt;
3932 short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
3933 float color[4];
3934
3935 /* Action Line
3936 * The alpha values action_get_color returns are only useful for drawing
3937 * strips backgrounds but here we're doing channel list backgrounds instead
3938 * so we ignore that and use our own when needed
3939 */
3940 nla_action_get_color(adt, (bAction *)ale->data, color);
3941
3942 if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
3943 color[3] = 1.0f;
3944 }
3945 else {
3946 color[3] = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f;
3947 }
3948
3949 /* only on top left corner, to show that this channel sits on top of the preceding ones
3950 * while still linking into the action line strip to the right
3951 */
3952 UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT);
3953
3954 /* draw slightly shifted up vertically to look like it has more separation from other channels,
3955 * but we then need to slightly shorten it so that it doesn't look like it overlaps
3956 */
3957 UI_draw_roundbox_4fv(true,
3958 offset,
3959 yminc + NLACHANNEL_SKIP,
3960 (float)v2d->cur.xmax,
3961 ymaxc + NLACHANNEL_SKIP - 1,
3962 8,
3963 color);
3964 }
3965
3966 /* name for nla action entries */
acf_nlaaction_name(bAnimListElem * ale,char * name)3967 static void acf_nlaaction_name(bAnimListElem *ale, char *name)
3968 {
3969 bAction *act = (bAction *)ale->data;
3970
3971 if (name) {
3972 if (act) {
3973 /* TODO: add special decoration when doing this in tweaking mode? */
3974 BLI_strncpy(name, act->id.name + 2, ANIM_CHAN_NAME_SIZE);
3975 }
3976 else {
3977 BLI_strncpy(name, "<No Action>", ANIM_CHAN_NAME_SIZE);
3978 }
3979 }
3980 }
3981
3982 /* name property for nla action entries */
acf_nlaaction_name_prop(bAnimListElem * ale,PointerRNA * ptr,PropertyRNA ** prop)3983 static bool acf_nlaaction_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
3984 {
3985 if (ale->data) {
3986 RNA_pointer_create(ale->id, &RNA_Action, ale->data, ptr);
3987 *prop = RNA_struct_name_property(ptr->type);
3988
3989 return (*prop != NULL);
3990 }
3991
3992 return false;
3993 }
3994
3995 /* check if some setting exists for this channel */
acf_nlaaction_setting_valid(bAnimContext * UNUSED (ac),bAnimListElem * ale,eAnimChannel_Settings setting)3996 static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac),
3997 bAnimListElem *ale,
3998 eAnimChannel_Settings setting)
3999 {
4000 AnimData *adt = ale->adt;
4001
4002 /* visibility of settings depends on various states... */
4003 switch (setting) {
4004 /* conditionally supported */
4005 case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
4006 if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
4007 /* this should only appear in tweakmode */
4008 return true;
4009 }
4010 else {
4011 return false;
4012 }
4013
4014 /* unsupported */
4015 default:
4016 return false;
4017 }
4018 }
4019
4020 /* get the appropriate flag(s) for the setting when it is valid */
acf_nlaaction_setting_flag(bAnimContext * UNUSED (ac),eAnimChannel_Settings setting,bool * neg)4021 static int acf_nlaaction_setting_flag(bAnimContext *UNUSED(ac),
4022 eAnimChannel_Settings setting,
4023 bool *neg)
4024 {
4025 /* clear extra return data first */
4026 *neg = false;
4027
4028 switch (setting) {
4029 case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
4030 *neg = true; /* XXX */
4031 return ADT_NLA_EDIT_NOMAP;
4032
4033 default: /* unsupported */
4034 return 0;
4035 }
4036 }
4037
4038 /* get pointer to the setting */
acf_nlaaction_setting_ptr(bAnimListElem * ale,eAnimChannel_Settings UNUSED (setting),short * type)4039 static void *acf_nlaaction_setting_ptr(bAnimListElem *ale,
4040 eAnimChannel_Settings UNUSED(setting),
4041 short *type)
4042 {
4043 AnimData *adt = ale->adt;
4044 return GET_ACF_FLAG_PTR(adt->flag, type);
4045 }
4046
4047 /* nla action type define */
4048 static bAnimChannelType ACF_NLAACTION = {
4049 "NLA Active Action", /* type name */
4050 ACHANNEL_ROLE_CHANNEL, /* role */
4051
4052 acf_nlaaction_color, /* backdrop color (NOTE: the backdrop handles this too,
4053 * since it needs special hacks). */
4054 acf_nlaaction_backdrop, /* backdrop */
4055 acf_generic_indention_flexible, /* indent level */
4056 acf_generic_group_offset,
4057 /* offset */ /* XXX? */
4058
4059 acf_nlaaction_name, /* name */
4060 acf_nlaaction_name_prop, /* name prop */
4061 acf_nlaaction_icon, /* icon */
4062
4063 acf_nlaaction_setting_valid, /* has setting */
4064 acf_nlaaction_setting_flag, /* flag for setting */
4065 acf_nlaaction_setting_ptr, /* pointer for setting */
4066 };
4067
4068 /* *********************************************** */
4069 /* Type Registration and General Access */
4070
4071 /* These globals only ever get directly accessed in this file */
4072 static bAnimChannelType *animchannelTypeInfo[ANIMTYPE_NUM_TYPES];
4073 static short ACF_INIT = 1; /* when non-zero, the list needs to be updated */
4074
4075 /* Initialize type info definitions */
ANIM_init_channel_typeinfo_data(void)4076 static void ANIM_init_channel_typeinfo_data(void)
4077 {
4078 int type = 0;
4079
4080 /* start initializing if necessary... */
4081 if (ACF_INIT) {
4082 ACF_INIT = 0;
4083
4084 /* NOTE: need to keep the order of these synchronized with the definition of
4085 * channel types (eAnim_ChannelType) in ED_anim_api.h
4086 */
4087 animchannelTypeInfo[type++] = NULL; /* None */
4088 animchannelTypeInfo[type++] = NULL; /* AnimData */
4089 animchannelTypeInfo[type++] = NULL; /* Special */
4090
4091 animchannelTypeInfo[type++] = &ACF_SUMMARY; /* Motion Summary */
4092
4093 animchannelTypeInfo[type++] = &ACF_SCENE; /* Scene */
4094 animchannelTypeInfo[type++] = &ACF_OBJECT; /* Object */
4095 animchannelTypeInfo[type++] = &ACF_GROUP; /* Group */
4096 animchannelTypeInfo[type++] = &ACF_FCURVE; /* F-Curve */
4097
4098 animchannelTypeInfo[type++] = &ACF_NLACONTROLS; /* NLA Control FCurve Expander */
4099 animchannelTypeInfo[type++] = &ACF_NLACURVE; /* NLA Control FCurve Channel */
4100
4101 animchannelTypeInfo[type++] = &ACF_FILLACTD; /* Object Action Expander */
4102 animchannelTypeInfo[type++] = &ACF_FILLDRIVERS; /* Drivers Expander */
4103
4104 animchannelTypeInfo[type++] = &ACF_DSMAT; /* Material Channel */
4105 animchannelTypeInfo[type++] = &ACF_DSLIGHT; /* Light Channel */
4106 animchannelTypeInfo[type++] = &ACF_DSCAM; /* Camera Channel */
4107 animchannelTypeInfo[type++] = &ACF_DSCACHEFILE; /* CacheFile Channel */
4108 animchannelTypeInfo[type++] = &ACF_DSCUR; /* Curve Channel */
4109 animchannelTypeInfo[type++] = &ACF_DSSKEY; /* ShapeKey Channel */
4110 animchannelTypeInfo[type++] = &ACF_DSWOR; /* World Channel */
4111 animchannelTypeInfo[type++] = &ACF_DSNTREE; /* NodeTree Channel */
4112 animchannelTypeInfo[type++] = &ACF_DSPART; /* Particle Channel */
4113 animchannelTypeInfo[type++] = &ACF_DSMBALL; /* MetaBall Channel */
4114 animchannelTypeInfo[type++] = &ACF_DSARM; /* Armature Channel */
4115 animchannelTypeInfo[type++] = &ACF_DSMESH; /* Mesh Channel */
4116 animchannelTypeInfo[type++] = &ACF_DSTEX; /* Texture Channel */
4117 animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */
4118 animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */
4119 animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */
4120 animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */
4121 animchannelTypeInfo[type++] = &ACF_DSMCLIP; /* MovieClip Channel */
4122 animchannelTypeInfo[type++] = &ACF_DSHAIR; /* Hair Channel */
4123 animchannelTypeInfo[type++] = &ACF_DSPOINTCLOUD; /* PointCloud Channel */
4124 animchannelTypeInfo[type++] = &ACF_DSVOLUME; /* Volume Channel */
4125 animchannelTypeInfo[type++] = &ACF_DSSIMULATION; /* Simulation Channel */
4126
4127 animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */
4128
4129 animchannelTypeInfo[type++] = &ACF_GPD; /* Grease Pencil Datablock */
4130 animchannelTypeInfo[type++] = &ACF_GPL; /* Grease Pencil Layer */
4131
4132 animchannelTypeInfo[type++] = &ACF_MASKDATA; /* Mask Datablock */
4133 animchannelTypeInfo[type++] = &ACF_MASKLAYER; /* Mask Layer */
4134
4135 animchannelTypeInfo[type++] = &ACF_NLATRACK; /* NLA Track */
4136 animchannelTypeInfo[type++] = &ACF_NLAACTION; /* NLA Action */
4137 }
4138 }
4139
4140 /* Get type info from given channel type */
ANIM_channel_get_typeinfo(bAnimListElem * ale)4141 const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
4142 {
4143 /* santiy checks */
4144 if (ale == NULL) {
4145 return NULL;
4146 }
4147
4148 /* init the typeinfo if not available yet... */
4149 ANIM_init_channel_typeinfo_data();
4150
4151 /* check if type is in bounds... */
4152 if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES)) {
4153 return animchannelTypeInfo[ale->type];
4154 }
4155
4156 return NULL;
4157 }
4158
4159 /* --------------------------- */
4160
4161 /* Print debug info string for the given channel */
ANIM_channel_debug_print_info(bAnimListElem * ale,short indent_level)4162 void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level)
4163 {
4164 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
4165
4166 /* print indents */
4167 for (; indent_level > 0; indent_level--) {
4168 printf(" ");
4169 }
4170
4171 /* print info */
4172 if (acf) {
4173 char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
4174
4175 /* get UI name */
4176 if (acf->name) {
4177 acf->name(ale, name);
4178 }
4179 else {
4180 BLI_strncpy(name, "<No name>", sizeof(name));
4181 }
4182
4183 /* print type name + ui name */
4184 printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name);
4185 }
4186 else if (ale) {
4187 printf("ChanType: <Unknown - %d>\n", ale->type);
4188 }
4189 else {
4190 printf("<Invalid channel - NULL>\n");
4191 }
4192 }
4193
4194 /* --------------------------- */
4195
4196 /* Check if some setting for a channel is enabled
4197 * Returns: 1 = On, 0 = Off, -1 = Invalid
4198 */
ANIM_channel_setting_get(bAnimContext * ac,bAnimListElem * ale,eAnimChannel_Settings setting)4199 short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
4200 {
4201 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
4202
4203 /* 1) check that the setting exists for the current context */
4204 if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
4205 /* 2) get pointer to check for flag in, and the flag to check for */
4206 short ptrsize;
4207 bool negflag;
4208 int flag;
4209 void *ptr;
4210
4211 flag = acf->setting_flag(ac, setting, &negflag);
4212 ptr = acf->setting_ptr(ale, setting, &ptrsize);
4213
4214 /* check if flag is enabled */
4215 if (ptr && flag) {
4216 switch (ptrsize) {
4217 case sizeof(int): /* integer pointer for setting */
4218 {
4219 const int *val = (int *)ptr;
4220
4221 if (negflag) {
4222 return ((*val) & flag) == 0;
4223 }
4224 return ((*val) & flag) != 0;
4225 }
4226 case sizeof(short): /* short pointer for setting */
4227 {
4228 const short *val = (short *)ptr;
4229
4230 if (negflag) {
4231 return ((*val) & flag) == 0;
4232 }
4233 return ((*val) & flag) != 0;
4234 }
4235 case sizeof(char): /* char pointer for setting */
4236 {
4237 const char *val = (char *)ptr;
4238
4239 if (negflag) {
4240 return ((*val) & flag) == 0;
4241 }
4242 return ((*val) & flag) != 0;
4243 }
4244 }
4245 }
4246 }
4247
4248 /* not found... */
4249 return -1;
4250 }
4251
4252 /* Quick macro for use in ANIM_channel_setting_set -
4253 * set flag for setting according the mode given. */
4254 #define ACF_SETTING_SET(sval, sflag, smode) \
4255 { \
4256 if (negflag) { \
4257 if (smode == ACHANNEL_SETFLAG_INVERT) { \
4258 (sval) ^= (sflag); \
4259 } \
4260 else if (smode == ACHANNEL_SETFLAG_ADD) { \
4261 (sval) &= ~(sflag); \
4262 } \
4263 else { \
4264 (sval) |= (sflag); \
4265 } \
4266 } \
4267 else { \
4268 if (smode == ACHANNEL_SETFLAG_INVERT) { \
4269 (sval) ^= (sflag); \
4270 } \
4271 else if (smode == ACHANNEL_SETFLAG_ADD) { \
4272 (sval) |= (sflag); \
4273 } \
4274 else { \
4275 (sval) &= ~(sflag); \
4276 } \
4277 } \
4278 } \
4279 (void)0
4280
4281 /* Change value of some setting for a channel
4282 * - setting: eAnimChannel_Settings
4283 * - mode: eAnimChannels_SetFlag
4284 */
ANIM_channel_setting_set(bAnimContext * ac,bAnimListElem * ale,eAnimChannel_Settings setting,eAnimChannels_SetFlag mode)4285 void ANIM_channel_setting_set(bAnimContext *ac,
4286 bAnimListElem *ale,
4287 eAnimChannel_Settings setting,
4288 eAnimChannels_SetFlag mode)
4289 {
4290 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
4291
4292 /* 1) check that the setting exists for the current context */
4293 if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
4294 /* 2) get pointer to check for flag in, and the flag to check for */
4295 short ptrsize;
4296 bool negflag;
4297 int flag;
4298 void *ptr;
4299
4300 flag = acf->setting_flag(ac, setting, &negflag);
4301 ptr = acf->setting_ptr(ale, setting, &ptrsize);
4302
4303 /* check if flag is enabled */
4304 if (ptr && flag) {
4305 switch (ptrsize) {
4306 case sizeof(int): /* integer pointer for setting */
4307 {
4308 int *val = (int *)ptr;
4309 ACF_SETTING_SET(*val, flag, mode);
4310 break;
4311 }
4312 case sizeof(short): /* short pointer for setting */
4313 {
4314 short *val = (short *)ptr;
4315 ACF_SETTING_SET(*val, flag, mode);
4316 break;
4317 }
4318 case sizeof(char): /* char pointer for setting */
4319 {
4320 char *val = (char *)ptr;
4321 ACF_SETTING_SET(*val, flag, mode);
4322 break;
4323 }
4324 }
4325 }
4326 }
4327 }
4328
4329 /* --------------------------- */
4330
4331 /* size of icons */
4332 #define ICON_WIDTH (0.85f * U.widget_unit)
4333 /* width of sliders */
4334 #define SLIDER_WIDTH (4 * U.widget_unit)
4335 /* min-width of rename textboxes */
4336 #define RENAME_TEXT_MIN_WIDTH (U.widget_unit)
4337 /* width of graph editor color bands */
4338 #define GRAPH_COLOR_BAND_WIDTH (0.3f * U.widget_unit)
4339 /* extra offset for the visibility icons in the graph editor */
4340 #define GRAPH_ICON_VISIBILITY_OFFSET (GRAPH_COLOR_BAND_WIDTH * 1.5f)
4341
4342 /* Helper - Check if a channel needs renaming */
achannel_is_being_renamed(const bAnimContext * ac,const bAnimChannelType * acf,size_t channel_index)4343 static bool achannel_is_being_renamed(const bAnimContext *ac,
4344 const bAnimChannelType *acf,
4345 size_t channel_index)
4346 {
4347 if (acf->name_prop && ac->ads) {
4348 /* if rename index matches, this channel is being renamed */
4349 if (ac->ads->renameIndex == channel_index + 1) {
4350 return true;
4351 }
4352 }
4353
4354 /* not being renamed */
4355 return false;
4356 }
4357
4358 /* Draw the given channel */
ANIM_channel_draw(bAnimContext * ac,bAnimListElem * ale,float yminc,float ymaxc,size_t channel_index)4359 void ANIM_channel_draw(
4360 bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index)
4361 {
4362 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
4363 View2D *v2d = &ac->region->v2d;
4364 short selected, offset;
4365 float y, ymid, ytext;
4366
4367 /* sanity checks - don't draw anything */
4368 if (ELEM(NULL, acf, ale)) {
4369 return;
4370 }
4371
4372 /* get initial offset */
4373 if (acf->get_offset) {
4374 offset = acf->get_offset(ac, ale);
4375 }
4376 else {
4377 offset = 0;
4378 }
4379
4380 /* calculate appropriate y-coordinates for icon buttons */
4381 y = (ymaxc - yminc) / 2 + yminc;
4382 ymid = y - 0.5f * ICON_WIDTH;
4383 /* y-coordinates for text is only 4 down from middle */
4384 ytext = y - 0.2f * U.widget_unit;
4385
4386 /* check if channel is selected */
4387 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT)) {
4388 selected = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
4389 }
4390 else {
4391 selected = 0;
4392 }
4393
4394 /* set blending again, as may not be set in previous step */
4395 GPU_blend(GPU_BLEND_ALPHA);
4396
4397 /* step 1) draw backdrop ........................................... */
4398 if (acf->draw_backdrop) {
4399 acf->draw_backdrop(ac, ale, yminc, ymaxc);
4400 }
4401
4402 /* step 2) draw expand widget ....................................... */
4403 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
4404 /* just skip - drawn as widget now */
4405 offset += ICON_WIDTH;
4406 }
4407
4408 /* step 3) draw icon ............................................... */
4409 if (acf->icon) {
4410 UI_icon_draw(offset, ymid, acf->icon(ale));
4411 offset += ICON_WIDTH;
4412 }
4413
4414 /* step 4) draw special toggles .................................
4415 * - in Graph Editor, check-boxes for visibility in curves area
4416 * - in NLA Editor, glowing dots for solo/not solo...
4417 * - in Grease Pencil mode, color swatches for layer color
4418 */
4419 if (ac->sl) {
4420 if ((ac->spacetype == SPACE_GRAPH) &&
4421 (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
4422 acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE))) {
4423 /* for F-Curves, draw color-preview of curve left to the visibility icon */
4424 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
4425 FCurve *fcu = (FCurve *)ale->data;
4426 uint pos = GPU_vertformat_attr_add(
4427 immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
4428
4429 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
4430
4431 /* F-Curve channels need to have a special 'color code' box drawn,
4432 * which is colored with whatever color the curve has stored.
4433 */
4434
4435 /* If the curve is hidden, make the rect less opaque. */
4436 float rect_alpha = (fcu->flag & FCURVE_VISIBLE) ? 1 : 0.3f;
4437 immUniformColor3fvAlpha(fcu->color, rect_alpha);
4438
4439 immRectf(pos, offset, yminc, offset + GRAPH_COLOR_BAND_WIDTH, ymaxc);
4440 immUnbindProgram();
4441 }
4442
4443 /* turn off blending, since not needed anymore... */
4444 GPU_blend(GPU_BLEND_NONE);
4445
4446 /* icon is drawn as widget now... */
4447 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
4448 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
4449 offset += ICON_WIDTH + GRAPH_ICON_VISIBILITY_OFFSET;
4450 }
4451 else {
4452 offset += ICON_WIDTH;
4453 }
4454 }
4455 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
4456 offset += ICON_WIDTH;
4457 }
4458 }
4459 else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
4460 /* just skip - drawn as widget now */
4461 offset += ICON_WIDTH;
4462 }
4463 }
4464
4465 /* step 5) draw name ............................................... */
4466 /* Don't draw this if renaming... */
4467 if (acf->name && !achannel_is_being_renamed(ac, acf, channel_index)) {
4468 const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
4469 char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
4470 uchar col[4];
4471
4472 /* set text color */
4473 /* XXX: if active, highlight differently? */
4474
4475 if (selected) {
4476 UI_GetThemeColor4ubv(TH_TEXT_HI, col);
4477 }
4478 else {
4479 UI_GetThemeColor4ubv(TH_TEXT, col);
4480 }
4481
4482 /* get name */
4483 acf->name(ale, name);
4484
4485 offset += 3;
4486 UI_fontstyle_draw_simple(fstyle, offset, ytext, name, col);
4487
4488 /* draw red underline if channel is disabled */
4489 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) {
4490 uint pos = GPU_vertformat_attr_add(
4491 immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
4492
4493 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
4494
4495 /* FIXME: replace hardcoded color here, and check on extents! */
4496 immUniformColor3f(1.0f, 0.0f, 0.0f);
4497
4498 GPU_line_width(2.0f);
4499
4500 immBegin(GPU_PRIM_LINES, 2);
4501 immVertex2f(pos, (float)offset, yminc);
4502 immVertex2f(pos, (float)v2d->cur.xmax, yminc);
4503 immEnd();
4504
4505 immUnbindProgram();
4506 }
4507 }
4508
4509 /* step 6) draw backdrops behind mute+protection toggles + (sliders) ....................... */
4510 /* - Reset offset - now goes from RHS of panel.
4511 * - Exception for graph editor, which needs extra space for the scroll bar.
4512 */
4513 if (ac->spacetype == SPACE_GRAPH &&
4514 ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_GROUP)) {
4515 offset = V2D_SCROLL_WIDTH;
4516 }
4517 else {
4518 offset = 0;
4519 }
4520
4521 /* TODO: when drawing sliders, make those draw instead of these toggles if not enough space */
4522
4523 if (v2d) {
4524 short draw_sliders = 0;
4525 float ymin_ofs = 0.0f;
4526 float color[3];
4527 uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
4528
4529 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
4530
4531 /* get and set backdrop color */
4532 acf->get_backdrop_color(ac, ale, color);
4533 immUniformColor3fv(color);
4534
4535 /* check if we need to show the sliders */
4536 if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH)) {
4537 switch (ac->spacetype) {
4538 case SPACE_ACTION: {
4539 SpaceAction *saction = (SpaceAction *)ac->sl;
4540 draw_sliders = (saction->flag & SACTION_SLIDERS);
4541 break;
4542 }
4543 case SPACE_GRAPH: {
4544 SpaceGraph *sipo = (SpaceGraph *)ac->sl;
4545 draw_sliders = (sipo->flag & SIPO_SLIDERS);
4546 break;
4547 }
4548 }
4549 }
4550
4551 /* check if there's enough space for the toggles if the sliders are drawn too */
4552 if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) {
4553 /* protect... */
4554 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
4555 offset += ICON_WIDTH;
4556 }
4557
4558 /* mute... */
4559 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) {
4560 offset += ICON_WIDTH;
4561 }
4562
4563 /* grease pencil visibility... */
4564 if (ale->type == ANIMTYPE_GPLAYER) {
4565 offset += ICON_WIDTH;
4566 }
4567
4568 /* modifiers toggle... */
4569 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) {
4570 offset += ICON_WIDTH;
4571 }
4572
4573 /* pinned... */
4574 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED)) {
4575 offset += ICON_WIDTH;
4576 }
4577
4578 /* NOTE: technically, NLA Action "pushdown" should be here too,
4579 * but there are no sliders there. */
4580
4581 /* NLA action channels have slightly different spacing requirements... */
4582 if (ale->type == ANIMTYPE_NLAACTION) {
4583 ymin_ofs = NLACHANNEL_SKIP;
4584 }
4585 }
4586
4587 /* Draw slider:
4588 * - Even if we can draw sliders for this view,
4589 * we must also check that the channel-type supports them
4590 * (only only F-Curves really can support them for now).
4591 * - Slider should start before the toggles (if they're visible)
4592 * to keep a clean line down the side.
4593 */
4594 if ((draw_sliders) &&
4595 ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY, ANIMTYPE_GPLAYER)) {
4596 /* adjust offset */
4597 offset += SLIDER_WIDTH;
4598 }
4599
4600 /* Finally draw a backdrop rect behind these:
4601 * - Starts from the point where the first toggle/slider starts.
4602 * - Ends past the space that might be reserved for a scroller.
4603 */
4604 immRectf(pos,
4605 v2d->cur.xmax - (float)offset,
4606 yminc + ymin_ofs,
4607 v2d->cur.xmax + EXTRA_SCROLL_PAD,
4608 ymaxc);
4609
4610 immUnbindProgram();
4611 }
4612 }
4613
4614 /* ------------------ */
4615
4616 /* callback for (normal) widget settings - send notifiers */
achannel_setting_widget_cb(bContext * C,void * UNUSED (arg1),void * UNUSED (arg2))4617 static void achannel_setting_widget_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
4618 {
4619 WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
4620 }
4621
4622 /* callback for widget settings that need flushing */
achannel_setting_flush_widget_cb(bContext * C,void * ale_npoin,void * setting_wrap)4623 static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void *setting_wrap)
4624 {
4625 bAnimListElem *ale_setting = (bAnimListElem *)ale_npoin;
4626 bAnimContext ac;
4627 ListBase anim_data = {NULL, NULL};
4628 int filter;
4629 int setting = POINTER_AS_INT(setting_wrap);
4630 short on = 0;
4631
4632 /* send notifiers before doing anything else... */
4633 WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
4634
4635 /* verify that we have a channel to operate on. */
4636 if (!ale_setting) {
4637 return;
4638 }
4639
4640 if (ale_setting->type == ANIMTYPE_GPLAYER) {
4641 /* draw cache updates for settings that affect the visible strokes */
4642 if (setting == ACHANNEL_SETTING_VISIBLE) {
4643 bGPdata *gpd = (bGPdata *)ale_setting->id;
4644 DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
4645 }
4646
4647 /* UI updates */
4648 WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
4649 }
4650
4651 /* Tag for full animation update, so that the settings will have an effect. */
4652 if (ale_setting->id) {
4653 DEG_id_tag_update(ale_setting->id, ID_RECALC_ANIMATION);
4654 }
4655 if (ale_setting->adt && ale_setting->adt->action) {
4656 /* Action is it's own datablock, so has to be tagged specifically. */
4657 DEG_id_tag_update(&ale_setting->adt->action->id, ID_RECALC_ANIMATION);
4658 }
4659
4660 /* verify animation context */
4661 if (ANIM_animdata_get_context(C, &ac) == 0) {
4662 return;
4663 }
4664
4665 /* check if the setting is on... */
4666 on = ANIM_channel_setting_get(&ac, ale_setting, setting);
4667
4668 /* on == -1 means setting not found... */
4669 if (on == -1) {
4670 return;
4671 }
4672
4673 /* get all channels that can possibly be chosen - but ignore hierarchy */
4674 filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
4675 ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
4676
4677 /* call API method to flush the setting */
4678 ANIM_flush_setting_anim_channels(&ac, &anim_data, ale_setting, setting, on);
4679
4680 /* free temp data */
4681 ANIM_animdata_freelist(&anim_data);
4682 }
4683
4684 /* callback for wrapping NLA Track "solo" toggle logic */
achannel_nlatrack_solo_widget_cb(bContext * C,void * ale_poin,void * UNUSED (arg2))4685 static void achannel_nlatrack_solo_widget_cb(bContext *C, void *ale_poin, void *UNUSED(arg2))
4686 {
4687 bAnimListElem *ale = ale_poin;
4688 AnimData *adt = ale->adt;
4689 NlaTrack *nlt = ale->data;
4690
4691 /* Toggle 'solo' mode. There are several complications here which need explaining:
4692 * - The method call is needed to perform a few additional validation operations
4693 * to ensure that the mode is applied properly
4694 * - BUT, since the button already toggles the value, we need to un-toggle it
4695 * before the API call gets to it, otherwise it will end up clearing the result
4696 * again!
4697 */
4698 nlt->flag ^= NLATRACK_SOLO;
4699 BKE_nlatrack_solo_toggle(adt, nlt);
4700
4701 /* send notifiers */
4702 DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
4703 WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
4704 }
4705
4706 /* callback for widget sliders - insert keyframes */
achannel_setting_slider_cb(bContext * C,void * id_poin,void * fcu_poin)4707 static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin)
4708 {
4709 ID *id = (ID *)id_poin;
4710 AnimData *adt = BKE_animdata_from_id(id);
4711 FCurve *fcu = (FCurve *)fcu_poin;
4712
4713 ReportList *reports = CTX_wm_reports(C);
4714 Scene *scene = CTX_data_scene(C);
4715 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
4716 ToolSettings *ts = scene->toolsettings;
4717 ListBase nla_cache = {NULL, NULL};
4718 PointerRNA id_ptr, ptr;
4719 PropertyRNA *prop;
4720 eInsertKeyFlags flag = 0;
4721 bool done = false;
4722 float cfra;
4723
4724 /* Get RNA pointer */
4725 RNA_id_pointer_create(id, &id_ptr);
4726
4727 /* Get NLA context for value remapping */
4728 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
4729 (float)CFRA);
4730 NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
4731 &nla_cache, &id_ptr, adt, &anim_eval_context, false);
4732
4733 /* get current frame and apply NLA-mapping to it (if applicable) */
4734 cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
4735
4736 /* Get flags for keyframing. */
4737 flag = ANIM_get_keyframing_flags(scene, true);
4738
4739 /* try to resolve the path stored in the F-Curve */
4740 if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
4741 /* set the special 'replace' flag if on a keyframe */
4742 if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
4743 flag |= INSERTKEY_REPLACE;
4744 }
4745
4746 /* insert a keyframe for this F-Curve */
4747 done = insert_keyframe_direct(
4748 reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, nla_context, flag);
4749
4750 if (done) {
4751 if (adt->action != NULL) {
4752 DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
4753 }
4754 DEG_id_tag_update(id, ID_RECALC_ANIMATION_NO_FLUSH);
4755 WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
4756 }
4757 }
4758
4759 BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
4760 }
4761
4762 /* callback for shapekey widget sliders - insert keyframes */
achannel_setting_slider_shapekey_cb(bContext * C,void * key_poin,void * kb_poin)4763 static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, void *kb_poin)
4764 {
4765 Main *bmain = CTX_data_main(C);
4766 Key *key = (Key *)key_poin;
4767 KeyBlock *kb = (KeyBlock *)kb_poin;
4768 char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
4769
4770 ReportList *reports = CTX_wm_reports(C);
4771 Scene *scene = CTX_data_scene(C);
4772 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
4773 ToolSettings *ts = scene->toolsettings;
4774 ListBase nla_cache = {NULL, NULL};
4775 PointerRNA id_ptr, ptr;
4776 PropertyRNA *prop;
4777 eInsertKeyFlags flag = 0;
4778 bool done = false;
4779
4780 /* Get RNA pointer */
4781 RNA_id_pointer_create((ID *)key, &id_ptr);
4782
4783 /* Get NLA context for value remapping */
4784 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
4785 (float)CFRA);
4786 NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
4787 &nla_cache, &id_ptr, key->adt, &anim_eval_context, false);
4788
4789 /* get current frame and apply NLA-mapping to it (if applicable) */
4790 const float remapped_frame = BKE_nla_tweakedit_remap(
4791 key->adt, anim_eval_context.eval_time, NLATIME_CONVERT_UNMAP);
4792
4793 /* get flags for keyframing */
4794 flag = ANIM_get_keyframing_flags(scene, true);
4795
4796 /* try to resolve the path stored in the F-Curve */
4797 if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
4798 /* find or create new F-Curve */
4799 /* XXX is the group name for this ok? */
4800 bAction *act = ED_id_action_ensure(bmain, (ID *)key);
4801 FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, &ptr, rna_path, 0);
4802
4803 /* set the special 'replace' flag if on a keyframe */
4804 if (fcurve_frame_has_keyframe(fcu, remapped_frame, 0)) {
4805 flag |= INSERTKEY_REPLACE;
4806 }
4807
4808 /* insert a keyframe for this F-Curve */
4809 const AnimationEvalContext remapped_anim_eval_context = BKE_animsys_eval_context_construct_at(
4810 &anim_eval_context, remapped_frame);
4811 done = insert_keyframe_direct(reports,
4812 ptr,
4813 prop,
4814 fcu,
4815 &remapped_anim_eval_context,
4816 ts->keyframe_type,
4817 nla_context,
4818 flag);
4819
4820 if (done) {
4821 WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
4822 }
4823 }
4824
4825 /* free the path */
4826 if (rna_path) {
4827 MEM_freeN(rna_path);
4828 }
4829
4830 BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
4831 }
4832
4833 /* callback for NLA Control Curve widget sliders - insert keyframes */
achannel_setting_slider_nla_curve_cb(bContext * C,void * UNUSED (id_poin),void * fcu_poin)4834 static void achannel_setting_slider_nla_curve_cb(bContext *C,
4835 void *UNUSED(id_poin),
4836 void *fcu_poin)
4837 {
4838 /* ID *id = (ID *)id_poin; */
4839 FCurve *fcu = (FCurve *)fcu_poin;
4840
4841 PointerRNA ptr;
4842 PropertyRNA *prop;
4843 int index;
4844
4845 ReportList *reports = CTX_wm_reports(C);
4846 Scene *scene = CTX_data_scene(C);
4847 ToolSettings *ts = scene->toolsettings;
4848 eInsertKeyFlags flag = 0;
4849 bool done = false;
4850 float cfra;
4851
4852 /* get current frame - *no* NLA mapping should be done */
4853 cfra = (float)CFRA;
4854
4855 /* get flags for keyframing */
4856 flag = ANIM_get_keyframing_flags(scene, true);
4857
4858 /* Get pointer and property from the slider -
4859 * this should all match up with the NlaStrip required. */
4860 UI_context_active_but_prop_get(C, &ptr, &prop, &index);
4861
4862 if (fcu && prop) {
4863 /* set the special 'replace' flag if on a keyframe */
4864 if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
4865 flag |= INSERTKEY_REPLACE;
4866 }
4867
4868 /* insert a keyframe for this F-Curve */
4869 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
4870 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
4871 cfra);
4872 done = insert_keyframe_direct(
4873 reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, flag);
4874
4875 if (done) {
4876 WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
4877 }
4878 }
4879 }
4880
4881 /* Draw a widget for some setting */
draw_setting_widget(bAnimContext * ac,bAnimListElem * ale,const bAnimChannelType * acf,uiBlock * block,int xpos,int ypos,int setting)4882 static void draw_setting_widget(bAnimContext *ac,
4883 bAnimListElem *ale,
4884 const bAnimChannelType *acf,
4885 uiBlock *block,
4886 int xpos,
4887 int ypos,
4888 int setting)
4889 {
4890 short ptrsize, butType;
4891 bool negflag;
4892 bool usetoggle = true;
4893 int flag, icon;
4894 void *ptr;
4895 const char *tooltip;
4896 uiBut *but = NULL;
4897 bool enabled;
4898
4899 /* get the flag and the pointer to that flag */
4900 flag = acf->setting_flag(ac, setting, &negflag);
4901 ptr = acf->setting_ptr(ale, setting, &ptrsize);
4902 enabled = ANIM_channel_setting_get(ac, ale, setting);
4903
4904 /* get the base icon for the setting */
4905 switch (setting) {
4906 case ACHANNEL_SETTING_VISIBLE: /* visibility eyes */
4907 // icon = ((enabled) ? ICON_HIDE_OFF : ICON_HIDE_ON);
4908 icon = ICON_HIDE_ON;
4909
4910 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
4911 tooltip = TIP_("F-Curve visibility in Graph Editor");
4912 }
4913 else if (ale->type == ANIMTYPE_GPLAYER) {
4914 tooltip = TIP_("Grease Pencil layer is visible in the viewport");
4915 }
4916 else {
4917 tooltip = TIP_("Channels are visible in Graph Editor for editing");
4918 }
4919 break;
4920
4921 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
4922 icon = ICON_UNPINNED;
4923 tooltip = TIP_("Channels are visible in Graph Editor for editing");
4924 break;
4925
4926 case ACHANNEL_SETTING_MOD_OFF: /* modifiers disabled */
4927 icon = ICON_MODIFIER_OFF;
4928 tooltip = TIP_("Enable F-Curve modifiers");
4929 break;
4930
4931 case ACHANNEL_SETTING_EXPAND: /* expanded triangle */
4932 // icon = ((enabled) ? ICON_TRIA_DOWN : ICON_TRIA_RIGHT);
4933 icon = ICON_TRIA_RIGHT;
4934 tooltip = TIP_("Make channels grouped under this channel visible");
4935 break;
4936
4937 case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */
4938 // icon = ((enabled) ? ICON_SOLO_OFF : ICON_SOLO_ON);
4939 icon = ICON_SOLO_OFF;
4940 tooltip = TIP_(
4941 "NLA Track is the only one evaluated in this animation data-block, with all others "
4942 "muted");
4943 break;
4944
4945 /* --- */
4946
4947 case ACHANNEL_SETTING_PROTECT: /* protected lock */
4948 /* TODO: what about when there's no protect needed? */
4949 // icon = ((enabled) ? ICON_LOCKED : ICON_UNLOCKED);
4950 icon = ICON_UNLOCKED;
4951
4952 if (ale->datatype != ALE_NLASTRIP) {
4953 tooltip = TIP_("Editability of keyframes for this channel");
4954 }
4955 else {
4956 tooltip = TIP_("Editability of NLA Strips in this track");
4957 }
4958 break;
4959
4960 case ACHANNEL_SETTING_MUTE: /* muted speaker */
4961 icon = ((enabled) ? ICON_CHECKBOX_DEHLT : ICON_CHECKBOX_HLT);
4962 usetoggle = false;
4963
4964 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
4965 tooltip = TIP_("Does F-Curve contribute to result");
4966 }
4967 else if ((ac) && (ac->spacetype == SPACE_NLA) && (ale->type != ANIMTYPE_NLATRACK)) {
4968 tooltip = TIP_(
4969 "Temporarily disable NLA stack evaluation (i.e. only the active action is evaluated)");
4970 }
4971 else if (ale->type == ANIMTYPE_GPLAYER) {
4972 tooltip = TIP_(
4973 "Shows all keyframes during animation playback and enabled all frames for editing "
4974 "(uncheck to use only the current keyframe during animation playback and editing)");
4975 }
4976 else {
4977 tooltip = TIP_("Do channels contribute to result (toggle channel muting)");
4978 }
4979 break;
4980
4981 case ACHANNEL_SETTING_PINNED: /* pin icon */
4982 // icon = ((enabled) ? ICON_PINNED : ICON_UNPINNED);
4983 icon = ICON_UNPINNED;
4984
4985 if (ale->type == ANIMTYPE_NLAACTION) {
4986 tooltip = TIP_("Display action without any time remapping (when unpinned)");
4987 }
4988 else {
4989 /* TODO: there are no other tools which require the 'pinning' concept yet */
4990 tooltip = NULL;
4991 }
4992 break;
4993
4994 default:
4995 tooltip = NULL;
4996 icon = 0;
4997 break;
4998 }
4999
5000 /* type of button */
5001 if (usetoggle) {
5002 if (negflag) {
5003 butType = UI_BTYPE_ICON_TOGGLE_N;
5004 }
5005 else {
5006 butType = UI_BTYPE_ICON_TOGGLE;
5007 }
5008 }
5009 else {
5010 if (negflag) {
5011 butType = UI_BTYPE_TOGGLE_N;
5012 }
5013 else {
5014 butType = UI_BTYPE_TOGGLE;
5015 }
5016 }
5017 /* draw button for setting */
5018 if (ptr && flag) {
5019 switch (ptrsize) {
5020 case sizeof(int): /* integer pointer for setting */
5021 but = uiDefIconButBitI(block,
5022 butType,
5023 flag,
5024 0,
5025 icon,
5026 xpos,
5027 ypos,
5028 ICON_WIDTH,
5029 ICON_WIDTH,
5030 ptr,
5031 0,
5032 0,
5033 0,
5034 0,
5035 tooltip);
5036 break;
5037
5038 case sizeof(short): /* short pointer for setting */
5039 but = uiDefIconButBitS(block,
5040 butType,
5041 flag,
5042 0,
5043 icon,
5044 xpos,
5045 ypos,
5046 ICON_WIDTH,
5047 ICON_WIDTH,
5048 ptr,
5049 0,
5050 0,
5051 0,
5052 0,
5053 tooltip);
5054 break;
5055
5056 case sizeof(char): /* char pointer for setting */
5057 but = uiDefIconButBitC(block,
5058 butType,
5059 flag,
5060 0,
5061 icon,
5062 xpos,
5063 ypos,
5064 ICON_WIDTH,
5065 ICON_WIDTH,
5066 ptr,
5067 0,
5068 0,
5069 0,
5070 0,
5071 tooltip);
5072 break;
5073 }
5074
5075 /* set call to send relevant notifiers and/or perform type-specific updates */
5076 if (but) {
5077 switch (setting) {
5078 /* settings needing flushing up/down hierarchy */
5079 case ACHANNEL_SETTING_VISIBLE: /* Graph Editor - 'visibility' toggles */
5080 case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
5081 case ACHANNEL_SETTING_MUTE: /* General - muting flags */
5082 case ACHANNEL_SETTING_PINNED: /* NLA Actions - 'map/nomap' */
5083 case ACHANNEL_SETTING_MOD_OFF:
5084 case ACHANNEL_SETTING_ALWAYS_VISIBLE:
5085 UI_but_funcN_set(but,
5086 achannel_setting_flush_widget_cb,
5087 MEM_dupallocN(ale),
5088 POINTER_FROM_INT(setting));
5089 break;
5090
5091 /* settings needing special attention */
5092 case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */
5093 UI_but_funcN_set(but, achannel_nlatrack_solo_widget_cb, MEM_dupallocN(ale), NULL);
5094 break;
5095
5096 /* no flushing */
5097 case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush,
5098 * otherwise all would open/close at once */
5099 default:
5100 UI_but_func_set(but, achannel_setting_widget_cb, NULL, NULL);
5101 break;
5102 }
5103
5104 if ((ale->fcurve_owner_id != NULL && ID_IS_LINKED(ale->fcurve_owner_id)) ||
5105 (ale->id != NULL && ID_IS_LINKED(ale->id))) {
5106 if (setting != ACHANNEL_SETTING_EXPAND) {
5107 UI_but_flag_enable(but, UI_BUT_DISABLED);
5108 }
5109 }
5110 }
5111 }
5112 }
5113
5114 /* Draw UI widgets the given channel */
ANIM_channel_draw_widgets(const bContext * C,bAnimContext * ac,bAnimListElem * ale,uiBlock * block,rctf * rect,size_t channel_index)5115 void ANIM_channel_draw_widgets(const bContext *C,
5116 bAnimContext *ac,
5117 bAnimListElem *ale,
5118 uiBlock *block,
5119 rctf *rect,
5120 size_t channel_index)
5121 {
5122 const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
5123 View2D *v2d = &ac->region->v2d;
5124 float ymid;
5125 const short channel_height = round_fl_to_int(BLI_rctf_size_y(rect));
5126 const bool is_being_renamed = achannel_is_being_renamed(ac, acf, channel_index);
5127
5128 /* sanity checks - don't draw anything */
5129 if (ELEM(NULL, acf, ale, block)) {
5130 return;
5131 }
5132
5133 /* get initial offset */
5134 short offset = rect->xmin;
5135 if (acf->get_offset) {
5136 offset += acf->get_offset(ac, ale);
5137 }
5138
5139 /* calculate appropriate y-coordinates for icon buttons */
5140 ymid = BLI_rctf_cent_y(rect) - 0.5f * ICON_WIDTH;
5141
5142 /* no button backdrop behind icons */
5143 UI_block_emboss_set(block, UI_EMBOSS_NONE);
5144
5145 /* step 1) draw expand widget ....................................... */
5146 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
5147 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_EXPAND);
5148 offset += ICON_WIDTH;
5149 }
5150
5151 /* step 2) draw icon ............................................... */
5152 if (acf->icon) {
5153 /* icon is not drawn here (not a widget) */
5154 offset += ICON_WIDTH;
5155 }
5156
5157 /* step 3) draw special toggles .................................
5158 * - in Graph Editor, checkboxes for visibility in curves area
5159 * - in NLA Editor, glowing dots for solo/not solo...
5160 * - in Grease Pencil mode, color swatches for layer color
5161 */
5162 if (ac->sl) {
5163 if ((ac->spacetype == SPACE_GRAPH) &&
5164 (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
5165 acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE))) {
5166 /* pin toggle */
5167 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
5168 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_ALWAYS_VISIBLE);
5169 offset += ICON_WIDTH;
5170 }
5171 /* visibility toggle */
5172 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
5173 /* For F-curves, add the extra space for the color bands. */
5174 if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
5175 offset += GRAPH_ICON_VISIBILITY_OFFSET;
5176 }
5177 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_VISIBLE);
5178 offset += ICON_WIDTH;
5179 }
5180 }
5181 else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
5182 /* 'solo' setting for NLA Tracks */
5183 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO);
5184 offset += ICON_WIDTH;
5185 }
5186 }
5187
5188 /* step 4) draw text - check if renaming widget is in use... */
5189 if (is_being_renamed) {
5190 PointerRNA ptr = {NULL};
5191 PropertyRNA *prop = NULL;
5192
5193 /* draw renaming widget if we can get RNA pointer for it
5194 * NOTE: property may only be available in some cases, even if we have
5195 * a callback available (e.g. broken F-Curve rename)
5196 */
5197 if (acf->name_prop(ale, &ptr, &prop)) {
5198 const short margin_x = 3 * round_fl_to_int(UI_DPI_FAC);
5199 const short width = ac->region->winx - offset - (margin_x * 2);
5200 uiBut *but;
5201
5202 UI_block_emboss_set(block, UI_EMBOSS);
5203
5204 but = uiDefButR(block,
5205 UI_BTYPE_TEXT,
5206 1,
5207 "",
5208 offset + margin_x,
5209 rect->ymin,
5210 MAX2(width, RENAME_TEXT_MIN_WIDTH),
5211 channel_height,
5212 &ptr,
5213 RNA_property_identifier(prop),
5214 -1,
5215 0,
5216 0,
5217 -1,
5218 -1,
5219 NULL);
5220
5221 /* copy what outliner does here, see outliner_buttons */
5222 if (UI_but_active_only(C, ac->region, block, but) == false) {
5223 ac->ads->renameIndex = 0;
5224
5225 /* send notifiers */
5226 WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
5227 }
5228
5229 UI_block_emboss_set(block, UI_EMBOSS_NONE);
5230 }
5231 else {
5232 /* Cannot get property/cannot or rename for some reason, so clear rename index
5233 * so that this doesn't hang around, and the name can be drawn normally - T47492
5234 */
5235 ac->ads->renameIndex = 0;
5236 WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
5237 }
5238 }
5239
5240 /* step 5) draw mute+protection toggles + (sliders) ....................... */
5241 /* reset offset - now goes from RHS of panel */
5242 offset = (int)rect->xmax;
5243
5244 /* TODO: when drawing sliders, make those draw instead of these toggles if not enough space. */
5245 if (v2d && !is_being_renamed) {
5246 short draw_sliders = 0;
5247
5248 /* check if we need to show the sliders */
5249 if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH)) {
5250 switch (ac->spacetype) {
5251 case SPACE_ACTION: {
5252 SpaceAction *saction = (SpaceAction *)ac->sl;
5253 draw_sliders = (saction->flag & SACTION_SLIDERS);
5254 break;
5255 }
5256 case SPACE_GRAPH: {
5257 SpaceGraph *sipo = (SpaceGraph *)ac->sl;
5258 draw_sliders = (sipo->flag & SIPO_SLIDERS);
5259 break;
5260 }
5261 }
5262 }
5263
5264 /* check if there's enough space for the toggles if the sliders are drawn too */
5265 if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) {
5266 /* protect... */
5267 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
5268 offset -= ICON_WIDTH;
5269 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_PROTECT);
5270 }
5271 /* mute... */
5272 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) {
5273 offset -= ICON_WIDTH;
5274 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MUTE);
5275 }
5276 if (ale->type == ANIMTYPE_GPLAYER) {
5277 /* Not technically "mute"
5278 * (in terms of anim channels, but this sets layer visibility instead). */
5279 offset -= ICON_WIDTH;
5280 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_VISIBLE);
5281 }
5282
5283 /* modifiers disable */
5284 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) {
5285 offset -= ICON_WIDTH;
5286 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MOD_OFF);
5287 }
5288
5289 /* ----------- */
5290
5291 /* pinned... */
5292 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED)) {
5293 offset -= ICON_WIDTH;
5294 draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_PINNED);
5295 }
5296
5297 /* NLA Action "pushdown" */
5298 if ((ale->type == ANIMTYPE_NLAACTION) && (ale->adt && ale->adt->action) &&
5299 !(ale->adt->flag & ADT_NLA_EDIT_ON)) {
5300 uiBut *but;
5301 PointerRNA *opptr_b;
5302
5303 UI_block_emboss_set(block, UI_EMBOSS);
5304
5305 offset -= UI_UNIT_X;
5306 but = uiDefIconButO(block,
5307 UI_BTYPE_BUT,
5308 "NLA_OT_action_pushdown",
5309 WM_OP_INVOKE_DEFAULT,
5310 ICON_NLA_PUSHDOWN,
5311 offset,
5312 ymid,
5313 UI_UNIT_X,
5314 UI_UNIT_X,
5315 NULL);
5316
5317 opptr_b = UI_but_operator_ptr_get(but);
5318 RNA_int_set(opptr_b, "channel_index", channel_index);
5319
5320 UI_block_emboss_set(block, UI_EMBOSS_NONE);
5321 }
5322 }
5323
5324 /* Draw slider:
5325 * - Even if we can draw sliders for this view, we must also check that the channel-type
5326 * supports them (only only F-Curves really can support them for now).
5327 * - To make things easier, we use RNA-autobuts for this so that changes are
5328 * reflected immediately, wherever they occurred.
5329 * BUT, we don't use the layout engine, otherwise we'd get wrong alignment,
5330 * and wouldn't be able to auto-keyframe.
5331 * - Slider should start before the toggles (if they're visible)
5332 * to keep a clean line down the side.
5333 * - Sliders are always drawn in Shapekey mode now. Prior to this
5334 * the SACTION_SLIDERS flag would be set when changing into Shapekey mode.
5335 */
5336 if (((draw_sliders) && ELEM(ale->type,
5337 ANIMTYPE_FCURVE,
5338 ANIMTYPE_NLACURVE,
5339 ANIMTYPE_SHAPEKEY,
5340 ANIMTYPE_GPLAYER)) ||
5341 ale->type == ANIMTYPE_SHAPEKEY) {
5342 /* adjust offset */
5343 /* TODO: make slider width dynamic,
5344 * so that they can be easier to use when the view is wide enough. */
5345 offset -= SLIDER_WIDTH;
5346
5347 /* need backdrop behind sliders... */
5348 UI_block_emboss_set(block, UI_EMBOSS);
5349
5350 if (ale->owner) { /* Slider using custom RNA Access ---------- */
5351 if (ale->type == ANIMTYPE_NLACURVE) {
5352 NlaStrip *strip = (NlaStrip *)ale->owner;
5353 FCurve *fcu = (FCurve *)ale->data;
5354 PointerRNA ptr;
5355 PropertyRNA *prop;
5356
5357 /* create RNA pointers */
5358 RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, &ptr);
5359 prop = RNA_struct_find_property(&ptr, fcu->rna_path);
5360
5361 /* create property slider */
5362 if (prop) {
5363 uiBut *but;
5364
5365 /* Create the slider button,
5366 * and assign relevant callback to ensure keyframes are inserted. */
5367 but = uiDefAutoButR(block,
5368 &ptr,
5369 prop,
5370 fcu->array_index,
5371 "",
5372 ICON_NONE,
5373 offset,
5374 ymid,
5375 SLIDER_WIDTH,
5376 channel_height);
5377 UI_but_func_set(but, achannel_setting_slider_nla_curve_cb, ale->id, ale->data);
5378 }
5379 }
5380 }
5381 else if (ale->id) { /* Slider using RNA Access --------------- */
5382 PointerRNA id_ptr, ptr;
5383 PropertyRNA *prop;
5384 char *rna_path = NULL;
5385 int array_index = 0;
5386 short free_path = 0;
5387
5388 /* get destination info */
5389 if (ale->type == ANIMTYPE_FCURVE) {
5390 FCurve *fcu = (FCurve *)ale->data;
5391
5392 rna_path = fcu->rna_path;
5393 array_index = fcu->array_index;
5394 }
5395 else if (ale->type == ANIMTYPE_SHAPEKEY) {
5396 KeyBlock *kb = (KeyBlock *)ale->data;
5397 Key *key = (Key *)ale->id;
5398
5399 rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
5400 free_path = 1;
5401 }
5402 /* Special for Grease Pencil Layer. */
5403 else if (ale->type == ANIMTYPE_GPLAYER) {
5404 bGPdata *gpd = (bGPdata *)ale->id;
5405 if ((gpd != NULL) && ((gpd->flag & GP_DATA_ANNOTATIONS) == 0)) {
5406 /* Reset slider offset, in order to add special gp icons. */
5407 offset += SLIDER_WIDTH;
5408
5409 char *gp_rna_path = NULL;
5410 bGPDlayer *gpl = (bGPDlayer *)ale->data;
5411
5412 /* Create the RNA pointers. */
5413 RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr);
5414 RNA_id_pointer_create(ale->id, &id_ptr);
5415 int icon;
5416
5417 /* Layer onion skinning switch. */
5418 offset -= ICON_WIDTH;
5419 UI_block_emboss_set(block, UI_EMBOSS_NONE);
5420 prop = RNA_struct_find_property(&ptr, "use_onion_skinning");
5421 gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop);
5422 if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) {
5423 icon = (gpl->onion_flag & GP_LAYER_ONIONSKIN) ? ICON_ONIONSKIN_ON :
5424 ICON_ONIONSKIN_OFF;
5425 uiDefAutoButR(block,
5426 &ptr,
5427 prop,
5428 array_index,
5429 "",
5430 icon,
5431 offset,
5432 ymid,
5433 ICON_WIDTH,
5434 channel_height);
5435 }
5436 MEM_freeN(gp_rna_path);
5437
5438 /* Mask Layer. */
5439 offset -= ICON_WIDTH;
5440 UI_block_emboss_set(block, UI_EMBOSS_NONE);
5441 prop = RNA_struct_find_property(&ptr, "use_mask_layer");
5442 gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop);
5443 if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) {
5444 icon = ICON_LAYER_ACTIVE;
5445 if (gpl->flag & GP_LAYER_USE_MASK) {
5446 icon = ICON_MOD_MASK;
5447 }
5448 else {
5449 icon = ICON_LAYER_ACTIVE;
5450 }
5451 uiDefAutoButR(block,
5452 &ptr,
5453 prop,
5454 array_index,
5455 "",
5456 icon,
5457 offset,
5458 ymid,
5459 ICON_WIDTH,
5460 channel_height);
5461 }
5462 MEM_freeN(gp_rna_path);
5463
5464 /* Layer opacity. */
5465 const short width = SLIDER_WIDTH * 0.6;
5466 offset -= width;
5467 UI_block_emboss_set(block, UI_EMBOSS);
5468 prop = RNA_struct_find_property(&ptr, "opacity");
5469 gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop);
5470 if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) {
5471 uiDefAutoButR(block,
5472 &ptr,
5473 prop,
5474 array_index,
5475 "",
5476 ICON_NONE,
5477 offset,
5478 ymid,
5479 width,
5480 channel_height);
5481 }
5482 MEM_freeN(gp_rna_path);
5483 }
5484 }
5485
5486 /* Only if RNA-Path found. */
5487 if (rna_path) {
5488 /* get RNA pointer, and resolve the path */
5489 RNA_id_pointer_create(ale->id, &id_ptr);
5490
5491 /* try to resolve the path */
5492 if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
5493 uiBut *but;
5494
5495 /* Create the slider button,
5496 * and assign relevant callback to ensure keyframes are inserted. */
5497 but = uiDefAutoButR(block,
5498 &ptr,
5499 prop,
5500 array_index,
5501 "",
5502 ICON_NONE,
5503 offset,
5504 ymid,
5505 SLIDER_WIDTH,
5506 channel_height);
5507
5508 /* assign keyframing function according to slider type */
5509 if (ale->type == ANIMTYPE_SHAPEKEY) {
5510 UI_but_func_set(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
5511 }
5512 else {
5513 UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data);
5514 }
5515 }
5516
5517 /* free the path if necessary */
5518 if (free_path) {
5519 MEM_freeN(rna_path);
5520 }
5521 }
5522 }
5523 else { /* Special Slider for stuff without RNA Access ---------- */
5524 /* TODO: only implement this case when we really need it... */
5525 }
5526 }
5527 }
5528 }
5529
5530 /* *********************************************** */
5531