Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py2
-rw-r--r--source/blender/editors/include/ED_anim_api.h8
-rw-r--r--source/blender/editors/space_action/action_data.c126
-rw-r--r--source/blender/editors/space_action/action_intern.h2
-rw-r--r--source/blender/editors/space_action/action_ops.c2
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c6
-rw-r--r--source/blender/editors/space_nla/nla_channels.c46
-rw-r--r--source/blender/editors/space_nla/nla_intern.h1
-rw-r--r--source/blender/editors/space_nla/nla_ops.c1
9 files changed, 179 insertions, 15 deletions
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index c4452ee61f4..bb08a7c392e 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -118,7 +118,7 @@ class DOPESHEET_HT_header(Header):
row.operator("action.layer_prev", text="", icon='TRIA_DOWN')
row.operator("action.layer_next", text="", icon='TRIA_UP')
- layout.template_ID(st, "action", new="action.new")
+ layout.template_ID(st, "action", new="action.new", unlink="action.unlink")
row = layout.row(align=True)
row.operator("action.push_down", text="Push Down", icon='NLA_PUSHDOWN')
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 4c7c78df349..9dea66adc7c 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -676,6 +676,14 @@ void ED_operatormacros_graph(void);
void ED_operatormacros_action(void);
/* ************************************************ */
+/* Animation Editor Exports */
+/* XXX: Should we be doing these here, or at all? */
+
+/* Action Editor - Action Management */
+struct AnimData *ED_actedit_animdata_from_context(struct bContext *C);
+void ED_animedit_unlink_action(struct bContext *C, struct ID *id, struct AnimData *adt, struct bAction *act, struct ReportList *reports);
+
+/* ************************************************ */
#endif /* __ED_ANIM_API_H__ */
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index a4eadd8a63b..e55da7dd4b3 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -81,10 +81,10 @@
#include "action_intern.h"
/* ************************************************************************** */
-/* ACTION MANAGEMENT */
+/* ACTION CREATION */
/* Helper function to find the active AnimData block from the Action Editor context */
-static AnimData *actedit_animdata_from_context(bContext *C)
+AnimData *ED_actedit_animdata_from_context(bContext *C)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
Object *ob = CTX_data_active_object(C);
@@ -234,7 +234,7 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
adt = ptr.data;
}
else if (ptr.type == &RNA_SpaceDopeSheetEditor) {
- adt = actedit_animdata_from_context(C);
+ adt = ED_actedit_animdata_from_context(C);
}
/* Perform stashing operation - But only if there is an action */
@@ -301,7 +301,7 @@ static int action_pushdown_poll(bContext *C)
{
if (ED_operator_action_active(C)) {
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
/* Check for AnimData, Actions, and that tweakmode is off */
if (adt && saction->action) {
@@ -320,7 +320,7 @@ static int action_pushdown_poll(bContext *C)
static int action_pushdown_exec(bContext *C, wmOperator *op)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
/* Do the deed... */
if (adt) {
@@ -368,7 +368,7 @@ void ACTION_OT_push_down(wmOperatorType *ot)
static int action_stash_exec(bContext *C, wmOperator *op)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
/* Perform stashing operation */
if (adt) {
@@ -431,7 +431,7 @@ void ACTION_OT_stash(wmOperatorType *ot)
static int action_stash_create_poll(bContext *C)
{
if (ED_operator_action_active(C)) {
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
/* Check tweakmode is off (as you don't want to be tampering with the action in that case) */
/* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */
@@ -461,7 +461,7 @@ static int action_stash_create_poll(bContext *C)
static int action_stash_create_exec(bContext *C, wmOperator *op)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
/* Check for no action... */
if (saction->action == NULL) {
@@ -521,6 +521,108 @@ void ACTION_OT_stash_and_create(wmOperatorType *ot)
}
/* ************************************************************************** */
+/* ACTION UNLINK */
+
+/* ******************* Action Unlink Operator ******************** */
+/* We use a custom unlink operator here, as there are some technicalities which need special care:
+ * 1) When in Tweak Mode, it shouldn't be possible to unlink the active action,
+ * or else, everything turns to custard.
+ * 2) If the Action doesn't have any other users, the user should at least get
+ * a warning that it is going to get lost.
+ * 3) We need a convenient way to exit Tweak Mode from the Action Editor
+ */
+
+void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports)
+{
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* If the old action only has a single user (that it's about to lose),
+ * warn user about it
+ *
+ * TODO: Maybe we should just save it for them? But then, there's the problem of
+ * trying to get rid of stuff that's actually unwanted!
+ */
+ if (act->id.us == 1) {
+ BKE_reportf(reports, RPT_ERROR,
+ "Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
+ act->id.name + 2);
+ }
+
+ /* If in Tweak Mode, don't unlink. Instead, this
+ * becomes a shortcut to exit Tweak Mode instead
+ */
+ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
+ /* Exit Tweak Mode */
+ BKE_nla_tweakmode_exit(adt);
+
+ /* Flush this to the Action Editor (if that's where this change was initiated) */
+ if (sa->spacetype == SPACE_ACTION) {
+ actedit_change_action(C, NULL);
+ }
+ }
+ else {
+ /* Unlink normally - Setting it to NULL should be enough to get the old one unlinked */
+ if (sa->spacetype == SPACE_ACTION) {
+ /* clear action editor -> action */
+ actedit_change_action(C, NULL);
+ }
+ else {
+ /* clear AnimData -> action */
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ /* create AnimData RNA pointers */
+ RNA_pointer_create(id, &RNA_AnimData, adt, &ptr);
+ prop = RNA_struct_find_property(&ptr, "action");
+
+ /* clear... */
+ RNA_property_pointer_set(&ptr, prop, PointerRNA_NULL);
+ RNA_property_update(C, &ptr, prop);
+ }
+ }
+}
+
+/* -------------------------- */
+
+static int action_unlink_poll(bContext *C)
+{
+ if (ED_operator_action_active(C)) {
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+
+ /* Only when there's an active action, in the right modes... */
+ if (saction->action && adt)
+ return true;
+ }
+
+ /* something failed... */
+ return false;
+}
+
+static int action_unlink_exec(bContext *C, wmOperator *op)
+{
+ AnimData *adt = ED_actedit_animdata_from_context(C);
+
+ if (adt && adt->action) {
+ ED_animedit_unlink_action(C, NULL, adt, adt->action, op->reports);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void ACTION_OT_unlink(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Unlink Action";
+ ot->idname = "ACTION_OT_unlink";
+ ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
+
+ /* callbacks */
+ ot->exec = action_unlink_exec;
+ ot->poll = action_unlink_poll;
+}
+
+/* ************************************************************************** */
/* ACTION BROWSING */
/* Get the NLA Track that the active action comes from, since this is not stored in AnimData */
@@ -631,7 +733,7 @@ static int action_layer_next_poll(bContext *C)
{
/* Action Editor's action editing modes only */
if (ED_operator_action_active(C)) {
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
if (adt) {
/* only allow if we're in tweakmode, and there's something above us... */
if (adt->flag & ADT_NLA_EDIT_ON) {
@@ -665,7 +767,7 @@ static int action_layer_next_poll(bContext *C)
static int action_layer_next_exec(bContext *C, wmOperator *op)
{
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
NlaTrack *act_track;
Scene *scene = CTX_data_scene(C);
@@ -742,7 +844,7 @@ static int action_layer_prev_poll(bContext *C)
{
/* Action Editor's action editing modes only */
if (ED_operator_action_active(C)) {
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
if (adt) {
if (adt->flag & ADT_NLA_EDIT_ON) {
/* Tweak Mode: We need to check if there are any tracks below the active one that we can move to */
@@ -775,7 +877,7 @@ static int action_layer_prev_poll(bContext *C)
static int action_layer_prev_exec(bContext *C, wmOperator *op)
{
- AnimData *adt = actedit_animdata_from_context(C);
+ AnimData *adt = ED_actedit_animdata_from_context(C);
NlaTrack *act_track;
NlaTrack *nlt;
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 3b0da089b9b..9f9b15c3c26 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -98,6 +98,8 @@ void ACTION_OT_snap(struct wmOperatorType *ot);
void ACTION_OT_mirror(struct wmOperatorType *ot);
void ACTION_OT_new(struct wmOperatorType *ot);
+void ACTION_OT_unlink(struct wmOperatorType *ot);
+
void ACTION_OT_push_down(struct wmOperatorType *ot);
void ACTION_OT_stash(struct wmOperatorType *ot);
void ACTION_OT_stash_and_create(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 431dd27d064..9ad0931a957 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -79,6 +79,8 @@ void action_operatortypes(void)
WM_operatortype_append(ACTION_OT_paste);
WM_operatortype_append(ACTION_OT_new);
+ WM_operatortype_append(ACTION_OT_unlink);
+
WM_operatortype_append(ACTION_OT_push_down);
WM_operatortype_append(ACTION_OT_stash);
WM_operatortype_append(ACTION_OT_stash_and_create);
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 66023ce1243..1fb7228dd98 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -159,7 +159,9 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
}
/* AnimData pointer */
- RNA_pointer_create(id, &RNA_AnimData, ale->adt, adt_ptr);
+ if (adt_ptr) {
+ RNA_pointer_create(id, &RNA_AnimData, ale->adt, adt_ptr);
+ }
/* set found status to -1, since setting to 1 would break the loop
* and potentially skip an active NLA-Track in some cases...
@@ -282,7 +284,7 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
/* Active Action Properties ------------------------------------- */
/* action */
row = uiLayoutRow(layout, true);
- uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACTION_OT_new", NULL, NULL /*"ACTION_OT_unlink"*/); // XXX: need to make these operators
+ uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACTION_OT_new", NULL, "NLA_OT_action_unlink");
/* extrapolation */
row = uiLayoutRow(layout, true);
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 5476d1c2683..70d9bfe99fe 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -504,6 +504,52 @@ void NLA_OT_action_pushdown(wmOperatorType *ot)
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
}
+/* ******************** Action Unlink ******************************** */
+
+static int nla_action_unlink_poll(bContext *C)
+{
+ if (ED_operator_nla_active(C)) {
+ return nla_panel_context(C, NULL, NULL, NULL);
+ }
+
+ /* something failed... */
+ return false;
+}
+
+static int nla_action_unlink_exec(bContext *C, wmOperator *op)
+{
+ PointerRNA adt_ptr;
+ AnimData *adt;
+
+ /* check context and also validity of pointer */
+ if (!nla_panel_context(C, &adt_ptr, NULL, NULL))
+ return OPERATOR_CANCELLED;
+
+ /* get animdata */
+ adt = adt_ptr.data;
+ if (adt == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* do unlinking */
+ if (adt && adt->action) {
+ ED_animedit_unlink_action(C, adt_ptr.id.data, adt, adt->action, op->reports);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void NLA_OT_action_unlink(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Unlink Action";
+ ot->idname = "NLA_OT_action_unlink";
+ ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
+
+ /* callbacks */
+ ot->exec = nla_action_unlink_exec;
+ ot->poll = nla_action_unlink_poll;
+}
+
/* ******************** Add Tracks Operator ***************************** */
/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index bd96b5a4de5..70fdb2d478d 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -137,6 +137,7 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac);
void NLA_OT_channels_click(wmOperatorType *ot);
void NLA_OT_action_pushdown(wmOperatorType *ot);
+void NLA_OT_action_unlink(wmOperatorType *ot);
void NLA_OT_tracks_add(wmOperatorType *ot);
void NLA_OT_tracks_delete(wmOperatorType *ot);
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index b3a875047db..43bc4b9df0f 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -114,6 +114,7 @@ void nla_operatortypes(void)
WM_operatortype_append(NLA_OT_channels_click);
WM_operatortype_append(NLA_OT_action_pushdown);
+ WM_operatortype_append(NLA_OT_action_unlink);
WM_operatortype_append(NLA_OT_tracks_add);
WM_operatortype_append(NLA_OT_tracks_delete);