doxygen: add newline after \file
[blender.git] / source / blender / editors / animation / anim_channels_edit.c
index 84b5983..3bcbe2d 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  *
  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
  * All rights reserved.
- *
- * Contributor(s): Joshua Leung
- *
- * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file blender/editors/animation/anim_channels_edit.c
- *  \ingroup edanimation
+/** \file
+ * \ingroup edanimation
  */
 
 
@@ -58,6 +52,7 @@
 #include "BKE_global.h"
 #include "BKE_scene.h"
 
+#include "DEG_depsgraph.h"
 #include "DEG_depsgraph_build.h"
 
 #include "UI_view2d.h"
@@ -669,7 +664,7 @@ static bool animedit_poll_channels_active(bContext *C)
        if (ELEM(NULL, sa, CTX_wm_region(C)))
                return 0;
        /* animation editor test */
-       if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_IPO, SPACE_NLA) == 0)
+       if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
                return 0;
 
        return 1;
@@ -686,7 +681,7 @@ static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
        if (ELEM(NULL, sa, CTX_wm_region(C)))
                return 0;
        /* animation editor test */
-       if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_IPO, SPACE_NLA) == 0)
+       if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
                return 0;
 
        /* NLA TweakMode test */
@@ -706,7 +701,7 @@ typedef enum eRearrangeAnimChan_Mode {
        REARRANGE_ANIMCHAN_TOP = -2,
        REARRANGE_ANIMCHAN_UP = -1,
        REARRANGE_ANIMCHAN_DOWN = 1,
-       REARRANGE_ANIMCHAN_BOTTOM = 2
+       REARRANGE_ANIMCHAN_BOTTOM = 2,
 } eRearrangeAnimChan_Mode;
 
 /* defines for rearranging channels */
@@ -715,7 +710,7 @@ static const EnumPropertyItem prop_animchannel_rearrange_types[] = {
        {REARRANGE_ANIMCHAN_UP, "UP", 0, "Up", ""},
        {REARRANGE_ANIMCHAN_DOWN, "DOWN", 0, "Down", ""},
        {REARRANGE_ANIMCHAN_BOTTOM, "BOTTOM", 0, "To Bottom", ""},
-       {0, NULL, 0, NULL, NULL}
+       {0, NULL, 0, NULL, NULL},
 };
 
 /* Reordering "Islands" Defines ----------------------------------- */
@@ -880,7 +875,8 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
                                                  Link *channel, eAnim_ChannelType type,
                                                  const bool is_hidden)
 {
-       tReorderChannelIsland *island = islands->last;  /* always try to add to last island if possible */
+       /* always try to add to last island if possible */
+       tReorderChannelIsland *island = islands->last;
        bool is_sel = false, is_untouchable = false;
 
        /* get flags - selected and untouchable from the channel */
@@ -1354,6 +1350,7 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
                        switch (ac.datatype) {
                                case ANIMCONT_NLA: /* NLA-tracks only */
                                        rearrange_nla_channels(&ac, adt, mode);
+                                       DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE);
                                        break;
 
                                case ANIMCONT_DRIVERS: /* Drivers list only */
@@ -1441,9 +1438,9 @@ static bool animchannels_grouping_poll(bContext *C)
 
                        break;
                }
-               case SPACE_IPO:
+               case SPACE_GRAPH:
                {
-                       SpaceIpo *sipo = (SpaceIpo *)sl;
+                       SpaceGraph *sipo = (SpaceGraph *)sl;
 
                        /* drivers can't have groups... */
                        if (sipo->mode != SIPO_MODE_ANIMATION)
@@ -1559,7 +1556,8 @@ static void ANIM_OT_channels_group(wmOperatorType *ot)
        ot->prop = RNA_def_string(ot->srna, "name", "New Group",
                                  sizeof(((bActionGroup *)NULL)->name),
                                  "Name", "Name of newly created group");
-       /* RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); */ /* XXX: still not too sure about this - keeping same text is confusing... */
+       /* XXX: still not too sure about this - keeping same text is confusing... */
+       // RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
 }
 
 /* ----------------------------------------------------------- */
@@ -1628,6 +1626,27 @@ static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
 
 /* ******************** Delete Channel Operator *********************** */
 
+static void update_dependencies_on_delete(bAnimListElem *ale)
+{
+       ID *id = ale->id;
+       AnimData *adt = BKE_animdata_from_id(id);
+       /* TODO(sergey): Technically, if the animation element is being deleted
+        * from a driver we don't have to tag action. This is something we can check
+        * for in the future. For now just do most reliable tag whic hwas always
+        * happening. */
+       if (adt != NULL) {
+               DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+               if (adt->action != NULL) {
+                       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+               }
+       }
+       /* Deals with NLA and drivers.
+        * Doesn't cause overhead for action updates, since object will receive
+        * animation update after dependency graph flushes update from action to
+        * all its users. */
+       DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+}
+
 static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
 {
        bAnimContext ac;
@@ -1672,8 +1691,10 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
                                }
 
                                /* free the group itself */
-                               if (adt->action)
+                               if (adt->action) {
                                        BLI_freelinkN(&adt->action->groups, agrp);
+                                       DEG_id_tag_update_ex(CTX_data_main(C), &adt->action->id, ID_RECALC_COPY_ON_WRITE);
+                               }
                                else
                                        MEM_freeN(agrp);
                        }
@@ -1698,6 +1719,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
 
                                /* try to free F-Curve */
                                ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
+                               update_dependencies_on_delete(ale);
                                break;
                        }
                        case ANIMTYPE_NLACURVE:
@@ -1719,6 +1741,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
                                /* unlink and free the F-Curve */
                                BLI_remlink(&strip->fcurves, fcu);
                                free_fcurve(fcu);
+                               update_dependencies_on_delete(ale);
                                break;
                        }
                        case ANIMTYPE_GPLAYER:
@@ -1729,6 +1752,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
 
                                /* try to delete the layer's data and the layer itself */
                                BKE_gpencil_layer_delete(gpd, gpl);
+                               ale->update = ANIM_UPDATE_DEPS;
                                break;
                        }
                        case ANIMTYPE_MASKLAYER:
@@ -1777,7 +1801,7 @@ static const EnumPropertyItem prop_animchannel_setflag_types[] = {
        {ACHANNEL_SETFLAG_CLEAR, "DISABLE", 0, "Disable", ""},
        {ACHANNEL_SETFLAG_ADD, "ENABLE", 0, "Enable", ""},
        {ACHANNEL_SETFLAG_INVERT, "INVERT", 0, "Invert", ""},
-       {0, NULL, 0, NULL, NULL}
+       {0, NULL, 0, NULL, NULL},
 };
 
 /* defines for set animation-channel settings */
@@ -1785,7 +1809,7 @@ static const EnumPropertyItem prop_animchannel_setflag_types[] = {
 static const EnumPropertyItem prop_animchannel_settings_types[] = {
        {ACHANNEL_SETTING_PROTECT, "PROTECT", 0, "Protect", ""},
        {ACHANNEL_SETTING_MUTE, "MUTE", 0, "Mute", ""},
-       {0, NULL, 0, NULL, NULL}
+       {0, NULL, 0, NULL, NULL},
 };
 
 
@@ -1821,7 +1845,7 @@ static void setflag_anim_channels(bAnimContext *ac, eAnimChannel_Settings settin
         * - but for Graph Editor, this gets used also from main region
         *   where hierarchy doesn't apply [#21276]
         */
-       if ((ac->spacetype == SPACE_IPO) && (ac->regiontype != RGN_TYPE_CHANNELS)) {
+       if ((ac->spacetype == SPACE_GRAPH) && (ac->regiontype != RGN_TYPE_CHANNELS)) {
                /* graph editor (case 2) */
                filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
        }
@@ -2200,7 +2224,7 @@ static bool animchannels_enable_poll(bContext *C)
                return 0;
 
        /* animation editor test - Action/Dopesheet/etc. and Graph only */
-       if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_IPO) == 0)
+       if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH) == 0)
                return 0;
 
        return 1;
@@ -2272,7 +2296,7 @@ static bool animchannels_find_poll(bContext *C)
                return 0;
 
        /* animation editor with dopesheet */
-       return ELEM(sa->spacetype, SPACE_ACTION, SPACE_IPO, SPACE_NLA);
+       return ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA);
 }
 
 /* find_invoke() - Get initial channels */
@@ -2731,7 +2755,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
 
                                /* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
                                if (ob != CTX_data_edit_object(C)) {
-                                       ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR);
+                                       ED_object_editmode_exit(C, EM_FREEDATA);
                                }
 
                                notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
@@ -2940,7 +2964,8 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
                                BKE_gpencil_layer_setactive(gpd, gpl);
                        }
 
-                       WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL); /* Grease Pencil updates */
+                       /* Grease Pencil updates */
+                       WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
                        notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Editors updates */
                        break;
                }
@@ -3010,17 +3035,24 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE
        v2d = &ar->v2d;
 
        /* select mode is either replace (deselect all, then add) or add/extend */
-       if (RNA_boolean_get(op->ptr, "extend"))
+       if (RNA_boolean_get(op->ptr, "extend")) {
                selectmode = SELECT_INVERT;
-       else if (RNA_boolean_get(op->ptr, "children_only"))
-               selectmode = -1;  /* this is a bit of a special case for ActionGroups only... should it be removed or extended to all instead? */
-       else
+       }
+       else if (RNA_boolean_get(op->ptr, "children_only")) {
+               /* this is a bit of a special case for ActionGroups only...
+                * should it be removed or extended to all instead? */
+               selectmode = -1;
+       }
+       else {
                selectmode = SELECT_REPLACE;
+       }
 
        /* figure out which channel user clicked in
-        * Note: although channels technically start at (y = ACHANNEL_FIRST), we need to adjust by half a channel's height
-        *       so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
-        *       ACHANNEL_HEIGHT_HALF.
+        *
+        * Note:
+        * although channels technically start at (y = ACHANNEL_FIRST),
+        * we need to adjust by half a channel's height so that the tops of channels get caught ok.
+        * Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use ACHANNEL_HEIGHT_HALF.
         */
        UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
        UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(&ac), 0, (float)ACHANNEL_HEIGHT_HALF(&ac), x, y, NULL, &channel_index);
@@ -3051,7 +3083,7 @@ static void ANIM_OT_channels_click(wmOperatorType *ot)
        ot->flag = OPTYPE_UNDO;
 
        /* properties */
-       /* NOTE: don't save settings, otherwise, can end up with some weird behaviour (sticky extend) */
+       /* NOTE: don't save settings, otherwise, can end up with some weird behavior (sticky extend) */
        prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); // SHIFTKEY
        RNA_def_property_flag(prop, PROP_SKIP_SAVE);