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:
authorJoshua Leung <aligorith@gmail.com>2015-04-04 01:36:46 +0300
committerJoshua Leung <aligorith@gmail.com>2015-04-04 01:37:06 +0300
commit53f4aa78175307e75e6a9c6deb6fb7f1caf766f9 (patch)
tree431fed49f98aee0023b9bffdbd3fb72b81d822e1 /source/blender/editors
parent34c4133daf01cd7b2b94bc54b3b78de21b3091b9 (diff)
WIP: Added dedicated operator for unlinking actions from the Action Editor (NLA buttons support to come)
After looking into this more carefully, I've found that we do in fact need a dedicate operator to add some custom logic when trying to unlink an action from the editor/datablocks. Specifically, this new operator does the following: 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 4) If none of the above apply, we can just unlink normally This commit implements this for the Action Editor, with stubs for the NLA Editor too. Those will be fixed next.
Diffstat (limited to 'source/blender/editors')
-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
8 files changed, 178 insertions, 14 deletions
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);