Blender V5.0
nla_tracks.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors, Joshua Leung. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdio>
10#include <cstdlib>
11#include <cstring>
12
13#include "DNA_anim_types.h"
14#include "DNA_object_types.h"
15#include "DNA_scene_types.h"
16
17#include "BLI_listbase.h"
18
19#include "BKE_anim_data.hh"
20#include "BKE_context.hh"
21#include "BKE_global.hh"
22#include "BKE_layer.hh"
23#include "BKE_nla.hh"
24#include "BKE_report.hh"
25
26#include "ANIM_action.hh"
27
28#include "ED_anim_api.hh"
29#include "ED_keyframes_edit.hh"
30#include "ED_object.hh"
31#include "ED_screen.hh"
32
33#include "RNA_access.hh"
34#include "RNA_define.hh"
35
36#include "WM_api.hh"
37#include "WM_types.hh"
38
39#include "DEG_depsgraph.hh"
41
42#include "UI_view2d.hh"
43
44#include "nla_intern.hh" /* own include */
45
46/* *********************************************** */
47/* Operators for NLA track-list which need to be different
48 * from the standard Animation Editor ones */
49
50/* ******************** Mouse-Click Operator *********************** */
51/* Depending on the track that was clicked on, the mouse click will activate whichever
52 * part of the track is relevant.
53 *
54 * NOTE: eventually,
55 * this should probably be phased out when many of these things are replaced with buttons
56 * --> Most tracks are now selection only.
57 */
58
59static int mouse_nla_tracks(bContext *C, bAnimContext *ac, int track_index, short selectmode)
60{
61 ListBase anim_data = {nullptr, nullptr};
62
63 int notifierFlags = 0;
64
65 /* get the track that was clicked on */
66 /* filter tracks */
69 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
70
71 /* get track from index */
72 bAnimListElem *ale = static_cast<bAnimListElem *>(BLI_findlink(&anim_data, track_index));
73 if (ale == nullptr) {
74 /* track not found */
75 if (G.debug & G_DEBUG) {
76 printf("Error: animation track (index = %d) not found in mouse_nla_tracks()\n", track_index);
77 }
78
79 ANIM_animdata_freelist(&anim_data);
80 return 0;
81 }
82
83 /* action to take depends on what track we've got */
84 /* WARNING: must keep this in sync with the equivalent function in `anim_channels_edit.cc`. */
85 switch (ale->type) {
86 case ANIMTYPE_SCENE: {
87 Scene *sce = static_cast<Scene *>(ale->data);
88 AnimData *adt = sce->adt;
89
90 /* set selection status */
91 if (selectmode == SELECT_INVERT) {
92 /* swap select */
93 sce->flag ^= SCE_DS_SELECTED;
94 if (adt) {
95 adt->flag ^= ADT_UI_SELECTED;
96 }
97 }
98 else {
99 sce->flag |= SCE_DS_SELECTED;
100 if (adt) {
101 adt->flag |= ADT_UI_SELECTED;
102 }
103 }
104
105 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
106 break;
107 }
108 case ANIMTYPE_OBJECT: {
109 ViewLayer *view_layer = ac->view_layer;
110 Base *base = static_cast<Base *>(ale->data);
111 Object *ob = base->object;
112 AnimData *adt = ob->adt;
113
114 if (nlaedit_is_tweakmode_on(ac) == 0 && (base->flag & BASE_SELECTABLE)) {
115 /* set selection status */
116 if (selectmode == SELECT_INVERT) {
117 /* swap select */
119
120 if (adt) {
121 adt->flag ^= ADT_UI_SELECTED;
122 }
123 }
124 else {
125 /* deselect all */
126 /* TODO: should this deselect all other types of tracks too? */
127 BKE_view_layer_synced_ensure(ac->scene, view_layer);
130 if (b->object->adt) {
131 b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
132 }
133 }
134
135 /* select object now */
137 if (adt) {
138 adt->flag |= ADT_UI_SELECTED;
139 }
140 }
141
142 /* change active object - regardless of whether it is now selected [#37883] */
144
145 if ((adt) && (adt->flag & ADT_UI_SELECTED)) {
146 adt->flag |= ADT_UI_ACTIVE;
147 }
148
149 /* notifiers - track was selected */
150 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
151 }
152 break;
153 }
154 case ANIMTYPE_FILLACTD: /* Action Expander */
155 case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
156 case ANIMTYPE_DSLAM:
157 case ANIMTYPE_DSCAM:
159 case ANIMTYPE_DSCUR:
160 case ANIMTYPE_DSSKEY:
161 case ANIMTYPE_DSWOR:
162 case ANIMTYPE_DSNTREE:
163 case ANIMTYPE_DSPART:
164 case ANIMTYPE_DSMBALL:
165 case ANIMTYPE_DSARM:
166 case ANIMTYPE_DSMESH:
167 case ANIMTYPE_DSTEX:
168 case ANIMTYPE_DSLAT:
170 case ANIMTYPE_DSSPK:
172 case ANIMTYPE_PALETTE:
173 case ANIMTYPE_DSHAIR:
177 /* sanity checking... */
178 if (ale->adt) {
179 /* select/deselect */
180 if (selectmode == SELECT_INVERT) {
181 /* inverse selection status of this AnimData block only */
182 ale->adt->flag ^= ADT_UI_SELECTED;
183 }
184 else {
185 /* select AnimData block by itself */
187 ale->adt->flag |= ADT_UI_SELECTED;
188 }
189
190 /* set active? */
191 if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) {
192 ale->adt->flag |= ADT_UI_ACTIVE;
193 }
194 }
195
196 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
197 break;
198 }
199 case ANIMTYPE_NLATRACK: {
200 NlaTrack *nlt = static_cast<NlaTrack *>(ale->data);
201
202 if (nlaedit_is_tweakmode_on(ac) == 0) {
203 /* set selection */
204 if (selectmode == SELECT_INVERT) {
205 /* inverse selection status of this F-Curve only */
206 nlt->flag ^= NLATRACK_SELECTED;
207 }
208 else {
209 /* select F-Curve by itself */
211 nlt->flag |= NLATRACK_SELECTED;
212 }
213
214 /* if NLA-Track is selected now,
215 * make NLA-Track the 'active' one in the visible list */
216 if (nlt->flag & NLATRACK_SELECTED) {
219 }
220
221 /* notifier flags - track was selected */
222 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
223 }
224 break;
225 }
226 case ANIMTYPE_NLAACTION: {
227 AnimData *adt = BKE_animdata_from_id(ale->id);
228
229 /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
230 * - this is useful when there's no clear divider, and makes more sense in
231 * the case of users trying to use this to change actions
232 * - in tweak-mode, clicking here gets us out of tweak-mode, as changing selection
233 * while in tweak-mode is really evil!
234 * - we disable "solo" flags too, to make it easier to work with stashed actions
235 * with less trouble
236 */
237 if (nlaedit_is_tweakmode_on(ac)) {
238 /* Exit tweak-mode immediately. */
240
241 /* changes to NLA-Action occurred */
242 notifierFlags |= ND_NLA_ACTCHANGE;
243 ale->update |= ANIM_UPDATE_DEPS;
244 }
245 else {
246 /* select/deselect */
247 if (selectmode == SELECT_INVERT) {
248 /* inverse selection status of this AnimData block only */
249 adt->flag ^= ADT_UI_SELECTED;
250 }
251 else {
252 /* select AnimData block by itself */
254 adt->flag |= ADT_UI_SELECTED;
255 }
256
257 /* set active? */
258 if (adt->flag & ADT_UI_SELECTED) {
259 adt->flag |= ADT_UI_ACTIVE;
260 }
261
262 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
263 }
264 break;
265 }
268 /* The NLA doesn't support layered Actions. */
269 break;
270 default:
271 if (G.debug & G_DEBUG) {
272 printf("Error: Invalid track type in mouse_nla_tracks()\n");
273 }
274 break;
275 }
276
277 /* free tracks */
278 ANIM_animdata_update(ac, &anim_data);
279 ANIM_animdata_freelist(&anim_data);
280
281 /* return the notifier-flags set */
282 return notifierFlags;
283}
284
285/* ------------------- */
286
287/* handle clicking */
289 wmOperator *op,
290 const wmEvent *event)
291{
292 bAnimContext ac;
293 ARegion *region;
294 View2D *v2d;
295 int track_index;
296 int notifierFlags = 0;
297 short selectmode;
298 float x, y;
299
300 /* get editor data */
301 if (ANIM_animdata_get_context(C, &ac) == 0) {
302 return OPERATOR_CANCELLED;
303 }
304
305 /* get useful pointers from animation context data */
306 SpaceNla *snla = reinterpret_cast<SpaceNla *>(ac.sl);
307 region = ac.region;
308 v2d = &region->v2d;
309
310 /* select mode is either replace (deselect all, then add) or add/extend */
311 if (RNA_boolean_get(op->ptr, "extend")) {
312 selectmode = SELECT_INVERT;
313 }
314 else {
315 selectmode = SELECT_REPLACE;
316 }
317
318 /* Figure out which track user clicked in. */
319 UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
321 NLATRACK_STEP(snla),
322 0,
324 x,
325 y,
326 nullptr,
327 &track_index);
328
329 /* handle mouse-click in the relevant track then */
330 notifierFlags = mouse_nla_tracks(C, &ac, track_index, selectmode);
331
332 /* set notifier that things have changed */
333 WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, nullptr);
334
335 return OPERATOR_FINISHED;
336}
337
339{
340 PropertyRNA *prop;
341
342 /* identifiers */
343 ot->name = "Mouse Click on NLA Tracks";
344 ot->idname = "NLA_OT_channels_click";
345 ot->description = "Handle clicks to select NLA tracks";
346
347 /* API callbacks. */
350
351 /* flags */
352 ot->flag = OPTYPE_UNDO;
353
354 /* props */
355 prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); /* SHIFTKEY */
357}
358
359/* *********************************************** */
360/* Special Operators */
361
362/* ******************** Action Push Down ******************************** */
363
365{
366 bAnimContext ac;
367 ID *id = nullptr;
368 AnimData *adt = nullptr;
369 int track_index = RNA_int_get(op->ptr, "track_index");
370
371 /* get editor data */
372 if (ANIM_animdata_get_context(C, &ac) == 0) {
373 return OPERATOR_CANCELLED;
374 }
375
376 /* get anim-channel to use (or more specifically, the animdata block behind it) */
377 if (track_index == -1) {
378 PointerRNA adt_ptr = {};
379
380 /* active animdata block */
381 if (nla_panel_context(C, &adt_ptr, nullptr, nullptr) == 0 || (adt_ptr.data == nullptr)) {
383 RPT_ERROR,
384 "No active AnimData block to use "
385 "(select a data-block expander first or set the appropriate flags on an AnimData "
386 "block)");
387 return OPERATOR_CANCELLED;
388 }
389
390 id = adt_ptr.owner_id;
391 adt = static_cast<AnimData *>(adt_ptr.data);
392 }
393 else {
394 /* indexed track */
395 ListBase anim_data = {nullptr, nullptr};
396
397 /* filter tracks */
400 ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype));
401
402 /* get track from index */
403 bAnimListElem *ale = static_cast<bAnimListElem *>(BLI_findlink(&anim_data, track_index));
404 if (ale == nullptr) {
405 BKE_reportf(op->reports, RPT_ERROR, "No animation track found at index %d", track_index);
406 ANIM_animdata_freelist(&anim_data);
407 return OPERATOR_CANCELLED;
408 }
409 if (ale->type != ANIMTYPE_NLAACTION) {
411 RPT_ERROR,
412 "Animation track at index %d is not a NLA 'Active Action' track",
413 track_index);
414 ANIM_animdata_freelist(&anim_data);
415 return OPERATOR_CANCELLED;
416 }
417
418 /* grab AnimData from the track */
419 adt = ale->adt;
420 id = ale->id;
421
422 /* we don't need anything here anymore, so free it all */
423 ANIM_animdata_freelist(&anim_data);
424 }
425
426 /* double-check that we are free to push down here... */
427 if (adt == nullptr) {
428 BKE_report(op->reports, RPT_WARNING, "Internal Error - AnimData block is not valid");
429 return OPERATOR_CANCELLED;
430 }
431 if (nlaedit_is_tweakmode_on(&ac)) {
434 "Cannot push down actions while tweaking a strip's action, exit tweak mode first");
435 return OPERATOR_CANCELLED;
436 }
437
438 bAction *action_to_push_down = adt->action;
439 if (!action_to_push_down) {
440 BKE_report(op->reports, RPT_WARNING, "No active action to push down");
441 return OPERATOR_CANCELLED;
442 }
443
444 /* 'push-down' action - only usable when not in Tweak-mode. */
446
447 Main *bmain = CTX_data_main(C);
449
450 /* The action needs updating too, as FCurve modifiers are to be reevaluated. They won't extend
451 * beyond the NLA strip after pushing down to the NLA. */
452 DEG_id_tag_update_ex(bmain, &action_to_push_down->id, ID_RECALC_ANIMATION);
453
454 /* set notifier that things have changed */
456 return OPERATOR_FINISHED;
457}
458
460{
461 /* identifiers */
462 ot->name = "Push Down Action";
463 ot->idname = "NLA_OT_action_pushdown";
464 ot->description = "Push action down onto the top of the NLA stack as a new strip";
465
466 /* callbacks */
469
470 /* flags */
472
473 /* properties */
474 ot->prop = RNA_def_int(ot->srna,
475 "track_index",
476 -1,
477 -1,
478 INT_MAX,
479 "Track Index",
480 "Index of NLA action track to perform pushdown operation on",
481 0,
482 INT_MAX);
484}
485
486/* ******************** Action Unlink ******************************** */
487
489{
491 PointerRNA adt_ptr;
492 return (nla_panel_context(C, &adt_ptr, nullptr, nullptr) && (adt_ptr.data != nullptr));
493 }
494
495 /* something failed... */
496 return false;
497}
498
500{
501 PointerRNA adt_ptr;
502
503 /* check context and also validity of pointer */
504 if (!nla_panel_context(C, &adt_ptr, nullptr, nullptr)) {
505 return OPERATOR_CANCELLED;
506 }
507
508 /* get animdata */
509 AnimData *adt = static_cast<AnimData *>(adt_ptr.data);
510 if (adt == nullptr) {
511 return OPERATOR_CANCELLED;
512 }
513
514 /* do unlinking */
515 if (adt->action) {
516 bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
517 ED_animedit_unlink_action(C, adt_ptr.owner_id, adt, adt->action, op->reports, force_delete);
518 }
519
520 return OPERATOR_FINISHED;
521}
522
524{
525 /* NOTE: this is hardcoded to match the behavior for the unlink button
526 * (in `interface_templates.cc`). */
527 RNA_boolean_set(op->ptr, "force_delete", event->modifier & KM_SHIFT);
528 return nla_action_unlink_exec(C, op);
529}
530
532{
533 PropertyRNA *prop;
534
535 /* identifiers */
536 ot->name = "Unlink Action";
537 ot->idname = "NLA_OT_action_unlink";
538 ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
539
540 /* callbacks */
544
545 /* properties */
546 prop = RNA_def_boolean(ot->srna,
547 "force_delete",
548 false,
549 "Force Delete",
550 "Clear Fake User and remove copy stashed in this data-block's NLA stack");
552}
553
554/* ******************** Add Tracks Operator ***************************** */
555/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
556
558{
559 ListBase anim_data = {nullptr, nullptr};
560 AnimData *lastAdt = nullptr;
561 bool added = false;
562
563 /* get a list of the (selected) NLA Tracks being shown in the NLA */
566 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
567
568 /* add tracks... */
569 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
570 if (ale->type == ANIMTYPE_NLATRACK) {
571 NlaTrack *nlt = static_cast<NlaTrack *>(ale->data);
572 AnimData *adt = ale->adt;
573 NlaTrack *new_track = nullptr;
574
575 const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
576
577 /* check if just adding a new track above this one,
578 * or whether we're adding a new one to the top of the stack that this one belongs to
579 */
580 if (above_sel) {
581 /* just add a new one above this one */
582 new_track = BKE_nlatrack_new_after(&adt->nla_tracks, nlt, is_liboverride);
583 BKE_nlatrack_set_active(&adt->nla_tracks, new_track);
584 ale->update = ANIM_UPDATE_DEPS;
585 added = true;
586 }
587 else if ((lastAdt == nullptr) || (adt != lastAdt)) {
588 /* add one track to the top of the owning AnimData's stack,
589 * then don't add anymore to this stack */
590 new_track = BKE_nlatrack_new_tail(&adt->nla_tracks, is_liboverride);
591 BKE_nlatrack_set_active(&adt->nla_tracks, new_track);
592 lastAdt = adt;
593 ale->update = ANIM_UPDATE_DEPS;
594 added = true;
595 }
596 }
597 }
598
599 /* free temp data */
600 ANIM_animdata_update(ac, &anim_data);
601 ANIM_animdata_freelist(&anim_data);
602
603 return added;
604}
605
607{
608 ListBase anim_data = {nullptr, nullptr};
609
610 bool added = false;
611
612 /* get a list of the selected AnimData blocks in the NLA */
616 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
617
618 /* check if selected AnimData blocks are empty, and add tracks if so... */
619 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
620 AnimData *adt = ale->adt;
621 NlaTrack *new_track;
622
623 /* sanity check */
625
626 /* ensure it is empty */
628 /* add new track to this AnimData block then */
629 new_track = BKE_nlatrack_new_tail(&adt->nla_tracks, ID_IS_OVERRIDE_LIBRARY(ale->id));
630 BKE_nlatrack_set_active(&adt->nla_tracks, new_track);
631 ale->update = ANIM_UPDATE_DEPS;
632 added = true;
633 }
634 }
635
636 /* cleanup */
637 ANIM_animdata_update(ac, &anim_data);
638 ANIM_animdata_freelist(&anim_data);
639
640 return added;
641}
642
643/* ----- */
644
646{
647 bAnimContext ac;
648 bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
649 bool op_done = false;
650
651 /* get editor data */
652 if (ANIM_animdata_get_context(C, &ac) == 0) {
653 return OPERATOR_CANCELLED;
654 }
655
656 /* perform adding in two passes - existing first so that we don't double up for empty */
657 op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
658 op_done |= nlaedit_add_tracks_empty(&ac);
659
660 /* done? */
661 if (op_done) {
663
664 /* set notifier that things have changed */
666
667 /* done */
668 return OPERATOR_FINISHED;
669 }
670
671 /* failed to add any tracks */
673 op->reports, RPT_WARNING, "Select an existing NLA Track or an empty action line first");
674
675 /* not done */
676 return OPERATOR_CANCELLED;
677}
678
680{
681 /* identifiers */
682 ot->name = "Add Tracks";
683 ot->idname = "NLA_OT_tracks_add";
684 ot->description = "Add NLA-Tracks above/after the selected tracks";
685
686 /* API callbacks. */
689
690 /* flags */
692
693 /* properties */
694 RNA_def_boolean(ot->srna,
695 "above_selected",
696 false,
697 "Above Selected",
698 "Add a new NLA Track above every existing selected one");
699}
700
701/* ******************** Delete Tracks Operator ***************************** */
702/* Delete selected NLA Tracks */
703
705{
706 bAnimContext ac;
707
708 ListBase anim_data = {nullptr, nullptr};
709
710 /* get editor data */
711 if (ANIM_animdata_get_context(C, &ac) == 0) {
712 return OPERATOR_CANCELLED;
713 }
714
715 /* get a list of the AnimData blocks being shown in the NLA */
718 ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype));
719
720 /* delete tracks */
721 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
722 if (ale->type == ANIMTYPE_NLATRACK) {
723 NlaTrack *nlt = static_cast<NlaTrack *>(ale->data);
724 AnimData *adt = ale->adt;
725
726 if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
727 /* No deletion of non-local tracks of override data. */
728 continue;
729 }
730
731 /* if track is currently 'solo', then AnimData should have its
732 * 'has solo' flag disabled
733 */
734 if (nlt->flag & NLATRACK_SOLO) {
736 }
737
738 /* call delete on this track - deletes all strips too */
740 ale->update = ANIM_UPDATE_DEPS;
741 }
742 }
743
744 /* free temp data */
745 ANIM_animdata_update(&ac, &anim_data);
746 ANIM_animdata_freelist(&anim_data);
747
749
750 /* set notifier that things have changed */
752
753 /* done */
754 return OPERATOR_FINISHED;
755}
756
758{
759 /* identifiers */
760 ot->name = "Delete Tracks";
761 ot->idname = "NLA_OT_tracks_delete";
762 ot->description = "Delete selected NLA-Tracks and the strips they contain";
763
764 /* API callbacks. */
767
768 /* flags */
770}
771
772/* *********************************************** */
773/* AnimData Related Operators */
774
775/* ******************** Include Objects Operator ***************************** */
776/* Include selected objects in NLA Editor, by giving them AnimData blocks
777 * NOTE: This doesn't help for non-object AnimData, where we do not have any effective
778 * selection mechanism in place. Unfortunately, this means that non-object AnimData
779 * once again becomes a second-class citizen here. However, at least for the most
780 * common use case, we now have a nice shortcut again.
781 */
782
784{
785 bAnimContext ac;
786
787 /* get editor data */
788 if (ANIM_animdata_get_context(C, &ac) == 0) {
789 return OPERATOR_CANCELLED;
790 }
791
792 /* ensure that filters are set so that the effect will be immediately visible */
793 SpaceNla *snla = reinterpret_cast<SpaceNla *>(ac.sl);
794 if (snla && snla->ads) {
796 }
797
798 /* operate on selected objects... */
799 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
800 /* ensure that object has AnimData... that's all */
801 BKE_animdata_ensure_id(&ob->id);
802 }
804
805 /* set notifier that things have changed */
807
808 /* done */
809 return OPERATOR_FINISHED;
810}
811
813{
814 /* identifiers */
815 ot->name = "Include Selected Objects";
816 ot->idname = "NLA_OT_selected_objects_add";
817 ot->description = "Make selected objects appear in NLA Editor by adding Animation Data";
818
819 /* API callbacks. */
822
823 /* flags */
825}
826
827/* *********************************************** */
Functions and classes to work with Actions.
AnimData * BKE_animdata_ensure_id(ID *id)
Definition anim_data.cc:97
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
#define CTX_DATA_BEGIN(C, Type, instance, member)
Main * CTX_data_main(const bContext *C)
#define CTX_DATA_END
@ G_DEBUG
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void BKE_nla_action_pushdown(OwnedAnimData owned_adt, bool is_liboverride)
void BKE_nlatrack_set_active(ListBase *tracks, NlaTrack *nlt)
NlaTrack * BKE_nlatrack_new_after(ListBase *nla_tracks, NlaTrack *prev, bool is_liboverride)
NlaTrack * BKE_nlatrack_new_tail(ListBase *nla_tracks, const bool is_liboverride)
bool BKE_nlatrack_is_nonlocal_in_liboverride(const ID *id, const NlaTrack *nlt)
void BKE_nlatrack_remove_and_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
@ RPT_WARNING
Definition BKE_report.hh:38
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert(a)
Definition BLI_assert.h:46
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1077
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
@ ADS_FILTER_NLA_NOACT
@ ADT_NLA_SOLO_TRACK
@ ADT_UI_ACTIVE
@ ADT_UI_SELECTED
@ NLATRACK_SOLO
@ NLATRACK_SELECTED
Object is a sort of wrapper for general info.
@ SCE_DS_SELECTED
#define BASE_SELECTABLE(v3d, base)
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ ACHANNEL_SETFLAG_CLEAR
@ ANIMTYPE_DSSPK
@ ANIMTYPE_DSTEX
@ ANIMTYPE_DSNTREE
@ ANIMTYPE_DSMBALL
@ ANIMTYPE_DSCAM
@ ANIMTYPE_DSLIGHTPROBE
@ ANIMTYPE_DSPOINTCLOUD
@ ANIMTYPE_DSPART
@ ANIMTYPE_DSLINESTYLE
@ ANIMTYPE_ACTION_SLOT
@ ANIMTYPE_DSCUR
@ ANIMTYPE_SCENE
@ ANIMTYPE_DSARM
@ ANIMTYPE_DSGPENCIL
@ ANIMTYPE_DSLAT
@ ANIMTYPE_NLAACTION
@ ANIMTYPE_DSMAT
@ ANIMTYPE_DSCACHEFILE
@ ANIMTYPE_DSVOLUME
@ ANIMTYPE_DSLAM
@ ANIMTYPE_PALETTE
@ ANIMTYPE_FILLACT_LAYERED
@ ANIMTYPE_FILLACTD
@ ANIMTYPE_OBJECT
@ ANIMTYPE_DSMESH
@ ANIMTYPE_NLATRACK
@ ANIMTYPE_DSWOR
@ ANIMTYPE_DSSKEY
@ ANIMTYPE_DSHAIR
#define NLATRACK_FIRST_TOP(ac)
#define NLATRACK_STEP(snla)
@ ANIM_UPDATE_DEPS
eAnimCont_Types
void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports, bool force_delete)
#define NLATRACK_NAMEWIDTH
eAnimFilter_Flags
@ ANIMFILTER_ANIMDATA
@ ANIMFILTER_DATA_VISIBLE
@ ANIMFILTER_LIST_VISIBLE
@ ANIMFILTER_LIST_CHANNELS
@ ANIMFILTER_NODUPLIS
@ ANIMFILTER_FCURVESONLY
@ ANIMFILTER_SEL
@ SELECT_INVERT
@ SELECT_REPLACE
bool ED_operator_nla_active(bContext *C)
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
@ PROP_HIDDEN
Definition RNA_types.hh:338
#define C
Definition RandGen.cpp:29
void UI_view2d_listview_view_to_cell(float columnwidth, float rowheight, float startx, float starty, float viewx, float viewy, int *r_column, int *r_row)
Definition view2d.cc:1621
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
Definition view2d.cc:1668
#define ND_NLA_ACTCHANGE
Definition WM_types.hh:498
@ KM_SHIFT
Definition WM_types.hh:278
#define NC_ANIMATION
Definition WM_types.hh:388
#define NA_ADDED
Definition WM_types.hh:586
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define NA_EDITED
Definition WM_types.hh:584
#define NA_REMOVED
Definition WM_types.hh:587
#define ND_NLA
Definition WM_types.hh:497
#define ND_ANIMCHAN
Definition WM_types.hh:496
#define NA_SELECTED
Definition WM_types.hh:589
void ANIM_anim_channels_select_set(bAnimContext *ac, eAnimChannels_SetFlag sel)
void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datatype, eAnimFilter_Flags filter, void *channel_data, eAnim_ChannelType channel_type)
void ANIM_animdata_freelist(ListBase *anim_data)
Definition anim_deps.cc:463
void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
Definition anim_deps.cc:356
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, const eAnimFilter_Flags filter_mode, void *data, const eAnimCont_Types datatype)
#define filter
#define printf(...)
DEG_id_tag_update_ex(cb_data->bmain, cb_data->owner_id, ID_RECALC_TAG_FOR_UNDO|ID_RECALC_SYNC_TO_EVAL)
#define G(x, y, z)
void base_select(Base *base, eObjectSelect_Mode mode)
void base_activate_with_mode_exit_if_needed(bContext *C, Base *base)
bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr)
bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
Definition nla_edit.cc:220
bool nlaedit_is_tweakmode_on(bAnimContext *ac)
Definition nla_ops.cc:71
bool nlaop_poll_tweakmode_off(bContext *C)
Definition nla_ops.cc:27
static int mouse_nla_tracks(bContext *C, bAnimContext *ac, int track_index, short selectmode)
Definition nla_tracks.cc:59
static wmOperatorStatus nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void NLA_OT_selected_objects_add(wmOperatorType *ot)
void NLA_OT_tracks_delete(wmOperatorType *ot)
void NLA_OT_tracks_add(wmOperatorType *ot)
static bool nla_action_unlink_poll(bContext *C)
void NLA_OT_action_unlink(wmOperatorType *ot)
void NLA_OT_channels_click(wmOperatorType *ot)
static wmOperatorStatus nlaedit_delete_tracks_exec(bContext *C, wmOperator *)
static wmOperatorStatus nlaedit_objects_add_exec(bContext *C, wmOperator *)
static wmOperatorStatus nlatracks_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus nlatracks_pushdown_exec(bContext *C, wmOperator *op)
static wmOperatorStatus nla_action_unlink_exec(bContext *C, wmOperator *op)
void NLA_OT_action_pushdown(wmOperatorType *ot)
bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
bool nlaedit_add_tracks_empty(bAnimContext *ac)
static wmOperatorStatus nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
bAction * action
ListBase nla_tracks
short flag
struct Object * object
Definition DNA_ID.h:414
struct AnimData * adt
ID * owner_id
Definition RNA_types.hh:51
void * data
Definition RNA_types.hh:53
struct AnimData * adt
struct bDopeSheet * ads
SpaceLink * sl
eAnimCont_Types datatype
ViewLayer * view_layer
ARegion * region
AnimData * adt
eAnim_ChannelType type
eAnim_Update_Flags update
wmEventModifierFlag modifier
Definition WM_types.hh:774
int mval[2]
Definition WM_types.hh:763
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4237